xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/include/bcmwifi_channels.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Misc utility routines for WL and Apps
3*4882a593Smuzhiyun  * This header file housing the define and function prototype use by
4*4882a593Smuzhiyun  * both the wl driver, tools & Apps.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2020, Broadcom.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      Unless you and Broadcom execute a separate written software license
9*4882a593Smuzhiyun  * agreement governing use of this software, this software is licensed to you
10*4882a593Smuzhiyun  * under the terms of the GNU General Public License version 2 (the "GPL"),
11*4882a593Smuzhiyun  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12*4882a593Smuzhiyun  * following added to such license:
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *      As a special exception, the copyright holders of this software give you
15*4882a593Smuzhiyun  * permission to link this software with independent modules, and to copy and
16*4882a593Smuzhiyun  * distribute the resulting executable under terms of your choice, provided that
17*4882a593Smuzhiyun  * you also meet, for each linked independent module, the terms and conditions of
18*4882a593Smuzhiyun  * the license of that module.  An independent module is a module which is not
19*4882a593Smuzhiyun  * derived from this software.  The special exception does not apply to any
20*4882a593Smuzhiyun  * modifications of the software.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * <<Broadcom-WL-IPTag/Dual:>>
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #ifndef	_bcmwifi_channels_h_
27*4882a593Smuzhiyun #define	_bcmwifi_channels_h_
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* A chanspec holds the channel number, band, bandwidth and primary 20MHz sub-band */
30*4882a593Smuzhiyun typedef uint16 chanspec_t;
31*4882a593Smuzhiyun typedef uint16 chanspec_band_t;
32*4882a593Smuzhiyun typedef uint16 chanspec_bw_t;
33*4882a593Smuzhiyun typedef uint16 chanspec_subband_t;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* channel defines */
36*4882a593Smuzhiyun #define CH_80MHZ_APART                   16u
37*4882a593Smuzhiyun #define CH_40MHZ_APART                    8u
38*4882a593Smuzhiyun #define CH_20MHZ_APART                    4u
39*4882a593Smuzhiyun #define CH_10MHZ_APART                    2u
40*4882a593Smuzhiyun #define CH_5MHZ_APART                     1u    /* 2G band channels are 5 Mhz apart */
41*4882a593Smuzhiyun #define CH_160MHZ_APART                  (32u * CH_5MHZ_APART)	/* 32 5Mhz-spaces */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define CH_MIN_2G_CHANNEL                 1u    /* Min channel in 2G band */
44*4882a593Smuzhiyun #define CH_MAX_2G_CHANNEL                14u    /* Max channel in 2G band */
45*4882a593Smuzhiyun #define CH_MIN_2G_40M_CHANNEL             3u    /* Min 40MHz center channel in 2G band */
46*4882a593Smuzhiyun #define CH_MAX_2G_40M_CHANNEL            11u    /* Max 40MHz center channel in 2G band */
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define CH_MIN_6G_CHANNEL                 1u    /* Min 20MHz channel in 6G band */
49*4882a593Smuzhiyun #define CH_MAX_6G_CHANNEL               253u    /* Max 20MHz channel in 6G band */
50*4882a593Smuzhiyun #define CH_MIN_6G_40M_CHANNEL             3u    /* Min 40MHz center channel in 6G band */
51*4882a593Smuzhiyun #define CH_MAX_6G_40M_CHANNEL           227u    /* Max 40MHz center channel in 6G band */
52*4882a593Smuzhiyun #define CH_MIN_6G_80M_CHANNEL             7u    /* Min 80MHz center channel in 6G band */
53*4882a593Smuzhiyun #define CH_MAX_6G_80M_CHANNEL           215u    /* Max 80MHz center channel in 6G band */
54*4882a593Smuzhiyun #define CH_MIN_6G_160M_CHANNEL           15u    /* Min 160MHz center channel in 6G band */
55*4882a593Smuzhiyun #define CH_MAX_6G_160M_CHANNEL          207u    /* Max 160MHz center channel in 6G band */
56*4882a593Smuzhiyun #define CH_MIN_6G_240M_CHANNEL		 23u	/* Min 240MHz center channel in 6G band */
57*4882a593Smuzhiyun #define CH_MAX_6G_240M_CHANNEL		167u	/* Max 240MHz center channel in 6G band */
58*4882a593Smuzhiyun #define CH_MIN_6G_320M_CHANNEL           31u    /* Min 320MHz center channel in 6G band */
59*4882a593Smuzhiyun #define CH_MAX_6G_320M_CHANNEL          199u    /* Max 320MHz center channel in 6G band */
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* maximum # channels the s/w supports */
62*4882a593Smuzhiyun #define MAXCHANNEL                      254u    /* max # supported channels.
63*4882a593Smuzhiyun 						 * DO NOT MAKE > 255: channels are uint8's all over
64*4882a593Smuzhiyun 						 */
65*4882a593Smuzhiyun #define MAXCHANNEL_NUM	(MAXCHANNEL - 1)	/* max channel number */
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define INVCHANNEL                      255u    /* error value for a bad channel */
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* length of channel vector bitmap is the MAXCHANNEL we want to handle rounded up to a byte */
70*4882a593Smuzhiyun /* The actual CHANVEC_LEN fix is leading to high static memory impact
71*4882a593Smuzhiyun * in all projects wherein the previous CHANVEC_LEN definition is used.
72*4882a593Smuzhiyun *
73*4882a593Smuzhiyun * Retaining the previous definition under MAXCHNL_ROM_COMPAT flag.
74*4882a593Smuzhiyun * All those chip porgrams where memory impact is observed need to define the same.
75*4882a593Smuzhiyun */
76*4882a593Smuzhiyun #ifdef MAXCHNL_ROM_COMPAT
77*4882a593Smuzhiyun #define CHANVEC_LEN (MAXCHANNEL + (8 - 1) / 8)
78*4882a593Smuzhiyun #else
79*4882a593Smuzhiyun #define CHANVEC_LEN ((MAXCHANNEL + (8 - 1)) / 8)
80*4882a593Smuzhiyun #endif
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /* channel bitvec */
83*4882a593Smuzhiyun typedef struct {
84*4882a593Smuzhiyun 	uint8   vec[CHANVEC_LEN];   /* bitvec of channels */
85*4882a593Smuzhiyun } chanvec_t;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /* make sure channel num is within valid range */
88*4882a593Smuzhiyun #define CH_NUM_VALID_RANGE(ch_num) ((ch_num) > 0 && (ch_num) <= MAXCHANNEL_NUM)
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun #define CHSPEC_CTLOVLP(sp1, sp2, sep)	\
91*4882a593Smuzhiyun 	((uint)ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (uint)(sep))
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun /* All builds use the new 11ac ratespec/chanspec */
94*4882a593Smuzhiyun #undef  D11AC_IOTYPES
95*4882a593Smuzhiyun #define D11AC_IOTYPES
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* For contiguous channel bandwidth other than 240MHz/320Mhz */
98*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN_MASK		0x00ffu
99*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN_SHIFT		0u
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /* For contiguous channel bandwidth >= 240MHz */
102*4882a593Smuzhiyun #define WL_CHANSPEC_GE240_CHAN_MASK	0x0003u
103*4882a593Smuzhiyun #define WL_CHANSPEC_GE240_CHAN_SHIFT	0u
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /* For discontiguous channel bandwidth */
106*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN0_MASK		0x000fu
107*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN0_SHIFT		0u
108*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN1_MASK		0x00f0u
109*4882a593Smuzhiyun #define WL_CHANSPEC_CHAN1_SHIFT		4u
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /* Non-320/Non-240 Mhz channel sideband indication */
112*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_MASK		0x0700u
113*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_SHIFT	8u
114*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LLL		0x0000u
115*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LLU		0x0100u
116*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LUL		0x0200u
117*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LUU		0x0300u
118*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_ULL		0x0400u
119*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_ULU		0x0500u
120*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_UUL		0x0600u
121*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_UUU		0x0700u
122*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LL		WL_CHANSPEC_CTL_SB_LLL
123*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LU		WL_CHANSPEC_CTL_SB_LLU
124*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_UL		WL_CHANSPEC_CTL_SB_LUL
125*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_UU		WL_CHANSPEC_CTL_SB_LUU
126*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_L		WL_CHANSPEC_CTL_SB_LLL
127*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_U		WL_CHANSPEC_CTL_SB_LLU
128*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_LOWER	WL_CHANSPEC_CTL_SB_LLL
129*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_UPPER	WL_CHANSPEC_CTL_SB_LLU
130*4882a593Smuzhiyun #define WL_CHANSPEC_CTL_SB_NONE		WL_CHANSPEC_CTL_SB_LLL
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* channel sideband indication for frequency >= 240MHz */
133*4882a593Smuzhiyun #define WL_CHANSPEC_GE240_SB_MASK	0x0780u
134*4882a593Smuzhiyun #define WL_CHANSPEC_GE240_SB_SHIFT	7u
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /* Bandwidth field */
137*4882a593Smuzhiyun #define WL_CHANSPEC_BW_MASK		0x3800u
138*4882a593Smuzhiyun #define WL_CHANSPEC_BW_SHIFT		11u
139*4882a593Smuzhiyun #define WL_CHANSPEC_BW_320		0x0000u
140*4882a593Smuzhiyun #define WL_CHANSPEC_BW_160160		0x0800u
141*4882a593Smuzhiyun #define WL_CHANSPEC_BW_20		0x1000u
142*4882a593Smuzhiyun #define WL_CHANSPEC_BW_40		0x1800u
143*4882a593Smuzhiyun #define WL_CHANSPEC_BW_80		0x2000u
144*4882a593Smuzhiyun #define WL_CHANSPEC_BW_160		0x2800u
145*4882a593Smuzhiyun #define WL_CHANSPEC_BW_8080		0x3000u
146*4882a593Smuzhiyun #define WL_CHANSPEC_BW_240		0x3800u
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /* Band field */
149*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_MASK		0xc000u
150*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_SHIFT		14u
151*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_2G		0x0000u
152*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_6G		0x4000u
153*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_4G		0x8000u
154*4882a593Smuzhiyun #define WL_CHANSPEC_BAND_5G		0xc000u
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun #define INVCHANSPEC			255u
157*4882a593Smuzhiyun #define MAX_CHANSPEC			0xFFFFu
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun #define WL_CHSPEC_BW(chspec)	((chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT)
160*4882a593Smuzhiyun #define MAX_BW_NUM		(uint8)(((WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT))
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #define WL_CHANNEL_BAND(ch)	(((uint)(ch) <= CH_MAX_2G_CHANNEL) ? \
163*4882a593Smuzhiyun 				 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun /* channel defines */
166*4882a593Smuzhiyun #define LOWER_20_SB(channel)		(((channel) > CH_10MHZ_APART) ? \
167*4882a593Smuzhiyun 					((channel) - CH_10MHZ_APART) : 0)
168*4882a593Smuzhiyun #define UPPER_20_SB(channel)		(((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
169*4882a593Smuzhiyun 					((channel) + CH_10MHZ_APART) : 0)
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /* pass a 80MHz channel number (uint8) to get respective LL, UU, LU, UL */
172*4882a593Smuzhiyun #define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0)
173*4882a593Smuzhiyun #define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \
174*4882a593Smuzhiyun 			   ((channel) + 3 * CH_10MHZ_APART) : 0)
175*4882a593Smuzhiyun #define LU_20_SB(channel) LOWER_20_SB(channel)
176*4882a593Smuzhiyun #define UL_20_SB(channel) UPPER_20_SB(channel)
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun #define LOWER_40_SB(channel)		((channel) - CH_20MHZ_APART)
179*4882a593Smuzhiyun #define UPPER_40_SB(channel)		((channel) + CH_20MHZ_APART)
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun #ifndef CHSPEC_WLCBANDUNIT
182*4882a593Smuzhiyun #define CHSPEC_WLCBANDUNIT(chspec) \
183*4882a593Smuzhiyun 	((CHSPEC_IS5G(chspec) || CHSPEC_IS6G(chspec)) ? BAND_5G_INDEX : BAND_2G_INDEX)
184*4882a593Smuzhiyun #endif
185*4882a593Smuzhiyun #define CH20MHZ_CHSPEC(channel)		(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
186*4882a593Smuzhiyun 						     WL_CHANNEL_BAND(channel))
187*4882a593Smuzhiyun #define NEXT_20MHZ_CHAN(channel)	(((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
188*4882a593Smuzhiyun 					((channel) + CH_20MHZ_APART) : 0)
189*4882a593Smuzhiyun #define CH40MHZ_CHSPEC(channel, ctlsb)	(chanspec_t) \
190*4882a593Smuzhiyun 					((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
191*4882a593Smuzhiyun 					 WL_CHANNEL_BAND(channel))
192*4882a593Smuzhiyun #define CH80MHZ_CHSPEC(channel, ctlsb)	(chanspec_t) \
193*4882a593Smuzhiyun 					((channel) | (ctlsb) | \
194*4882a593Smuzhiyun 					 WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
195*4882a593Smuzhiyun #define CH160MHZ_CHSPEC(channel, ctlsb)	(chanspec_t) \
196*4882a593Smuzhiyun 					((channel) | (ctlsb) | \
197*4882a593Smuzhiyun 					 WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun /* simple MACROs to get different fields of chanspec */
200*4882a593Smuzhiyun #define CHSPEC_CHANNEL(chspec)	((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
201*4882a593Smuzhiyun #define CHSPEC_CHAN0(chspec)	(((chspec) & WL_CHANSPEC_CHAN0_MASK) >> WL_CHANSPEC_CHAN0_SHIFT)
202*4882a593Smuzhiyun #define CHSPEC_CHAN1(chspec)	(((chspec) & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT)
203*4882a593Smuzhiyun #define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
204*4882a593Smuzhiyun #define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
205*4882a593Smuzhiyun #define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
206*4882a593Smuzhiyun #define CHSPEC_GE240_CHAN(chspec)	(((chspec) & WL_CHANSPEC_GE240_CHAN_MASK) >> \
207*4882a593Smuzhiyun 					WL_CHANSPEC_GE240_CHAN_SHIFT)
208*4882a593Smuzhiyun #define CHSPEC_GE240_SB(chspec)	((chspec) & WL_CHANSPEC_GE240_SB_MASK)
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #define CHSPEC_IS20(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
211*4882a593Smuzhiyun #define CHSPEC_IS20_5G(chspec)	((((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \
212*4882a593Smuzhiyun 				 CHSPEC_IS5G(chspec))
213*4882a593Smuzhiyun #ifndef CHSPEC_IS40
214*4882a593Smuzhiyun #define CHSPEC_IS40(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
215*4882a593Smuzhiyun #endif
216*4882a593Smuzhiyun #ifndef CHSPEC_IS80
217*4882a593Smuzhiyun #define CHSPEC_IS80(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
218*4882a593Smuzhiyun #endif
219*4882a593Smuzhiyun #ifndef CHSPEC_IS160
220*4882a593Smuzhiyun #define CHSPEC_IS160(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
221*4882a593Smuzhiyun #endif
222*4882a593Smuzhiyun #define CHSPEC_IS8080(chspec)	(FALSE)
223*4882a593Smuzhiyun #ifndef CHSPEC_IS320
224*4882a593Smuzhiyun #ifdef WL11BE
225*4882a593Smuzhiyun #define CHSPEC_IS320(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_320)
226*4882a593Smuzhiyun #else
227*4882a593Smuzhiyun #define CHSPEC_IS320(chspec)	(FALSE)
228*4882a593Smuzhiyun #endif
229*4882a593Smuzhiyun #endif /* CHSPEC_IS320 */
230*4882a593Smuzhiyun #ifndef CHSPEC_IS240
231*4882a593Smuzhiyun #ifdef WL11BE
232*4882a593Smuzhiyun #define CHSPEC_IS240(chspec)    (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_240)
233*4882a593Smuzhiyun #else
234*4882a593Smuzhiyun #define CHSPEC_IS240(chspec)	(FALSE)
235*4882a593Smuzhiyun #endif
236*4882a593Smuzhiyun #endif /* CHSPEC_IS240 */
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* pass a center channel and get channel offset from it by 10MHz */
239*4882a593Smuzhiyun #define CH_OFF_10MHZ_MULTIPLES(channel, offset)				\
240*4882a593Smuzhiyun ((uint8) (((offset) < 0) ?						\
241*4882a593Smuzhiyun 	  (((channel) > (WL_CHANSPEC_CHAN_MASK & ((uint16)((-(offset)) * CH_10MHZ_APART)))) ? \
242*4882a593Smuzhiyun 	   ((channel) + (offset) * CH_10MHZ_APART) : 0) :		\
243*4882a593Smuzhiyun 	  ((((uint16)(channel) + (uint16)(offset) * CH_10MHZ_APART) < (uint16)MAXCHANNEL) ? \
244*4882a593Smuzhiyun 	   ((channel) + (offset) * CH_10MHZ_APART) : 0)))
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun uint wf_chspec_first_20_sb(chanspec_t chspec);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun #if defined(WL_BW160MHZ)
249*4882a593Smuzhiyun /* pass a 160MHz center channel to get 20MHz subband channel numbers */
250*4882a593Smuzhiyun #define LLL_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel, -7)
251*4882a593Smuzhiyun #define LLU_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel, -5)
252*4882a593Smuzhiyun #define LUL_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel, -3)
253*4882a593Smuzhiyun #define LUU_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel, -1)
254*4882a593Smuzhiyun #define ULL_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel,  1)
255*4882a593Smuzhiyun #define ULU_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel,  3)
256*4882a593Smuzhiyun #define UUL_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel,  5)
257*4882a593Smuzhiyun #define UUU_20_SB_160(channel)  CH_OFF_10MHZ_MULTIPLES(channel,  7)
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun /* get lowest 20MHz sideband of a given chspec
260*4882a593Smuzhiyun  * (works with 20, 40, 80, 160)
261*4882a593Smuzhiyun  */
262*4882a593Smuzhiyun #define CH_FIRST_20_SB(chspec)  ((uint8) (\
263*4882a593Smuzhiyun 		CHSPEC_IS160(chspec) ? LLL_20_SB_160(CHSPEC_CHANNEL(chspec)) : (\
264*4882a593Smuzhiyun 			CHSPEC_IS80(chspec) ? LL_20_SB(CHSPEC_CHANNEL(chspec)) : (\
265*4882a593Smuzhiyun 				CHSPEC_IS40(chspec) ? LOWER_20_SB(CHSPEC_CHANNEL(chspec)) : \
266*4882a593Smuzhiyun 					CHSPEC_CHANNEL(chspec)))))
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun /* get upper most 20MHz sideband of a given chspec
269*4882a593Smuzhiyun  * (works with 20, 40, 80, 160)
270*4882a593Smuzhiyun  */
271*4882a593Smuzhiyun #define CH_LAST_20_SB(chspec)  ((uint8) (\
272*4882a593Smuzhiyun 		CHSPEC_IS160(chspec) ? UUU_20_SB_160(CHSPEC_CHANNEL(chspec)) : (\
273*4882a593Smuzhiyun 			CHSPEC_IS80(chspec) ? UU_20_SB(CHSPEC_CHANNEL(chspec)) : (\
274*4882a593Smuzhiyun 				CHSPEC_IS40(chspec) ? UPPER_20_SB(CHSPEC_CHANNEL(chspec)) : \
275*4882a593Smuzhiyun 					CHSPEC_CHANNEL(chspec)))))
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun /* call this with chspec and a valid 20MHz sideband of this channel to get the next 20MHz sideband
278*4882a593Smuzhiyun  * (works with 20, 40, 80, 160)
279*4882a593Smuzhiyun  * resolves to 0 if called with upper most channel
280*4882a593Smuzhiyun  */
281*4882a593Smuzhiyun #define CH_NEXT_20_SB(chspec, channel)  ((uint8) (\
282*4882a593Smuzhiyun 			((uint8) ((channel) + CH_20MHZ_APART) > CH_LAST_20_SB(chspec) ? 0 : \
283*4882a593Smuzhiyun 				((channel) + CH_20MHZ_APART))))
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun #else /* WL_BW160MHZ */
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun #define LLL_20_SB_160(channel)  0
288*4882a593Smuzhiyun #define LLU_20_SB_160(channel)  0
289*4882a593Smuzhiyun #define LUL_20_SB_160(channel)  0
290*4882a593Smuzhiyun #define LUU_20_SB_160(channel)  0
291*4882a593Smuzhiyun #define ULL_20_SB_160(channel)  0
292*4882a593Smuzhiyun #define ULU_20_SB_160(channel)  0
293*4882a593Smuzhiyun #define UUL_20_SB_160(channel)  0
294*4882a593Smuzhiyun #define UUU_20_SB_160(channel)  0
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun /* get lowest 20MHz sideband of a given chspec
297*4882a593Smuzhiyun  * (works with 20, 40, 80)
298*4882a593Smuzhiyun  */
299*4882a593Smuzhiyun #define CH_FIRST_20_SB(chspec)  ((uint8) (\
300*4882a593Smuzhiyun 			CHSPEC_IS80(chspec) ? LL_20_SB(CHSPEC_CHANNEL(chspec)) : (\
301*4882a593Smuzhiyun 				CHSPEC_IS40(chspec) ? LOWER_20_SB(CHSPEC_CHANNEL(chspec)) : \
302*4882a593Smuzhiyun 					CHSPEC_CHANNEL(chspec))))
303*4882a593Smuzhiyun /* get upper most 20MHz sideband of a given chspec
304*4882a593Smuzhiyun  * (works with 20, 40, 80, 160)
305*4882a593Smuzhiyun  */
306*4882a593Smuzhiyun #define CH_LAST_20_SB(chspec)  ((uint8) (\
307*4882a593Smuzhiyun 			CHSPEC_IS80(chspec) ? UU_20_SB(CHSPEC_CHANNEL(chspec)) : (\
308*4882a593Smuzhiyun 				CHSPEC_IS40(chspec) ? UPPER_20_SB(CHSPEC_CHANNEL(chspec)) : \
309*4882a593Smuzhiyun 					CHSPEC_CHANNEL(chspec))))
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun /* call this with chspec and a valid 20MHz sideband of this channel to get the next 20MHz sideband
312*4882a593Smuzhiyun  * (works with 20, 40, 80, 160)
313*4882a593Smuzhiyun  * resolves to 0 if called with upper most channel
314*4882a593Smuzhiyun  */
315*4882a593Smuzhiyun #define CH_NEXT_20_SB(chspec, channel)  ((uint8) (\
316*4882a593Smuzhiyun 			((uint8) ((channel) + CH_20MHZ_APART) > CH_LAST_20_SB(chspec) ? 0 : \
317*4882a593Smuzhiyun 				((channel) + CH_20MHZ_APART))))
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun #endif /* WL_BW160MHZ */
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* Iterator for 20MHz side bands of a chanspec: (chanspec_t chspec, uint8 channel)
322*4882a593Smuzhiyun  * 'chspec' chanspec_t of interest (used in loop, better to pass a resolved value than a macro)
323*4882a593Smuzhiyun  * 'channel' must be a variable (not an expression).
324*4882a593Smuzhiyun  */
325*4882a593Smuzhiyun #define FOREACH_20_SB(chspec, channel) \
326*4882a593Smuzhiyun 	for (channel = (uint8)wf_chspec_first_20_sb(chspec); channel;	\
327*4882a593Smuzhiyun 			channel = CH_NEXT_20_SB((chspec), channel))
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun /* Uses iterator to populate array with all side bands involved (sorted lower to upper).
330*4882a593Smuzhiyun  *     'chspec' chanspec_t of interest
331*4882a593Smuzhiyun  *     'psb' pointer to uint8 array of enough size to hold all side bands for the given chspec
332*4882a593Smuzhiyun  */
333*4882a593Smuzhiyun #define GET_ALL_SB(chspec, psb) do { \
334*4882a593Smuzhiyun 		uint8 channel, idx = 0; \
335*4882a593Smuzhiyun 		chanspec_t chspec_local = chspec; \
336*4882a593Smuzhiyun 		FOREACH_20_SB(chspec_local, channel) \
337*4882a593Smuzhiyun 			(psb)[idx++] = channel; \
338*4882a593Smuzhiyun } while (0)
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun /* given a chanspec of any bw, tests if primary20 SB is in lower 20, 40, 80 respectively */
341*4882a593Smuzhiyun #define IS_CTL_IN_L20(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_U) /* CTL SB is in low 20 of any 40 */
342*4882a593Smuzhiyun #define IS_CTL_IN_L40(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_UL)	/* in low 40 of any 80 */
343*4882a593Smuzhiyun #define IS_CTL_IN_L80(chspec) !((chspec) & WL_CHANSPEC_CTL_SB_ULL)	/* in low 80 of 160 */
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun #define BW_LE40(bw)		((bw) == WL_CHANSPEC_BW_20 || ((bw) == WL_CHANSPEC_BW_40))
346*4882a593Smuzhiyun #define BW_LE80(bw)		(BW_LE40(bw) || ((bw) == WL_CHANSPEC_BW_80))
347*4882a593Smuzhiyun #define BW_LE160(bw)		(BW_LE80(bw) || ((bw) == WL_CHANSPEC_BW_160))
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun #define CHSPEC_IS6G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_6G)
350*4882a593Smuzhiyun #define CHSPEC_IS5G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
351*4882a593Smuzhiyun #define CHSPEC_IS2G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
352*4882a593Smuzhiyun #define CHSPEC_SB_UPPER(chspec)	\
353*4882a593Smuzhiyun 	((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
354*4882a593Smuzhiyun 	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
355*4882a593Smuzhiyun #define CHSPEC_SB_LOWER(chspec)	\
356*4882a593Smuzhiyun 	((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
357*4882a593Smuzhiyun 	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun #ifdef WL_6G_BAND
360*4882a593Smuzhiyun #define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS2G(chspec) ? WLC_BAND_2G : CHSPEC_IS5G(chspec) ? \
361*4882a593Smuzhiyun 	WLC_BAND_5G : WLC_BAND_6G)
362*4882a593Smuzhiyun #else
363*4882a593Smuzhiyun #define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS2G(chspec) ? WLC_BAND_2G : WLC_BAND_5G)
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun #define CHSPEC_BW_CHANGED(prev_chspec, curr_chspec) \
367*4882a593Smuzhiyun 	(((prev_chspec) & WL_CHANSPEC_BW_MASK) != ((curr_chspec) & WL_CHANSPEC_BW_MASK))
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun #if (defined(WL_BAND6G) && !defined(WL_BAND6G_DISABLED))
370*4882a593Smuzhiyun #define CHSPEC_IS_5G_6G(chspec)		(CHSPEC_IS5G(chspec) || CHSPEC_IS6G(chspec))
371*4882a593Smuzhiyun #define CHSPEC_IS20_5G_6G(chspec)	((((chspec) & \
372*4882a593Smuzhiyun 					WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \
373*4882a593Smuzhiyun 					(CHSPEC_IS5G(chspec) || CHSPEC_IS6G(chspec)))
374*4882a593Smuzhiyun #else
375*4882a593Smuzhiyun #define CHSPEC_IS_5G_6G(chspec)		(CHSPEC_IS5G(chspec))
376*4882a593Smuzhiyun #define CHSPEC_IS20_5G_6G(chspec)	(CHSPEC_IS20_5G(chspec))
377*4882a593Smuzhiyun #endif
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun /**
380*4882a593Smuzhiyun  * Number of chars needed for wf_chspec_ntoa() destination character buffer.
381*4882a593Smuzhiyun  */
382*4882a593Smuzhiyun #ifdef WL11BE
383*4882a593Smuzhiyun #define CHANSPEC_STR_LEN    22
384*4882a593Smuzhiyun #else
385*4882a593Smuzhiyun #define CHANSPEC_STR_LEN    20
386*4882a593Smuzhiyun #endif
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun /*
389*4882a593Smuzhiyun  * This function returns TRUE if both the chanspec can co-exist in PHY.
390*4882a593Smuzhiyun  * Addition to primary20 channel, the function checks for side band for 2g 40 channels
391*4882a593Smuzhiyun  */
392*4882a593Smuzhiyun extern bool wf_chspec_coexist(chanspec_t chspec1, chanspec_t chspec2);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun #define CHSPEC_IS_BW_160_WIDE(chspec) (CHSPEC_BW(chspec) == WL_CHANSPEC_BW_160 ||\
395*4882a593Smuzhiyun 	CHSPEC_BW(chspec) == WL_CHANSPEC_BW_8080)
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun /* BW inequality comparisons, GE (>=), GT (>) */
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun #define CHSPEC_BW_GE(chspec, bw) (CHSPEC_BW(chspec) >= (bw))
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun #define CHSPEC_BW_GT(chspec, bw) (CHSPEC_BW(chspec) > (bw))
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun /* Legacy Chanspec defines
404*4882a593Smuzhiyun  * These are the defines for the previous format of the chanspec_t
405*4882a593Smuzhiyun  */
406*4882a593Smuzhiyun #define WL_LCHANSPEC_CHAN_MASK		0x00ff
407*4882a593Smuzhiyun #define WL_LCHANSPEC_CHAN_SHIFT		     0
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun #define WL_LCHANSPEC_CTL_SB_MASK	0x0300
410*4882a593Smuzhiyun #define WL_LCHANSPEC_CTL_SB_SHIFT	     8
411*4882a593Smuzhiyun #define WL_LCHANSPEC_CTL_SB_LOWER	0x0100
412*4882a593Smuzhiyun #define WL_LCHANSPEC_CTL_SB_UPPER	0x0200
413*4882a593Smuzhiyun #define WL_LCHANSPEC_CTL_SB_NONE	0x0300
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun #define WL_LCHANSPEC_BW_MASK		0x0C00
416*4882a593Smuzhiyun #define WL_LCHANSPEC_BW_SHIFT		    10
417*4882a593Smuzhiyun #define WL_LCHANSPEC_BW_10		0x0400
418*4882a593Smuzhiyun #define WL_LCHANSPEC_BW_20		0x0800
419*4882a593Smuzhiyun #define WL_LCHANSPEC_BW_40		0x0C00
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun #define WL_LCHANSPEC_BAND_MASK		0xf000
422*4882a593Smuzhiyun #define WL_LCHANSPEC_BAND_SHIFT		    12
423*4882a593Smuzhiyun #define WL_LCHANSPEC_BAND_5G		0x1000
424*4882a593Smuzhiyun #define WL_LCHANSPEC_BAND_2G		0x2000
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun #define LCHSPEC_CHANNEL(chspec)	((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK))
427*4882a593Smuzhiyun #define LCHSPEC_BAND(chspec)	((chspec) & WL_LCHANSPEC_BAND_MASK)
428*4882a593Smuzhiyun #define LCHSPEC_CTL_SB(chspec)	((chspec) & WL_LCHANSPEC_CTL_SB_MASK)
429*4882a593Smuzhiyun #define LCHSPEC_BW(chspec)	((chspec) & WL_LCHANSPEC_BW_MASK)
430*4882a593Smuzhiyun #define LCHSPEC_IS20(chspec)	(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
431*4882a593Smuzhiyun #define LCHSPEC_IS40(chspec)	(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
432*4882a593Smuzhiyun #define LCHSPEC_IS5G(chspec)	(((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
433*4882a593Smuzhiyun #define LCHSPEC_IS2G(chspec)	(((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun #define LCHSPEC_SB_UPPER(chspec)	\
436*4882a593Smuzhiyun 	((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_UPPER) && \
437*4882a593Smuzhiyun 	(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
438*4882a593Smuzhiyun #define LCHSPEC_SB_LOWER(chspec)	\
439*4882a593Smuzhiyun 	((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_LOWER) && \
440*4882a593Smuzhiyun 	(((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun #define LCHSPEC_CREATE(chan, band, bw, sb)  ((uint16)((chan) | (sb) | (bw) | (band)))
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun #define CH20MHZ_LCHSPEC(channel) \
445*4882a593Smuzhiyun 	(chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \
446*4882a593Smuzhiyun 	WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
447*4882a593Smuzhiyun 	WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G))
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun #define GET_ALL_EXT wf_get_all_ext
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun /*
452*4882a593Smuzhiyun  * WF_CHAN_FACTOR_* constants are used to calculate channel frequency
453*4882a593Smuzhiyun  * given a channel number.
454*4882a593Smuzhiyun  * chan_freq = chan_factor * 500Mhz + chan_number * 5
455*4882a593Smuzhiyun  */
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun /**
458*4882a593Smuzhiyun  * Channel Factor for the starting frequence of 2.4 GHz channels.
459*4882a593Smuzhiyun  * The value corresponds to 2407 MHz.
460*4882a593Smuzhiyun  */
461*4882a593Smuzhiyun #define WF_CHAN_FACTOR_2_4_G		4814u	/* 2.4 GHz band, 2407 MHz */
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun /**
464*4882a593Smuzhiyun  * Channel Factor for the starting frequence of 4.9 GHz channels.
465*4882a593Smuzhiyun  * The value corresponds to 4000 MHz.
466*4882a593Smuzhiyun  */
467*4882a593Smuzhiyun #define WF_CHAN_FACTOR_4_G		8000u	/* 4.9 GHz band for Japan */
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun /**
470*4882a593Smuzhiyun  * Channel Factor for the starting frequence of 5 GHz channels.
471*4882a593Smuzhiyun  * The value corresponds to 5000 MHz.
472*4882a593Smuzhiyun  */
473*4882a593Smuzhiyun #define WF_CHAN_FACTOR_5_G		10000u	/* 5   GHz band, 5000 MHz */
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun /**
476*4882a593Smuzhiyun  * Channel Factor for the starting frequence of 6 GHz channels.
477*4882a593Smuzhiyun  * The value corresponds to 5940 MHz.
478*4882a593Smuzhiyun  */
479*4882a593Smuzhiyun #define WF_CHAN_FACTOR_6_G		11900u	/* 6   GHz band, 5950 MHz */
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun #define WLC_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun /**
484*4882a593Smuzhiyun  *  No of sub-band value of the specified Mhz chanspec
485*4882a593Smuzhiyun  */
486*4882a593Smuzhiyun #define WF_NUM_SIDEBANDS_40MHZ   2u
487*4882a593Smuzhiyun #define WF_NUM_SIDEBANDS_80MHZ   4u
488*4882a593Smuzhiyun #define WF_NUM_SIDEBANDS_160MHZ  8u
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun /**
491*4882a593Smuzhiyun  * Return the chanspec bandwidth in MHz
492*4882a593Smuzhiyun  */
493*4882a593Smuzhiyun uint wf_bw_chspec_to_mhz(chanspec_t chspec);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun /**
496*4882a593Smuzhiyun  * Return the bandwidth string for a given chanspec
497*4882a593Smuzhiyun  */
498*4882a593Smuzhiyun const char *wf_chspec_to_bw_str(chanspec_t chspec);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun /**
501*4882a593Smuzhiyun  * Convert chanspec to ascii string, or formats hex of an invalid chanspec.
502*4882a593Smuzhiyun  */
503*4882a593Smuzhiyun char * wf_chspec_ntoa_ex(chanspec_t chspec, char *buf);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun /**
506*4882a593Smuzhiyun  * Convert chanspec to ascii string, or returns NULL on error.
507*4882a593Smuzhiyun  */
508*4882a593Smuzhiyun char * wf_chspec_ntoa(chanspec_t chspec, char *buf);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun /**
511*4882a593Smuzhiyun  * Convert ascii string to chanspec
512*4882a593Smuzhiyun  */
513*4882a593Smuzhiyun chanspec_t wf_chspec_aton(const char *a);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun /**
516*4882a593Smuzhiyun  * Verify the chanspec fields are valid for a chanspec_t
517*4882a593Smuzhiyun  */
518*4882a593Smuzhiyun bool wf_chspec_malformed(chanspec_t chanspec);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun /**
521*4882a593Smuzhiyun  * Verify the chanspec specifies a valid channel according to 802.11.
522*4882a593Smuzhiyun  */
523*4882a593Smuzhiyun bool wf_chspec_valid(chanspec_t chanspec);
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun /**
526*4882a593Smuzhiyun  * Verify that the channel is a valid 20MHz channel according to 802.11.
527*4882a593Smuzhiyun  */
528*4882a593Smuzhiyun bool wf_valid_20MHz_chan(uint channel, chanspec_band_t band);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun /**
531*4882a593Smuzhiyun  * Verify that the center channel is a valid 40MHz center channel according to 802.11.
532*4882a593Smuzhiyun  */
533*4882a593Smuzhiyun bool wf_valid_40MHz_center_chan(uint center_channel, chanspec_band_t band);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun /**
536*4882a593Smuzhiyun  * Verify that the center channel is a valid 80MHz center channel according to 802.11.
537*4882a593Smuzhiyun  */
538*4882a593Smuzhiyun bool wf_valid_80MHz_center_chan(uint center_channel, chanspec_band_t band);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun /**
541*4882a593Smuzhiyun  * Verify that the center channel is a valid 160MHz center channel according to 802.11.
542*4882a593Smuzhiyun  */
543*4882a593Smuzhiyun bool wf_valid_160MHz_center_chan(uint center_channel, chanspec_band_t band);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun /**
546*4882a593Smuzhiyun  * Verify that the center channel is a valid 240MHz center channel according to 802.11.
547*4882a593Smuzhiyun  */
548*4882a593Smuzhiyun bool wf_valid_240MHz_center_chan(uint center_channel, chanspec_band_t band);
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun /**
551*4882a593Smuzhiyun  * Verify that the center channel is a valid 320MHz center channel according to 802.11.
552*4882a593Smuzhiyun  */
553*4882a593Smuzhiyun bool wf_valid_320MHz_center_chan(uint center_channel, chanspec_band_t band);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun /**
556*4882a593Smuzhiyun  * Create a 20MHz chanspec for the given band.
557*4882a593Smuzhiyun  */
558*4882a593Smuzhiyun chanspec_t wf_create_20MHz_chspec(uint channel, chanspec_band_t band);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun /**
561*4882a593Smuzhiyun  * Returns the chanspec for a 40MHz channel given the primary 20MHz channel number,
562*4882a593Smuzhiyun  * the center channel number, and the band.
563*4882a593Smuzhiyun  */
564*4882a593Smuzhiyun chanspec_t wf_create_40MHz_chspec(uint primary_channel, uint center_channel,
565*4882a593Smuzhiyun                                   chanspec_band_t band);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun /**
568*4882a593Smuzhiyun  * Returns the chanspec for a 40MHz channel given the primary 20MHz channel number,
569*4882a593Smuzhiyun  * the sub-band for the primary 20MHz channel, and the band.
570*4882a593Smuzhiyun  */
571*4882a593Smuzhiyun chanspec_t wf_create_40MHz_chspec_primary_sb(uint primary_channel,
572*4882a593Smuzhiyun                                              chanspec_subband_t primary_subband,
573*4882a593Smuzhiyun                                              chanspec_band_t band);
574*4882a593Smuzhiyun /**
575*4882a593Smuzhiyun  * Returns the chanspec for an 80MHz channel given the primary 20MHz channel number,
576*4882a593Smuzhiyun  * the center channel number, and the band.
577*4882a593Smuzhiyun  */
578*4882a593Smuzhiyun chanspec_t wf_create_80MHz_chspec(uint primary_channel, uint center_channel,
579*4882a593Smuzhiyun                                   chanspec_band_t band);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun /**
582*4882a593Smuzhiyun  * Returns the chanspec for an 160MHz channel given the primary 20MHz channel number,
583*4882a593Smuzhiyun  * the center channel number, and the band.
584*4882a593Smuzhiyun  */
585*4882a593Smuzhiyun chanspec_t wf_create_160MHz_chspec(uint primary_channel, uint center_channel,
586*4882a593Smuzhiyun                                    chanspec_band_t band);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun /**
589*4882a593Smuzhiyun  * Returns the chanspec for an 240MHz channel given the primary 20MHz channel number,
590*4882a593Smuzhiyun  * the center channel number, and the band.
591*4882a593Smuzhiyun  */
592*4882a593Smuzhiyun chanspec_t wf_create_240MHz_chspec(uint primary_channel, uint center_channel,
593*4882a593Smuzhiyun                                    chanspec_band_t band);
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun /**
596*4882a593Smuzhiyun  * Returns the chanspec for an 320MHz channel given the primary 20MHz channel number,
597*4882a593Smuzhiyun  * the center channel number, and the band.
598*4882a593Smuzhiyun  */
599*4882a593Smuzhiyun chanspec_t wf_create_320MHz_chspec(uint primary_channel, uint center_channel,
600*4882a593Smuzhiyun                                    chanspec_band_t band);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun /**
603*4882a593Smuzhiyun  * Returns the chanspec for an 80+80MHz channel given the primary 20MHz channel number,
604*4882a593Smuzhiyun  * the center channel numbers for each frequency segment, and the band.
605*4882a593Smuzhiyun  */
606*4882a593Smuzhiyun chanspec_t wf_create_8080MHz_chspec(uint primary_channel, uint chan0, uint chan1,
607*4882a593Smuzhiyun                                     chanspec_band_t band);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun /**
610*4882a593Smuzhiyun  * Returns the chanspec for an 160+160MHz channel given the primary 20MHz channel number,
611*4882a593Smuzhiyun  * the center channel numbers for each frequency segment, and the band.
612*4882a593Smuzhiyun  */
613*4882a593Smuzhiyun chanspec_t wf_create_160160MHz_chspec(uint primary_channel, uint chan0, uint chan1,
614*4882a593Smuzhiyun                                       chanspec_band_t band);
615*4882a593Smuzhiyun /**
616*4882a593Smuzhiyun  * Returns the chanspec given the primary 20MHz channel number,
617*4882a593Smuzhiyun  * the center channel number, channel width, and the band.
618*4882a593Smuzhiyun  *
619*4882a593Smuzhiyun  * The channel width must be 20, 40, 80, or 160 MHz.
620*4882a593Smuzhiyun  */
621*4882a593Smuzhiyun chanspec_t wf_create_chspec(uint primary_channel, uint center_channel,
622*4882a593Smuzhiyun                             chanspec_bw_t bw, chanspec_band_t band);
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun /**
625*4882a593Smuzhiyun  * Returns the chanspec given the primary 20MHz channel number,
626*4882a593Smuzhiyun  * channel width, and the band.
627*4882a593Smuzhiyun  */
628*4882a593Smuzhiyun chanspec_t wf_create_chspec_from_primary(uint primary_channel, chanspec_bw_t bw,
629*4882a593Smuzhiyun                                          chanspec_band_t band);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun /**
632*4882a593Smuzhiyun  * Returns the chanspec given the index of primary 20MHz channel within whole
633*4882a593Smuzhiyun  * channel, the center channel number, channel width, and the band.
634*4882a593Smuzhiyun  *
635*4882a593Smuzhiyun  * The channel width must be 20, 40, 80, or 160 MHz.
636*4882a593Smuzhiyun  */
637*4882a593Smuzhiyun chanspec_t wf_create_chspec_sb(uint sb, uint center_channel, chanspec_bw_t bw,
638*4882a593Smuzhiyun                                chanspec_band_t band);
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun /**
641*4882a593Smuzhiyun  * Returns the chanspec for an 160+160MHz channel given the index of primary 20MHz
642*4882a593Smuzhiyun  * channel within whole channel pair (0-3 if within chan0, 4-7 if within chan1),
643*4882a593Smuzhiyun  * the center channel numbers for each frequency segment, and the band.
644*4882a593Smuzhiyun  */
645*4882a593Smuzhiyun chanspec_t wf_create_160160MHz_chspec_sb(uint sb, uint chan0, uint chan1,
646*4882a593Smuzhiyun                                          chanspec_band_t band);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun /**
649*4882a593Smuzhiyun  * Return the primary 20MHz channel.
650*4882a593Smuzhiyun  */
651*4882a593Smuzhiyun uint8 wf_chspec_primary20_chan(chanspec_t chspec);
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun /* alias for old function name */
654*4882a593Smuzhiyun #define wf_chspec_ctlchan(c) wf_chspec_primary20_chan(c)
655*4882a593Smuzhiyun 
656*4882a593Smuzhiyun /**
657*4882a593Smuzhiyun  * Return the primary 20MHz chanspec of a given chanspec
658*4882a593Smuzhiyun  */
659*4882a593Smuzhiyun chanspec_t wf_chspec_primary20_chspec(chanspec_t chspec);
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun /* alias for old function name */
662*4882a593Smuzhiyun #define wf_chspec_ctlchspec(c) wf_chspec_primary20_chspec(c)
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun /**
665*4882a593Smuzhiyun  * Return the primary 40MHz chanspec for a 40MHz or wider channel
666*4882a593Smuzhiyun  */
667*4882a593Smuzhiyun chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec);
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun /**
670*4882a593Smuzhiyun  * Return the channel number for a given frequency and base frequency
671*4882a593Smuzhiyun  */
672*4882a593Smuzhiyun int wf_mhz2channel(uint freq, uint start_factor);
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun /**
675*4882a593Smuzhiyun  * Return the center frequency in MHz of the given channel and base frequency.
676*4882a593Smuzhiyun  */
677*4882a593Smuzhiyun int wf_channel2mhz(uint channel, uint start_factor);
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun /**
680*4882a593Smuzhiyun  * Returns the chanspec 80Mhz channel corresponding to the following input
681*4882a593Smuzhiyun  * parameters
682*4882a593Smuzhiyun  *
683*4882a593Smuzhiyun  *	primary_channel - primary 20Mhz channel
684*4882a593Smuzhiyun  *	center_channel   - center frequecny of the 80Mhz channel
685*4882a593Smuzhiyun  *
686*4882a593Smuzhiyun  * The center_channel can be one of {42, 58, 106, 122, 138, 155}
687*4882a593Smuzhiyun  *
688*4882a593Smuzhiyun  * returns INVCHANSPEC in case of error
689*4882a593Smuzhiyun  */
690*4882a593Smuzhiyun extern chanspec_t wf_chspec_80(uint8 center_channel, uint8 primary_channel);
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun /**
693*4882a593Smuzhiyun  * Convert ctl chan and bw to chanspec
694*4882a593Smuzhiyun  *
695*4882a593Smuzhiyun  * @param	ctl_ch		channel
696*4882a593Smuzhiyun  * @param	bw	        bandwidth
697*4882a593Smuzhiyun  *
698*4882a593Smuzhiyun  * @return	> 0 if successful or 0 otherwise
699*4882a593Smuzhiyun  *
700*4882a593Smuzhiyun  */
701*4882a593Smuzhiyun extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun /*
704*4882a593Smuzhiyun  * Returns the 80+80 MHz chanspec corresponding to the following input parameters
705*4882a593Smuzhiyun  *
706*4882a593Smuzhiyun  *    primary_20mhz - Primary 20 MHz channel
707*4882a593Smuzhiyun  *    chan0_80MHz - center channel number of one frequency segment
708*4882a593Smuzhiyun  *    chan1_80MHz - center channel number of the other frequency segment
709*4882a593Smuzhiyun  *
710*4882a593Smuzhiyun  * Parameters chan0_80MHz and chan1_80MHz are channel numbers in {42, 58, 106, 122, 138, 155}.
711*4882a593Smuzhiyun  * The primary channel must be contained in one of the 80MHz channels. This routine
712*4882a593Smuzhiyun  * will determine which frequency segment is the primary 80 MHz segment.
713*4882a593Smuzhiyun  *
714*4882a593Smuzhiyun  * Returns INVCHANSPEC in case of error.
715*4882a593Smuzhiyun  *
716*4882a593Smuzhiyun  * Refer to 802.11-2016 section 22.3.14 "Channelization".
717*4882a593Smuzhiyun  */
718*4882a593Smuzhiyun extern chanspec_t wf_chspec_get8080_chspec(uint8 primary_20mhz,
719*4882a593Smuzhiyun 	uint8 chan0_80Mhz, uint8 chan1_80Mhz);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun /**
722*4882a593Smuzhiyun  * Returns the center channel of the primary 80 MHz sub-band of the provided chanspec
723*4882a593Smuzhiyun  *
724*4882a593Smuzhiyun  * @param	chspec    input chanspec
725*4882a593Smuzhiyun  *
726*4882a593Smuzhiyun  * @return	center channel number of the primary 80MHz sub-band of the input.
727*4882a593Smuzhiyun  *		Will return the center channel of an input 80MHz chspec.
728*4882a593Smuzhiyun  *		Will return INVCHANNEL if the chspec is malformed or less than 80MHz bw.
729*4882a593Smuzhiyun  */
730*4882a593Smuzhiyun extern uint8 wf_chspec_primary80_channel(chanspec_t chanspec);
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun /**
733*4882a593Smuzhiyun  * Returns the center channel of the secondary 80 MHz sub-band of the provided chanspec
734*4882a593Smuzhiyun  *
735*4882a593Smuzhiyun  * @param	chspec    input chanspec
736*4882a593Smuzhiyun  *
737*4882a593Smuzhiyun  * @return	center channel number of the secondary 80MHz sub-band of the input.
738*4882a593Smuzhiyun  *		Will return INVCHANNEL if the chspec is malformed or bw is not greater than 80MHz.
739*4882a593Smuzhiyun  */
740*4882a593Smuzhiyun extern uint8 wf_chspec_secondary80_channel(chanspec_t chanspec);
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun /**
743*4882a593Smuzhiyun  * Returns the chanspec for the primary 80MHz sub-band of an 160MHz or 80+80 channel
744*4882a593Smuzhiyun  *
745*4882a593Smuzhiyun  * @param	chspec    input chanspec
746*4882a593Smuzhiyun  *
747*4882a593Smuzhiyun  * @return	An 80MHz chanspec describing the primary 80MHz sub-band of the input.
748*4882a593Smuzhiyun  *		Will return an input 80MHz chspec as is.
749*4882a593Smuzhiyun  *		Will return INVCHANSPEC if the chspec is malformed or less than 80MHz bw.
750*4882a593Smuzhiyun  */
751*4882a593Smuzhiyun extern chanspec_t wf_chspec_primary80_chspec(chanspec_t chspec);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun /**
754*4882a593Smuzhiyun  * Returns the chanspec for the secondary 80MHz sub-band of an 160MHz or 80+80 channel
755*4882a593Smuzhiyun  * The sideband in the chanspec is always set to WL_CHANSPEC_CTL_SB_LL since this sub-band
756*4882a593Smuzhiyun  * does not contain the primary 20MHz channel.
757*4882a593Smuzhiyun  *
758*4882a593Smuzhiyun  * @param	chspec    input chanspec
759*4882a593Smuzhiyun  *
760*4882a593Smuzhiyun  * @return	An 80MHz chanspec describing the secondary 80MHz sub-band of the input.
761*4882a593Smuzhiyun  *		Will return INVCHANSPEC if the chspec is malformed or bw is not greater than 80MHz.
762*4882a593Smuzhiyun  */
763*4882a593Smuzhiyun extern chanspec_t wf_chspec_secondary80_chspec(chanspec_t chspec);
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun /**
766*4882a593Smuzhiyun  * Returns the center channel of the primary 160MHz sub-band of the provided chanspec
767*4882a593Smuzhiyun  *
768*4882a593Smuzhiyun  * @param	chspec    input chanspec
769*4882a593Smuzhiyun  *
770*4882a593Smuzhiyun  * @return	center channel number of the primary 160MHz sub-band of the input.
771*4882a593Smuzhiyun  *		Will return the center channel of an input 160MHz chspec.
772*4882a593Smuzhiyun  *		Will return INVCHANNEL if the chspec is malformed or less than 160MHz bw.
773*4882a593Smuzhiyun  */
774*4882a593Smuzhiyun extern uint8 wf_chspec_primary160_channel(chanspec_t chanspec);
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun /**
777*4882a593Smuzhiyun  * Returns the chanspec for the primary 160MHz sub-band of an 320MHz channel
778*4882a593Smuzhiyun  *
779*4882a593Smuzhiyun  * @param	chspec    input chanspec
780*4882a593Smuzhiyun  *
781*4882a593Smuzhiyun  * @return	An 160MHz chanspec describing the primary 160MHz sub-band of the input.
782*4882a593Smuzhiyun  *		Will return an input 160MHz chspec as is.
783*4882a593Smuzhiyun  *		Will return INVCHANSPEC if the chspec is malformed or less than 160MHz bw.
784*4882a593Smuzhiyun  */
785*4882a593Smuzhiyun extern chanspec_t wf_chspec_primary160_chspec(chanspec_t chspec);
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun /*
788*4882a593Smuzhiyun  * For 160MHz or 80P80 chanspec, set ch[0]/ch[1] to be the low/high 80 Mhz channels
789*4882a593Smuzhiyun  *
790*4882a593Smuzhiyun  * For 20/40/80MHz chanspec, set ch[0] to be the center freq, and chan[1]=-1
791*4882a593Smuzhiyun  */
792*4882a593Smuzhiyun extern void wf_chspec_get_80p80_channels(chanspec_t chspec, uint8 *ch);
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun /* wf_chanspec_iter_... iterator API is deprecated. Use wlc_clm_chanspec_iter_... API instead */
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun struct wf_iter_range {
797*4882a593Smuzhiyun 	uint8 start;
798*4882a593Smuzhiyun 	uint8 end;
799*4882a593Smuzhiyun };
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun /* Internal structure for wf_chanspec_iter_* functions.
802*4882a593Smuzhiyun  * Do not directly access the members. Only use the related
803*4882a593Smuzhiyun  * functions to query and manipulate the structure.
804*4882a593Smuzhiyun  */
805*4882a593Smuzhiyun typedef struct chanspec_iter {
806*4882a593Smuzhiyun 	uint8 state;
807*4882a593Smuzhiyun 	chanspec_t chanspec;
808*4882a593Smuzhiyun 	chanspec_band_t band;
809*4882a593Smuzhiyun 	chanspec_bw_t bw;
810*4882a593Smuzhiyun 	struct wf_iter_range range;
811*4882a593Smuzhiyun 	union {
812*4882a593Smuzhiyun 		uint8 range_id;
813*4882a593Smuzhiyun 		struct {
814*4882a593Smuzhiyun 			uint8 ch0;
815*4882a593Smuzhiyun 			uint8 ch1;
816*4882a593Smuzhiyun 		};
817*4882a593Smuzhiyun 	};
818*4882a593Smuzhiyun } wf_chanspec_iter_t;
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun /**
821*4882a593Smuzhiyun  * Initialize a chanspec iteration structure.
822*4882a593Smuzhiyun  * The parameters define the set of chanspecs to generate in the iteration.
823*4882a593Smuzhiyun  * After initialization wf_chanspec_iter_current() will return the first chanspec
824*4882a593Smuzhiyun  * in the set. A call to wf_chanspec_iter_next() will advance the interation
825*4882a593Smuzhiyun  * to the next chanspec in the set.
826*4882a593Smuzhiyun  *
827*4882a593Smuzhiyun  * Example use:
828*4882a593Smuzhiyun  *      wf_chanspec_iter_t iter;
829*4882a593Smuzhiyun  *      chanspec_t chanspec;
830*4882a593Smuzhiyun  *
831*4882a593Smuzhiyun  *      wf_chanspec_iter_init(&iter, band, bw);
832*4882a593Smuzhiyun  *
833*4882a593Smuzhiyun  *      while (wf_chanspec_iter_next(&iter, &chanspec)) {
834*4882a593Smuzhiyun  *              ... do some work ...
835*4882a593Smuzhiyun  *      }
836*4882a593Smuzhiyun  *
837*4882a593Smuzhiyun  * @param iter  pointer to a wf_chanspec_iter_t structure to initialize
838*4882a593Smuzhiyun  * @param band  chanspec_band_t value specifying the band of interest
839*4882a593Smuzhiyun  * @param bw    chanspec_bw_t value specifying the bandwidth of interest,
840*4882a593Smuzhiyun  *              or INVCHANSPEC to specify all bandwidths
841*4882a593Smuzhiyun  *
842*4882a593Smuzhiyun  * @return a success value, FALSE on error, or TRUE if OK
843*4882a593Smuzhiyun  */
844*4882a593Smuzhiyun bool wf_chanspec_iter_init(wf_chanspec_iter_t *iter, chanspec_band_t band, chanspec_bw_t bw);
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun /**
847*4882a593Smuzhiyun  * Advance the iteration to the next chanspec in the set.
848*4882a593Smuzhiyun  *
849*4882a593Smuzhiyun  * @param iter    pointer to a wf_chanspec_iter_t structure
850*4882a593Smuzhiyun  * @param chspec  pointer to storage for the next chanspec. Return value will be INVCHANSPEC
851*4882a593Smuzhiyun  *                if the iteration ended. Pass in NULL if return value is not desired.
852*4882a593Smuzhiyun  *
853*4882a593Smuzhiyun  * @return a success value, TRUE if there was another chanspec in the iteration, FALSE if not
854*4882a593Smuzhiyun  */
855*4882a593Smuzhiyun bool wf_chanspec_iter_next(wf_chanspec_iter_t *iter, chanspec_t *chspec);
856*4882a593Smuzhiyun 
857*4882a593Smuzhiyun /**
858*4882a593Smuzhiyun  * Return the current chanspec of the iteration.
859*4882a593Smuzhiyun  *
860*4882a593Smuzhiyun  * @param iter  pointer to a wf_chanspec_iter_t structure
861*4882a593Smuzhiyun  *
862*4882a593Smuzhiyun  * @return the current chanspec_t
863*4882a593Smuzhiyun  */
864*4882a593Smuzhiyun chanspec_t wf_chanspec_iter_current(wf_chanspec_iter_t *iter);
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun /* Populates array with all 20MHz side bands of a given chanspec_t in the following order:
867*4882a593Smuzhiyun  *		primary20, ext20, two ext40s, four ext80s.
868*4882a593Smuzhiyun  *     'chspec' is the chanspec of interest
869*4882a593Smuzhiyun  *     'pext' must point to an uint8 array of long enough to hold all side bands of the given chspec
870*4882a593Smuzhiyun  *
871*4882a593Smuzhiyun  * Works with 20, 40, 80 and 160MHz chspec
872*4882a593Smuzhiyun  */
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun extern void wf_get_all_ext(chanspec_t chspec, uint8 *chan_ptr);
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun /*
877*4882a593Smuzhiyun  * Given two chanspecs, returns true if they overlap.
878*4882a593Smuzhiyun  * (Overlap: At least one 20MHz subband is common between the two chanspecs provided)
879*4882a593Smuzhiyun  */
880*4882a593Smuzhiyun extern bool wf_chspec_overlap(chanspec_t chspec0, chanspec_t chspec1);
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun extern uint8 channel_bw_to_width(chanspec_t chspec);
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun uint8 wf_chspec_320_id2cch(chanspec_t chanspec);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun uint8 wf_chspec_240_id2cch(chanspec_t chanspec);
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun #endif	/* _bcmwifi_channels_h_ */
889