Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/external/cache/sources/wl/shared/bcmwifi.c
Views: 3959
/*1* Misc utility routines used by kernel or app-level.2* Contents are wifi-specific, used by any kernel or app-level3* software that might want wifi things as it grows.4*5* $Copyright Open Broadcom Corporation$6* $Id: bcmwifi.c 241182 2011-02-17 21:50:03Z gmo $7*/89#include <typedefs.h>1011#ifdef BCMDRIVER12#include <osl.h>13#include <bcmutils.h>14#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))15#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))16#else17#include <stdio.h>18#include <stdlib.h>19#include <ctype.h>20#ifndef ASSERT21#define ASSERT(exp)22#endif23#endif24#include <bcmwifi.h>2526#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))27#include <bcmstdlib.h>28#endif293031323334char *35wf_chspec_ntoa(chanspec_t chspec, char *buf)36{37const char *band, *bw, *sb;38uint channel;3940band = "";41bw = "";42sb = "";43channel = CHSPEC_CHANNEL(chspec);4445if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) ||46(CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL))47band = (CHSPEC_IS2G(chspec)) ? "b" : "a";48if (CHSPEC_IS40(chspec)) {49if (CHSPEC_SB_UPPER(chspec)) {50sb = "u";51channel += CH_10MHZ_APART;52} else {53sb = "l";54channel -= CH_10MHZ_APART;55}56} else if (CHSPEC_IS10(chspec)) {57bw = "n";58}596061snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb);62return (buf);63}646566chanspec_t67wf_chspec_aton(char *a)68{69char *endp = NULL;70uint channel, band, bw, ctl_sb;71char c;7273channel = strtoul(a, &endp, 10);747576if (endp == a)77return 0;7879if (channel > MAXCHANNEL)80return 0;8182band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);83bw = WL_CHANSPEC_BW_20;84ctl_sb = WL_CHANSPEC_CTL_SB_NONE;8586a = endp;8788c = tolower(a[0]);89if (c == '\0')90goto done;919293if (c == 'a' || c == 'b') {94band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;95a++;96c = tolower(a[0]);97if (c == '\0')98goto done;99}100101102if (c == 'n') {103bw = WL_CHANSPEC_BW_10;104} else if (c == 'l') {105bw = WL_CHANSPEC_BW_40;106ctl_sb = WL_CHANSPEC_CTL_SB_LOWER;107108if (channel <= (MAXCHANNEL - CH_20MHZ_APART))109channel += CH_10MHZ_APART;110else111return 0;112} else if (c == 'u') {113bw = WL_CHANSPEC_BW_40;114ctl_sb = WL_CHANSPEC_CTL_SB_UPPER;115116if (channel > CH_20MHZ_APART)117channel -= CH_10MHZ_APART;118else119return 0;120} else {121return 0;122}123124done:125return (channel | band | bw | ctl_sb);126}127128129bool130wf_chspec_malformed(chanspec_t chanspec)131{132133if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))134return TRUE;135136if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))137return TRUE;138139140if (CHSPEC_IS20(chanspec)) {141if (!CHSPEC_SB_NONE(chanspec))142return TRUE;143} else {144if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))145return TRUE;146}147148return FALSE;149}150151152uint8153wf_chspec_ctlchan(chanspec_t chspec)154{155uint8 ctl_chan;156157158if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {159return CHSPEC_CHANNEL(chspec);160} else {161162ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40);163164if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {165166ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));167} else {168ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER);169170ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));171}172}173174return ctl_chan;175}176177chanspec_t178wf_chspec_ctlchspec(chanspec_t chspec)179{180chanspec_t ctl_chspec = 0;181uint8 channel;182183ASSERT(!wf_chspec_malformed(chspec));184185186if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {187return chspec;188} else {189if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {190channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec));191} else {192channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec));193}194ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;195ctl_chspec |= CHSPEC_BAND(chspec);196}197return ctl_chspec;198}199200201int202wf_mhz2channel(uint freq, uint start_factor)203{204int ch = -1;205uint base;206int offset;207208209if (start_factor == 0) {210if (freq >= 2400 && freq <= 2500)211start_factor = WF_CHAN_FACTOR_2_4_G;212else if (freq >= 5000 && freq <= 6000)213start_factor = WF_CHAN_FACTOR_5_G;214}215216if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)217return 14;218219base = start_factor / 2;220221222if ((freq < base) || (freq > base + 1000))223return -1;224225offset = freq - base;226ch = offset / 5;227228229if (offset != (ch * 5))230return -1;231232233if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))234return -1;235236return ch;237}238239240int241wf_channel2mhz(uint ch, uint start_factor)242{243int freq;244245if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||246(ch > 200))247freq = -1;248else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14))249freq = 2484;250else251freq = ch * 5 + start_factor / 2;252253return freq;254}255256257