1/* 2 * Wireless network adapter utilities 3 * 4 * Copyright 2007, 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: wl.c,v 1.1.1.1 2008/10/15 03:31:22 james26_jang Exp $ 13 */ 14#include <typedefs.h> 15#include <string.h> 16#include <stdio.h> 17#include <unistd.h> 18#include <errno.h> 19#include <sys/ioctl.h> 20#include <net/if.h> 21 22#include <bcmutils.h> 23#include <wlutils.h> 24 25int 26wl_probe(char *name) 27{ 28 int ret, val; 29 30#if defined(linux) 31 char buf[DEV_TYPE_LEN]; 32 if ((ret = wl_get_dev_type(name, buf, DEV_TYPE_LEN)) < 0) 33 return ret; 34 /* Check interface */ 35 if (strncmp(buf, "wl", 2)) 36 return -1; 37#else 38 /* Check interface */ 39 if ((ret = wl_ioctl(name, WLC_GET_MAGIC, &val, sizeof(val)))) 40 return ret; 41#endif 42 if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val)))) 43 return ret; 44 if (val > WLC_IOCTL_VERSION) 45 return -1; 46 47 return ret; 48} 49 50int 51wl_iovar_getbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) 52{ 53 int err; 54 uint namelen; 55 uint iolen; 56 57 namelen = strlen(iovar) + 1; /* length of iovar name plus null */ 58 iolen = namelen + paramlen; 59 60 /* check for overflow */ 61 if (iolen > buflen) 62 return (BCME_BUFTOOSHORT); 63 64 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ 65 memcpy((int8*)bufptr + namelen, param, paramlen); 66 67 err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); 68 69 return (err); 70} 71 72int 73wl_iovar_setbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) 74{ 75 uint namelen; 76 uint iolen; 77 78 namelen = strlen(iovar) + 1; /* length of iovar name plus null */ 79 iolen = namelen + paramlen; 80 81 /* check for overflow */ 82 if (iolen > buflen) 83 return (BCME_BUFTOOSHORT); 84 85 memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ 86 memcpy((int8*)bufptr + namelen, param, paramlen); 87 88 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); 89} 90 91int 92wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen) 93{ 94 char smbuf[WLC_IOCTL_SMLEN]; 95 96 return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf)); 97} 98 99int 100wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen) 101{ 102 char smbuf[WLC_IOCTL_SMLEN]; 103 int ret; 104 105 /* use the return buffer if it is bigger than what we have on the stack */ 106 if (buflen > sizeof(smbuf)) { 107 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen); 108 } else { 109 ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf)); 110 if (ret == 0) 111 memcpy(bufptr, smbuf, buflen); 112 } 113 114 return ret; 115} 116 117/* 118 * set named driver variable to int value 119 * calling example: wl_iovar_setint(ifname, "arate", rate) 120*/ 121int 122wl_iovar_setint(char *ifname, char *iovar, int val) 123{ 124 return wl_iovar_set(ifname, iovar, &val, sizeof(val)); 125} 126 127/* 128 * get named driver variable to int value and return error indication 129 * calling example: wl_iovar_getint(ifname, "arate", &rate) 130 */ 131int 132wl_iovar_getint(char *ifname, char *iovar, int *val) 133{ 134 return wl_iovar_get(ifname, iovar, val, sizeof(int)); 135} 136 137/* 138 * format a bsscfg indexed iovar buffer 139 */ 140static int 141wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen, int *plen) 142{ 143 char *prefix = "bsscfg:"; 144 int8* p; 145 uint prefixlen; 146 uint namelen; 147 uint iolen; 148 149 prefixlen = strlen(prefix); /* length of bsscfg prefix */ 150 namelen = strlen(iovar) + 1; /* length of iovar name + null */ 151 iolen = prefixlen + namelen + sizeof(int) + paramlen; 152 153 /* check for overflow */ 154 if (buflen < 0 || iolen > (uint)buflen) { 155 *plen = 0; 156 return BCME_BUFTOOSHORT; 157 } 158 159 p = (int8*)bufptr; 160 161 /* copy prefix, no null */ 162 memcpy(p, prefix, prefixlen); 163 p += prefixlen; 164 165 /* copy iovar name including null */ 166 memcpy(p, iovar, namelen); 167 p += namelen; 168 169 /* bss config index as first param */ 170 memcpy(p, &bssidx, sizeof(int32)); 171 p += sizeof(int32); 172 173 /* parameter buffer follows */ 174 if (paramlen) 175 memcpy(p, param, paramlen); 176 177 *plen = iolen; 178 return 0; 179} 180 181/* 182 * set named & bss indexed driver variable to buffer value 183 */ 184int 185wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen) 186{ 187 int err; 188 int iolen; 189 190 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); 191 if (err) 192 return err; 193 194 return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); 195} 196 197/* 198 * get named & bss indexed driver variable buffer value 199 */ 200int 201wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen) 202{ 203 int err; 204 int iolen; 205 206 err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); 207 if (err) 208 return err; 209 210 return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); 211} 212 213/* 214 * set named & bss indexed driver variable to buffer value 215 */ 216int 217wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen) 218{ 219 char smbuf[WLC_IOCTL_SMLEN]; 220 221 return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf)); 222} 223 224/* 225 * get named & bss indexed driver variable buffer value 226 */ 227int 228wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len) 229{ 230 char smbuf[WLC_IOCTL_SMLEN]; 231 int err; 232 233 /* use the return buffer if it is bigger than what we have on the stack */ 234 if (len > (int)sizeof(smbuf)) { 235 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len); 236 } else { 237 memset(smbuf, 0, sizeof(smbuf)); 238 err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf)); 239 if (err == 0) 240 memcpy(outbuf, smbuf, len); 241 } 242 243 return err; 244} 245 246/* 247 * set named & bss indexed driver variable to int value 248 */ 249int 250wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val) 251{ 252 return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int)); 253} 254 255/* 256void 257wl_printlasterror(char *name) 258{ 259 char err_buf[WLC_IOCTL_SMLEN]; 260 strcpy(err_buf, "bcmerrstr"); 261 262 fprintf(stderr, "Error: "); 263 if ( wl_ioctl(name, WLC_GET_VAR, err_buf, sizeof (err_buf)) != 0) 264 fprintf(stderr, "Error getting the Errorstring from driver\n"); 265 else 266 fprintf(stderr, err_buf); 267} 268*/ 269