Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / shared / bcmwifi.c
blob0a9db485ac39c4ddab29c00ca46e88e7c989574d
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.
6 * Copyright 2007, Broadcom Corporation
7 * All Rights Reserved.
8 *
9 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
10 * the contents of this file may not be disclosed to third parties, copied
11 * or duplicated in any form, in whole or in part, without the prior
12 * written permission of Broadcom Corporation.
13 * $Id$
16 #include <typedefs.h>
18 #ifdef BCMDRIVER
19 #include <osl.h>
20 #include <bcmutils.h>
21 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
22 #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
23 #elif defined(__IOPOS__)
24 #include <bcmutils.h>
25 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
26 #define tolower(c) (bcm_tolower((c)))
27 #else
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #endif /* BCMDRIVER */
32 #include <bcmwifi.h>
34 /* Chanspec ASCII representation:
35 * <channel><band><bandwidth><ctl-sideband>
36 * digit [AB] N [UL]
38 * <channel>: channel number of the 10MHz or 20MHz channel,
39 * or control sideband channel of 40MHz channel.
40 * <band>: A for 5GHz, B for 2.4GHz
41 * <bandwidth>: N for 10MHz, nothing for 20MHz or 40MHz
42 * (ctl-sideband spec implies 40MHz)
43 * <ctl-sideband>: U for upper, L for lower
45 * <band> may be omitted on input, and will be assumed to be
46 * 2.4GHz if channel number <= 14.
48 * Examples: ...
50 /* given a chanspec and a string buffer, format the chanspec as a
51 * string, and return the original pointer a. On error, return's NULL
53 char *
54 wf_chspec_ntoa(chanspec_t chspec, char *buf)
56 const char *band, *bw, *sb;
57 uint channel;
59 bw = "";
60 sb = "";
61 channel = CHSPEC_CHANNEL(chspec);
62 band = (CHSPEC_IS2G(chspec)) ? "b" : "a";
63 if (CHSPEC_IS40(chspec)) {
64 if (CHSPEC_SB_UPPER(chspec)) {
65 sb = "u";
66 channel += CH_10MHZ_APART;
67 } else {
68 sb = "l";
69 channel -= CH_10MHZ_APART;
71 } else if (CHSPEC_IS10(chspec)) {
72 bw = "n";
75 sprintf(buf, "%d%s%s%s", channel, band, bw, sb);
76 return (buf);
79 /* given a chanspec string, convert to a chanspec.
80 * On error, return 0
83 chanspec_t
84 wf_chspec_aton(char *a)
86 char *endp;
87 uint channel, band, bw, ctl_sb;
88 bool band_set = FALSE, bw_set = FALSE, ctl_sb_set = FALSE;
89 int error = 0;
91 channel = strtoul(a, &endp, 10);
92 if (endp == a)
93 return 0;
95 if (channel > MAXCHANNEL)
96 return 0;
98 band = ((channel <= WLC_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
99 bw = WL_CHANSPEC_BW_20;
100 ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
102 a = endp;
103 while (*a != 0 && error != -1) {
104 switch (tolower((int)*a)) {
105 case 'a':
106 case 'b':
107 if (!band_set) {
108 band = (tolower((int)*a) == 'a') ?
109 WL_CHANSPEC_BAND_5G : WL_CHANSPEC_BAND_2G;
110 band_set = TRUE;
111 } else {
112 error = -1;
114 break;
115 case 'n':
116 if (!bw_set) {
117 bw = WL_CHANSPEC_BW_10;
118 bw_set = TRUE;
119 } else {
120 error = -1;
122 break;
123 case 'l':
124 case 'u':
125 if (!ctl_sb_set && !bw_set) {
126 ctl_sb = (tolower((int)*a) == 'l') ?
127 WL_CHANSPEC_CTL_SB_LOWER : WL_CHANSPEC_CTL_SB_UPPER;
128 ctl_sb_set = TRUE;
129 if (ctl_sb == WL_CHANSPEC_CTL_SB_LOWER)
130 channel = UPPER_20_SB(channel);
131 else
132 channel = LOWER_20_SB(channel);
133 bw = WL_CHANSPEC_BW_40;
134 bw_set = TRUE;
135 } else if (bw_set) {
136 error = -1;
137 } else {
138 error = -1;
140 break;
141 default:
142 error = -1;
143 break;
145 a++;
148 if (bw_set && (bw == WL_CHANSPEC_BW_40) && !ctl_sb_set)
149 error = -1;
151 if (ctl_sb_set && !bw_set)
152 error = -1;
154 if (!error)
155 return ((channel | band | bw | ctl_sb));
157 return 0;
160 #ifdef CONFIG_NET_RADIO
161 /* channel info structure */
162 typedef struct {
163 uint chan; /* channel number */
164 uint freq; /* in Mhz */
165 } chan_info_t;
167 static chan_info_t chan_info[] = {
168 /* B channels */
169 { 1, 2412},
170 { 2, 2417},
171 { 3, 2422},
172 { 4, 2427},
173 { 5, 2432},
174 { 6, 2437},
175 { 7, 2442},
176 { 8, 2447},
177 { 9, 2452},
178 { 10, 2457},
179 { 11, 2462},
180 { 12, 2467},
181 { 13, 2472},
182 { 14, 2484},
184 /* A channels */
185 /* 11a usa low */
186 { 36, 5180},
187 { 40, 5200},
188 { 44, 5220},
189 { 48, 5240},
190 { 52, 5260},
191 { 56, 5280},
192 { 60, 5300},
193 { 64, 5320},
195 /* 11a Europe */
196 { 100, 5500},
197 { 104, 5520},
198 { 108, 5540},
199 { 112, 5560},
200 { 116, 5580},
201 { 120, 5600},
202 { 124, 5620},
203 { 128, 5640},
204 { 132, 5660},
205 { 136, 5680},
206 { 140, 5700},
208 /* 11a usa high */
209 { 149, 5745},
210 { 153, 5765},
211 { 157, 5785},
212 { 161, 5805},
214 /* 11a japan */
215 { 184, 4920},
216 { 188, 4940},
217 { 192, 4960},
218 { 196, 4980},
219 { 200, 5000},
220 { 204, 5020},
221 { 208, 5040},
222 { 212, 5060},
223 { 216, 5080}
227 uint
228 freq2channel(uint freq)
230 int i;
232 for (i = 0; i < (int)ARRAYSIZE(chan_info); i++) {
233 if (chan_info[i].freq == freq)
234 return (chan_info[i].chan);
236 return (0);
239 uint
240 channel2freq(uint channel)
242 uint i;
244 for (i = 0; i < ARRAYSIZE(chan_info); i++)
245 if (chan_info[i].chan == channel)
246 return (chan_info[i].freq);
247 return (0);
249 #endif /* CONFIG_NET_RADIO */