5738e2cd049d3ec0c777ca2cd2a3f0c684d33363
[openwrt/svn-archive/archive.git] / package / nvram / src / wl.c
1 /*
2 * Wireless network adapter utilities
3 *
4 * Copyright 2004, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id$
13 */
14 #include <string.h>
15
16 #include <typedefs.h>
17 #include <wlutils.h>
18
19 int
20 wl_probe(char *name)
21 {
22 int ret, val;
23
24 /* Check interface */
25 if ((ret = wl_ioctl(name, WLC_GET_MAGIC, &val, sizeof(val))))
26 return ret;
27 if (val != WLC_IOCTL_MAGIC)
28 return -1;
29 if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val))))
30 return ret;
31 if (val > WLC_IOCTL_VERSION)
32 return -1;
33
34 return ret;
35 }
36
37 int
38 wl_set_val(char *name, char *var, void *val, int len)
39 {
40 char buf[128];
41 int buf_len;
42
43 /* check for overflow */
44 if ((buf_len = strlen(var)) + 1 + len > sizeof(buf))
45 return -1;
46
47 strcpy(buf, var);
48 buf_len += 1;
49
50 /* append int value onto the end of the name string */
51 memcpy(&buf[buf_len], val, len);
52 buf_len += len;
53
54 return wl_ioctl(name, WLC_SET_VAR, buf, buf_len);
55 }
56
57 int
58 wl_get_val(char *name, char *var, void *val, int len)
59 {
60 char buf[128];
61 int ret;
62
63 /* check for overflow */
64 if (strlen(var) + 1 > sizeof(buf) || len > sizeof(buf))
65 return -1;
66
67 strcpy(buf, var);
68 if ((ret = wl_ioctl(name, WLC_GET_VAR, buf, sizeof(buf))))
69 return ret;
70
71 memcpy(val, buf, len);
72 return 0;
73 }
74
75 int
76 wl_set_int(char *name, char *var, int val)
77 {
78 return wl_set_val(name, var, &val, sizeof(val));
79 }
80
81 int
82 wl_get_int(char *name, char *var, int *val)
83 {
84 return wl_get_val(name, var, val, sizeof(*val));
85 }
86
87 /**************************************************************************
88 * The following code is from Broadcom (wl.c) *
89 **************************************************************************/
90
91 int
92 wl_iovar_getbuf(char *ifname, char *iovar, void *param,
93 int paramlen, void *bufptr, int buflen)
94 {
95 int err;
96 uint namelen;
97 uint iolen;
98
99 namelen = strlen(iovar) + 1; /* length of iovar name plus null */
100 iolen = namelen + paramlen;
101
102 /* check for overflow */
103 if (iolen > buflen)
104 return (-1);
105
106 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */
107 memcpy((int8*)bufptr + namelen, param, paramlen);
108
109 err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen);
110
111 return (err);
112 }
113
114 int
115 wl_iovar_setbuf(char *ifname, char *iovar, void *param,
116 int paramlen, void *bufptr, int buflen)
117 {
118 uint namelen;
119 uint iolen;
120
121 namelen = strlen(iovar) + 1; /* length of iovar name plus null */
122 iolen = namelen + paramlen;
123
124 /* check for overflow */
125 if (iolen > buflen)
126 return (-1);
127
128 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */
129 memcpy((int8*)bufptr + namelen, param, paramlen);
130
131 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen);
132 }
133
134 int
135 wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen)
136 {
137 char smbuf[WLC_IOCTL_SMLEN];
138
139 return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf));
140 }
141
142 int
143 wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen)
144 {
145 char smbuf[WLC_IOCTL_SMLEN];
146 int ret;
147
148 /* use the return buffer if it is bigger than what we have on the stack */
149 if (buflen > sizeof(smbuf)) {
150 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen);
151 } else {
152 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf));
153 if (ret == 0)
154 memcpy(bufptr, smbuf, buflen);
155 }
156
157 return ret;
158 }
159
160 /*
161 * set named driver variable to int value
162 * calling example: wl_iovar_setint(ifname, "arate", rate)
163 */
164 int
165 wl_iovar_setint(char *ifname, char *iovar, int val)
166 {
167 return wl_iovar_set(ifname, iovar, &val, sizeof(val));
168 }
169
170 /*
171 * get named driver variable to int value and return error indication
172 * calling example: wl_iovar_getint(ifname, "arate", &rate)
173 */
174 int
175 wl_iovar_getint(char *ifname, char *iovar, int *val)
176 {
177 return wl_iovar_get(ifname, iovar, val, sizeof(int));
178 }
179
180 /*
181 * format a bsscfg indexed iovar buffer
182 */
183 static int
184 wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param,
185 int paramlen, void *bufptr, int buflen, int *plen)
186 {
187 char *prefix = "bsscfg:";
188 int8* p;
189 uint prefixlen;
190 uint namelen;
191 uint iolen;
192
193 prefixlen = strlen(prefix); /* length of bsscfg prefix */
194 namelen = strlen(iovar) + 1; /* length of iovar name + null */
195 iolen = prefixlen + namelen + sizeof(int) + paramlen;
196
197 /* check for overflow */
198 if (buflen < 0 || iolen > (uint)buflen) {
199 *plen = 0;
200 return -1;
201 }
202
203 p = (int8*)bufptr;
204
205 /* copy prefix, no null */
206 memcpy(p, prefix, prefixlen);
207 p += prefixlen;
208
209 /* copy iovar name including null */
210 memcpy(p, iovar, namelen);
211 p += namelen;
212
213 /* bss config index as first param */
214 memcpy(p, &bssidx, sizeof(int32));
215 p += sizeof(int32);
216
217 /* parameter buffer follows */
218 if (paramlen)
219 memcpy(p, param, paramlen);
220
221 *plen = iolen;
222 return 0;
223 }
224
225 /*
226 * set named & bss indexed driver variable to buffer value
227 */
228 int
229 wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param,
230 int paramlen, void *bufptr, int buflen)
231 {
232 int err;
233 uint iolen;
234
235 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen);
236 if (err)
237 return err;
238
239 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen);
240 }
241
242 /*
243 * get named & bss indexed driver variable buffer value
244 */
245 int
246 wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param,
247 int paramlen, void *bufptr, int buflen)
248 {
249 int err;
250 uint iolen;
251
252 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen);
253 if (err)
254 return err;
255
256 return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen);
257 }
258
259 /*
260 * set named & bss indexed driver variable to buffer value
261 */
262 int
263 wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen)
264 {
265 char smbuf[WLC_IOCTL_SMLEN];
266
267 return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf));
268 }
269
270 /*
271 * get named & bss indexed driver variable buffer value
272 */
273 int
274 wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len)
275 {
276 char smbuf[WLC_IOCTL_SMLEN];
277 int err;
278
279 /* use the return buffer if it is bigger than what we have on the stack */
280 if (len > (int)sizeof(smbuf)) {
281 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len);
282 } else {
283 memset(smbuf, 0, sizeof(smbuf));
284 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf));
285 if (err == 0)
286 memcpy(outbuf, smbuf, len);
287 }
288
289 return err;
290 }
291
292 /*
293 * set named & bss indexed driver variable to int value
294 */
295 int
296 wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val)
297 {
298 return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int));
299 }