Path: blob/next/external/cache/sources/wl/shared/wlu_common.c
17850 views
/*1* Common code for wl routines2*3* $Copyright (C) 2002-2005 Broadcom Corporation$4*5* $Id: wlu_common.c 288685 2011-10-08 00:50:34Z pgarg $6*/78#ifdef WIN329#include <windows.h>10#endif1112#include "wlu_common.h"13#include "wlu.h"14#include <bcmendian.h>1516extern int wl_get(void *wl, int cmd, void *buf, int len);17extern int wl_set(void *wl, int cmd, void *buf, int len);1819wl_cmd_list_t cmd_list;20int cmd_pkt_list_num;21bool cmd_batching_mode;2223const char *wlu_av0;2425#ifdef SERDOWNLOAD26extern int debug;27#endif2829#ifdef ATE_BUILD30int wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len);31int wlu_get(void *wl, int cmd, void *cmdbuf, int len);32int wlu_set(void *wl, int cmd, void *cmdbuf, int len);33int add_one_batched_cmd(int cmd, void *cmdbuf, int len);34int wlu_iovar_setint(void *wl, const char *iovar, int val);35int wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen);36#endif /* ATE_BUILD */3738/*39* format an iovar buffer40* iovar name is converted to lower case41*/42static uint43wl_iovar_mkbuf(const char *name, char *data, uint datalen, char *iovar_buf, uint buflen, int *perr)44{45uint iovar_len;46char *p;4748iovar_len = strlen(name) + 1;4950/* check for overflow */51if ((iovar_len + datalen) > buflen) {52*perr = BCME_BUFTOOSHORT;53return 0;54}5556/* copy data to the buffer past the end of the iovar name string */57if (datalen > 0)58memmove(&iovar_buf[iovar_len], data, datalen);5960/* copy the name to the beginning of the buffer */61strcpy(iovar_buf, name);6263/* wl command line automatically converts iovar names to lower case for64* ease of use65*/66p = iovar_buf;67while (*p != '\0') {68*p = tolower((int)*p);69p++;70}7172*perr = 0;73return (iovar_len + datalen);74}7576void77init_cmd_batchingmode(void)78{79cmd_pkt_list_num = 0;80cmd_batching_mode = FALSE;81}8283void84clean_up_cmd_list(void)85{86wl_seq_cmd_pkt_t *this_cmd, *next_cmd;8788this_cmd = cmd_list.head;89while (this_cmd != NULL) {90next_cmd = this_cmd->next;91if (this_cmd->data != NULL) {92free(this_cmd->data);93}94free(this_cmd);95this_cmd = next_cmd;96}97cmd_list.head = NULL;98cmd_list.tail = NULL;99cmd_pkt_list_num = 0;100}101102int103add_one_batched_cmd(int cmd, void *cmdbuf, int len)104{105wl_seq_cmd_pkt_t *new_cmd;106107new_cmd = malloc(sizeof(wl_seq_cmd_pkt_t));108109if (new_cmd == NULL) {110printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",111(int)sizeof(wl_seq_cmd_pkt_t), cmd_pkt_list_num);112goto free_and_exit;113} else {114#ifdef SERDOWNLOAD115if (debug)116#endif /* SERDOWNLOAD */117printf("batching %dth command %d\n", cmd_pkt_list_num+1, cmd);118119}120121new_cmd->cmd_header.cmd = cmd;122new_cmd->cmd_header.len = len;123new_cmd->next = NULL;124125new_cmd->data = malloc(len);126127if (new_cmd->data == NULL) {128printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",129len, cmd_pkt_list_num);130free(new_cmd);131goto free_and_exit;132}133134memcpy(new_cmd->data, cmdbuf, len);135136if (cmd_list.tail != NULL)137cmd_list.tail->next = new_cmd;138else139cmd_list.head = new_cmd;140141cmd_list.tail = new_cmd;142143cmd_pkt_list_num ++;144return 0;145146free_and_exit:147148clean_up_cmd_list();149150if (cmd_batching_mode) {151cmd_batching_mode = FALSE;152}153else {154printf("calling add_one_batched_cmd() at non-command-batching mode, weird\n");155}156157return -1;158}159160#ifndef ATE_BUILD161int162wlu_get_req_buflen(int cmd, void *cmdbuf, int len)163{164int modified_len = len;165char *cmdstr = (char *)cmdbuf;166167if (len == WLC_IOCTL_MAXLEN) {168if ((strcmp(cmdstr, "dump") == 0) ||169(cmd == WLC_SCAN_RESULTS))170modified_len = WLC_IOCTL_MAXLEN;171else172modified_len = WLC_IOCTL_MEDLEN;173}174return modified_len;175}176#endif /* !ATE_BUILD */177178/* now IOCTL GET commands shall call wlu_get() instead of wl_get() so that the commands179* can be batched when needed180*/181int182wlu_get(void *wl, int cmd, void *cmdbuf, int len)183{184if (cmd_batching_mode) {185if (!WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd)) {186printf("IOCTL GET command %d is not supported in batching mode\n", cmd);187return IOCTL_ERROR;188}189}190191return wl_get(wl, cmd, cmdbuf, len);192}193194/* now IOCTL SET commands shall call wlu_set() instead of wl_set() so that the commands195* can be batched when needed196*/197int198wlu_set(void *wl, int cmd, void *cmdbuf, int len)199{200if (cmd_batching_mode) {201return add_one_batched_cmd(cmd, cmdbuf, len);202}203else {204return wl_set(wl, cmd, cmdbuf, len);205}206}207208/*209* get named iovar providing both parameter and i/o buffers210* iovar name is converted to lower case211*/212int213wlu_iovar_getbuf(void* wl, const char *iovar,214void *param, int paramlen, void *bufptr, int buflen)215{216int err;217218wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);219if (err)220return err;221222return wlu_get(wl, WLC_GET_VAR, bufptr, buflen);223}224225/*226* set named iovar providing both parameter and i/o buffers227* iovar name is converted to lower case228*/229int230wlu_iovar_setbuf(void* wl, const char *iovar,231void *param, int paramlen, void *bufptr, int buflen)232{233int err;234int iolen;235236iolen = wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);237if (err)238return err;239240return wlu_set(wl, WLC_SET_VAR, bufptr, iolen);241}242243/*244* get named iovar without parameters into a given buffer245* iovar name is converted to lower case246*/247int248wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len)249{250char smbuf[WLC_IOCTL_SMLEN];251int err;252253/* use the return buffer if it is bigger than what we have on the stack */254if (len > (int)sizeof(smbuf)) {255err = wlu_iovar_getbuf(wl, iovar, NULL, 0, outbuf, len);256} else {257memset(smbuf, 0, sizeof(smbuf));258err = wlu_iovar_getbuf(wl, iovar, NULL, 0, smbuf, sizeof(smbuf));259if (err == 0)260memcpy(outbuf, smbuf, len);261}262263return err;264}265266/*267* set named iovar given the parameter buffer268* iovar name is converted to lower case269*/270int271wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen)272{273char smbuf[WLC_IOCTL_SMLEN*2];274275memset(smbuf, 0, sizeof(smbuf));276277return wlu_iovar_setbuf(wl, iovar, param, paramlen, smbuf, sizeof(smbuf));278}279280/*281* get named iovar as an integer value282* iovar name is converted to lower case283*/284int285wlu_iovar_getint(void *wl, const char *iovar, int *pval)286{287int ret;288289ret = wlu_iovar_get(wl, iovar, pval, sizeof(int));290if (ret >= 0)291{292*pval = dtoh32(*pval);293}294return ret;295}296297/*298* set named iovar given an integer parameter299* iovar name is converted to lower case300*/301int302wlu_iovar_setint(void *wl, const char *iovar, int val)303{304val = htod32(val);305return wlu_iovar_set(wl, iovar, &val, sizeof(int));306}307308309