1 /* 2 * Misc utility routines for WL and Apps 3 * This header file housing the define and function prototype use by 4 * both the wl driver, tools & Apps. 5 * 6 * Copyright (C) 1999-2017, Broadcom Corporation 7 * 8 * Unless you and Broadcom execute a separate written software license 9 * agreement governing use of this software, this software is licensed to you 10 * under the terms of the GNU General Public License version 2 (the "GPL"), 11 * available at http://www.broadcom.com/licenses/GPLv2.php, with the 12 * following added to such license: 13 * 14 * As a special exception, the copyright holders of this software give you 15 * permission to link this software with independent modules, and to copy and 16 * distribute the resulting executable under terms of your choice, provided that 17 * you also meet, for each linked independent module, the terms and conditions of 18 * the license of that module. An independent module is a module which is not 19 * derived from this software. The special exception does not apply to any 20 * modifications of the software. 21 * 22 * Notwithstanding the above, under no circumstances may you combine this 23 * software in any way with any other Broadcom software provided under a license 24 * other than the GPL, without Broadcom's express prior written consent. 25 * 26 * 27 * <<Broadcom-WL-IPTag/Open:>> 28 * 29 * $Id: bcmwifi_channels.h 612483 2016-01-14 03:44:27Z $ 30 */ 31 32 #ifndef _bcmwifi_channels_h_ 33 #define _bcmwifi_channels_h_ 34 35 36 /* A chanspec holds the channel number, band, bandwidth and control sideband */ 37 typedef uint16 chanspec_t; 38 39 /* channel defines */ 40 #define CH_UPPER_SB 0x01 41 #define CH_LOWER_SB 0x02 42 #define CH_EWA_VALID 0x04 43 #define CH_80MHZ_APART 16 44 #define CH_40MHZ_APART 8 45 #define CH_20MHZ_APART 4 46 #define CH_10MHZ_APART 2 47 #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ 48 #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ 49 50 /* maximum # channels the s/w supports */ 51 #define MAXCHANNEL 224 /* max # supported channels. The max channel no is above, 52 * this is that + 1 rounded up to a multiple of NBBY (8). 53 * DO NOT MAKE it > 255: channels are uint8's all over 54 */ 55 #define MAXCHANNEL_NUM (MAXCHANNEL - 1) /* max channel number */ 56 57 /* channel bitvec */ 58 typedef struct { 59 uint8 vec[MAXCHANNEL/8]; /* bitvec of channels */ 60 } chanvec_t; 61 62 /* make sure channel num is within valid range */ 63 #define CH_NUM_VALID_RANGE(ch_num) ((ch_num) > 0 && (ch_num) <= MAXCHANNEL_NUM) 64 65 #define CHSPEC_CTLOVLP(sp1, sp2, sep) \ 66 (ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < (sep)) 67 68 /* All builds use the new 11ac ratespec/chanspec */ 69 #undef D11AC_IOTYPES 70 #define D11AC_IOTYPES 71 72 #define WL_CHANSPEC_CHAN_MASK 0x00ff 73 #define WL_CHANSPEC_CHAN_SHIFT 0 74 #define WL_CHANSPEC_CHAN1_MASK 0x000f 75 #define WL_CHANSPEC_CHAN1_SHIFT 0 76 #define WL_CHANSPEC_CHAN2_MASK 0x00f0 77 #define WL_CHANSPEC_CHAN2_SHIFT 4 78 79 #define WL_CHANSPEC_CTL_SB_MASK 0x0700 80 #define WL_CHANSPEC_CTL_SB_SHIFT 8 81 #define WL_CHANSPEC_CTL_SB_LLL 0x0000 82 #define WL_CHANSPEC_CTL_SB_LLU 0x0100 83 #define WL_CHANSPEC_CTL_SB_LUL 0x0200 84 #define WL_CHANSPEC_CTL_SB_LUU 0x0300 85 #define WL_CHANSPEC_CTL_SB_ULL 0x0400 86 #define WL_CHANSPEC_CTL_SB_ULU 0x0500 87 #define WL_CHANSPEC_CTL_SB_UUL 0x0600 88 #define WL_CHANSPEC_CTL_SB_UUU 0x0700 89 #define WL_CHANSPEC_CTL_SB_LL WL_CHANSPEC_CTL_SB_LLL 90 #define WL_CHANSPEC_CTL_SB_LU WL_CHANSPEC_CTL_SB_LLU 91 #define WL_CHANSPEC_CTL_SB_UL WL_CHANSPEC_CTL_SB_LUL 92 #define WL_CHANSPEC_CTL_SB_UU WL_CHANSPEC_CTL_SB_LUU 93 #define WL_CHANSPEC_CTL_SB_L WL_CHANSPEC_CTL_SB_LLL 94 #define WL_CHANSPEC_CTL_SB_U WL_CHANSPEC_CTL_SB_LLU 95 #define WL_CHANSPEC_CTL_SB_LOWER WL_CHANSPEC_CTL_SB_LLL 96 #define WL_CHANSPEC_CTL_SB_UPPER WL_CHANSPEC_CTL_SB_LLU 97 #define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL 98 99 #define WL_CHANSPEC_BW_MASK 0x3800 100 #define WL_CHANSPEC_BW_SHIFT 11 101 #define WL_CHANSPEC_BW_5 0x0000 102 #define WL_CHANSPEC_BW_10 0x0800 103 #define WL_CHANSPEC_BW_20 0x1000 104 #define WL_CHANSPEC_BW_40 0x1800 105 #define WL_CHANSPEC_BW_80 0x2000 106 #define WL_CHANSPEC_BW_160 0x2800 107 #define WL_CHANSPEC_BW_8080 0x3000 108 #define WL_CHANSPEC_BW_2P5 0x3800 109 110 #define WL_CHANSPEC_BAND_MASK 0xc000 111 #define WL_CHANSPEC_BAND_SHIFT 14 112 #define WL_CHANSPEC_BAND_2G 0x0000 113 #define WL_CHANSPEC_BAND_3G 0x4000 114 #define WL_CHANSPEC_BAND_4G 0x8000 115 #define WL_CHANSPEC_BAND_5G 0xc000 116 #define INVCHANSPEC 255 117 #define MAX_CHANSPEC 0xFFFF 118 119 #define WL_CHANNEL_BAND(ch) (((ch) <= CH_MAX_2G_CHANNEL) ? \ 120 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G) 121 122 /* channel defines */ 123 #define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? \ 124 ((channel) - CH_10MHZ_APART) : 0) 125 #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ 126 ((channel) + CH_10MHZ_APART) : 0) 127 128 #define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0) 129 #define UU_20_SB(channel) (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \ 130 ((channel) + 3 * CH_10MHZ_APART) : 0) 131 #define LU_20_SB(channel) LOWER_20_SB(channel) 132 #define UL_20_SB(channel) UPPER_20_SB(channel) 133 134 #define LOWER_40_SB(channel) ((channel) - CH_20MHZ_APART) 135 #define UPPER_40_SB(channel) ((channel) + CH_20MHZ_APART) 136 #define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) 137 #define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ 138 (((channel) <= CH_MAX_2G_CHANNEL) ? \ 139 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) 140 #define CH2P5MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_2P5 | \ 141 (((channel) <= CH_MAX_2G_CHANNEL) ? \ 142 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) 143 #define CH5MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_5 | \ 144 (((channel) <= CH_MAX_2G_CHANNEL) ? \ 145 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) 146 #define CH10MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_10 | \ 147 (((channel) <= CH_MAX_2G_CHANNEL) ? \ 148 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) 149 #define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ 150 ((channel) + CH_20MHZ_APART) : 0) 151 #define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ 152 ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ 153 ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ 154 WL_CHANSPEC_BAND_5G)) 155 #define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ 156 ((channel) | (ctlsb) | \ 157 WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G) 158 #define CH160MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ 159 ((channel) | (ctlsb) | \ 160 WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G) 161 #define CHBW_CHSPEC(bw, channel) (chanspec_t)((chanspec_t)(channel) | (bw) | \ 162 (((channel) <= CH_MAX_2G_CHANNEL) ? \ 163 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) 164 165 /* simple MACROs to get different fields of chanspec */ 166 #ifdef WL11AC_80P80 167 #define CHSPEC_CHANNEL(chspec) wf_chspec_channel(chspec) 168 #else 169 #define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK)) 170 #endif 171 #define CHSPEC_CHAN1(chspec) ((chspec) & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT 172 #define CHSPEC_CHAN2(chspec) ((chspec) & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT 173 #define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) 174 #define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) 175 #define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) 176 177 #ifdef WL11N_20MHZONLY 178 #ifdef WL11ULB 179 #define CHSPEC_IS2P5(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_2P5) 180 #define CHSPEC_IS5(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_5) 181 #define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) 182 #else 183 #define CHSPEC_IS2P5(chspec) 0 184 #define CHSPEC_IS5(chspec) 0 185 #define CHSPEC_IS10(chspec) 0 186 #endif 187 #define CHSPEC_IS20(chspec) 1 188 #define CHSPEC_IS20_2G(chspec) ((((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \ 189 CHSPEC_IS2G(chspec)) 190 #ifndef CHSPEC_IS40 191 #define CHSPEC_IS40(chspec) 0 192 #endif 193 #ifndef CHSPEC_IS80 194 #define CHSPEC_IS80(chspec) 0 195 #endif 196 #ifndef CHSPEC_IS160 197 #define CHSPEC_IS160(chspec) 0 198 #endif 199 #ifndef CHSPEC_IS8080 200 #define CHSPEC_IS8080(chspec) 0 201 #endif 202 #define BW_LE20(bw) TRUE 203 #define CHSPEC_ISLE20(chspec) TRUE 204 #else /* !WL11N_20MHZONLY */ 205 206 #define CHSPEC_IS2P5(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_2P5) 207 #define CHSPEC_IS5(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_5) 208 #define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) 209 #define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) 210 #define CHSPEC_IS20_5G(chspec) ((((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) && \ 211 CHSPEC_IS5G(chspec)) 212 #ifndef CHSPEC_IS40 213 #define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) 214 #endif 215 #ifndef CHSPEC_IS80 216 #define CHSPEC_IS80(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80) 217 #endif 218 #ifndef CHSPEC_IS160 219 #define CHSPEC_IS160(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160) 220 #endif 221 #ifndef CHSPEC_IS8080 222 #define CHSPEC_IS8080(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080) 223 #endif 224 225 #ifdef WL11ULB 226 #define BW_LT20(bw) (((bw) == WL_CHANSPEC_BW_2P5) || \ 227 ((bw) == WL_CHANSPEC_BW_5) || \ 228 ((bw) == WL_CHANSPEC_BW_10)) 229 #define CHSPEC_BW_LT20(chspec) (BW_LT20(CHSPEC_BW(chspec))) 230 /* This MACRO is strictly to avoid abandons in existing code with ULB feature and is in no way 231 * optimial to use. Should be replaced with CHSPEC_BW_LE() instead 232 */ 233 #define BW_LE20(bw) (((bw) == WL_CHANSPEC_BW_2P5) || \ 234 ((bw) == WL_CHANSPEC_BW_5) || \ 235 ((bw) == WL_CHANSPEC_BW_10) || \ 236 ((bw) == WL_CHANSPEC_BW_20)) 237 #define CHSPEC_ISLE20(chspec) (BW_LE20(CHSPEC_BW(chspec))) 238 239 #else /* WL11ULB */ 240 #define BW_LE20(bw) ((bw) == WL_CHANSPEC_BW_20) 241 #define CHSPEC_ISLE20(chspec) (CHSPEC_IS20(chspec)) 242 #endif /* WL11ULB */ 243 #endif /* !WL11N_20MHZONLY */ 244 245 #define BW_LE40(bw) (BW_LE20(bw) || ((bw) == WL_CHANSPEC_BW_40)) 246 #define BW_LE80(bw) (BW_LE40(bw) || ((bw) == WL_CHANSPEC_BW_80)) 247 #define BW_LE160(bw) (BW_LE80(bw) || ((bw) == WL_CHANSPEC_BW_160)) 248 #define CHSPEC_BW_LE20(chspec) (BW_LE20(CHSPEC_BW(chspec))) 249 #define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) 250 #define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) 251 #define CHSPEC_SB_UPPER(chspec) \ 252 ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \ 253 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) 254 #define CHSPEC_SB_LOWER(chspec) \ 255 ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \ 256 (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)) 257 #define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) 258 259 /** 260 * Number of chars needed for wf_chspec_ntoa() destination character buffer. 261 */ 262 #define CHANSPEC_STR_LEN 20 263 264 265 #define CHSPEC_IS_BW_160_WIDE(chspec) (CHSPEC_BW(chspec) == WL_CHANSPEC_BW_160 ||\ 266 CHSPEC_BW(chspec) == WL_CHANSPEC_BW_8080) 267 268 /* BW inequality comparisons, LE (<=), GE (>=), LT (<), GT (>), comparisons can be made 269 * as simple numeric comparisons, with the exception that 160 is the same BW as 80+80, 270 * but have different numeric values; (WL_CHANSPEC_BW_160 < WL_CHANSPEC_BW_8080). 271 * 272 * The LT/LE/GT/GE macros check first checks whether both chspec bandwidth and bw are 160 wide. 273 * If both chspec bandwidth and bw is not 160 wide, then the comparison is made. 274 */ 275 #ifdef WL11ULB 276 #define CHSPEC_BW_GE(chspec, bw) \ 277 (((CHSPEC_IS_BW_160_WIDE(chspec) &&\ 278 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\ 279 (CHSPEC_BW(chspec) >= (bw))) && \ 280 (!(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_2P5 && (bw) != WL_CHANSPEC_BW_2P5))) 281 #else /* WL11ULB */ 282 #define CHSPEC_BW_GE(chspec, bw) \ 283 ((CHSPEC_IS_BW_160_WIDE(chspec) &&\ 284 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\ 285 (CHSPEC_BW(chspec) >= (bw))) 286 #endif /* WL11ULB */ 287 288 #ifdef WL11ULB 289 #define CHSPEC_BW_LE(chspec, bw) \ 290 (((CHSPEC_IS_BW_160_WIDE(chspec) &&\ 291 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\ 292 (CHSPEC_BW(chspec) <= (bw))) || \ 293 (CHSPEC_BW(chspec) == WL_CHANSPEC_BW_2P5)) 294 #else /* WL11ULB */ 295 #define CHSPEC_BW_LE(chspec, bw) \ 296 ((CHSPEC_IS_BW_160_WIDE(chspec) &&\ 297 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) ||\ 298 (CHSPEC_BW(chspec) <= (bw))) 299 #endif /* WL11ULB */ 300 301 #ifdef WL11ULB 302 #define CHSPEC_BW_GT(chspec, bw) \ 303 ((!(CHSPEC_IS_BW_160_WIDE(chspec) &&\ 304 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\ 305 (CHSPEC_BW(chspec) > (bw))) && \ 306 (CHSPEC_BW(chspec) != WL_CHANSPEC_BW_2P5)) 307 #else /* WL11ULB */ 308 #define CHSPEC_BW_GT(chspec, bw) \ 309 (!(CHSPEC_IS_BW_160_WIDE(chspec) &&\ 310 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\ 311 (CHSPEC_BW(chspec) > (bw))) 312 #endif /* WL11ULB */ 313 314 #ifdef WL11ULB 315 #define CHSPEC_BW_LT(chspec, bw) \ 316 ((!(CHSPEC_IS_BW_160_WIDE(chspec) &&\ 317 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\ 318 (CHSPEC_BW(chspec) < (bw))) || \ 319 ((CHSPEC_BW(chspec) == WL_CHANSPEC_BW_2P5 && (bw) != WL_CHANSPEC_BW_2P5))) 320 #else /* WL11ULB */ 321 #define CHSPEC_BW_LT(chspec, bw) \ 322 (!(CHSPEC_IS_BW_160_WIDE(chspec) &&\ 323 ((bw) == WL_CHANSPEC_BW_160 || (bw) == WL_CHANSPEC_BW_8080)) &&\ 324 (CHSPEC_BW(chspec) < (bw))) 325 #endif /* WL11ULB */ 326 327 /* Legacy Chanspec defines 328 * These are the defines for the previous format of the chanspec_t 329 */ 330 #define WL_LCHANSPEC_CHAN_MASK 0x00ff 331 #define WL_LCHANSPEC_CHAN_SHIFT 0 332 333 #define WL_LCHANSPEC_CTL_SB_MASK 0x0300 334 #define WL_LCHANSPEC_CTL_SB_SHIFT 8 335 #define WL_LCHANSPEC_CTL_SB_LOWER 0x0100 336 #define WL_LCHANSPEC_CTL_SB_UPPER 0x0200 337 #define WL_LCHANSPEC_CTL_SB_NONE 0x0300 338 339 #define WL_LCHANSPEC_BW_MASK 0x0C00 340 #define WL_LCHANSPEC_BW_SHIFT 10 341 #define WL_LCHANSPEC_BW_10 0x0400 342 #define WL_LCHANSPEC_BW_20 0x0800 343 #define WL_LCHANSPEC_BW_40 0x0C00 344 345 #define WL_LCHANSPEC_BAND_MASK 0xf000 346 #define WL_LCHANSPEC_BAND_SHIFT 12 347 #define WL_LCHANSPEC_BAND_5G 0x1000 348 #define WL_LCHANSPEC_BAND_2G 0x2000 349 350 #define LCHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK)) 351 #define LCHSPEC_BAND(chspec) ((chspec) & WL_LCHANSPEC_BAND_MASK) 352 #define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK) 353 #define LCHSPEC_BW(chspec) ((chspec) & WL_LCHANSPEC_BW_MASK) 354 #define LCHSPEC_IS10(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10) 355 #define LCHSPEC_IS20(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20) 356 #define LCHSPEC_IS40(chspec) (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40) 357 #define LCHSPEC_IS5G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G) 358 #define LCHSPEC_IS2G(chspec) (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G) 359 360 #define LCHSPEC_SB_UPPER(chspec) \ 361 ((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_UPPER) && \ 362 (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)) 363 #define LCHSPEC_SB_LOWER(chspec) \ 364 ((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_LOWER) && \ 365 (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)) 366 367 #define LCHSPEC_CREATE(chan, band, bw, sb) ((uint16)((chan) | (sb) | (bw) | (band))) 368 369 #define CH20MHZ_LCHSPEC(channel) \ 370 (chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \ 371 WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ 372 WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G)) 373 374 /* 375 * WF_CHAN_FACTOR_* constants are used to calculate channel frequency 376 * given a channel number. 377 * chan_freq = chan_factor * 500Mhz + chan_number * 5 378 */ 379 380 /** 381 * Channel Factor for the starting frequence of 2.4 GHz channels. 382 * The value corresponds to 2407 MHz. 383 */ 384 #define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */ 385 386 /** 387 * Channel Factor for the starting frequence of 5 GHz channels. 388 * The value corresponds to 5000 MHz. 389 */ 390 #define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */ 391 392 /** 393 * Channel Factor for the starting frequence of 4.9 GHz channels. 394 * The value corresponds to 4000 MHz. 395 */ 396 #define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ 397 398 #define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ 399 400 /** 401 * No of sub-band vlaue of the specified Mhz chanspec 402 */ 403 #define WF_NUM_SIDEBANDS_40MHZ 2 404 #define WF_NUM_SIDEBANDS_80MHZ 4 405 #define WF_NUM_SIDEBANDS_8080MHZ 4 406 #define WF_NUM_SIDEBANDS_160MHZ 8 407 408 /** 409 * Convert chanspec to ascii string 410 * 411 * @param chspec chanspec format 412 * @param buf ascii string of chanspec 413 * 414 * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes 415 * Original chanspec in case of error 416 * 417 * @see CHANSPEC_STR_LEN 418 */ 419 extern char *wf_chspec_ntoa_ex(chanspec_t chspec, char *buf); 420 421 /** 422 * Convert chanspec to ascii string 423 * 424 * @param chspec chanspec format 425 * @param buf ascii string of chanspec 426 * 427 * @return pointer to buf with room for at least CHANSPEC_STR_LEN bytes 428 * NULL in case of error 429 * 430 * @see CHANSPEC_STR_LEN 431 */ 432 extern char *wf_chspec_ntoa(chanspec_t chspec, char *buf); 433 434 /** 435 * Convert ascii string to chanspec 436 * 437 * @param a pointer to input string 438 * 439 * @return >= 0 if successful or 0 otherwise 440 */ 441 extern chanspec_t wf_chspec_aton(const char *a); 442 443 /** 444 * Verify the chanspec fields are valid. 445 * 446 * Verify the chanspec is using a legal set field values, i.e. that the chanspec 447 * specified a band, bw, ctl_sb and channel and that the combination could be 448 * legal given some set of circumstances. 449 * 450 * @param chanspec input chanspec to verify 451 * 452 * @return TRUE if the chanspec is malformed, FALSE if it looks good. 453 */ 454 extern bool wf_chspec_malformed(chanspec_t chanspec); 455 456 /** 457 * Verify the chanspec specifies a valid channel according to 802.11. 458 * 459 * @param chanspec input chanspec to verify 460 * 461 * @return TRUE if the chanspec is a valid 802.11 channel 462 */ 463 extern bool wf_chspec_valid(chanspec_t chanspec); 464 465 /** 466 * Return the primary (control) channel. 467 * 468 * This function returns the channel number of the primary 20MHz channel. For 469 * 20MHz channels this is just the channel number. For 40MHz or wider channels 470 * it is the primary 20MHz channel specified by the chanspec. 471 * 472 * @param chspec input chanspec 473 * 474 * @return Returns the channel number of the primary 20MHz channel 475 */ 476 extern uint8 wf_chspec_ctlchan(chanspec_t chspec); 477 478 /* 479 * Return the bandwidth string. 480 * 481 * This function returns the bandwidth string for the passed chanspec. 482 * 483 * @param chspec input chanspec 484 * 485 * @return Returns the bandwidth string 486 */ 487 extern const char *wf_chspec_to_bw_str(chanspec_t chspec); 488 489 /** 490 * Return the primary (control) chanspec. 491 * 492 * This function returns the chanspec of the primary 20MHz channel. For 20MHz 493 * channels this is just the chanspec. For 40MHz or wider channels it is the 494 * chanspec of the primary 20MHZ channel specified by the chanspec. 495 * 496 * @param chspec input chanspec 497 * 498 * @return Returns the chanspec of the primary 20MHz channel 499 */ 500 extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); 501 502 /** 503 * Return a channel number corresponding to a frequency. 504 * 505 * This function returns the chanspec for the primary 40MHz of an 80MHz channel. 506 * The control sideband specifies the same 20MHz channel that the 80MHz channel is using 507 * as the primary 20MHz channel. 508 */ 509 extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec); 510 511 /* 512 * Return the channel number for a given frequency and base frequency. 513 * The returned channel number is relative to the given base frequency. 514 * If the given base frequency is zero, a base frequency of 5 GHz is assumed for 515 * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz. 516 * 517 * Frequency is specified in MHz. 518 * The base frequency is specified as (start_factor * 500 kHz). 519 * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for 520 * 2.4 GHz and 5 GHz bands. 521 * 522 * The returned channel will be in the range [1, 14] in the 2.4 GHz band 523 * and [0, 200] otherwise. 524 * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the 525 * frequency is not a 2.4 GHz channel, or if the frequency is not and even 526 * multiple of 5 MHz from the base frequency to the base plus 1 GHz. 527 * 528 * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 529 * 530 * @param freq frequency in MHz 531 * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz 532 * 533 * @return Returns a channel number 534 * 535 * @see WF_CHAN_FACTOR_2_4_G 536 * @see WF_CHAN_FACTOR_5_G 537 */ 538 extern int wf_mhz2channel(uint freq, uint start_factor); 539 540 /** 541 * Return the center frequency in MHz of the given channel and base frequency. 542 * 543 * Return the center frequency in MHz of the given channel and base frequency. 544 * The channel number is interpreted relative to the given base frequency. 545 * 546 * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. 547 * The base frequency is specified as (start_factor * 500 kHz). 548 * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for 549 * 2.4 GHz and 5 GHz bands. 550 * The channel range of [1, 14] is only checked for a start_factor of 551 * WF_CHAN_FACTOR_2_4_G (4814). 552 * Odd start_factors produce channels on .5 MHz boundaries, in which case 553 * the answer is rounded down to an integral MHz. 554 * -1 is returned for an out of range channel. 555 * 556 * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 557 * 558 * @param channel input channel number 559 * @param start_factor base frequency in 500 kHz units, e.g. 10000 for 5 GHz 560 * 561 * @return Returns a frequency in MHz 562 * 563 * @see WF_CHAN_FACTOR_2_4_G 564 * @see WF_CHAN_FACTOR_5_G 565 */ 566 extern int wf_channel2mhz(uint channel, uint start_factor); 567 568 /** 569 * Returns the chanspec 80Mhz channel corresponding to the following input 570 * parameters 571 * 572 * primary_channel - primary 20Mhz channel 573 * center_channel - center frequecny of the 80Mhz channel 574 * 575 * The center_channel can be one of {42, 58, 106, 122, 138, 155} 576 * 577 * returns INVCHANSPEC in case of error 578 */ 579 extern chanspec_t wf_chspec_80(uint8 center_channel, uint8 primary_channel); 580 581 /** 582 * Convert ctl chan and bw to chanspec 583 * 584 * @param ctl_ch channel 585 * @param bw bandwidth 586 * 587 * @return > 0 if successful or 0 otherwise 588 * 589 */ 590 extern uint16 wf_channel2chspec(uint ctl_ch, uint bw); 591 592 extern uint wf_channel2freq(uint channel); 593 extern uint wf_freq2channel(uint freq); 594 595 /* 596 * Returns the 80+80 MHz chanspec corresponding to the following input parameters 597 * 598 * primary_20mhz - Primary 20 MHz channel 599 * chan0_80MHz - center channel number of one frequency segment 600 * chan1_80MHz - center channel number of the other frequency segment 601 * 602 * Parameters chan0_80MHz and chan1_80MHz are channel numbers in {42, 58, 106, 122, 138, 155}. 603 * The primary channel must be contained in one of the 80MHz channels. This routine 604 * will determine which frequency segment is the primary 80 MHz segment. 605 * 606 * Returns INVCHANSPEC in case of error. 607 * 608 * Refer to IEEE802.11ac section 22.3.14 "Channelization". 609 */ 610 extern chanspec_t wf_chspec_get8080_chspec(uint8 primary_20mhz, 611 uint8 chan0_80Mhz, uint8 chan1_80Mhz); 612 613 /* 614 * Returns the primary 80 Mhz channel for the provided chanspec 615 * 616 * chanspec - Input chanspec for which the 80MHz primary channel has to be retrieved 617 * 618 * returns -1 in case the provided channel is 20/40 Mhz chanspec 619 */ 620 extern uint8 wf_chspec_primary80_channel(chanspec_t chanspec); 621 622 /* 623 * Returns the secondary 80 Mhz channel for the provided chanspec 624 * 625 * chanspec - Input chanspec for which the 80MHz secondary channel has to be retrieved 626 * 627 * returns -1 in case the provided channel is 20/40 Mhz chanspec 628 */ 629 extern uint8 wf_chspec_secondary80_channel(chanspec_t chanspec); 630 631 /* 632 * This function returns the chanspec for the primary 80MHz of an 160MHz or 80+80 channel. 633 */ 634 extern chanspec_t wf_chspec_primary80_chspec(chanspec_t chspec); 635 636 #ifdef WL11AC_80P80 637 /* 638 * This function returns the centre chanel for the given chanspec. 639 * In case of 80+80 chanspec it returns the primary 80 Mhz centre channel 640 */ 641 extern uint8 wf_chspec_channel(chanspec_t chspec); 642 #endif 643 extern chanspec_t wf_channel_create_chspec_frm_opclass(uint8 opclass, uint8 channel); 644 extern int wf_channel_create_opclass_frm_chspec(chanspec_t chspec); 645 #endif /* _bcmwifi_channels_h_ */ 646