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