brintos

brintos / linux-shallow public Read only

0
0
Text · 6.0 KiB · 1e2b1e4 Raw
248 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2013 Broadcom Corporation4 */5/*********************channel spec common functions*********************/6 7#include <linux/module.h>8 9#include <brcmu_utils.h>10#include <brcmu_wifi.h>11#include <brcmu_d11.h>12 13static u16 d11n_sb(enum brcmu_chan_sb sb)14{15	switch (sb) {16	case BRCMU_CHAN_SB_NONE:17		return BRCMU_CHSPEC_D11N_SB_N;18	case BRCMU_CHAN_SB_L:19		return BRCMU_CHSPEC_D11N_SB_L;20	case BRCMU_CHAN_SB_U:21		return BRCMU_CHSPEC_D11N_SB_U;22	default:23		WARN_ON(1);24	}25	return 0;26}27 28static u16 d11n_bw(enum brcmu_chan_bw bw)29{30	switch (bw) {31	case BRCMU_CHAN_BW_20:32		return BRCMU_CHSPEC_D11N_BW_20;33	case BRCMU_CHAN_BW_40:34		return BRCMU_CHSPEC_D11N_BW_40;35	default:36		WARN_ON(1);37	}38	return 0;39}40 41static void brcmu_d11n_encchspec(struct brcmu_chan *ch)42{43	if (ch->bw == BRCMU_CHAN_BW_20)44		ch->sb = BRCMU_CHAN_SB_NONE;45 46	ch->chspec = 0;47	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,48			BRCMU_CHSPEC_CH_SHIFT, ch->chnum);49	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,50			0, d11n_sb(ch->sb));51	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,52			0, d11n_bw(ch->bw));53 54	if (ch->chnum <= CH_MAX_2G_CHANNEL)55		ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;56	else57		ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;58}59 60static u16 d11ac_bw(enum brcmu_chan_bw bw)61{62	switch (bw) {63	case BRCMU_CHAN_BW_20:64		return BRCMU_CHSPEC_D11AC_BW_20;65	case BRCMU_CHAN_BW_40:66		return BRCMU_CHSPEC_D11AC_BW_40;67	case BRCMU_CHAN_BW_80:68		return BRCMU_CHSPEC_D11AC_BW_80;69	case BRCMU_CHAN_BW_160:70		return BRCMU_CHSPEC_D11AC_BW_160;71	default:72		WARN_ON(1);73	}74	return 0;75}76 77static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)78{79	if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)80		ch->sb = BRCMU_CHAN_SB_L;81 82	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,83			BRCMU_CHSPEC_CH_SHIFT, ch->chnum);84	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,85			BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);86	brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,87			0, d11ac_bw(ch->bw));88 89	ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;90	if (ch->chnum <= CH_MAX_2G_CHANNEL)91		ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;92	else93		ch->chspec |= BRCMU_CHSPEC_D11AC_BND_5G;94}95 96static void brcmu_d11n_decchspec(struct brcmu_chan *ch)97{98	u16 val;99 100	ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);101	ch->control_ch_num = ch->chnum;102 103	switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {104	case BRCMU_CHSPEC_D11N_BW_20:105		ch->bw = BRCMU_CHAN_BW_20;106		ch->sb = BRCMU_CHAN_SB_NONE;107		break;108	case BRCMU_CHSPEC_D11N_BW_40:109		ch->bw = BRCMU_CHAN_BW_40;110		val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK;111		if (val == BRCMU_CHSPEC_D11N_SB_L) {112			ch->sb = BRCMU_CHAN_SB_L;113			ch->control_ch_num -= CH_10MHZ_APART;114		} else {115			ch->sb = BRCMU_CHAN_SB_U;116			ch->control_ch_num += CH_10MHZ_APART;117		}118		break;119	default:120		WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);121		break;122	}123 124	switch (ch->chspec & BRCMU_CHSPEC_D11N_BND_MASK) {125	case BRCMU_CHSPEC_D11N_BND_5G:126		ch->band = BRCMU_CHAN_BAND_5G;127		break;128	case BRCMU_CHSPEC_D11N_BND_2G:129		ch->band = BRCMU_CHAN_BAND_2G;130		break;131	default:132		WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);133		break;134	}135}136 137static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)138{139	u16 val;140 141	ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);142	ch->control_ch_num = ch->chnum;143 144	switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {145	case BRCMU_CHSPEC_D11AC_BW_20:146		ch->bw = BRCMU_CHAN_BW_20;147		ch->sb = BRCMU_CHAN_SB_NONE;148		break;149	case BRCMU_CHSPEC_D11AC_BW_40:150		ch->bw = BRCMU_CHAN_BW_40;151		val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK;152		if (val == BRCMU_CHSPEC_D11AC_SB_L) {153			ch->sb = BRCMU_CHAN_SB_L;154			ch->control_ch_num -= CH_10MHZ_APART;155		} else if (val == BRCMU_CHSPEC_D11AC_SB_U) {156			ch->sb = BRCMU_CHAN_SB_U;157			ch->control_ch_num += CH_10MHZ_APART;158		} else {159			WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);160		}161		break;162	case BRCMU_CHSPEC_D11AC_BW_80:163		ch->bw = BRCMU_CHAN_BW_80;164		ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,165					 BRCMU_CHSPEC_D11AC_SB_SHIFT);166		switch (ch->sb) {167		case BRCMU_CHAN_SB_LL:168			ch->control_ch_num -= CH_30MHZ_APART;169			break;170		case BRCMU_CHAN_SB_LU:171			ch->control_ch_num -= CH_10MHZ_APART;172			break;173		case BRCMU_CHAN_SB_UL:174			ch->control_ch_num += CH_10MHZ_APART;175			break;176		case BRCMU_CHAN_SB_UU:177			ch->control_ch_num += CH_30MHZ_APART;178			break;179		default:180			WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);181			break;182		}183		break;184	case BRCMU_CHSPEC_D11AC_BW_160:185		ch->bw = BRCMU_CHAN_BW_160;186		ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,187					 BRCMU_CHSPEC_D11AC_SB_SHIFT);188		switch (ch->sb) {189		case BRCMU_CHAN_SB_LLL:190			ch->control_ch_num -= CH_70MHZ_APART;191			break;192		case BRCMU_CHAN_SB_LLU:193			ch->control_ch_num -= CH_50MHZ_APART;194			break;195		case BRCMU_CHAN_SB_LUL:196			ch->control_ch_num -= CH_30MHZ_APART;197			break;198		case BRCMU_CHAN_SB_LUU:199			ch->control_ch_num -= CH_10MHZ_APART;200			break;201		case BRCMU_CHAN_SB_ULL:202			ch->control_ch_num += CH_10MHZ_APART;203			break;204		case BRCMU_CHAN_SB_ULU:205			ch->control_ch_num += CH_30MHZ_APART;206			break;207		case BRCMU_CHAN_SB_UUL:208			ch->control_ch_num += CH_50MHZ_APART;209			break;210		case BRCMU_CHAN_SB_UUU:211			ch->control_ch_num += CH_70MHZ_APART;212			break;213		default:214			WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);215			break;216		}217		break;218	case BRCMU_CHSPEC_D11AC_BW_8080:219	default:220		WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);221		break;222	}223 224	switch (ch->chspec & BRCMU_CHSPEC_D11AC_BND_MASK) {225	case BRCMU_CHSPEC_D11AC_BND_5G:226		ch->band = BRCMU_CHAN_BAND_5G;227		break;228	case BRCMU_CHSPEC_D11AC_BND_2G:229		ch->band = BRCMU_CHAN_BAND_2G;230		break;231	default:232		WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);233		break;234	}235}236 237void brcmu_d11_attach(struct brcmu_d11inf *d11inf)238{239	if (d11inf->io_type == BRCMU_D11N_IOTYPE) {240		d11inf->encchspec = brcmu_d11n_encchspec;241		d11inf->decchspec = brcmu_d11n_decchspec;242	} else {243		d11inf->encchspec = brcmu_d11ac_encchspec;244		d11inf->decchspec = brcmu_d11ac_decchspec;245	}246}247EXPORT_SYMBOL(brcmu_d11_attach);248