18ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt/* 28ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Misc utility routines used by kernel or app-level. 38ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Contents are wifi-specific, used by any kernel or app-level 48ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * software that might want wifi things as it grows. 58ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 6832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt * Copyright (C) 1999-2012, Broadcom Corporation 78ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 8832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt * Unless you and Broadcom execute a separate written software license 98ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * agreement governing use of this software, this software is licensed to you 108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * under the terms of the GNU General Public License version 2 (the "GPL"), 118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * available at http://www.broadcom.com/licenses/GPLv2.php, with the 128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * following added to such license: 138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * As a special exception, the copyright holders of this software give you 158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * permission to link this software with independent modules, and to copy and 168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * distribute the resulting executable under terms of your choice, provided that 178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * you also meet, for each linked independent module, the terms and conditions of 188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * the license of that module. An independent module is a module which is not 198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * derived from this software. The special exception does not apply to any 208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * modifications of the software. 218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * 228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * Notwithstanding the above, under no circumstances may you combine this 238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * software in any way with any other Broadcom software provided under a license 248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt * other than the GPL, without Broadcom's express prior written consent. 254a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt * $Id: bcmwifi_channels.c 309193 2012-01-19 00:03:57Z $ 268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt */ 278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 28832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#include <bcm_cfg.h> 298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <typedefs.h> 308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifdef BCMDRIVER 328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <osl.h> 338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmutils.h> 348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) 358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c)) 368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#else 378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <stdio.h> 388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <stdlib.h> 398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <ctype.h> 408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#ifndef ASSERT 418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#define ASSERT(exp) 428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 444a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt 454a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#ifdef _bcmwifi_c_ 464a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt 478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmwifi.h> 484a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#else 494a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#include <bcmwifi_channels.h> 504a3a0faf9abf605caf9ff7b27755d867b9ac9403Dmitry Shmidt#endif 518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL)) 538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#include <bcmstdlib.h> 548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt#endif 558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 56832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#ifndef D11AC_IOTYPES 57832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 58832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 59832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchar * 658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_chspec_ntoa(chanspec_t chspec, char *buf) 668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt const char *band, *bw, *sb; 688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint channel; 698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 708ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt band = ""; 718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = ""; 728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sb = ""; 738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel = CHSPEC_CHANNEL(chspec); 748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) || 768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL)) 778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt band = (CHSPEC_IS2G(chspec)) ? "b" : "a"; 788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_IS40(chspec)) { 798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_SB_UPPER(chspec)) { 808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sb = "u"; 818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel += CH_10MHZ_APART; 828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt sb = "l"; 848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel -= CH_10MHZ_APART; 858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else if (CHSPEC_IS10(chspec)) { 878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = "n"; 888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb); 928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (buf); 938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchanspec_t 97832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_aton(const char *a) 988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt char *endp = NULL; 1008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint channel, band, bw, ctl_sb; 1018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt char c; 1028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel = strtoul(a, &endp, 10); 1048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (endp == a) 1078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 1088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (channel > MAXCHANNEL) 1108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 1118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); 1138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = WL_CHANSPEC_BW_20; 1148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_sb = WL_CHANSPEC_CTL_SB_NONE; 1158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt a = endp; 1178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt c = tolower(a[0]); 1198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (c == '\0') 1208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto done; 1218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (c == 'a' || c == 'b') { 1248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G; 1258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt a++; 1268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt c = tolower(a[0]); 1278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (c == '\0') 1288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt goto done; 1298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (c == 'n') { 1338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = WL_CHANSPEC_BW_10; 1348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else if (c == 'l') { 1358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = WL_CHANSPEC_BW_40; 1368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_sb = WL_CHANSPEC_CTL_SB_LOWER; 1378ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1388ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (channel <= (MAXCHANNEL - CH_20MHZ_APART)) 1398ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel += CH_10MHZ_APART; 1408ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 1418ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 1428ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else if (c == 'u') { 1438ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt bw = WL_CHANSPEC_BW_40; 1448ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_sb = WL_CHANSPEC_CTL_SB_UPPER; 1458ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1468ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (channel > CH_20MHZ_APART) 1478ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel -= CH_10MHZ_APART; 1488ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 1498ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 1508ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 1518ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 0; 1528ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1538ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1548ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtdone: 1558ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return (channel | band | bw | ctl_sb); 1568ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 1578ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1588ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1598ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtbool 1608ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_chspec_malformed(chanspec_t chanspec) 1618ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 1628ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1638ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) 1648ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return TRUE; 1658ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1668ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec)) 1678ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return TRUE; 1688ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1698ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 170832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS20(chanspec)) { 1718ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!CHSPEC_SB_NONE(chanspec)) 1728ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return TRUE; 1738ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 1748ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) 1758ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return TRUE; 1768ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 1778ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1788ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return FALSE; 1798ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 1808ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1818ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtuint8 1838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_chspec_ctlchan(chanspec_t chspec) 1848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 1858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint8 ctl_chan; 1868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { 1898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return CHSPEC_CHANNEL(chspec); 1908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 1918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40); 1938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { 1958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 1968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); 1978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 1988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER); 1998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); 2018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return ctl_chan; 2058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 2068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtchanspec_t 2088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_chspec_ctlchspec(chanspec_t chspec) 2098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 2108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt chanspec_t ctl_chspec = 0; 2118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint8 channel; 2128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ASSERT(!wf_chspec_malformed(chspec)); 2148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 2168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { 2178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return chspec; 2188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 2198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { 2208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); 2218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } else { 2228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); 2238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; 2258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ctl_chspec |= CHSPEC_BAND(chspec); 2268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 2278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return ctl_chspec; 2288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 2298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 230832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#else 231832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 232832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 233832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 234832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 235832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 236832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 237832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic const char *wf_chspec_bw_str[] = 238832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 239832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "5", 240832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "10", 241832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "20", 242832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "40", 243832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "80", 244832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "160", 245832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "80+80", 246832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt "na" 247832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt}; 248832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 249832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic const uint8 wf_chspec_bw_mhz[] = 250832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{5, 10, 20, 40, 80, 160, 160}; 251832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 252832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define WF_NUM_BW \ 253832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt (sizeof(wf_chspec_bw_mhz)/sizeof(uint8)) 254832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 255832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 256832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic const uint8 wf_5g_40m_chans[] = 257832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159}; 258832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define WF_NUM_5G_40M_CHANS \ 259832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt (sizeof(wf_5g_40m_chans)/sizeof(uint8)) 260832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 261832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 262832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic const uint8 wf_5g_80m_chans[] = 263832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{42, 58, 106, 122, 138, 155}; 264832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define WF_NUM_5G_80M_CHANS \ 265832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt (sizeof(wf_5g_80m_chans)/sizeof(uint8)) 266832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 267832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 268832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic const uint8 wf_5g_160m_chans[] = 269832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{50, 114}; 270832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#define WF_NUM_5G_160M_CHANS \ 271832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt (sizeof(wf_5g_160m_chans)/sizeof(uint8)) 272832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 273832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 274832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 275832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic uint 276832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbw_chspec_to_mhz(chanspec_t chspec) 277832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 278832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint bw; 279832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 280832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT; 281832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (bw >= WF_NUM_BW ? 0 : wf_chspec_bw_mhz[bw]); 282832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 283832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 284832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 285832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic uint8 286832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtcenter_chan_to_edge(uint bw) 287832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 288832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 289832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (uint8)(((bw - 20) / 2) / 5); 290832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 291832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 292832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 293832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic uint8 294832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchannel_low_edge(uint center_ch, uint bw) 295832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 296832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (uint8)(center_ch - center_chan_to_edge(bw)); 297832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 298832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 299832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 300832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic int 301832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchannel_to_sb(uint center_ch, uint ctl_ch, uint bw) 302832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 303832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint lowest = channel_low_edge(center_ch, bw); 304832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint sb; 305832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 306832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if ((ctl_ch - lowest) % 4) { 307832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 308832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return -1; 309832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 310832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 311832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = ((ctl_ch - lowest) / 4); 312832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 313832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 314832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb >= (bw / 20)) { 315832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 316832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return -1; 317832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 318832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 319832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return sb; 320832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 321832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 322832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 323832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic uint8 324832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchannel_to_ctl_chan(uint center_ch, uint bw, uint sb) 325832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 326832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (uint8)(channel_low_edge(center_ch, bw) + sb * 4); 327832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 328832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 329832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 330832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic int 331832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchannel_80mhz_to_id(uint ch) 332832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 333832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint i; 334832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt for (i = 0; i < WF_NUM_5G_80M_CHANS; i ++) { 335832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (ch == wf_5g_80m_chans[i]) 336832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return i; 337832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 338832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 339832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return -1; 340832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 341832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 342832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 343832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchar * 344832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_ntoa(chanspec_t chspec, char *buf) 345832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 346832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt const char *band; 347832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint ctl_chan; 348832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 349832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (wf_chspec_malformed(chspec)) 350832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return NULL; 351832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 352832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt band = ""; 353832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 354832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 355832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if ((CHSPEC_IS2G(chspec) && CHSPEC_CHANNEL(chspec) > CH_MAX_2G_CHANNEL) || 356832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt (CHSPEC_IS5G(chspec) && CHSPEC_CHANNEL(chspec) <= CH_MAX_2G_CHANNEL)) 357832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt band = (CHSPEC_IS2G(chspec)) ? "2g" : "5g"; 358832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 359832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 360832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ctl_chan = wf_chspec_ctlchan(chspec); 361832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 362832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 363832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS20(chspec)) { 364832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, ctl_chan); 365832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (!CHSPEC_IS8080(chspec)) { 366832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt const char *bw; 367832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt const char *sb = ""; 368832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 369832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt bw = wf_chspec_bw_str[(chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT]; 370832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 371832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#ifdef CHANSPEC_NEW_40MHZ_FORMAT 372832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 373832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS40(chspec) && CHSPEC_IS2G(chspec)) { 374832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; 375832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 376832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 377832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s%s", band, ctl_chan, bw, sb); 378832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#else 379832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 380832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS40(chspec)) { 381832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l"; 382832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt snprintf(buf, CHANSPEC_STR_LEN, "%s%d%s", band, ctl_chan, sb); 383832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 384832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, ctl_chan, bw); 385832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 386832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#endif 387832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 388832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 389832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 390832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chan1 = (chspec & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT; 391832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chan2 = (chspec & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT; 392832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 393832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 394832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chan1 = (chan1 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan1] : 0; 395832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chan2 = (chan2 < WF_NUM_5G_80M_CHANS) ? wf_5g_80m_chans[chan2] : 0; 396832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 397832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 398832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt snprintf(buf, CHANSPEC_STR_LEN, "%d/80+80/%d-%d", ctl_chan, chan1, chan2); 399832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 400832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 401832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (buf); 402832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 403832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 404832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtstatic int 405832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtread_uint(const char **p, unsigned int *num) 406832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 407832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt unsigned long val; 408832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt char *endp = NULL; 409832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 410832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt val = strtoul(*p, &endp, 10); 411832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 412832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (endp == *p) 413832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 414832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 415832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 416832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt *p = endp; 417832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 418832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt *num = (unsigned int)val; 419832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 420832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 1; 421832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 422832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 423832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 424832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchanspec_t 425832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_aton(const char *a) 426832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 427832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chanspec_t chspec; 428832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chspec_ch, chspec_band, bw, chspec_bw, chspec_sb; 429832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint num, ctl_ch; 430832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint ch1, ch2; 431832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt char c, sb_ul = '\0'; 432832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt int i; 433832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 434832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt bw = 20; 435832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = 0; 436832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = ch1 = ch2 = 0; 437832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 438832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 439832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!read_uint(&a, &num)) 440832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 441832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 442832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 443832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt c = tolower(a[0]); 444832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c == 'g') { 445832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 446832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 447832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 448832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (num == 2) 449832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_band = WL_CHANSPEC_BAND_2G; 450832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else if (num == 5) 451832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_band = WL_CHANSPEC_BAND_5G; 452832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else 453832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 454832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 455832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 456832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!read_uint(&a, &ctl_ch)) 457832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 458832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 459832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt c = tolower(a[0]); 460832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 461832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else { 462832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 463832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ctl_ch = num; 464832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_band = ((ctl_ch <= CH_MAX_2G_CHANNEL) ? 465832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); 466832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 467832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 468832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c == '\0') { 469832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 470832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_20; 471832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt goto done_read; 472832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 473832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 474832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 475832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 476832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 477832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c == 'u' || c == 'l') { 478832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb_ul = c; 479832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_40; 480832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt goto done_read; 481832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 482832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 483832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 484832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c != '/') 485832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 486832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 487832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 488832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!read_uint(&a, &bw)) 489832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 490832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 491832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 492832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (bw == 20) { 493832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_20; 494832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (bw == 40) { 495832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_40; 496832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (bw == 80) { 497832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_80; 498832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (bw == 160) { 499832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_160; 500832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 501832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 502832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 503832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 504832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 505832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 506832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt c = tolower(a[0]); 507832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 508832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 509832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) { 510832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c == 'u' || c == 'l') { 511832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 512832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb_ul = c; 513832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt goto done_read; 514832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 515832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 516832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 517832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 518832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (c == '+') { 519832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 520832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt static const char *plus80 = "80/"; 521832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 522832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 523832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw = WL_CHANSPEC_BW_8080; 524832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 525832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 526832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 527832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 528832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt for (i = 0; i < 3; i++) { 529832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (*a++ != *plus80++) { 530832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 531832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 532832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 533832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 534832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 535832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!read_uint(&a, &ch1)) 536832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 537832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 538832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 539832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (a[0] != '-') 540832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 541832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 542832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 543832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 544832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!read_uint(&a, &ch2)) 545832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 546832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 547832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 548832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtdone_read: 549832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 550832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt while (a[0] == ' ') { 551832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt a ++; 552832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 553832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 554832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 555832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (a[0] != '\0') 556832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 557832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 558832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 559832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 560832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 561832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb_ul != '\0') { 562832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb_ul == 'l') { 563832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = UPPER_20_SB(ctl_ch); 564832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = WL_CHANSPEC_CTL_SB_LLL; 565832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (sb_ul == 'u') { 566832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = LOWER_20_SB(ctl_ch); 567832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = WL_CHANSPEC_CTL_SB_LLU; 568832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 569832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 570832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 571832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else if (chspec_bw == WL_CHANSPEC_BW_20) { 572832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = ctl_ch; 573832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = 0; 574832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 575832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 576832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else if (chspec_bw != WL_CHANSPEC_BW_8080) { 577832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 578832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt const uint8 *center_ch = NULL; 579832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt int num_ch = 0; 580832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt int sb = -1; 581832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 582832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_40) { 583832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_40m_chans; 584832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_40M_CHANS; 585832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_80) { 586832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_80m_chans; 587832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_80M_CHANS; 588832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_160) { 589832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_160m_chans; 590832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_160M_CHANS; 591832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 592832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 593832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 594832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 595832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt for (i = 0; i < num_ch; i ++) { 596832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = channel_to_sb(center_ch[i], ctl_ch, bw); 597832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb >= 0) { 598832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = center_ch[i]; 599832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; 600832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt break; 601832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 602832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 603832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 604832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 605832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb < 0) { 606832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 607832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 608832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 609832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 610832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else { 611832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt int ch1_id = 0, ch2_id = 0; 612832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt int sb; 613832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 614832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch1_id = channel_80mhz_to_id(ch1); 615832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch2_id = channel_80mhz_to_id(ch2); 616832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 617832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 618832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (ch1 >= ch2 || ch1_id < 0 || ch2_id < 0) 619832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 620832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 621832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 622832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch = (((uint16)ch1_id << WL_CHANSPEC_CHAN1_SHIFT) | 623832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ((uint16)ch2_id << WL_CHANSPEC_CHAN2_SHIFT)); 624832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 625832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 626832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 627832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 628832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = channel_to_sb(ch1, ctl_ch, bw); 629832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb < 0) { 630832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 631832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = channel_to_sb(ch2, ctl_ch, bw); 632832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb < 0) { 633832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 634832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 635832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 636832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 637832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb += 4; 638832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 639832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 640832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_sb = sb << WL_CHANSPEC_CTL_SB_SHIFT; 641832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 642832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 643832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec = (chspec_ch | chspec_band | chspec_bw | chspec_sb); 644832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 645832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (wf_chspec_malformed(chspec)) 646832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return 0; 647832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 648832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return chspec; 649832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 650832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 651832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 652832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbool 653832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_malformed(chanspec_t chanspec) 654832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 655832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chspec_bw = CHSPEC_BW(chanspec); 656832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chspec_ch = CHSPEC_CHANNEL(chanspec); 657832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 658832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 659832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS2G(chanspec)) { 660832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 661832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw != WL_CHANSPEC_BW_20 && 662832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw != WL_CHANSPEC_BW_40) { 663832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 664832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 665832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (CHSPEC_IS5G(chanspec)) { 666832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_8080) { 667832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint ch1_id, ch2_id; 668832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 669832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 670832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch1_id = CHSPEC_CHAN1(chanspec); 671832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch2_id = CHSPEC_CHAN2(chanspec); 672832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (ch1_id >= WF_NUM_5G_80M_CHANS || ch2_id >= WF_NUM_5G_80M_CHANS) 673832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 674832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 675832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 676832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (ch2_id <= ch1_id) 677832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 678832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 || 679832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) { 680832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 681832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch > MAXCHANNEL) { 682832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 683832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 684832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 685832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 686832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 687832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 688832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 689832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 690832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 691832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 692832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 693832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 694832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_20) { 695832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_CTL_SB(chanspec) != WL_CHANSPEC_CTL_SB_LLL) 696832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 697832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_40) { 698832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LLU) 699832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 700832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_80) { 701832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_CTL_SB(chanspec) > WL_CHANSPEC_CTL_SB_LUU) 702832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 703832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 704832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 705832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return FALSE; 706832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 707832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 708832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 709832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtbool 710832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_valid(chanspec_t chanspec) 711832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 712832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chspec_bw = CHSPEC_BW(chanspec); 713832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint chspec_ch = CHSPEC_CHANNEL(chanspec); 714832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 715832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (wf_chspec_malformed(chanspec)) 716832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return FALSE; 717832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 718832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS2G(chanspec)) { 719832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 720832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_20) { 721832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch >= 1 && chspec_ch <= 14) 722832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 723832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_40) { 724832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch >= 3 && chspec_ch <= 11) 725832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 726832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 727832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (CHSPEC_IS5G(chanspec)) { 728832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_8080) { 729832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint16 ch1, ch2; 730832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 731832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch1 = wf_5g_80m_chans[CHSPEC_CHAN1(chanspec)]; 732832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ch2 = wf_5g_80m_chans[CHSPEC_CHAN2(chanspec)]; 733832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 734832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 735832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (ch2 > ch1 + CH_80MHZ_APART) 736832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 737832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 738832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt const uint8 *center_ch; 739832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint num_ch, i; 740832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 741832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40) { 742832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_40m_chans; 743832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_40M_CHANS; 744832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_80) { 745832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_80m_chans; 746832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_80M_CHANS; 747832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (chspec_bw == WL_CHANSPEC_BW_160) { 748832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_ch = wf_5g_160m_chans; 749832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt num_ch = WF_NUM_5G_160M_CHANS; 750832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 751832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 752832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return FALSE; 753832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 754832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 755832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 756832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_bw == WL_CHANSPEC_BW_20) { 757832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 758832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt for (i = 0; i < num_ch; i ++) { 759832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch == (uint)LOWER_20_SB(center_ch[i]) || 760832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch == (uint)UPPER_20_SB(center_ch[i])) 761832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt break; 762832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 763832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 764832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (i == num_ch) { 765832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 766832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch == 34 || chspec_ch == 38 || 767832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec_ch == 42 || chspec_ch == 46) 768832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt i = 0; 769832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 770832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 771832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 772832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt for (i = 0; i < num_ch; i ++) { 773832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (chspec_ch == center_ch[i]) 774832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt break; 775832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 776832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 777832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 778832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (i < num_ch) { 779832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 780832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return TRUE; 781832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 782832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 783832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 784832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 785832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return FALSE; 786832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 787832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 788832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 789832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtuint8 790832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_ctlchan(chanspec_t chspec) 791832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 792832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint center_chan; 793832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint bw_mhz; 794832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint sb; 795832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 796832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ASSERT(!wf_chspec_malformed(chspec)); 797832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 798832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 799832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS20(chspec)) { 800832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return CHSPEC_CHANNEL(chspec); 801832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 802832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT; 803832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 804832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS8080(chspec)) { 805832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt bw_mhz = 80; 806832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 807832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb < 4) { 808832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan = CHSPEC_CHAN1(chspec); 809832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 810832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else { 811832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan = CHSPEC_CHAN2(chspec); 812832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb -= 4; 813832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 814832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 815832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 816832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan = wf_5g_80m_chans[center_chan]; 817832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 818832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt else { 819832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt bw_mhz = bw_chspec_to_mhz(chspec); 820832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT; 821832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 822832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 823832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return (channel_to_ctl_chan(center_chan, bw_mhz, sb)); 824832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 825832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 826832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 827832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 828832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtchanspec_t 829832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtwf_chspec_ctlchspec(chanspec_t chspec) 830832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 831832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chanspec_t ctl_chspec = chspec; 832832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint8 ctl_chan; 833832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 834832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ASSERT(!wf_chspec_malformed(chspec)); 835832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 836832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 837832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (!CHSPEC_IS20(chspec)) { 838832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ctl_chan = wf_chspec_ctlchan(chspec); 839832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ctl_chspec = ctl_chan | WL_CHANSPEC_BW_20; 840832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ctl_chspec |= CHSPEC_BAND(chspec); 841832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 842832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return ctl_chspec; 843832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 844832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 845832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt#endif 846832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 847832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 848832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidtextern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec) 849832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt{ 850832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chanspec_t chspec40 = chspec; 851832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint center_chan; 852832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt uint sb; 853832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 854832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt ASSERT(!wf_chspec_malformed(chspec)); 855832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 856832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (CHSPEC_IS80(chspec)) { 857832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan = CHSPEC_CHANNEL(chspec); 858832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = CHSPEC_CTL_SB(chspec); 859832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 860832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt if (sb == WL_CHANSPEC_CTL_SB_UL) { 861832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 862832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = WL_CHANSPEC_CTL_SB_L; 863832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan += CH_20MHZ_APART; 864832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else if (sb == WL_CHANSPEC_CTL_SB_UU) { 865832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 866832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb = WL_CHANSPEC_CTL_SB_U; 867832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan += CH_20MHZ_APART; 868832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } else { 869832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 870832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 871832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt center_chan -= CH_20MHZ_APART; 872832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 873832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 874832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 875832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt chspec40 = (WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_40 | 876832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt sb | center_chan); 877832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt } 878832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 879832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt return chspec40; 880832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt} 881832523286e7a5d2fb5ea9f4b87659508d44cdf45Dmitry Shmidt 8828ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 8838ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint 8848ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_mhz2channel(uint freq, uint start_factor) 8858ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 8868ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int ch = -1; 8878ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt uint base; 8888ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int offset; 8898ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 8908ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 8918ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (start_factor == 0) { 8928ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (freq >= 2400 && freq <= 2500) 8938ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt start_factor = WF_CHAN_FACTOR_2_4_G; 8948ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else if (freq >= 5000 && freq <= 6000) 8958ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt start_factor = WF_CHAN_FACTOR_5_G; 8968ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt } 8978ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 8988ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) 8998ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return 14; 9008ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9018ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt base = start_factor / 2; 9028ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9038ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9048ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if ((freq < base) || (freq > base + 1000)) 9058ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -1; 9068ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9078ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt offset = freq - base; 9088ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt ch = offset / 5; 9098ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9108ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9118ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (offset != (ch * 5)) 9128ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -1; 9138ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9148ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9158ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13)) 9168ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return -1; 9178ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9188ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return ch; 9198ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 9208ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9218ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9228ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtint 9238ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidtwf_channel2mhz(uint ch, uint start_factor) 9248ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt{ 9258ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt int freq; 9268ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9278ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || 9288ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt (ch > 200)) 9298ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt freq = -1; 9308ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) 9318ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt freq = 2484; 9328ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt else 9338ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt freq = ch * 5 + start_factor / 2; 9348ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt 9358ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt return freq; 9368ce1727333a1c411bb88330d69f82386a118c6bfDmitry Shmidt} 937