Lines Matching +full:convert +full:- +full:channels
2 * Misc utility routines used by kernel or app-level.
3 * Contents are wifi-specific, used by any kernel or app-level
23 * <<Broadcom-WL-IPTag/Dual:>>
32 #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
55 * [<band>'g']<channel>['/'<bandwidth>[<primary-sideband>]
56 * ['/'<1st-channel-segment>'-'<2nd-channel-segment>]]
64 * 240MHz, 320MHz, or 160+160MHz channels.
67 * <primary-sideband>:
70 * For 2.4GHz band 40MHz channels, the same primary channel may be the
76 * 40MHz, the U/L specification is not necessary or allowed since the channels are
77 * non-overlapping and the primary 20MHz channel position is derived from its
79 * <1st-channel-segment>
80 * <2nd-channel-segment>:
83 * or 160MHz channels.
89 * 40MHz channels is also allowed: <channel><primary-sideband>
93 * <primary-sideband>:
98 * 5g8 20MHz 8 - -
99 * 52 20MHz 52 - -
100 * 52/40 40MHz 54 52-56 52
101 * 56/40 40MHz 54 52-56 56
102 * 52/80 80MHz 58 52-64 52
103 * 56/80 80MHz 58 52-64 56
104 * 60/80 80MHz 58 52-64 60
105 * 64/80 80MHz 58 52-64 64
106 * 52/160 160MHz 50 36-64 52
107 * 36/160 160MGz 50 36-64 36
108 * 36/80+80/42-106 80+80MHz 42,106 36-48,100-112 36
112 * 2g8 20MHz 8 - -
113 * 8 20MHz 8 - -
114 * 6 20MHz 6 - -
115 * 6/40l 40MHz 8 6-10 6
116 * 6l 40MHz 8 6-10 6
117 * 6/40u 40MHz 4 2-6 6
118 * 6u 40MHz 4 2-6 6
139 /* 40MHz channels in 2.4GHz band */
145 /* 40MHz channels in 5GHz band */
151 /* 80MHz channels in 5GHz band */
157 /* 160MHz channels in 5GHz band */
163 /** 80MHz channels in 6GHz band */
166 /** 160MHz channels in 6GHz band */
169 /** 240MHz channels in 6GHz band */
172 /** 320MHz channels in 6GHz band */
220 /* edge channels separated by BW - 10MHz on each side in center_chan_to_edge()
248 return (center_ch - center_chan_to_edge(bw)); in channel_low_edge()
252 * return -1 on error
261 (primary_ch - lowest) % 4) { in channel_to_sb()
265 return -1; in channel_to_sb()
268 sb = ((primary_ch - lowest) / 4); in channel_to_sb()
278 return -1; in channel_to_sb()
292 * return -1 on error
303 return -1; in channel_80mhz_to_id()
307 * return -1 on error
312 /* The 6GHz center channels start at 7, and have a spacing of 16 */ in channel_6g_80mhz_to_id()
315 ((ch - CH_MIN_6G_80M_CHANNEL) % 16) == 0) { // even multiple of 16 in channel_6g_80mhz_to_id()
316 return (ch - CH_MIN_6G_80M_CHANNEL) / 16; in channel_6g_80mhz_to_id()
319 return -1; in channel_6g_80mhz_to_id()
323 * return -1 on error
335 return -1; in channel_5g_160mhz_to_id()
339 * return -1 on error
344 /* The 6GHz center channels start at 15, and have a spacing of 32 */ in channel_6g_160mhz_to_id()
347 ((ch - CH_MIN_6G_160M_CHANNEL) % 32) == 0) { in channel_6g_160mhz_to_id()
348 return (ch - CH_MIN_6G_160M_CHANNEL) / 32; in channel_6g_160mhz_to_id()
351 return -1; in channel_6g_160mhz_to_id()
355 * return -1 on error
360 /* The 6GHz center channels start at 23, and have a spacing of 48 */ in channel_6g_240mhz_to_id()
363 ((ch - CH_MIN_6G_240M_CHANNEL) % 48) == 0) { in channel_6g_240mhz_to_id()
364 return (ch - CH_MIN_6G_240M_CHANNEL) / 48; in channel_6g_240mhz_to_id()
367 return -1; in channel_6g_240mhz_to_id()
371 * return -1 on error
376 /* The 6GHz center channels start at 31, and have a spacing of 64 */ in channel_6g_320mhz_to_id()
379 ((ch - CH_MIN_6G_320M_CHANNEL) % 64) == 0) { in channel_6g_320mhz_to_id()
380 return (ch - CH_MIN_6G_320M_CHANNEL) / 64; in channel_6g_320mhz_to_id()
383 return -1; in channel_6g_320mhz_to_id()
400 /* The 6GHz center channels have a spacing of 48 in wf_chspec_6G_id240_to_ch()
409 /* Retrive the chan_id and convert it to center channel */
436 /* The 6GHz center channels have a spacing of 64 in wf_chspec_6G_id320_to_ch()
445 /* Retrive the chan_id and convert it to center channel */
459 * Convert chanspec to ascii string, or formats hex of an invalid chanspec.
483 * Convert chanspec to ascii string, or return NULL on error.
509 /* check for non-default band spec */ in wf_chspec_ntoa()
585 * Convert ascii string to chanspec
658 /* convert to chspec value */ in wf_chspec_aton()
708 * Need to convert pri_ch, and sb_ul into in wf_chspec_aton()
726 /* If the bw is 40/80/160/240/320 (and not 40MHz 2G), the channels are in wf_chspec_aton()
727 * non-overlapping in 5G or 6G bands. Each primary channel is contained in wf_chspec_aton()
730 * sub-band spec was given. in wf_chspec_aton()
832 * 80+80 SB info is relative to the primary 80MHz sub-band. in BCMPOSTTRAPFN()
861 uint chspec_ch = -1; in wf_chspec_valid()
886 * and a valid sub-band value for the bandwidth. in wf_chspec_valid()
888 * Since all sub-band specs are valid for any channel, the only thing remaining to in wf_chspec_valid()
892 * or both center channels for an 80+80MHz channel, in wf_chspec_valid()
894 * Also, 80+80MHz channels need to be non-contiguous. in wf_chspec_valid()
956 iter->state = WF_ITER_DONE; in wf_chanspec_iter_init()
957 iter->chanspec = INVCHANSPEC; in wf_chanspec_iter_init()
986 iter->state = WF_ITER_INIT; in wf_chanspec_iter_init()
987 iter->band = band; in wf_chanspec_iter_init()
988 iter->bw = bw; in wf_chanspec_iter_init()
989 iter->range_id = RANGE_ID_INVAL; in wf_chanspec_iter_init()
1001 chanspec_band_t band = iter->band; in wf_chanspec_iter_firstchan()
1002 chanspec_bw_t bw = iter->bw; in wf_chanspec_iter_firstchan()
1012 /* 2g has overlapping 40MHz channels, so cannot just use the in wf_chanspec_iter_firstchan()
1027 chspec = wf_create_chspec_from_primary(iter->range.start, bw, band); in wf_chanspec_iter_firstchan()
1030 iter->chanspec = chspec; in wf_chanspec_iter_firstchan()
1039 return iter->chanspec; in wf_chanspec_iter_current()
1049 chanspec_band_t band = iter->band; in wf_chanspec_iter_next()
1054 if (iter->state == WF_ITER_INIT) { in wf_chanspec_iter_next()
1055 iter->state = WF_ITER_RUN; in wf_chanspec_iter_next()
1058 } else if (iter->state == WF_ITER_DONE) { in wf_chanspec_iter_next()
1072 *chspec = iter->chanspec; in wf_chanspec_iter_next()
1118 chanspec_t chspec = iter->chanspec; in wf_chanspec_iter_next_2g()
1125 } else if (iter->bw == INVCHANSPEC) { in wf_chanspec_iter_next_2g()
1126 /* hit the end of 20M channels, go to 40M if bw was unspecified */ in wf_chanspec_iter_next_2g()
1131 iter->state = WF_ITER_DONE; in wf_chanspec_iter_next_2g()
1136 if (CHSPEC_SB_LOWER(iter->chanspec)) { in wf_chanspec_iter_next_2g()
1147 iter->state = WF_ITER_DONE; in wf_chanspec_iter_next_2g()
1152 iter->chanspec = chspec; in wf_chanspec_iter_next_2g()
1159 * The 5g iterator uses ranges of primary 20MHz channels, and the current BW, to create
1167 chanspec_t chspec = iter->chanspec; in wf_chanspec_iter_next_5g()
1170 uint8 end = iter->range.end; in wf_chanspec_iter_next_5g()
1180 ch = iter->range.start; in wf_chanspec_iter_next_5g()
1181 } else if (iter->bw == INVCHANSPEC) { in wf_chanspec_iter_next_5g()
1186 iter->range_id = RANGE_ID_INVAL; in wf_chanspec_iter_next_5g()
1188 ch = iter->range.start; in wf_chanspec_iter_next_5g()
1194 /* no more channels, ranges, or BWs */ in wf_chanspec_iter_next_5g()
1203 iter->chanspec = chspec; in wf_chanspec_iter_next_5g()
1207 iter->state = WF_ITER_DONE; in wf_chanspec_iter_next_5g()
1213 * Helper function to set up the next range of primary 20MHz channels to
1215 * iter->range_id
1217 * iter->range.start
1218 * iter->range.end
1225 uint8 range_id = iter->range_id; in wf_chanspec_iter_next_5g_range()
1226 const uint8 *channels; in wf_chanspec_iter_next_5g_range() local
1237 iter->range_id = range_id; in wf_chanspec_iter_next_5g_range()
1238 iter->range = wf_5g_iter_ranges[range_id]; in wf_chanspec_iter_next_5g_range()
1246 channels = wf_5g_40m_chans; in wf_chanspec_iter_next_5g_range()
1249 channels = wf_5g_80m_chans; in wf_chanspec_iter_next_5g_range()
1252 channels = wf_5g_160m_chans; in wf_chanspec_iter_next_5g_range()
1264 uint8 ch = channels[range_id]; in wf_chanspec_iter_next_5g_range()
1267 iter->range_id = range_id; in wf_chanspec_iter_next_5g_range()
1268 iter->range.start = ch - offset; in wf_chanspec_iter_next_5g_range()
1269 iter->range.end = ch + offset; in wf_chanspec_iter_next_5g_range()
1278 * The 6g iterator uses ranges of primary 20MHz channels, and the current BW, to create
1280 * Each BW in 6g has one contiguous range of primary 20MHz channels. When a range is
1286 chanspec_t chspec = iter->chanspec; in wf_chanspec_iter_next_6g()
1289 uint8 end = iter->range.end; in wf_chanspec_iter_next_6g()
1304 * of the valid channels in the range. in wf_chanspec_iter_next_6g()
1313 * Note: (iter->bw == INVCHANSPEC) indicates an unspecified BW for the interation, in wf_chanspec_iter_next_6g()
1317 iter->bw == INVCHANSPEC && in wf_chanspec_iter_next_6g()
1320 ch = iter->range.start; in wf_chanspec_iter_next_6g()
1324 iter->chanspec = chspec; in wf_chanspec_iter_next_6g()
1328 iter->state = WF_ITER_DONE; in wf_chanspec_iter_next_6g()
1335 * primary channels for the 6g band and for the BW being iterated.
1349 iter->range.start = CH_MIN_6G_CHANNEL; in wf_chanspec_iter_6g_range_init()
1350 iter->range.end = CH_MAX_6G_CHANNEL; in wf_chanspec_iter_6g_range_init()
1378 /* We don't have an array of legal 20MHz 5G channels, but they are in wf_valid_20MHz_chan()
1379 * each side of the legal 40MHz channels. Check the chanspec in wf_valid_20MHz_chan()
1380 * channel against either side of the 40MHz channels. in wf_valid_20MHz_chan()
1397 /* check for legacy JP channels on failure */ in wf_valid_20MHz_chan()
1411 /* Use the simple pattern of 6GHz 20MHz channels for validity check */ in wf_valid_20MHz_chan()
1414 ((((channel - CH_MIN_6G_CHANNEL) % 4) == 0) || // even multiple of 4 in wf_valid_20MHz_chan()
1441 /* use the 5GHz lookup of 40MHz channels */ in wf_valid_40MHz_center_chan()
1449 /* Use the simple pattern of 6GHz center channels */ in wf_valid_40MHz_center_chan()
1452 ((center_channel - CH_MIN_6G_40M_CHANNEL) % 8) == 0) { // even multiple of 8 in wf_valid_40MHz_center_chan()
1500 /* use the 5GHz lookup of 40MHz channels */ in wf_valid_160MHz_center_chan()
1507 /* Use the simple pattern of 6GHz center channels */ in wf_valid_160MHz_center_chan()
1510 ((center_channel - CH_MIN_6G_160M_CHANNEL) % 32) == 0) { // even multiple of 32 in wf_valid_160MHz_center_chan()
1530 /* Use the simple pattern of 6GHz center channels */ in wf_valid_240MHz_center_chan()
1533 ((center_channel - CH_MIN_6G_240M_CHANNEL) % 48) == 0) { // even multiple of 48 in wf_valid_240MHz_center_chan()
1553 /* Use the simple pattern of 6GHz center channels */ in wf_valid_320MHz_center_chan()
1556 ((center_channel - CH_MIN_6G_320M_CHANNEL) % 64) == 0) { // even multiple of 64 in wf_valid_320MHz_center_chan()
1565 * This function returns TRUE if both the chanspec can co-exist in PHY.
1566 * Addition to primary20 channel, the function checks for side band for 2g 40 channels
1621 * The center_channel can be one of the 802.11 spec valid 40MHz chenter channels
1633 * Will return -1 if not a valid pair for 40MHz in wf_create_40MHz_chspec()
1651 * the sub-band for the primary 20MHz channel, and the band.
1654 * @param primary_subband sub-band of the 20MHz primary channel (chanspec_subband_t value)
1657 * The primary channel and sub-band should describe one of the 802.11 spec valid
1658 * 40MHz channels in the given band.
1672 center_channel = primary_channel - CH_10MHZ_APART; in wf_create_40MHz_chspec_primary_sb()
1700 * Will return -1 if not a valid pair for 80MHz in wf_create_80MHz_chspec()
1735 * Will return -1 if not a valid pair for 160MHz in wf_create_160MHz_chspec()
1761 * The primary channel must be contained in one of the 80 MHz channels. This routine
1766 * Refer to 802.11-2016 section 21.3.14 "Channelization".
1774 int chan0_id = -1, chan1_id = -1; in wf_create_8080MHz_chspec()
1777 /* frequency segments need to be non-contiguous, so the channel separation needs in wf_create_8080MHz_chspec()
1780 if ((uint)ABS((int)(chan0 - chan1)) <= CH_80MHZ_APART) { in wf_create_8080MHz_chspec()
1793 if (chan0_id == -1 || chan1_id == -1) { in wf_create_8080MHz_chspec()
1834 * The primary channel must be contained in one of the 160 MHz channels. This routine
1847 int chan0_id = -1, chan1_id = -1; in wf_create_160160MHz_chspec()
1850 /* frequency segments need to be non-contiguous, so the channel separation needs in wf_create_160160MHz_chspec()
1853 if ((uint)ABS((int)(chan0 - chan1)) <= CH_160MHZ_APART) { in wf_create_160160MHz_chspec()
1866 if (chan0_id == -1 || chan1_id == -1) { in wf_create_160160MHz_chspec()
1914 int chan_id = -1; in wf_create_240MHz_chspec()
1921 if (chan_id == -1) { in wf_create_240MHz_chspec()
1926 * Will return -1 if not a valid pair for 240MHz in wf_create_240MHz_chspec()
1954 * The primary channel must be contained in one of the 320 MHz channels.
1965 int chan_id = -1; in wf_create_320MHz_chspec()
1972 if (chan_id == -1) { in wf_create_320MHz_chspec()
1977 * Will return -1 if not a valid pair for 320MHz in wf_create_320MHz_chspec()
2008 * The center_channel can be one of the 802.11 spec valid center channels
2018 int sb = -1; in wf_create_chspec()
2021 /* 20MHz channels have matching center and primary channels */ in wf_create_chspec()
2032 /* calculate the sub-band index */ in wf_create_chspec()
2036 /* if we have a good sub-band, assemble the chanspec, and use wf_chspec_valid() in wf_create_chspec()
2078 * center_channel parameter. As a result, it can not create 40MHz channels on
2083 * For the 2GHz band, 40MHz channels overlap, so two 40MHz channels may
2087 * 5GHz and 6GHz bands have non-overlapping 40/80/160 MHz channels, so a
2090 * 80+80MHz channels also cannot be uniquely defined. This function will return
2101 /* For 5GHz, use the lookup tables for valid 40/80/160 center channels in wf_create_chspec_from_primary()
2157 mask = ~(ch_per_block - 1); in wf_create_chspec_from_primary()
2158 base = 1 + ((primary_channel - 1) & mask); in wf_create_chspec_from_primary()
2174 * 20MHz channels this is just the channel number. For 40MHz or wider channels
2204 /* convert from channel index to channel number */ in wf_chspec_primary20_chan()
2212 /* convert from channel index to channel number */ in wf_chspec_primary20_chan()
2247 * channels this is just the chanspec. For 40MHz or wider channels it is the
2281 int sb = -1; in wf_channel2chspec()
2330 * The primary 40MHz channel is the 40MHz sub-band that contains the primary 20MHz channel.
2352 /* determine primary 40 MHz sub-channel of an 80 MHz chanspec */ in wf_chspec_primary40_chspec()
2359 center_chan -= CH_20MHZ_APART; in wf_chspec_primary40_chspec()
2365 sb -= WL_CHANSPEC_CTL_SB_UL; in wf_chspec_primary40_chspec()
2382 * @return Returns a channel number > 0, or -1 on error
2392 * freq (GHz) -> assumed base freq (GHz)
2393 * 2G band 2.4 - 2.5 2.407
2394 * 5G band 5.0 - 5.940 5.000
2395 * 6G band 5.940 - 7.205 5.940
2411 * Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
2416 int ch = -1; in wf_mhz2channel()
2438 return -1; in wf_mhz2channel()
2444 return -1; in wf_mhz2channel()
2447 offset = freq - base; in wf_mhz2channel()
2452 return -1; in wf_mhz2channel()
2457 * handled above as it is a non-5MHz offset in wf_mhz2channel()
2460 ch = -1; in wf_mhz2channel()
2466 ch = -1; in wf_mhz2channel()
2469 ch = -1; in wf_mhz2channel()
2487 * Odd start_factors produce channels on .5 MHz boundaries, in which case
2489 * -1 is returned for an out of range channel.
2491 * Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
2510 freq = -1; in wf_channel2mhz()
2533 * primary_channel - primary 20Mhz channel
2534 * center_channel - center frequecny of the 80Mhz channel
2567 * primary_20mhz - Primary 20 MHz channel
2568 * chan0 - center channel number of one frequency segment
2569 * chan1 - center channel number of the other frequency segment
2572 * The primary channel must be contained in one of the 80MHz channels. This routine
2577 * Refer to 802.11-2016 section 22.3.14 "Channelization".
2593 if (chan0_id == -1 || chan1_id == -1) in wf_chspec_get8080_chspec()
2624 * Returns the center channel of the primary 80 MHz sub-band of the provided chanspec
2644 * Returns the center channel of the secondary 80 MHz sub-band of the provided chanspec
2664 * Returns the chanspec for the primary 80MHz sub-band of an 160MHz or 80+80 channel
2683 center_chan -= CH_40MHZ_APART; in wf_chspec_primary80_chspec()
2688 sb -= WL_CHANSPEC_CTL_SB_ULL; in wf_chspec_primary80_chspec()
2702 * Returns the chanspec for the secondary 80MHz sub-band of an 160MHz or 80+80 channel
2724 center_chan -= CH_40MHZ_APART; in wf_chspec_secondary80_chspec()
2741 * For 160MHz or 80P80 chanspec, set ch[0]/ch[1] to be the low/high 80 Mhz channels
2743 * For 20/40/80MHz chanspec, set ch[0] to be the center freq, and chan[1]=-1
2751 ch[0] = center_chan - CH_40MHZ_APART; in wf_chspec_get_80p80_channels()
2757 ch[1] = -1; in wf_chspec_get_80p80_channels()
2764 * Returns the center channel of the primary 160MHz sub-band of the provided chanspec
2784 * Returns the chanspec for the primary 160MHz sub-band of an 240/320MHz or 160+160 channel
2808 center_chan -= CH_40MHZ_APART; in wf_chspec_primary160_chspec()
2812 sb -= 4u; in wf_chspec_primary160_chspec()
2829 center_chan -= CH_80MHZ_APART; in wf_chspec_primary160_chspec()
2834 sb -= 8u; in wf_chspec_primary160_chspec()
2869 (pext)[1] = (IS_CTL_IN_L20(t) ? pri_ch + CH_20MHZ_APART : pri_ch - CH_20MHZ_APART); in wf_get_all_ext()
2876 pri_ch + CH_40MHZ_APART : pri_ch - CH_40MHZ_APART), WL_CHANSPEC_BW_40); in wf_get_all_ext()
2901 if ((uint)ABS(ch0 - ch1) < CH_20MHZ_APART) { in wf_chspec_overlap()
2964 /* frequency segments need to be non-contiguous, so the channel in wf_create_160160MHz_chspec_sb()
2967 if ((uint)ABS((int)(chan0 - chan1)) <= CH_160MHZ_APART) { in wf_create_160160MHz_chspec_sb()
2982 if ((chan0_id == -1) || (chan1_id == -1)) { in wf_create_160160MHz_chspec_sb()
2994 sb -= WL_CHANSPEC_CTL_SB_ULL; in wf_create_160160MHz_chspec_sb()