libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / router / shared / wl.c
blob1d630008b0e671b951d8c9b49ce86262ae5e8a1f
1 /*
2 * Wireless network adapter utilities
4 * Copyright 2005, 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.
12 * $Id: wl.c,v 1.1.1.9 2005/03/07 07:31:20 kanki Exp $
14 #include <string.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <sys/ioctl.h>
19 #include <net/if.h>
21 #include <typedefs.h>
22 #include <bcmutils.h>
23 #include <wlutils.h>
24 #include <wlioctl.h>
26 #include "shared.h"
28 // xref: nas,wlconf
29 int wl_probe(char *name)
31 int ret, val;
33 #if defined(linux)
34 char buf[DEV_TYPE_LEN];
35 if ((ret = wl_get_dev_type(name, buf, DEV_TYPE_LEN)) < 0)
36 return ret;
37 /* Check interface */
38 if (strncmp(buf, "wl", 2))
39 return -1;
40 #else
41 /* Check interface */
42 if ((ret = wl_ioctl(name, WLC_GET_MAGIC, &val, sizeof(val))))
43 return ret;
44 #endif
45 if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val))))
46 return ret;
47 if (val > WLC_IOCTL_VERSION)
48 return -1;
50 return ret;
53 // xref: nas,wlconf,
54 int wl_set_val(char *name, char *var, void *val, int len)
56 char buf[WLC_IOCTL_SMLEN];
57 int buf_len;
59 /* check for overflow */
60 if ((buf_len = strlen(var)) + 1 + len > sizeof(buf))
61 return -1;
63 strcpy(buf, var);
64 buf_len += 1;
66 /* append int value onto the end of the name string */
67 memcpy(&buf[buf_len], val, len);
68 buf_len += len;
70 return wl_ioctl(name, WLC_SET_VAR, buf, buf_len);
73 // xref: nas,wlconf,
74 int wl_get_val(char *name, char *var, void *val, int len)
76 char buf[WLC_IOCTL_SMLEN];
77 int ret;
79 /* check for overflow */
80 if (strlen(var) + 1 > sizeof(buf) || len > sizeof(buf))
81 return -1;
83 strcpy(buf, var);
84 if ((ret = wl_ioctl(name, WLC_GET_VAR, buf, sizeof(buf))))
85 return ret;
87 memcpy(val, buf, len);
88 return 0;
91 // xref: wlconf,
92 int wl_set_int(char *name, char *var, int val)
94 return wl_set_val(name, var, &val, sizeof(val));
97 #if 0 // not used
98 int wl_get_int(char *name, char *var, int *val)
100 return wl_get_val(name, var, val, sizeof(*val));
102 #endif
105 #ifndef WL_BSS_INFO_VERSION
106 #error WL_BSS_INFO_VERSION
107 #endif
109 #if WL_BSS_INFO_VERSION >= 108
110 int
111 wl_iovar_getbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen)
113 int err;
114 uint namelen;
115 uint iolen;
117 namelen = strlen(iovar) + 1; /* length of iovar name plus null */
118 iolen = namelen + paramlen;
120 /* check for overflow */
121 if (iolen > buflen)
122 return (BCME_BUFTOOSHORT);
124 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */
125 memcpy((int8*)bufptr + namelen, param, paramlen);
127 err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen);
129 return (err);
132 int
133 wl_iovar_setbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen)
135 uint namelen;
136 uint iolen;
138 namelen = strlen(iovar) + 1; /* length of iovar name plus null */
139 iolen = namelen + paramlen;
141 /* check for overflow */
142 if (iolen > buflen)
143 return (BCME_BUFTOOSHORT);
145 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */
146 memcpy((int8*)bufptr + namelen, param, paramlen);
148 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen);
152 wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen)
154 char smbuf[WLC_IOCTL_SMLEN];
156 return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf));
160 wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen)
162 char smbuf[WLC_IOCTL_SMLEN];
163 int ret;
165 /* use the return buffer if it is bigger than what we have on the stack */
166 if (buflen > sizeof(smbuf)) {
167 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen);
168 } else {
169 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf));
170 if (ret == 0)
171 memcpy(bufptr, smbuf, buflen);
174 return ret;
178 * set named driver variable to int value
179 * calling example: wl_iovar_setint(ifname, "arate", rate)
182 wl_iovar_setint(char *ifname, char *iovar, int val)
184 return wl_iovar_set(ifname, iovar, &val, sizeof(val));
188 * get named driver variable to int value and return error indication
189 * calling example: wl_iovar_getint(ifname, "arate", &rate)
192 wl_iovar_getint(char *ifname, char *iovar, int *val)
194 return wl_iovar_get(ifname, iovar, val, sizeof(int));
198 * format a bsscfg indexed iovar buffer
200 static int
201 wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen, int *plen)
203 char *prefix = "bsscfg:";
204 int8* p;
205 uint prefixlen;
206 uint namelen;
207 uint iolen;
209 prefixlen = strlen(prefix); /* length of bsscfg prefix */
210 namelen = strlen(iovar) + 1; /* length of iovar name + null */
211 iolen = prefixlen + namelen + sizeof(int) + paramlen;
213 /* check for overflow */
214 if (buflen < 0 || iolen > (uint)buflen) {
215 *plen = 0;
216 return BCME_BUFTOOSHORT;
219 p = (int8*)bufptr;
221 /* copy prefix, no null */
222 memcpy(p, prefix, prefixlen);
223 p += prefixlen;
225 /* copy iovar name including null */
226 memcpy(p, iovar, namelen);
227 p += namelen;
229 /* bss config index as first param */
230 memcpy(p, &bssidx, sizeof(int32));
231 p += sizeof(int32);
233 /* parameter buffer follows */
234 if (paramlen)
235 memcpy(p, param, paramlen);
237 *plen = iolen;
239 // bufptr = bsscfg:<iovar>0<bssidx><param>
240 return 0;
244 * set named & bss indexed driver variable to buffer value
247 wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen)
249 int err;
250 uint iolen;
252 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen);
253 if (err)
254 return err;
256 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen);
260 * get named & bss indexed driver variable buffer value
263 wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen)
265 int err;
266 uint iolen;
268 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen);
269 if (err)
270 return err;
272 return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen);
277 * set named & bss indexed driver variable to buffer value
280 wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen)
282 char smbuf[WLC_IOCTL_SMLEN];
284 return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf));
288 * get named & bss indexed driver variable buffer value
291 wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len)
293 char smbuf[WLC_IOCTL_SMLEN];
294 int err;
296 /* use the return buffer if it is bigger than what we have on the stack */
297 if (len > (int)sizeof(smbuf)) {
298 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len);
299 } else {
300 memset(smbuf, 0, sizeof(smbuf));
301 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf));
302 if (err == 0)
303 memcpy(outbuf, smbuf, len);
306 return err;
310 * set named & bss indexed driver variable to int value
313 wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val)
315 return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int));
317 #endif // WL_BSS_INFO_VERSION >= 108