CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/wl/shared/bcmwifi.c
Views: 3959
1
/*
2
* Misc utility routines used by kernel or app-level.
3
* Contents are wifi-specific, used by any kernel or app-level
4
* software that might want wifi things as it grows.
5
*
6
* $Copyright Open Broadcom Corporation$
7
* $Id: bcmwifi.c 241182 2011-02-17 21:50:03Z gmo $
8
*/
9
10
#include <typedefs.h>
11
12
#ifdef BCMDRIVER
13
#include <osl.h>
14
#include <bcmutils.h>
15
#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
16
#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
17
#else
18
#include <stdio.h>
19
#include <stdlib.h>
20
#include <ctype.h>
21
#ifndef ASSERT
22
#define ASSERT(exp)
23
#endif
24
#endif
25
#include <bcmwifi.h>
26
27
#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
28
#include <bcmstdlib.h>
29
#endif
30
31
32
33
34
35
char *
36
wf_chspec_ntoa(chanspec_t chspec, char *buf)
37
{
38
const char *band, *bw, *sb;
39
uint channel;
40
41
band = "";
42
bw = "";
43
sb = "";
44
channel = CHSPEC_CHANNEL(chspec);
45
46
if ((CHSPEC_IS2G(chspec) && channel > CH_MAX_2G_CHANNEL) ||
47
(CHSPEC_IS5G(chspec) && channel <= CH_MAX_2G_CHANNEL))
48
band = (CHSPEC_IS2G(chspec)) ? "b" : "a";
49
if (CHSPEC_IS40(chspec)) {
50
if (CHSPEC_SB_UPPER(chspec)) {
51
sb = "u";
52
channel += CH_10MHZ_APART;
53
} else {
54
sb = "l";
55
channel -= CH_10MHZ_APART;
56
}
57
} else if (CHSPEC_IS10(chspec)) {
58
bw = "n";
59
}
60
61
62
snprintf(buf, 6, "%d%s%s%s", channel, band, bw, sb);
63
return (buf);
64
}
65
66
67
chanspec_t
68
wf_chspec_aton(char *a)
69
{
70
char *endp = NULL;
71
uint channel, band, bw, ctl_sb;
72
char c;
73
74
channel = strtoul(a, &endp, 10);
75
76
77
if (endp == a)
78
return 0;
79
80
if (channel > MAXCHANNEL)
81
return 0;
82
83
band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
84
bw = WL_CHANSPEC_BW_20;
85
ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
86
87
a = endp;
88
89
c = tolower(a[0]);
90
if (c == '\0')
91
goto done;
92
93
94
if (c == 'a' || c == 'b') {
95
band = (c == 'a') ? WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;
96
a++;
97
c = tolower(a[0]);
98
if (c == '\0')
99
goto done;
100
}
101
102
103
if (c == 'n') {
104
bw = WL_CHANSPEC_BW_10;
105
} else if (c == 'l') {
106
bw = WL_CHANSPEC_BW_40;
107
ctl_sb = WL_CHANSPEC_CTL_SB_LOWER;
108
109
if (channel <= (MAXCHANNEL - CH_20MHZ_APART))
110
channel += CH_10MHZ_APART;
111
else
112
return 0;
113
} else if (c == 'u') {
114
bw = WL_CHANSPEC_BW_40;
115
ctl_sb = WL_CHANSPEC_CTL_SB_UPPER;
116
117
if (channel > CH_20MHZ_APART)
118
channel -= CH_10MHZ_APART;
119
else
120
return 0;
121
} else {
122
return 0;
123
}
124
125
done:
126
return (channel | band | bw | ctl_sb);
127
}
128
129
130
bool
131
wf_chspec_malformed(chanspec_t chanspec)
132
{
133
134
if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
135
return TRUE;
136
137
if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
138
return TRUE;
139
140
141
if (CHSPEC_IS20(chanspec)) {
142
if (!CHSPEC_SB_NONE(chanspec))
143
return TRUE;
144
} else {
145
if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
146
return TRUE;
147
}
148
149
return FALSE;
150
}
151
152
153
uint8
154
wf_chspec_ctlchan(chanspec_t chspec)
155
{
156
uint8 ctl_chan;
157
158
159
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
160
return CHSPEC_CHANNEL(chspec);
161
} else {
162
163
ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40);
164
165
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
166
167
ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
168
} else {
169
ASSERT(CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_LOWER);
170
171
ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
172
}
173
}
174
175
return ctl_chan;
176
}
177
178
chanspec_t
179
wf_chspec_ctlchspec(chanspec_t chspec)
180
{
181
chanspec_t ctl_chspec = 0;
182
uint8 channel;
183
184
ASSERT(!wf_chspec_malformed(chspec));
185
186
187
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
188
return chspec;
189
} else {
190
if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
191
channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
192
} else {
193
channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
194
}
195
ctl_chspec = channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
196
ctl_chspec |= CHSPEC_BAND(chspec);
197
}
198
return ctl_chspec;
199
}
200
201
202
int
203
wf_mhz2channel(uint freq, uint start_factor)
204
{
205
int ch = -1;
206
uint base;
207
int offset;
208
209
210
if (start_factor == 0) {
211
if (freq >= 2400 && freq <= 2500)
212
start_factor = WF_CHAN_FACTOR_2_4_G;
213
else if (freq >= 5000 && freq <= 6000)
214
start_factor = WF_CHAN_FACTOR_5_G;
215
}
216
217
if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
218
return 14;
219
220
base = start_factor / 2;
221
222
223
if ((freq < base) || (freq > base + 1000))
224
return -1;
225
226
offset = freq - base;
227
ch = offset / 5;
228
229
230
if (offset != (ch * 5))
231
return -1;
232
233
234
if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
235
return -1;
236
237
return ch;
238
}
239
240
241
int
242
wf_channel2mhz(uint ch, uint start_factor)
243
{
244
int freq;
245
246
if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
247
(ch > 200))
248
freq = -1;
249
else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14))
250
freq = 2484;
251
else
252
freq = ch * 5 + start_factor / 2;
253
254
return freq;
255
}
256
257