#define CONFIG_BCM43341B0 "config_43341b0.txt"\r
#define CONFIG_BCM43241B4 "config_43241b4.txt"\r
#define CONFIG_BCM4339A0 "config_4339a0.txt"\r
+#define CONFIG_BCM43454C0 "config_43454c0.txt"\r
#define CONFIG_BCM43455C0 "config_43455c0.txt"\r
#define CONFIG_BCM43456C5 "config_43456c5.txt"\r
#define CONFIG_BCM4354A1 "config_4354a1.txt"\r
#define FW_BCM43438A0 "fw_bcm43438a0"\r
#define FW_BCM43438A1 "fw_bcm43438a1"\r
#define FW_BCM43436B0 "fw_bcm43436b0"\r
-#define FW_BCM43012B0 "fw_bcm43012b0"\r
+#define FW_BCM43013B0 "fw_bcm43013b0"\r
#define FW_BCM43341B1 "fw_bcm43341b0_ag"\r
#define FW_BCM43241B4 "fw_bcm43241b4_ag"\r
#define FW_BCM4339A0 "fw_bcm4339a0_ag"\r
#define FW_BCM4359B1 "fw_bcm4359b1_ag"\r
#define FW_BCM4359C0 "fw_bcm4359c0_ag"\r
\r
-#define CLM_BCM43012B0 "clm_bcm43012b0"\r
+#define CLM_BCM43013B0 "clm_bcm43013b0"\r
#endif\r
#ifdef BCMPCIE\r
#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"\r
+#define FW_BCM4359C0 "fw_bcm4359c0_pcie_ag"\r
#endif\r
\r
#define htod32(i) i\r
}\r
#endif\r
\r
+void\r
+dhd_conf_free_country_list(conf_country_list_t *country_list)\r
+{\r
+ int i;\r
+\r
+ CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
+ for (i=0; i<country_list->count; i++) {\r
+ if (country_list->cspec[i]) {\r
+ CONFIG_TRACE(("%s Free cspec %p\n", __FUNCTION__, country_list->cspec[i]));\r
+ kfree(country_list->cspec[i]);\r
+ }\r
+ }\r
+ country_list->count = 0;\r
+}\r
+\r
void\r
dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)\r
{\r
/* find out the last '/' */\r
i = strlen(fw_path);\r
while (i > 0) {\r
- if (fw_path[i] == '/') break;\r
+ if (fw_path[i] == '/') {\r
+ i++;\r
+ break;\r
+ }\r
i--;\r
}\r
#ifdef BAND_AG\r
case BCM4330_CHIP_ID:\r
if (ag_type == FW_TYPE_G) {\r
if (chiprev == BCM4330B2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4330B2);\r
+ strcpy(&fw_path[i], FW_BCM4330B2);\r
} else {\r
if (chiprev == BCM4330B2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4330B2_AG);\r
+ strcpy(&fw_path[i], FW_BCM4330B2_AG);\r
}\r
break;\r
case BCM43362_CHIP_ID:\r
if (chiprev == BCM43362A0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43362A0);\r
+ strcpy(&fw_path[i], FW_BCM43362A0);\r
else\r
- strcpy(&fw_path[i+1], FW_BCM43362A2);\r
+ strcpy(&fw_path[i], FW_BCM43362A2);\r
break;\r
case BCM43430_CHIP_ID:\r
if (chiprev == BCM43430A0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43438A0);\r
+ strcpy(&fw_path[i], FW_BCM43438A0);\r
else if (chiprev == BCM43430A1_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43438A1);\r
+ strcpy(&fw_path[i], FW_BCM43438A1);\r
else if (chiprev == BCM43430A2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43436B0);\r
+ strcpy(&fw_path[i], FW_BCM43436B0);\r
break;\r
case BCM43012_CHIP_ID:\r
- if (chiprev == BCM43012B0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43012B0);\r
+ if (chiprev == BCM43013B0_CHIP_REV)\r
+ strcpy(&fw_path[i], FW_BCM43013B0);\r
break;\r
case BCM4334_CHIP_ID:\r
if (chiprev == BCM4334B1_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4334B1);\r
+ strcpy(&fw_path[i], FW_BCM4334B1);\r
break;\r
case BCM43340_CHIP_ID:\r
case BCM43341_CHIP_ID:\r
if (chiprev == BCM43341B0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43341B1);\r
+ strcpy(&fw_path[i], FW_BCM43341B1);\r
break;\r
case BCM4324_CHIP_ID:\r
if (chiprev == BCM43241B4_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43241B4);\r
+ strcpy(&fw_path[i], FW_BCM43241B4);\r
break;\r
case BCM4335_CHIP_ID:\r
if (chiprev == BCM4335A0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4339A0);\r
+ strcpy(&fw_path[i], FW_BCM4339A0);\r
break;\r
case BCM4339_CHIP_ID:\r
if (chiprev == BCM4339A0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4339A0);\r
- break;\r
- case BCM43454_CHIP_ID:\r
- if (chiprev == BCM43455C0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43455C0);\r
+ strcpy(&fw_path[i], FW_BCM4339A0);\r
break;\r
case BCM4345_CHIP_ID:\r
+ case BCM43454_CHIP_ID:\r
if (chiprev == BCM43455C0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43455C0);\r
- else if (chiprev == BCM43455C5_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM43456C5);\r
+ strcpy(&fw_path[i], FW_BCM43455C0);\r
+ else if (chiprev == BCM43456C5_CHIP_REV)\r
+ strcpy(&fw_path[i], FW_BCM43456C5);\r
break;\r
case BCM4354_CHIP_ID:\r
if (chiprev == BCM4354A1_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4354A1);\r
+ strcpy(&fw_path[i], FW_BCM4354A1);\r
else if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+ strcpy(&fw_path[i], FW_BCM4356A2);\r
break;\r
case BCM4356_CHIP_ID:\r
case BCM4371_CHIP_ID:\r
if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+ strcpy(&fw_path[i], FW_BCM4356A2);\r
break;\r
case BCM43569_CHIP_ID:\r
if (chiprev == BCM4358A3_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4358A3);\r
+ strcpy(&fw_path[i], FW_BCM4358A3);\r
break;\r
case BCM4359_CHIP_ID:\r
if (chiprev == BCM4359B1_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4359B1);\r
+ strcpy(&fw_path[i], FW_BCM4359B1);\r
else if (chiprev == BCM4359C0_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4359C0);\r
+ strcpy(&fw_path[i], FW_BCM4359C0);\r
break;\r
#endif\r
#ifdef BCMPCIE\r
case BCM4354_CHIP_ID:\r
case BCM4356_CHIP_ID:\r
if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+ strcpy(&fw_path[i], FW_BCM4356A2);\r
+ break;\r
+ case BCM4359_CHIP_ID:\r
+ if (chiprev == BCM4359C0_CHIP_REV)\r
+ strcpy(&fw_path[i], FW_BCM4359C0);\r
break;\r
#endif\r
default:\r
- strcpy(&fw_path[i+1], "fw_bcmdhd");\r
+ strcpy(&fw_path[i], "fw_bcmdhd");\r
}\r
strcat(fw_path, fw_tail);\r
\r
/* find out the last '/' */\r
i = strlen(clm_path);\r
while (i > 0) {\r
- if (clm_path[i] == '/') break;\r
+ if (clm_path[i] == '/') {\r
+ i++;\r
+ break;\r
+ }\r
i--;\r
}\r
\r
switch (chip) {\r
#ifdef BCMSDIO\r
case BCM43012_CHIP_ID:\r
- if (chiprev == BCM43012B0_CHIP_REV)\r
- strcpy(&clm_path[i+1], CLM_BCM43012B0);\r
+ if (chiprev == BCM43013B0_CHIP_REV)\r
+ strcpy(&clm_path[i], CLM_BCM43013B0);\r
break;\r
#endif\r
default:\r
- strcpy(&clm_path[i+1], "clm_bcmdhd");\r
+ strcpy(&clm_path[i], "clm_bcmdhd");\r
}\r
strcat(clm_path, fw_tail);\r
\r
/* find out the last '/' */\r
i = strlen(nv_path);\r
while (i > 0) {\r
- if (nv_path[i] == '/') break;\r
+ if (nv_path[i] == '/') {\r
+ i++;\r
+ break;\r
+ }\r
i--;\r
}\r
\r
- strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);\r
+ strcpy(&nv_path[i], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);\r
\r
CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));\r
}\r
/* find out the last '/' */\r
i = strlen(dst_path);\r
while (i > 0) {\r
- if (dst_path[i] == '/') break;\r
+ if (dst_path[i] == '/') {\r
+ i++;\r
+ break;\r
+ }\r
i--;\r
}\r
- strcpy(&dst_path[i+1], dst_name);\r
+ strcpy(&dst_path[i], dst_name);\r
\r
CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));\r
}\r
/* find out the last '/' */\r
i = strlen(conf_path);\r
while (i > 0) {\r
- if (conf_path[i] == '/') break;\r
+ if (conf_path[i] == '/') {\r
+ i++;\r
+ break;\r
+ }\r
i--;\r
}\r
\r
#ifdef BCMSDIO\r
case BCM4330_CHIP_ID:\r
if (chiprev == BCM4330B2_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4330B2);\r
+ strcpy(&conf_path[i], CONFIG_BCM4330B2);\r
break;\r
case BCM43362_CHIP_ID:\r
if (chiprev == BCM43362A0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43362A0);\r
+ strcpy(&conf_path[i], CONFIG_BCM43362A0);\r
else\r
- strcpy(&conf_path[i+1], CONFIG_BCM43362A2);\r
+ strcpy(&conf_path[i], CONFIG_BCM43362A2);\r
break;\r
case BCM43430_CHIP_ID:\r
if (chiprev == BCM43430A0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43438A0);\r
+ strcpy(&conf_path[i], CONFIG_BCM43438A0);\r
else if (chiprev == BCM43430A1_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43438A1);\r
+ strcpy(&conf_path[i], CONFIG_BCM43438A1);\r
else if (chiprev == BCM43430A2_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43436B0);\r
+ strcpy(&conf_path[i], CONFIG_BCM43436B0);\r
break;\r
case BCM4334_CHIP_ID:\r
if (chiprev == BCM4334B1_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4334B1);\r
+ strcpy(&conf_path[i], CONFIG_BCM4334B1);\r
break;\r
case BCM43340_CHIP_ID:\r
case BCM43341_CHIP_ID:\r
if (chiprev == BCM43341B0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43341B0);\r
+ strcpy(&conf_path[i], CONFIG_BCM43341B0);\r
break;\r
case BCM4324_CHIP_ID:\r
if (chiprev == BCM43241B4_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43241B4);\r
+ strcpy(&conf_path[i], CONFIG_BCM43241B4);\r
break;\r
case BCM4335_CHIP_ID:\r
if (chiprev == BCM4335A0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
+ strcpy(&conf_path[i], CONFIG_BCM4339A0);\r
break;\r
- case BCM4345_CHIP_ID:\r
case BCM43454_CHIP_ID:\r
if (chiprev == BCM43455C0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43455C0);\r
- else if (chiprev == BCM43455C5_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM43456C5);\r
+ strcpy(&conf_path[i], CONFIG_BCM43454C0);\r
+ break;\r
+ case BCM4345_CHIP_ID:\r
+ if (chiprev == BCM43455C0_CHIP_REV)\r
+ strcpy(&conf_path[i], CONFIG_BCM43455C0);\r
+ else if (chiprev == BCM43456C5_CHIP_REV)\r
+ strcpy(&conf_path[i], CONFIG_BCM43456C5);\r
break;\r
case BCM4339_CHIP_ID:\r
if (chiprev == BCM4339A0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
+ strcpy(&conf_path[i], CONFIG_BCM4339A0);\r
break;\r
case BCM4354_CHIP_ID:\r
if (chiprev == BCM4354A1_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4354A1);\r
+ strcpy(&conf_path[i], CONFIG_BCM4354A1);\r
else if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
break;\r
case BCM4356_CHIP_ID:\r
case BCM4371_CHIP_ID:\r
if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
break;\r
case BCM43569_CHIP_ID:\r
if (chiprev == BCM4358A3_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4358A3);\r
+ strcpy(&conf_path[i], CONFIG_BCM4358A3);\r
break;\r
case BCM4359_CHIP_ID:\r
if (chiprev == BCM4359B1_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4359B1);\r
+ strcpy(&conf_path[i], CONFIG_BCM4359B1);\r
else if (chiprev == BCM4359C0_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4359C0);\r
+ strcpy(&conf_path[i], CONFIG_BCM4359C0);\r
break;\r
#endif\r
#ifdef BCMPCIE\r
case BCM4354_CHIP_ID:\r
case BCM4356_CHIP_ID:\r
if (chiprev == BCM4356A2_CHIP_REV)\r
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
+ break;\r
+ case BCM4359_CHIP_ID:\r
+ if (chiprev == BCM4359C0_CHIP_REV)\r
+ strcpy(&conf_path[i], CONFIG_BCM4359C0);\r
break;\r
#endif\r
}\r
return band;\r
}\r
\r
-int\r
-dhd_conf_set_country(dhd_pub_t *dhd)\r
-{\r
- int bcmerror = -1;\r
-\r
- memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
- printf("%s: set country %s, revision %d\n", __FUNCTION__,\r
- dhd->conf->cspec.ccode, dhd->conf->cspec.rev);\r
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);\r
-\r
- return bcmerror;\r
-}\r
-\r
int\r
dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)\r
{\r
bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));\r
if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)\r
CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));\r
- else\r
- printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
\r
return bcmerror;\r
}\r
\r
int\r
-dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)\r
+dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs)\r
{\r
int bcmerror = -1, i;\r
struct dhd_conf *conf = dhd->conf;\r
+ conf_country_list_t *country_list;\r
+\r
+ if ((nodfs > 0 || dhd->op_mode & DHD_FLAG_HOSTAP_MODE) &&\r
+ conf->country_list_nodfs.count > 0) {\r
+ country_list = &conf->country_list_nodfs;\r
+ } else {\r
+ country_list = &conf->country_list;\r
+ }\r
\r
- for (i = 0; i < conf->country_list.count; i++) {\r
- if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {\r
- memcpy(cspec->ccode,\r
- conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);\r
- cspec->rev = conf->country_list.cspec[i].rev;\r
+ for (i = 0; i < country_list->count; i++) {\r
+ if (!strncmp(cspec->country_abbrev, country_list->cspec[i]->country_abbrev, 2)) {\r
+ memcpy(cspec->ccode, country_list->cspec[i]->ccode, WLC_CNTRY_BUF_SZ);\r
+ cspec->rev = country_list->cspec[i]->rev;\r
printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
return 0;\r
}\r
return bcmerror;\r
}\r
\r
+int\r
+dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec)\r
+{\r
+ int bcmerror = -1;\r
+\r
+ memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
+\r
+ printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);\r
+ dhd_conf_get_country(dhd, cspec);\r
+ printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
+\r
+ return bcmerror;\r
+}\r
+\r
int\r
dhd_conf_fix_country(dhd_pub_t *dhd)\r
{\r
uint band;\r
wl_uint32_list_t *list;\r
u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
+ wl_country_t cspec;\r
\r
if (!(dhd && dhd->conf)) {\r
return bcmerror;\r
dtoh32(list->count)<11)) {\r
CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",\r
__FUNCTION__, bcmerror, dtoh32(list->count)));\r
- if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {\r
- strcpy(dhd->conf->cspec.country_abbrev, "US");\r
- dhd->conf->cspec.rev = 0;\r
- strcpy(dhd->conf->cspec.ccode, "US");\r
- dhd_conf_set_country(dhd);\r
+ dhd_conf_map_country_list(dhd, &dhd->conf->cspec, 0);\r
+ if ((bcmerror = dhd_conf_set_country(dhd, &dhd->conf->cspec)) < 0) {\r
+ strcpy(cspec.country_abbrev, "US");\r
+ cspec.rev = 0;\r
+ strcpy(cspec.ccode, "US");\r
+ dhd_conf_map_country_list(dhd, &cspec, 0);\r
+ dhd_conf_set_country(dhd, &cspec);\r
}\r
}\r
\r
return;\r
}\r
\r
+void\r
+dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int p2p_mode, int miracast_mode)\r
+{\r
+ int i;\r
+ struct dhd_conf *conf = dhd->conf;\r
+ bool set = true;\r
+\r
+ for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+ set = true;\r
+ set &= (conf->mchan[i].bw >= 0);\r
+ set &= ((conf->mchan[i].p2p_mode == -1) | (conf->mchan[i].p2p_mode == p2p_mode));\r
+ set &= ((conf->mchan[i].miracast_mode == -1) | (conf->mchan[i].miracast_mode == miracast_mode));\r
+ if (set) {\r
+ dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mchan_bw", conf->mchan[i].bw, 0, FALSE);\r
+ }\r
+ }\r
+\r
+ return;\r
+}\r
+\r
#ifdef PKT_FILTER_SUPPORT\r
void\r
dhd_conf_add_pkt_filter(dhd_pub_t *dhd)\r
{\r
int i, j;\r
- char str[12];\r
+ char str[16];\r
#define MACS "%02x%02x%02x%02x%02x%02x"\r
\r
/*\r
}\r
dhd->pktfilter_count += i;\r
\r
- for(i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
+ if (dhd->conf->magic_pkt_filter_add) {\r
+ strcat(dhd->conf->magic_pkt_filter_add, " 0x");\r
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
for (j=0; j<16; j++)\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
+ strcat(dhd->conf->magic_pkt_filter_add, " 0x");\r
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));\r
for (j=0; j<16; j++)\r
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);\r
- dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];\r
+ strncat(dhd->conf->magic_pkt_filter_add, str, 12);\r
+ dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add;\r
dhd->pktfilter_count += 1;\r
}\r
}\r
char *pch, *pick_tmp;\r
struct dhd_conf *conf = dhd->conf;\r
char *data = full_param+len_param;\r
+ wl_country_t *cspec;\r
\r
/* Process country_list:\r
* country_list=[country1]:[ccode1]/[regrev1],\r
pch = bcmstrtok(&pick_tmp, ":", 0);\r
if (!pch)\r
break;\r
- strcpy(conf->country_list.cspec[i].country_abbrev, pch);\r
+ cspec = NULL;\r
+ if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {\r
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+ break;\r
+ }\r
+ conf->country_list.count++;\r
+ memset(cspec, 0, sizeof(wl_country_t));\r
+ conf->country_list.cspec[i] = cspec;\r
+\r
+ strcpy(cspec->country_abbrev, pch);\r
pch = bcmstrtok(&pick_tmp, "/", 0);\r
if (!pch)\r
break;\r
- memcpy(conf->country_list.cspec[i].ccode, pch, 2);\r
+ memcpy(cspec->ccode, pch, 2);\r
pch = bcmstrtok(&pick_tmp, ", ", 0);\r
if (!pch)\r
break;\r
- conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);\r
- conf->country_list.count ++;\r
+ cspec->rev = (int32)simple_strtol(pch, NULL, 10);\r
CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,\r
- conf->country_list.cspec[i].country_abbrev,\r
- conf->country_list.cspec[i].ccode,\r
- conf->country_list.cspec[i].rev));\r
+ cspec->country_abbrev, cspec->ccode, cspec->rev));\r
}\r
printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);\r
}\r
+ else if (!strncmp("country_list_nodfs=", full_param, len_param)) {\r
+ pick_tmp = data;\r
+ for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {\r
+ /* Process country code */\r
+ pch = bcmstrtok(&pick_tmp, ":", 0);\r
+ if (!pch)\r
+ break;\r
+ cspec = NULL;\r
+ if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {\r
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+ break;\r
+ }\r
+ conf->country_list_nodfs.count++;\r
+ memset(cspec, 0, sizeof(wl_country_t));\r
+ conf->country_list_nodfs.cspec[i] = cspec;\r
+\r
+ strcpy(cspec->country_abbrev, pch);\r
+ pch = bcmstrtok(&pick_tmp, "/", 0);\r
+ if (!pch)\r
+ break;\r
+ memcpy(cspec->ccode, pch, 2);\r
+ pch = bcmstrtok(&pick_tmp, ", ", 0);\r
+ if (!pch)\r
+ break;\r
+ cspec->rev = (int32)simple_strtol(pch, NULL, 10);\r
+ CONFIG_TRACE(("%s: country_list_nodfs abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,\r
+ cspec->country_abbrev, cspec->ccode, cspec->rev));\r
+ }\r
+ printf("%s: %d nodfs country in list\n", __FUNCTION__, conf->country_list_nodfs.count);\r
+ }\r
+ else\r
+ return false;\r
+\r
+ return true;\r
+}\r
+\r
+bool\r
+dhd_conf_read_mchan_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
+{\r
+ int i;\r
+ char *pch, *pick_tmp, *pick_tmp2;\r
+ struct dhd_conf *conf = dhd->conf;\r
+ char *data = full_param+len_param;\r
+\r
+ /* Process mchan_bw and btc_params_mgmt:\r
+ * mchan_bw=[val]/[any/go/gc]/[any/source/sink]\r
+ * Ex: mchan_bw=80/go/source, 30/gc/sink\r
+ */\r
+ if (!strncmp("mchan_bw=", full_param, len_param)) {\r
+ pick_tmp = data;\r
+ for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+ pick_tmp2 = bcmstrtok(&pick_tmp, ", ", 0);\r
+ if (!pick_tmp2)\r
+ break;\r
+ pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+ if (!pch) {\r
+ break;\r
+ } else {\r
+ conf->mchan[i].bw = (int)simple_strtol(pch, NULL, 0);\r
+ if (conf->mchan[i].bw < 0 || conf->mchan[i].bw > 100) {\r
+ CONFIG_ERROR(("%s: wrong bw %d\n", __FUNCTION__, conf->mchan[i].bw));\r
+ conf->mchan[i].bw = 0;\r
+ break;\r
+ }\r
+ }\r
+ pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+ if (!pch) {\r
+ break;\r
+ } else {\r
+ if (bcmstrstr(pch, "any")) {\r
+ conf->mchan[i].p2p_mode = -1;\r
+ } else if (bcmstrstr(pch, "go")) {\r
+ conf->mchan[i].p2p_mode = WL_P2P_IF_GO;\r
+ } else if (bcmstrstr(pch, "gc")) {\r
+ conf->mchan[i].p2p_mode = WL_P2P_IF_CLIENT;\r
+ }\r
+ }\r
+ pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+ if (!pch) {\r
+ break;\r
+ } else {\r
+ if (bcmstrstr(pch, "any")) {\r
+ conf->mchan[i].miracast_mode = -1;\r
+ } else if (bcmstrstr(pch, "source")) {\r
+ conf->mchan[i].miracast_mode = MIRACAST_SOURCE;\r
+ } else if (bcmstrstr(pch, "sink")) {\r
+ conf->mchan[i].miracast_mode = MIRACAST_SINK;\r
+ }\r
+ }\r
+ }\r
+ for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+ if (conf->mchan[i].bw >= 0)\r
+ printf("%s: mchan_bw=%d/%d/%d\n", __FUNCTION__,\r
+ conf->mchan[i].bw, conf->mchan[i].p2p_mode, conf->mchan[i].miracast_mode);\r
+ }\r
+ }\r
else\r
return false;\r
\r
printf("\n");\r
}\r
else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {\r
- pick_tmp = data;\r
- pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
- i=0;\r
- while (pch != NULL && i<DHD_CONF_FILTER_MAX) {\r
- strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);\r
- printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);\r
- pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
- i++;\r
+ if (!(conf->magic_pkt_filter_add = kmalloc(MAGIC_PKT_FILTER_LEN, GFP_KERNEL))) {\r
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+ } else {\r
+ memset(conf->magic_pkt_filter_add, 0, MAGIC_PKT_FILTER_LEN);\r
+ strcpy(conf->magic_pkt_filter_add, data);\r
+ printf("%s: magic_pkt_filter_add = %s\n", __FUNCTION__, conf->magic_pkt_filter_add);\r
}\r
- conf->magic_pkt_filter_add.count = i;\r
}\r
else\r
return false;\r
conf->bus_rxglom = TRUE;\r
printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);\r
}\r
- else if (!strncmp("dhd_poll=", full_param, len_param)) {\r
- if (!strncmp(data, "0", 1))\r
- conf->dhd_poll = 0;\r
- else\r
- conf->dhd_poll = 1;\r
- printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);\r
- }\r
else if (!strncmp("deferred_tx_len=", full_param, len_param)) {\r
conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);\r
printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);\r
}\r
#endif\r
\r
+#ifdef BCMPCIE\r
+bool\r
+dhd_conf_read_pcie_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
+{\r
+ struct dhd_conf *conf = dhd->conf;\r
+ char *data = full_param+len_param;\r
+\r
+ if (!strncmp("bus:deepsleep_disable=", full_param, len_param)) {\r
+ if (!strncmp(data, "0", 1))\r
+ conf->bus_deepsleep_disable = 0;\r
+ else\r
+ conf->bus_deepsleep_disable = 1;\r
+ printf("%s: bus:deepsleep_disable = %d\n", __FUNCTION__, conf->bus_deepsleep_disable);\r
+ }\r
+ else\r
+ return false;\r
+\r
+ return true;\r
+}\r
+#endif\r
+\r
bool\r
dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
{\r
conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);\r
printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);\r
}\r
+#ifdef SUSPEND_EVENT\r
+ else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {\r
+ if (!strncmp(data, "1", 1))\r
+ conf->suspend_eventmask_enable = TRUE;\r
+ else\r
+ conf->suspend_eventmask_enable = FALSE;\r
+ printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);\r
+ }\r
+#endif\r
else\r
return false;\r
\r
char *pch, *pick_tmp;\r
int i;\r
\r
- if (!strncmp("band=", full_param, len_param)) {\r
+ if (!strncmp("dhd_poll=", full_param, len_param)) {\r
+ if (!strncmp(data, "0", 1))\r
+ conf->dhd_poll = 0;\r
+ else\r
+ conf->dhd_poll = 1;\r
+ printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);\r
+ }\r
+ else if (!strncmp("dhd_watchdog_ms=", full_param, len_param)) {\r
+ dhd_watchdog_ms = (int)simple_strtol(data, NULL, 10);\r
+ printf("%s: dhd_watchdog_ms = %d\n", __FUNCTION__, dhd_watchdog_ms);\r
+ }\r
+ else if (!strncmp("band=", full_param, len_param)) {\r
/* Process band:\r
* band=a for 5GHz only and band=b for 2.4GHz only\r
*/\r
conf->tsq = (int)simple_strtol(data, NULL, 10);\r
printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);\r
}\r
+ else if (!strncmp("ctrl_resched=", full_param, len_param)) {\r
+ conf->ctrl_resched = (int)simple_strtol(data, NULL, 10);\r
+ printf("%s: ctrl_resched = %d\n", __FUNCTION__, conf->ctrl_resched);\r
+ }\r
+ else if (!strncmp("dhd_ioctl_timeout_msec=", full_param, len_param)) {\r
+ conf->dhd_ioctl_timeout_msec = (int)simple_strtol(data, NULL, 10);\r
+ printf("%s: dhd_ioctl_timeout_msec = %d\n", __FUNCTION__, conf->dhd_ioctl_timeout_msec);\r
+ }\r
else\r
return false;\r
\r
continue;\r
else if (dhd_conf_read_country_list(dhd, pick, len_param))\r
continue;\r
+ else if (dhd_conf_read_mchan_params(dhd, pick, len_param))\r
+ continue;\r
#ifdef PKT_FILTER_SUPPORT\r
else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))\r
continue;\r
else if (dhd_conf_read_sdio_params(dhd, pick, len_param))\r
continue;\r
#endif /* BCMSDIO */\r
+#ifdef BCMPCIE\r
+ else if (dhd_conf_read_pcie_params(dhd, pick, len_param))\r
+ continue;\r
+#endif /* BCMPCIE */\r
else if (dhd_conf_read_pm_params(dhd, pick, len_param))\r
continue;\r
else if (dhd_conf_read_others(dhd, pick, len_param))\r
dhd_conf_preinit(dhd_pub_t *dhd)\r
{\r
struct dhd_conf *conf = dhd->conf;\r
+ int i;\r
\r
CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
\r
dhd_conf_free_mac_list(&conf->nv_by_mac);\r
dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);\r
#endif\r
+ dhd_conf_free_country_list(&conf->country_list);\r
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+ if (conf->magic_pkt_filter_add)\r
+ kfree(conf->magic_pkt_filter_add);\r
memset(&conf->country_list, 0, sizeof(conf_country_list_t));\r
conf->band = -1;\r
conf->mimo_bw_cap = -1;\r
#ifdef PKT_FILTER_SUPPORT\r
memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));\r
memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));\r
- memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));\r
#endif\r
conf->srl = -1;\r
conf->lrl = -1;\r
conf->txbf = -1;\r
conf->lpc = -1;\r
conf->disable_proptx = -1;\r
+ conf->dhd_poll = -1;\r
#ifdef BCMSDIO\r
conf->bus_txglom = -1;\r
conf->use_rxchain = 0;\r
conf->txglom_ext = FALSE;\r
conf->tx_max_offset = 0;\r
conf->txglomsize = SDPCM_DEFGLOM_SIZE;\r
- conf->dhd_poll = -1;\r
conf->txctl_tmo_fix = 5;\r
conf->tx_in_rx = TRUE;\r
conf->txglom_mode = SDPCM_TXGLOM_MDESC;\r
conf->txinrx_thres = -1;\r
conf->sd_f2_blocksize = 0;\r
conf->oob_enabled_later = FALSE;\r
+#endif\r
+#ifdef BCMPCIE\r
+ conf->bus_deepsleep_disable = 1;\r
#endif\r
conf->ampdu_ba_wsize = 0;\r
conf->ampdu_hostreorder = -1;\r
conf->num_different_channels = -1;\r
conf->xmit_in_suspend = TRUE;\r
conf->ap_in_suspend = 0;\r
+#ifdef SUSPEND_EVENT\r
+ conf->suspend_eventmask_enable = FALSE;\r
+ memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));\r
+ memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));\r
+#endif\r
#ifdef IDHCP\r
conf->dhcpc_enable = -1;\r
conf->dhcpd_enable = -1;\r
conf->rsdb_mode = -2;\r
conf->vhtmode = -1;\r
conf->autocountry = -1;\r
+ conf->ctrl_resched = 2;\r
+ conf->dhd_ioctl_timeout_msec = 0;\r
#ifdef IAPSTA_PREINIT\r
memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));\r
memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));\r
memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));\r
#endif\r
+ for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+ memset(&conf->mchan[i], -1, sizeof(mchan_params_t));\r
+ }\r
#ifdef CUSTOMER_HW_AMLOGIC\r
dhd_slpauto = FALSE;\r
+ conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
#endif\r
if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||\r
conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||\r
conf->chip == BCM4359_CHIP_ID) {\r
#ifdef DHDTCPACK_SUPPRESS\r
+#ifdef BCMSDIO\r
conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;\r
+#endif\r
#endif\r
dhd_rxbound = 128;\r
dhd_txbound = 64;\r
dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
#endif\r
+ dhd_conf_free_country_list(&dhd->conf->country_list);\r
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+ if (dhd->conf->magic_pkt_filter_add)\r
+ kfree(dhd->conf->magic_pkt_filter_add);\r
memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
return 0;\r
}\r
dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
#endif\r
+ dhd_conf_free_country_list(&dhd->conf->country_list);\r
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+ if (dhd->conf->magic_pkt_filter_add)\r
+ kfree(dhd->conf->magic_pkt_filter_add);\r
MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
}\r
dhd->conf = NULL;\r
-\r
-\r
-#include <linux/module.h>\r
-#include <linux/netdevice.h>\r
-#include <net/netlink.h>\r
-\r
-#include <wl_android.h>\r
-#include <wldev_common.h>\r
-#include <wlioctl.h>\r
-#include <bcmutils.h>\r
-#include <linux_osl.h>\r
-#include <dhd_dbg.h>\r
-#include <dngl_stats.h>\r
-#include <dhd.h>\r
-#include <dhd_config.h>\r
-\r
-#define htod32(i) i\r
-#define htod16(i) i\r
-#define dtoh32(i) i\r
-#define dtoh16(i) i\r
-#define htodchanspec(i) i\r
-#define dtohchanspec(i) i\r
-#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))\r
-\r
-#define CMD_CHANNEL "CHANNEL"\r
-#define CMD_CHANNELS "CHANNELS"\r
-#define CMD_ROAM_TRIGGER "ROAM_TRIGGER"\r
-#define CMD_KEEP_ALIVE "KEEP_ALIVE"\r
-#define CMD_PM "PM"\r
-#define CMD_MONITOR "MONITOR"\r
-#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM"\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-#define CMD_IAPSTA_INIT "IAPSTA_INIT"\r
-#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG"\r
-#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE"\r
-#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE"\r
-#ifdef PROP_TXSTATUS\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#include <dhd_wlfc.h>\r
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/netlink.h>
+
+#include <wl_android.h>
+#include <wldev_common.h>
+#include <wlioctl.h>
+#include <bcmutils.h>
+#include <linux_osl.h>
+#include <dhd_dbg.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_config.h>
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+
+#define CMD_CHANNEL "CHANNEL"
+#define CMD_CHANNELS "CHANNELS"
+#define CMD_ROAM_TRIGGER "ROAM_TRIGGER"
+#define CMD_KEEP_ALIVE "KEEP_ALIVE"
+#define CMD_PM "PM"
+#define CMD_MONITOR "MONITOR"
+#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM"
+
+#ifdef WL_EXT_IAPSTA
+#define CMD_IAPSTA_INIT "IAPSTA_INIT"
+#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG"
+#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE"
+#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE"
+#ifdef PROP_TXSTATUS
+#ifdef PROP_TXSTATUS_VSDB
+#include <dhd_wlfc.h>
extern int disable_proptx;
-#endif /* PROP_TXSTATUS_VSDB */\r
-#endif\r
-#endif\r
-#ifdef IDHCP\r
-#define CMD_DHCPC_ENABLE "DHCPC_ENABLE"\r
-#define CMD_DHCPC_DUMP "DHCPC_DUMP"\r
-#endif\r
-#define CMD_WL "WL"\r
-\r
-#define IEEE80211_BAND_2GHZ 0\r
-#define IEEE80211_BAND_5GHZ 1\r
-\r
-int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)\r
-{\r
- int ret;\r
-\r
- ret = wldev_ioctl(dev, cmd, arg, len, set);\r
- if (ret)\r
- ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret));\r
- return ret;\r
-}\r
-\r
-int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val)\r
-{\r
- int ret;\r
-\r
- ret = wldev_iovar_getint(dev, iovar, val);\r
- if (ret)\r
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));\r
-\r
- return ret;\r
-}\r
-\r
-int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)\r
-{\r
- int ret;\r
-\r
- ret = wldev_iovar_setint(dev, iovar, val);\r
- if (ret)\r
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));\r
-\r
- return ret;\r
-}\r
-\r
-int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name,\r
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)\r
-{\r
- int ret;\r
-\r
- ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);\r
- if (ret != 0)\r
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
- return ret;\r
-}\r
-\r
-int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,\r
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)\r
-{\r
- int ret;\r
-\r
- ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);\r
- if (ret != 0)\r
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
- return ret;\r
-}\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name,\r
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)\r
-{\r
- int ret;\r
- \r
- ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen,\r
- buf, buflen, bsscfg_idx, buf_sync);\r
- if (ret < 0)\r
- ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
- return ret;\r
-}\r
-\r
-int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name,\r
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)\r
-{\r
- int ret;\r
- \r
- ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen,\r
- buf, buflen, bsscfg_idx, buf_sync);\r
- if (ret < 0)\r
- ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
- return ret;\r
-}\r
-#endif\r
+#endif /* PROP_TXSTATUS_VSDB */
+#endif
+#endif
+#ifdef IDHCP
+#define CMD_DHCPC_ENABLE "DHCPC_ENABLE"
+#define CMD_DHCPC_DUMP "DHCPC_DUMP"
+#endif
+#define CMD_WL "WL"
+
+#define IEEE80211_BAND_2GHZ 0
+#define IEEE80211_BAND_5GHZ 1
+
+int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
+{
+ int ret;
+
+ ret = wldev_ioctl(dev, cmd, arg, len, set);
+ if (ret)
+ ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret));
+ return ret;
+}
+
+int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val)
+{
+ int ret;
+
+ ret = wldev_iovar_getint(dev, iovar, val);
+ if (ret)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)
+{
+ int ret;
+
+ ret = wldev_iovar_setint(dev, iovar, val);
+ if (ret)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
+ if (ret != 0)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
+ if (ret != 0)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+#ifdef WL_EXT_IAPSTA
+int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen,
+ buf, buflen, bsscfg_idx, buf_sync);
+ if (ret < 0)
+ ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen,
+ buf, buflen, bsscfg_idx, buf_sync);
+ if (ret < 0)
+ ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+#endif
/* Return a legacy chanspec given a new chanspec
* Returns INVCHANSPEC on error
*/
static chanspec_t
-wl_ext_chspec_to_legacy(chanspec_t chspec)\r
+wl_ext_chspec_to_legacy(chanspec_t chspec)
{
chanspec_t lchspec;
if (wf_chspec_malformed(chspec)) {
- ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n",\r
+ ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
chspec));
return INVCHANSPEC;
}
} else {
/* cannot express the bandwidth */
char chanbuf[CHANSPEC_STR_LEN];
- ANDROID_ERROR((\r
- "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "\r
+ ANDROID_ERROR((
+ "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
"to pre-11ac format\n",
wf_chspec_ntoa(chspec, chanbuf), chspec));
return INVCHANSPEC;
}
return lchspec;
-}\r
+}
/* given a chanspec value, do the endian and chanspec version conversion to
* a chanspec_t value
* Returns INVCHANSPEC on error
*/
static chanspec_t
-wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)\r
+wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
{
- if (ioctl_ver == 1) {\r
- chanspec = wl_ext_chspec_to_legacy(chanspec);\r
+ if (ioctl_ver == 1) {
+ chanspec = wl_ext_chspec_to_legacy(chanspec);
if (chanspec == INVCHANSPEC) {
return chanspec;
}
chanspec = htodchanspec(chanspec);
return chanspec;
-}\r
-\r
-static int\r
-wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)\r
-{\r
- int ret = 0;\r
- s32 val = 0;\r
-\r
- val = 1;\r
- ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0);\r
- if (ret) {\r
- ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret));\r
- return ret;\r
- }\r
- val = dtoh32(val);\r
- if (val != WLC_IOCTL_VERSION && val != 1) {\r
- ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",\r
- val, WLC_IOCTL_VERSION));\r
- return BCME_VERSION;\r
- }\r
- *ioctl_ver = val;\r
-\r
- return ret;\r
-}\r
-\r
-static int\r
-wl_ext_set_chanspec(struct net_device *dev, uint16 channel)\r
-{\r
- s32 _chan = channel;\r
+}
+
+static int
+wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)
+{
+ int ret = 0;
+ s32 val = 0;
+
+ val = 1;
+ ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0);
+ if (ret) {
+ ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret));
+ return ret;
+ }
+ val = dtoh32(val);
+ if (val != WLC_IOCTL_VERSION && val != 1) {
+ ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+ val, WLC_IOCTL_VERSION));
+ return BCME_VERSION;
+ }
+ *ioctl_ver = val;
+
+ return ret;
+}
+
+static int
+wl_ext_set_chanspec(struct net_device *dev, uint16 channel)
+{
+ s32 _chan = channel;
chanspec_t chspec = 0;
- chanspec_t fw_chspec = 0;\r
- u32 bw = WL_CHANSPEC_BW_20;\r
+ chanspec_t fw_chspec = 0;
+ u32 bw = WL_CHANSPEC_BW_20;
s32 err = BCME_OK;
- s32 bw_cap = 0;\r
- s8 iovar_buf[WLC_IOCTL_SMLEN];\r
+ s32 bw_cap = 0;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
struct {
u32 band;
u32 bw_cap;
- } param = {0, 0};\r
- uint band;\r
- int ioctl_ver = 0;\r
-\r
- if (_chan <= CH_MAX_2G_CHANNEL)\r
- band = IEEE80211_BAND_2GHZ;\r
- else\r
- band = IEEE80211_BAND_5GHZ;\r
- wl_ext_get_ioctl_ver(dev, &ioctl_ver);\r
-\r
- if (band == IEEE80211_BAND_5GHZ) {\r
+ } param = {0, 0};
+ uint band;
+ int ioctl_ver = 0;
+
+ if (_chan <= CH_MAX_2G_CHANNEL)
+ band = IEEE80211_BAND_2GHZ;
+ else
+ band = IEEE80211_BAND_5GHZ;
+ wl_ext_get_ioctl_ver(dev, &ioctl_ver);
+
+ if (band == IEEE80211_BAND_5GHZ) {
param.band = WLC_BAND_5G;
err = wldev_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
if (err) {
if (err != BCME_UNSUPPORTED) {
- ANDROID_ERROR(("bw_cap failed, %d\n", err));\r
+ ANDROID_ERROR(("bw_cap failed, %d\n", err));
return err;
} else {
err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
if (err) {
- ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err));\r
+ ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err));
}
if (bw_cap != WLC_N_BW_20ALL)
bw = WL_CHANSPEC_BW_40;
}
} else {
- if (WL_BW_CAP_80MHZ(iovar_buf[0]))\r
+ if (WL_BW_CAP_80MHZ(iovar_buf[0]))
bw = WL_CHANSPEC_BW_80;
- else if (WL_BW_CAP_40MHZ(iovar_buf[0]))\r
+ else if (WL_BW_CAP_40MHZ(iovar_buf[0]))
bw = WL_CHANSPEC_BW_40;
else
bw = WL_CHANSPEC_BW_20;
- }\r
- }\r
- else if (band == IEEE80211_BAND_2GHZ)\r
- bw = WL_CHANSPEC_BW_20;\r
-\r
+ }
+ }
+ else if (band == IEEE80211_BAND_2GHZ)
+ bw = WL_CHANSPEC_BW_20;
+
set_channel:
chspec = wf_channel2chspec(_chan, bw);
if (wf_chspec_valid(chspec)) {
- fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec);\r
+ fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec);
if (fw_chspec != INVCHANSPEC) {
- if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {\r
+ if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {
if (bw == WL_CHANSPEC_BW_80)
- goto change_bw;\r
- wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);\r
- printf("%s: channel %d\n", __FUNCTION__, _chan);\r
+ goto change_bw;
+ wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);
+ printf("%s: channel %d\n", __FUNCTION__, _chan);
} else if (err) {
- ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err));\r
- } else\r
- printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec);\r
+ ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err));
+ } else
+ printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec);
} else {
- ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__));\r
+ ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__));
err = BCME_ERROR;
}
} else {
bw = 0;
if (bw)
goto set_channel;
- ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));\r
+ ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));
err = BCME_ERROR;
- }\r
-\r
- return err;\r
-}\r
-\r
-int\r
-wl_ext_channel(struct net_device *dev, char* command, int total_len)\r
-{\r
- int ret;\r
- int channel=0;\r
- channel_info_t ci;\r
- int bytes_written = 0;\r
-\r
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
- sscanf(command, "%*s %d", &channel);\r
-\r
- if (channel > 0) {\r
- ret = wl_ext_set_chanspec(dev, channel);\r
- } else {\r
- if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {\r
- ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel));\r
- ANDROID_TRACE(("target_channel %d\n", ci.target_channel));\r
- ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel));\r
- bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-int\r
-wl_ext_channels(struct net_device *dev, char* command, int total_len)\r
-{\r
- int ret, i;\r
- int bytes_written = -1;\r
- u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
- wl_uint32_list_t *list;\r
-\r
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
- memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
- list = (wl_uint32_list_t *)(void *) valid_chan_list;\r
- list->count = htod32(WL_NUMCHANNELS);\r
- ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0);\r
- if (ret<0) {\r
- ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret));\r
- } else {\r
- bytes_written = snprintf(command, total_len, "channels");\r
- for (i = 0; i < dtoh32(list->count); i++) {\r
- bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i]));\r
- printf("%d ", dtoh32(list->element[i]));\r
- }\r
- printf("\n");\r
- ret = bytes_written;\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-int\r
-wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)\r
-{\r
- int ret = 0;\r
- int roam_trigger[2] = {0, 0};\r
- int trigger[2]= {0, 0};\r
- int bytes_written=-1;\r
-\r
- sscanf(command, "%*s %10d", &roam_trigger[0]);\r
-\r
- if (roam_trigger[0]) {\r
- roam_trigger[1] = WLC_BAND_ALL;\r
- ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1);\r
- if (ret)\r
- ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
- } else {\r
- roam_trigger[1] = WLC_BAND_2G;\r
- ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);\r
- if (!ret)\r
- trigger[0] = roam_trigger[0];\r
- else\r
- ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
-\r
- roam_trigger[1] = WLC_BAND_5G;\r
- ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);\r
- if (!ret)\r
- trigger[1] = roam_trigger[0];\r
- else\r
- ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
-\r
- ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1]));\r
- bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]);\r
- ret = bytes_written;\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static int\r
-wl_ext_pattern_atoh(char *src, char *dst)\r
-{\r
- int i;\r
- if (strncmp(src, "0x", 2) != 0 &&\r
- strncmp(src, "0X", 2) != 0) {\r
- ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n"));\r
- return -1;\r
- }\r
- src = src + 2; /* Skip past 0x */\r
- if (strlen(src) % 2 != 0) {\r
- DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));\r
- return -1;\r
- }\r
- for (i = 0; *src != '\0'; i++) {\r
- char num[3];\r
- bcm_strncpy_s(num, sizeof(num), src, 2);\r
- num[2] = '\0';\r
- dst[i] = (uint8)strtoul(num, NULL, 16);\r
- src += 2;\r
- }\r
- return i;\r
-}\r
-\r
-int\r
-wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)\r
-{\r
- wl_mkeep_alive_pkt_t *mkeep_alive_pktp;\r
- int ret = -1, i;\r
- int id, period=-1, len_bytes=0, buf_len=0;\r
- char data[200]="\0";\r
- char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0";\r
- int bytes_written = -1;\r
-\r
- ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));\r
- sscanf(command, "%*s %d %d %s", &id, &period, data);\r
- ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data));\r
-\r
- if (period >= 0) {\r
- mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf;\r
- mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION);\r
- mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);\r
- mkeep_alive_pktp->keep_alive_id = id;\r
- buf_len += WL_MKEEP_ALIVE_FIXED_LEN;\r
- mkeep_alive_pktp->period_msec = period;\r
- if (strlen(data)) {\r
- len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data);\r
- buf_len += len_bytes;\r
- }\r
- mkeep_alive_pktp->len_bytes = htod16(len_bytes);\r
-\r
- ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,\r
- iovar_buf, sizeof(iovar_buf), NULL);\r
- } else {\r
- if (id < 0)\r
- id = 0;\r
- ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL);\r
- if (ret) {\r
- goto exit;\r
- } else {\r
- mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;\r
- printf("Id :%d\n"\r
- "Period (msec) :%d\n"\r
- "Length :%d\n"\r
- "Packet :0x",\r
- mkeep_alive_pktp->keep_alive_id,\r
- dtoh32(mkeep_alive_pktp->period_msec),\r
- dtoh16(mkeep_alive_pktp->len_bytes));\r
- for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {\r
- printf("%02x", mkeep_alive_pktp->data[i]);\r
- }\r
- printf("\n");\r
- }\r
- bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec));\r
- bytes_written += snprintf(command+bytes_written, total_len, "0x");\r
- for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {\r
- bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]);\r
- }\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- \r
-exit:\r
- return ret;\r
-}\r
-\r
-int\r
-wl_ext_pm(struct net_device *dev, char *command, int total_len)\r
-{\r
- int pm=-1, ret = -1;\r
- char *pm_local;\r
- int bytes_written=-1;\r
-\r
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
- sscanf(command, "%*s %d", &pm);\r
-\r
- if (pm >= 0) {\r
- ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);\r
- if (ret)\r
- ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret));\r
- } else {\r
- ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE);\r
- if (!ret) {\r
- ANDROID_TRACE(("%s: PM = %d\n", __func__, pm));\r
- if (pm == PM_OFF)\r
- pm_local = "PM_OFF";\r
- else if(pm == PM_MAX)\r
- pm_local = "PM_MAX";\r
- else if(pm == PM_FAST)\r
- pm_local = "PM_FAST";\r
- else {\r
- pm = 0;\r
- pm_local = "Invalid";\r
- }\r
- bytes_written = snprintf(command, total_len, "PM %s", pm_local);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-static int\r
-wl_ext_monitor(struct net_device *dev, char *command, int total_len)\r
-{\r
- int val, ret = -1;\r
- int bytes_written=-1;\r
-\r
- sscanf(command, "%*s %d", &val);\r
-\r
- if (val >=0) {\r
- ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);\r
- if (ret)\r
- ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));\r
- } else {\r
- ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE);\r
- if (!ret) {\r
- ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val));\r
- bytes_written = snprintf(command, total_len, "monitor %d", val);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-struct wl_apsta_params g_apsta_params;\r
-static int\r
-wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)\r
-{\r
- char hex[] = "XX";\r
- unsigned char *data = wsec_key->data;\r
- char *keystr = key;\r
-\r
- switch (strlen(keystr)) {\r
- case 5:\r
- case 13:\r
- case 16:\r
- wsec_key->len = strlen(keystr);\r
- memcpy(data, keystr, wsec_key->len + 1);\r
- break;\r
- case 12:\r
- case 28:\r
- case 34:\r
- case 66:\r
- /* strip leading 0x */\r
- if (!strnicmp(keystr, "0x", 2))\r
- keystr += 2;\r
- else\r
- return -1;\r
- /* fall through */\r
- case 10:\r
- case 26:\r
- case 32:\r
- case 64:\r
- wsec_key->len = strlen(keystr) / 2;\r
- while (*keystr) {\r
- strncpy(hex, keystr, 2);\r
- *data++ = (char) strtoul(hex, NULL, 16);\r
- keystr += 2;\r
- }\r
- break;\r
- default:\r
- return -1;\r
- }\r
-\r
- switch (wsec_key->len) {\r
- case 5:\r
- wsec_key->algo = CRYPTO_ALGO_WEP1;\r
- break;\r
- case 13:\r
- wsec_key->algo = CRYPTO_ALGO_WEP128;\r
- break;\r
- case 16:\r
- /* default to AES-CCM */\r
- wsec_key->algo = CRYPTO_ALGO_AES_CCM;\r
- break;\r
- case 32:\r
- wsec_key->algo = CRYPTO_ALGO_TKIP;\r
- break;\r
- default:\r
- return -1;\r
- }\r
-\r
- /* Set as primary wsec_key by default */\r
- wsec_key->flags |= WL_PRIMARY_KEY;\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_bgnmode(struct wl_if_info *cur_if)\r
-{\r
- struct net_device *dev = cur_if->dev;\r
- bgnmode_t bgnmode = cur_if->bgnmode;\r
- int val;\r
-\r
- if (bgnmode == 0)\r
- return 0;\r
-\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- if (bgnmode == IEEE80211B) {\r
- wl_ext_iovar_setint(dev, "nmode", 0);\r
- val = 0;\r
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
- ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__));\r
- } else if (bgnmode == IEEE80211G) {\r
- wl_ext_iovar_setint(dev, "nmode", 0);\r
- val = 2;\r
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
- ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__));\r
- } else if (bgnmode == IEEE80211BG) {\r
- wl_ext_iovar_setint(dev, "nmode", 0);\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
- ANDROID_TRACE(("%s: Network mode: : B/G mixed\n", __FUNCTION__));\r
- } else if (bgnmode == IEEE80211BGN) {\r
- wl_ext_iovar_setint(dev, "nmode", 0);\r
- wl_ext_iovar_setint(dev, "nmode", 1);\r
- wl_ext_iovar_setint(dev, "vhtmode", 0);\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
- ANDROID_TRACE(("%s: Network mode: : B/G/N mixed\n", __FUNCTION__));\r
- } else if (bgnmode == IEEE80211BGNAC) {\r
- wl_ext_iovar_setint(dev, "nmode", 0);\r
- wl_ext_iovar_setint(dev, "nmode", 1);\r
- wl_ext_iovar_setint(dev, "vhtmode", 1);\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
- ANDROID_TRACE(("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__));\r
- }\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)\r
-{\r
- struct net_device *dev = cur_if->dev;\r
- authmode_t amode = cur_if->amode;\r
- int auth=0, wpa_auth=0;\r
-\r
- if (amode == AUTH_OPEN) {\r
- auth = 0;\r
- wpa_auth = 0;\r
- ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));\r
- } else if (amode == AUTH_SHARED) {\r
- auth = 1;\r
- wpa_auth = 0;\r
- ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));\r
- } else if (amode == AUTH_WPAPSK) {\r
- auth = 0;\r
- wpa_auth = 4;\r
- ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));\r
- } else if (amode == AUTH_WPA2PSK) {\r
- auth = 0;\r
- wpa_auth = 128;\r
- ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));\r
- } else if (amode == AUTH_WPAWPA2PSK) {\r
- auth = 0;\r
- wpa_auth = 132;\r
- ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));\r
- }\r
- wl_ext_iovar_setint(dev, "auth", auth);\r
-\r
- wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)\r
-{\r
- struct net_device *dev = cur_if->dev;\r
- int wsec=0;\r
- struct wl_wsec_key wsec_key;\r
- wsec_pmk_t psk;\r
- encmode_t emode = cur_if->emode;\r
- char *key = cur_if->key;\r
-\r
- memset(&wsec_key, 0, sizeof(wsec_key));\r
- memset(&psk, 0, sizeof(psk));\r
- if (emode == ENC_NONE) {\r
- wsec = 0;\r
- ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__));\r
- } else if (emode == ENC_WEP) {\r
- wsec = 1;\r
- wl_ext_parse_wep(key, &wsec_key);\r
- ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__));\r
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, wsec_key.data));\r
- } else if (emode == ENC_TKIP) {\r
- wsec = 2;\r
- psk.key_len = strlen(key);\r
- psk.flags = WSEC_PASSPHRASE;\r
- memcpy(psk.key, key, strlen(key));\r
- ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__));\r
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
- } else if (emode == ENC_AES) {\r
- wsec = 4;\r
- psk.key_len = strlen(key);\r
- psk.flags = WSEC_PASSPHRASE;\r
- memcpy(psk.key, key, strlen(key));\r
- ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__));\r
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
- } else if (emode == ENC_TKIPAES) {\r
- wsec = 6;\r
- psk.key_len = strlen(key);\r
- psk.flags = WSEC_PASSPHRASE;\r
- memcpy(psk.key, key, strlen(key));\r
- ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__));\r
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
- }\r
-\r
- wl_ext_iovar_setint(dev, "wsec", wsec);\r
-\r
- if (wsec == 1) {\r
- wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1);\r
- } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) {\r
- if (dev) {\r
- if (cur_if->ifmode == ISTA_MODE)\r
- wl_ext_iovar_setint(dev, "sup_wpa", 1);\r
- wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1);\r
- } else {\r
- ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__));\r
- }\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)\r
-{\r
- s32 val = 0;\r
- char *pch, *pick_tmp, *param;\r
- wlc_ssid_t ssid = { 0, {0} };\r
- s8 iovar_buf[WLC_IOCTL_SMLEN];\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
- wl_interface_create_t iface;\r
- struct dhd_pub *dhd;\r
- wl_p2p_if_t ifreq;\r
-\r
- if (apsta_params->init) {\r
- ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));\r
- return -1;\r
- }\r
-\r
- dhd = dhd_get_pub(dev);\r
- memset(apsta_params, 0, sizeof(struct wl_apsta_params));\r
-\r
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-\r
- pick_tmp = command;\r
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- while (param != NULL) {\r
- if (!strcmp(param, "mode")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- if (!strcmp(pch, "sta")) {\r
- apsta_params->apstamode = ISTAONLY_MODE;\r
- } else if (!strcmp(pch, "ap")) {\r
- apsta_params->apstamode = IAPONLY_MODE;\r
- } else if (!strcmp(pch, "apsta")) {\r
- apsta_params->apstamode = IAPSTA_MODE;\r
- } else if (!strcmp(pch, "dualap")) {\r
- apsta_params->apstamode = IDUALAP_MODE;\r
- } else if (!strcmp(pch, "gosta")) {\r
- if (!FW_SUPPORTED(dhd, p2p)) {\r
- return -1;\r
- }\r
- apsta_params->apstamode = IGOSTA_MODE;\r
- } else if (!strcmp(pch, "gcsta")) {\r
- if (!FW_SUPPORTED(dhd, p2p)) {\r
- return -1;\r
- }\r
- apsta_params->apstamode = IGCSTA_MODE;\r
- } else {\r
- ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- } else if (!strcmp(param, "vifname")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- strcpy(apsta_params->vif.ifname, pch);\r
- else {\r
- ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- }\r
-\r
- if (apsta_params->apstamode == 0) {\r
- ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));\r
- return -1;\r
- }\r
-\r
- apsta_params->pif.dev = dev;\r
- apsta_params->pif.bssidx = 0;\r
- strcpy(apsta_params->pif.ifname, dev->name);\r
- strcpy(apsta_params->pif.ssid, "tttp");\r
- apsta_params->pif.maxassoc = -1;\r
- apsta_params->pif.channel = 1;\r
-\r
- if (!strlen(apsta_params->vif.ifname))\r
- strcpy(apsta_params->vif.ifname, "wlan1");\r
- strcpy(apsta_params->vif.ssid, "tttv");\r
- apsta_params->vif.maxassoc = -1;\r
- apsta_params->vif.channel = 1;\r
-\r
- if (apsta_params->apstamode == ISTAONLY_MODE) {\r
- apsta_params->pif.ifmode = ISTA_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls\r
- // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- } else if (apsta_params->apstamode == IAPONLY_MODE) {\r
- apsta_params->pif.ifmode = IAP_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
+ }
+
+ return err;
+}
+
+int
+wl_ext_channel(struct net_device *dev, char* command, int total_len)
+{
+ int ret;
+ int channel=0;
+ channel_info_t ci;
+ int bytes_written = 0;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &channel);
+
+ if (channel > 0) {
+ ret = wl_ext_set_chanspec(dev, channel);
+ } else {
+ if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
+ ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel));
+ ANDROID_TRACE(("target_channel %d\n", ci.target_channel));
+ ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel));
+ bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+int
+wl_ext_channels(struct net_device *dev, char* command, int total_len)
+{
+ int ret, i;
+ int bytes_written = -1;
+ u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+ wl_uint32_list_t *list;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ memset(valid_chan_list, 0, sizeof(valid_chan_list));
+ list = (wl_uint32_list_t *)(void *) valid_chan_list;
+ list->count = htod32(WL_NUMCHANNELS);
+ ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0);
+ if (ret<0) {
+ ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret));
+ } else {
+ bytes_written = snprintf(command, total_len, "channels");
+ for (i = 0; i < dtoh32(list->count); i++) {
+ bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i]));
+ printf("%d ", dtoh32(list->element[i]));
+ }
+ printf("\n");
+ ret = bytes_written;
+ }
+
+ return ret;
+}
+
+int
+wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)
+{
+ int ret = 0;
+ int roam_trigger[2] = {0, 0};
+ int trigger[2]= {0, 0};
+ int bytes_written=-1;
+
+ sscanf(command, "%*s %10d", &roam_trigger[0]);
+
+ if (roam_trigger[0]) {
+ roam_trigger[1] = WLC_BAND_ALL;
+ ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+ } else {
+ roam_trigger[1] = WLC_BAND_2G;
+ ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
+ if (!ret)
+ trigger[0] = roam_trigger[0];
+ else
+ ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+
+ roam_trigger[1] = WLC_BAND_5G;
+ ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
+ if (!ret)
+ trigger[1] = roam_trigger[0];
+ else
+ ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+
+ ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1]));
+ bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]);
+ ret = bytes_written;
+ }
+
+ return ret;
+}
+
+static int
+wl_ext_pattern_atoh(char *src, char *dst)
+{
+ int i;
+ if (strncmp(src, "0x", 2) != 0 &&
+ strncmp(src, "0X", 2) != 0) {
+ ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+ return -1;
+ }
+ src = src + 2; /* Skip past 0x */
+ if (strlen(src) % 2 != 0) {
+ DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
+ return -1;
+ }
+ for (i = 0; *src != '\0'; i++) {
+ char num[3];
+ bcm_strncpy_s(num, sizeof(num), src, 2);
+ num[2] = '\0';
+ dst[i] = (uint8)strtoul(num, NULL, 16);
+ src += 2;
+ }
+ return i;
+}
+
+int
+wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)
+{
+ wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
+ int ret = -1, i;
+ int id, period=-1, len_bytes=0, buf_len=0;
+ char data[200]="\0";
+ char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0";
+ int bytes_written = -1;
+
+ ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));
+ sscanf(command, "%*s %d %d %s", &id, &period, data);
+ ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data));
+
+ if (period >= 0) {
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf;
+ mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION);
+ mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+ mkeep_alive_pktp->keep_alive_id = id;
+ buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+ mkeep_alive_pktp->period_msec = period;
+ if (strlen(data)) {
+ len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data);
+ buf_len += len_bytes;
+ }
+ mkeep_alive_pktp->len_bytes = htod16(len_bytes);
+
+ ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,
+ iovar_buf, sizeof(iovar_buf), NULL);
+ } else {
+ if (id < 0)
+ id = 0;
+ ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL);
+ if (ret) {
+ goto exit;
+ } else {
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;
+ printf("Id :%d\n"
+ "Period (msec) :%d\n"
+ "Length :%d\n"
+ "Packet :0x",
+ mkeep_alive_pktp->keep_alive_id,
+ dtoh32(mkeep_alive_pktp->period_msec),
+ dtoh16(mkeep_alive_pktp->len_bytes));
+ for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+ printf("%02x", mkeep_alive_pktp->data[i]);
+ }
+ printf("\n");
+ }
+ bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec));
+ bytes_written += snprintf(command+bytes_written, total_len, "0x");
+ for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+ bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]);
+ }
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+
+exit:
+ return ret;
+}
+
+int
+wl_ext_pm(struct net_device *dev, char *command, int total_len)
+{
+ int pm=-1, ret = -1;
+ char *pm_local;
+ int bytes_written=-1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &pm);
+
+ if (pm >= 0) {
+ ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret));
+ } else {
+ ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE);
+ if (!ret) {
+ ANDROID_TRACE(("%s: PM = %d\n", __func__, pm));
+ if (pm == PM_OFF)
+ pm_local = "PM_OFF";
+ else if(pm == PM_MAX)
+ pm_local = "PM_MAX";
+ else if(pm == PM_FAST)
+ pm_local = "PM_FAST";
+ else {
+ pm = 0;
+ pm_local = "Invalid";
+ }
+ bytes_written = snprintf(command, total_len, "PM %s", pm_local);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+static int
+wl_ext_monitor(struct net_device *dev, char *command, int total_len)
+{
+ int val, ret = -1;
+ int bytes_written=-1;
+
+ sscanf(command, "%*s %d", &val);
+
+ if (val >=0) {
+ ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));
+ } else {
+ ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE);
+ if (!ret) {
+ ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val));
+ bytes_written = snprintf(command, total_len, "monitor %d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+#ifdef WL_EXT_IAPSTA
+struct wl_apsta_params g_apsta_params;
+static int
+wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)
+{
+ char hex[] = "XX";
+ unsigned char *data = wsec_key->data;
+ char *keystr = key;
+
+ switch (strlen(keystr)) {
+ case 5:
+ case 13:
+ case 16:
+ wsec_key->len = strlen(keystr);
+ memcpy(data, keystr, wsec_key->len + 1);
+ break;
+ case 12:
+ case 28:
+ case 34:
+ case 66:
+ /* strip leading 0x */
+ if (!strnicmp(keystr, "0x", 2))
+ keystr += 2;
+ else
+ return -1;
+ /* fall through */
+ case 10:
+ case 26:
+ case 32:
+ case 64:
+ wsec_key->len = strlen(keystr) / 2;
+ while (*keystr) {
+ strncpy(hex, keystr, 2);
+ *data++ = (char) strtoul(hex, NULL, 16);
+ keystr += 2;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ switch (wsec_key->len) {
+ case 5:
+ wsec_key->algo = CRYPTO_ALGO_WEP1;
+ break;
+ case 13:
+ wsec_key->algo = CRYPTO_ALGO_WEP128;
+ break;
+ case 16:
+ /* default to AES-CCM */
+ wsec_key->algo = CRYPTO_ALGO_AES_CCM;
+ break;
+ case 32:
+ wsec_key->algo = CRYPTO_ALGO_TKIP;
+ break;
+ default:
+ return -1;
+ }
+
+ /* Set as primary wsec_key by default */
+ wsec_key->flags |= WL_PRIMARY_KEY;
+
+ return 0;
+}
+
+static int
+wl_ext_set_bgnmode(struct wl_if_info *cur_if)
+{
+ struct net_device *dev = cur_if->dev;
+ bgnmode_t bgnmode = cur_if->bgnmode;
+ int val;
+
+ if (bgnmode == 0)
+ return 0;
+
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ if (bgnmode == IEEE80211B) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 0;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211G) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 2;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BG) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G mixed\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BGN) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ wl_ext_iovar_setint(dev, "nmode", 1);
+ wl_ext_iovar_setint(dev, "vhtmode", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G/N mixed\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BGNAC) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ wl_ext_iovar_setint(dev, "nmode", 1);
+ wl_ext_iovar_setint(dev, "vhtmode", 1);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G/N/AC mixed\n", __FUNCTION__));
+ }
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+
+ return 0;
+}
+
+static int
+wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
+{
+ struct net_device *dev = cur_if->dev;
+ authmode_t amode = cur_if->amode;
+ int auth=0, wpa_auth=0;
+
+ if (amode == AUTH_OPEN) {
+ auth = 0;
+ wpa_auth = 0;
+ ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));
+ } else if (amode == AUTH_SHARED) {
+ auth = 1;
+ wpa_auth = 0;
+ ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));
+ } else if (amode == AUTH_WPAPSK) {
+ auth = 0;
+ wpa_auth = 4;
+ ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));
+ } else if (amode == AUTH_WPA2PSK) {
+ auth = 0;
+ wpa_auth = 128;
+ ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));
+ } else if (amode == AUTH_WPAWPA2PSK) {
+ auth = 0;
+ wpa_auth = 132;
+ ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));
+ }
+ wl_ext_iovar_setint(dev, "auth", auth);
+
+ wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);
+
+ return 0;
+}
+
+static int
+wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
+{
+ struct net_device *dev = cur_if->dev;
+ int wsec=0;
+ struct wl_wsec_key wsec_key;
+ wsec_pmk_t psk;
+ encmode_t emode = cur_if->emode;
+ char *key = cur_if->key;
+
+ memset(&wsec_key, 0, sizeof(wsec_key));
+ memset(&psk, 0, sizeof(psk));
+ if (emode == ENC_NONE) {
+ wsec = 0;
+ ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__));
+ } else if (emode == ENC_WEP) {
+ wsec = 1;
+ wl_ext_parse_wep(key, &wsec_key);
+ ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, wsec_key.data));
+ } else if (emode == ENC_TKIP) {
+ wsec = 2;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ } else if (emode == ENC_AES) {
+ wsec = 4;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ } else if (emode == ENC_TKIPAES) {
+ wsec = 6;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ }
+
+ wl_ext_iovar_setint(dev, "wsec", wsec);
+
+ if (wsec == 1) {
+ wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1);
+ } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) {
+ if (dev) {
+ if (cur_if->ifmode == ISTA_MODE)
+ wl_ext_iovar_setint(dev, "sup_wpa", 1);
+ wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1);
+ } else {
+ ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__));
+ }
+ }
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
+{
+ s32 val = 0;
+ char *pch, *pick_tmp, *param;
+ wlc_ssid_t ssid = { 0, {0} };
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ wl_interface_create_t iface;
+ struct dhd_pub *dhd;
+ wl_p2p_if_t ifreq;
+ wl_country_t cspec = {{0}, 0, {0}};
+
+ if (apsta_params->init) {
+ ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));
+ return -1;
+ }
+
+ dhd = dhd_get_pub(dev);
+ memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "mode")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch) {
+ if (!strcmp(pch, "sta")) {
+ apsta_params->apstamode = ISTAONLY_MODE;
+ } else if (!strcmp(pch, "ap")) {
+ apsta_params->apstamode = IAPONLY_MODE;
+ } else if (!strcmp(pch, "apsta")) {
+ apsta_params->apstamode = IAPSTA_MODE;
+ } else if (!strcmp(pch, "dualap")) {
+ apsta_params->apstamode = IDUALAP_MODE;
+ } else if (!strcmp(pch, "gosta")) {
+ if (!FW_SUPPORTED(dhd, p2p)) {
+ return -1;
+ }
+ apsta_params->apstamode = IGOSTA_MODE;
+ } else if (!strcmp(pch, "gcsta")) {
+ if (!FW_SUPPORTED(dhd, p2p)) {
+ return -1;
+ }
+ apsta_params->apstamode = IGCSTA_MODE;
+ } else {
+ ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ } else if (!strcmp(param, "vifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(apsta_params->vif.ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+
+ if (apsta_params->apstamode == 0) {
+ ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+ return -1;
+ }
+
+ apsta_params->pif.dev = dev;
+ apsta_params->pif.bssidx = 0;
+ strcpy(apsta_params->pif.ifname, dev->name);
+ strcpy(apsta_params->pif.ssid, "tttp");
+ apsta_params->pif.maxassoc = -1;
+ apsta_params->pif.channel = 1;
+
+ if (!strlen(apsta_params->vif.ifname))
+ strcpy(apsta_params->vif.ifname, "wlan1");
+ strcpy(apsta_params->vif.ssid, "tttv");
+ apsta_params->vif.maxassoc = -1;
+ apsta_params->vif.channel = 1;
+
+ if (apsta_params->apstamode == ISTAONLY_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls
+ // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apsta_params->apstamode == IAPONLY_MODE) {
+ apsta_params->pif.ifmode = IAP_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */\r
- dhd_arp_offload_set(dhd, 0);\r
- dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
- wl_ext_iovar_setint(dev, "mpc", 0);\r
- wl_ext_iovar_setint(dev, "apsta", 0);\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);\r
- } else if (apsta_params->apstamode == IAPSTA_MODE) {\r
- apsta_params->pif.ifmode = ISTA_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- apsta_params->vif.ifmode = IAP_MODE;\r
- apsta_params->vif.ifstate = IF_STATE_INIT;\r
- wl_ext_iovar_setint(dev, "mpc", 0);\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_iovar_setint(dev, "apsta", 1);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- if (FW_SUPPORTED(dhd, rsdb)) {\r
- bzero(&iface, sizeof(wl_interface_create_t));\r
- iface.ver = WL_INTERFACE_CREATE_VER;\r
- iface.flags = WL_INTERFACE_CREATE_AP;\r
- wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,\r
- WLC_IOCTL_SMLEN, 1, NULL);\r
- } else {\r
- wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,\r
- WLC_IOCTL_SMLEN, 1, NULL);\r
- }\r
- }\r
- else if (apsta_params->apstamode == IDUALAP_MODE) {\r
- apsta_params->pif.ifmode = IAP_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- apsta_params->vif.ifmode = IAP_MODE;\r
- apsta_params->vif.ifstate = IF_STATE_INIT;\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_iovar_setint(dev, "apsta", 0);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);\r
- /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */\r
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ wl_ext_iovar_setint(dev, "apsta", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
+ } else if (apsta_params->apstamode == IAPSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ if (FW_SUPPORTED(dhd, rsdb)) {
+ bzero(&iface, sizeof(wl_interface_create_t));
+ iface.ver = WL_INTERFACE_CREATE_VER;
+ iface.flags = WL_INTERFACE_CREATE_AP;
+ wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface),
+ iovar_buf, WLC_IOCTL_SMLEN, 1, NULL);
+ } else {
+ wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,
+ WLC_IOCTL_SMLEN, 1, NULL);
+ }
+ }
+ else if (apsta_params->apstamode == IDUALAP_MODE) {
+ apsta_params->pif.ifmode = IAP_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 0);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
+ /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */\r
- dhd_arp_offload_set(dhd, 0);\r
- dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
- bzero(&iface, sizeof(wl_interface_create_t));\r
- iface.ver = WL_INTERFACE_CREATE_VER;\r
- iface.flags = WL_INTERFACE_CREATE_AP;\r
- wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,\r
- WLC_IOCTL_SMLEN, 1, NULL);\r
- }\r
- else if (apsta_params->apstamode == IGOSTA_MODE) {\r
- apsta_params->pif.ifmode = ISTA_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- apsta_params->vif.ifmode = IAP_MODE;\r
- apsta_params->vif.ifstate = IF_STATE_INIT;\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_iovar_setint(dev, "apsta", 1);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- bzero(&ifreq, sizeof(wl_p2p_if_t));\r
- ifreq.type = htod32(WL_P2P_IF_GO);\r
- wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),\r
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- }\r
- else if (apsta_params->apstamode == IGCSTA_MODE) {\r
- apsta_params->pif.ifmode = ISTA_MODE;\r
- apsta_params->pif.ifstate = IF_STATE_INIT;\r
- apsta_params->vif.ifmode = ISTA_MODE;\r
- apsta_params->vif.ifstate = IF_STATE_INIT;\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_iovar_setint(dev, "apsta", 1);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- bzero(&ifreq, sizeof(wl_p2p_if_t));\r
- ifreq.type = htod32(WL_P2P_IF_CLIENT);\r
- wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),\r
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- }\r
-\r
- wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);\r
- printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);\r
-\r
- apsta_params->init = TRUE;\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)\r
-{\r
- int i;\r
- char *pch, *pick_tmp, *param;\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
- char ifname[IFNAMSIZ+1];\r
- struct wl_if_info *cur_if = &apsta_params->pif;\r
-\r
- if (!apsta_params->init) {\r
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
- return -1;\r
- }\r
-\r
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-\r
- pick_tmp = command;\r
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
-\r
- if (param != NULL) {\r
- if (strcmp(param, "ifname")) {\r
- ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
-\r
- while (param != NULL) {\r
- if (!strcmp(param, "ifname")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- strcpy(ifname, pch);\r
- else {\r
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
- cur_if = &apsta_params->pif;\r
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
- cur_if = &apsta_params->vif;\r
- } else {\r
- ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,\r
- ifname, apsta_params->apstamode));\r
- return -1;\r
- }\r
- } else if (!strcmp(param, "ssid")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- strcpy(cur_if->ssid, pch);\r
- } else if (!strcmp(param, "bssid")) {\r
- pch = bcmstrtok(&pick_tmp, ": ", 0);\r
- for (i=0; i<6 && pch; i++) {\r
- ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16);\r
- pch = bcmstrtok(&pick_tmp, ": ", 0);\r
- }\r
- } else if (!strcmp(param, "bgnmode")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- if (!strcmp(pch, "b"))\r
- cur_if->bgnmode = IEEE80211B;\r
- else if (!strcmp(pch, "g"))\r
- cur_if->bgnmode = IEEE80211G;\r
- else if (!strcmp(pch, "bg"))\r
- cur_if->bgnmode = IEEE80211BG;\r
- else if (!strcmp(pch, "bgn"))\r
- cur_if->bgnmode = IEEE80211BGN;\r
- else if (!strcmp(pch, "bgnac"))\r
- cur_if->bgnmode = IEEE80211BGNAC;\r
- else {\r
- ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- } else if (!strcmp(param, "hidden")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- if (!strcmp(pch, "n"))\r
- cur_if->hidden = 0;\r
- else if (!strcmp(pch, "y"))\r
- cur_if->hidden = 1;\r
- else {\r
- ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- } else if (!strcmp(param, "maxassoc")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10);\r
- } else if (!strcmp(param, "chan")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- cur_if->channel = (int)simple_strtol(pch, NULL, 10);\r
- } else if (!strcmp(param, "amode")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- if (!strcmp(pch, "open"))\r
- cur_if->amode = AUTH_OPEN;\r
- else if (!strcmp(pch, "shared"))\r
- cur_if->amode = AUTH_SHARED;\r
- else if (!strcmp(pch, "wpapsk"))\r
- cur_if->amode = AUTH_WPAPSK;\r
- else if (!strcmp(pch, "wpa2psk"))\r
- cur_if->amode = AUTH_WPA2PSK;\r
- else if (!strcmp(pch, "wpawpa2psk")) \r
- cur_if->amode = AUTH_WPAWPA2PSK;\r
- else {\r
- ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",\r
- __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- } else if (!strcmp(param, "emode")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- if (!strcmp(pch, "none"))\r
- cur_if->emode = ENC_NONE;\r
- else if (!strcmp(pch, "wep"))\r
- cur_if->emode = ENC_WEP;\r
- else if (!strcmp(pch, "tkip"))\r
- cur_if->emode = ENC_TKIP;\r
- else if (!strcmp(pch, "aes"))\r
- cur_if->emode = ENC_AES;\r
- else if (!strcmp(pch, "tkipaes")) \r
- cur_if->emode = ENC_TKIPAES;\r
- else {\r
- ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",\r
- __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- } else if (!strcmp(param, "key")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch) {\r
- strcpy(cur_if->key, pch);\r
- }\r
- }\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)\r
-{\r
- char *pch, *pick_tmp, *param;\r
- s8 iovar_buf[WLC_IOCTL_SMLEN];\r
- wlc_ssid_t ssid = { 0, {0} };\r
- scb_val_t scbval;\r
- struct {\r
- s32 tmp;\r
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ bzero(&iface, sizeof(wl_interface_create_t));
+ iface.ver = WL_INTERFACE_CREATE_VER;
+ iface.flags = WL_INTERFACE_CREATE_AP;
+ wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface),
+ iovar_buf, WLC_IOCTL_SMLEN, 1, NULL);
+ }
+ else if (apsta_params->apstamode == IGOSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ bzero(&ifreq, sizeof(wl_p2p_if_t));
+ ifreq.type = htod32(WL_P2P_IF_GO);
+ wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+ else if (apsta_params->apstamode == IGCSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = ISTA_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ bzero(&ifreq, sizeof(wl_p2p_if_t));
+ ifreq.type = htod32(WL_P2P_IF_CLIENT);
+ wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+ wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
+ printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);
+
+ apsta_params->init = TRUE;
+
+ return 0;
+}
+
+static int
+wl_ext_parse_config(struct wl_if_info *cur_if, char *command, char **pick_next)
+{
+ char *pch, *pick_tmp;
+ char name[20], data[100];
+ int i, j;
+ char *ifname_head = NULL;
+
+ typedef struct config_map_t {
+ char name[20];
+ char *head;
+ char *tail;
+ } config_map_t;
+
+ config_map_t config_map [] = {
+ {" ifname ", NULL, NULL},
+ {" ssid ", NULL, NULL},
+ {" bssid ", NULL, NULL},
+ {" bgnmode ", NULL, NULL},
+ {" hidden ", NULL, NULL},
+ {" maxassoc ", NULL, NULL},
+ {" chan ", NULL, NULL},
+ {" amode ", NULL, NULL},
+ {" emode ", NULL, NULL},
+ {" key ", NULL, NULL},
+ };
+ config_map_t *row, *row_prev;
+
+ pick_tmp = command;
+
+ // reset head and tail
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ row->head = NULL;
+ row->tail = pick_tmp + strlen(pick_tmp);;
+ }
+
+ // pick head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ pch = strstr(pick_tmp, row->name);
+ if (pch) {
+ row->head = pch;
+ }
+ }
+
+ // sort by head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]) - 1; i++) {
+ row_prev = &config_map[i];
+ for (j = i+1; j < sizeof(config_map)/sizeof(config_map[0]); j++) {
+ row = &config_map[j];
+ if (row->head < row_prev->head) {
+ strcpy(name, row_prev->name);
+ strcpy(row_prev->name, row->name);
+ strcpy(row->name, name);
+ pch = row_prev->head;
+ row_prev->head = row->head;
+ row->head = pch;
+ }
+ }
+ }
+
+ // pick tail
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]) - 1; i++) {
+ row_prev = &config_map[i];
+ row = &config_map[i+1];
+ if (row_prev->head) {
+ row_prev->tail = row->head;
+ }
+ }
+
+ // remove name from head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ if (row->head) {
+ if (!strcmp(row->name, " ifname ")) {
+ ifname_head = row->head + 1;
+ break;
+ }
+ row->head += strlen(row->name);
+ }
+ }
+
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ if (row->head) {
+ memset(data, 0, sizeof(data));
+ if (row->tail) {
+ strncpy(data, row->head, row->tail-row->head);
+ } else {
+ strcpy(data, row->head);
+ }
+ pick_tmp = data;
+
+ if (!strcmp(row->name, " ssid ")) {
+ strcpy(cur_if->ssid, pick_tmp);
+ } else if (!strcmp(row->name, " bssid ")) {
+ pch = bcmstrtok(&pick_tmp, ": ", 0);
+ for (j=0; j<6 && pch; j++) {
+ ((u8 *)&cur_if->bssid)[j] = (int)simple_strtol(pch, NULL, 16);
+ pch = bcmstrtok(&pick_tmp, ": ", 0);
+ }
+ } else if (!strcmp(row->name, " bgnmode ")) {
+ if (!strcmp(pick_tmp, "b"))
+ cur_if->bgnmode = IEEE80211B;
+ else if (!strcmp(pick_tmp, "g"))
+ cur_if->bgnmode = IEEE80211G;
+ else if (!strcmp(pick_tmp, "bg"))
+ cur_if->bgnmode = IEEE80211BG;
+ else if (!strcmp(pick_tmp, "bgn"))
+ cur_if->bgnmode = IEEE80211BGN;
+ else if (!strcmp(pick_tmp, "bgnac"))
+ cur_if->bgnmode = IEEE80211BGNAC;
+ else {
+ ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " hidden ")) {
+ if (!strcmp(pick_tmp, "n"))
+ cur_if->hidden = 0;
+ else if (!strcmp(pick_tmp, "y"))
+ cur_if->hidden = 1;
+ else {
+ ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " maxassoc ")) {
+ cur_if->maxassoc = (int)simple_strtol(pick_tmp, NULL, 10);
+ } else if (!strcmp(row->name, " chan ")) {
+ cur_if->channel = (int)simple_strtol(pick_tmp, NULL, 10);
+ } else if (!strcmp(row->name, " amode ")) {
+ if (!strcmp(pick_tmp, "open"))
+ cur_if->amode = AUTH_OPEN;
+ else if (!strcmp(pick_tmp, "shared"))
+ cur_if->amode = AUTH_SHARED;
+ else if (!strcmp(pick_tmp, "wpapsk"))
+ cur_if->amode = AUTH_WPAPSK;
+ else if (!strcmp(pick_tmp, "wpa2psk"))
+ cur_if->amode = AUTH_WPA2PSK;
+ else if (!strcmp(pick_tmp, "wpawpa2psk"))
+ cur_if->amode = AUTH_WPAWPA2PSK;
+ else {
+ ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",
+ __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " emode ")) {
+ if (!strcmp(pick_tmp, "none"))
+ cur_if->emode = ENC_NONE;
+ else if (!strcmp(pick_tmp, "wep"))
+ cur_if->emode = ENC_WEP;
+ else if (!strcmp(pick_tmp, "tkip"))
+ cur_if->emode = ENC_TKIP;
+ else if (!strcmp(pick_tmp, "aes"))
+ cur_if->emode = ENC_AES;
+ else if (!strcmp(pick_tmp, "tkipaes"))
+ cur_if->emode = ENC_TKIPAES;
+ else {
+ ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",
+ __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " key ")) {
+ strcpy(cur_if->key, pick_tmp);
+ }
+ }
+ }
+
+ *pick_next = ifname_head;
+ return 0;
+}
+
+static int
+wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)
+{
+ int ret=0;
+ char *pch, *pch2, *pick_tmp, *pick_next=NULL, *param;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if = &apsta_params->pif;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config
+
+ while (pick_tmp != NULL) {
+ memset(ifname, 0, IFNAMSIZ+1);
+ if (!strncmp(pick_tmp, "ifname ", strlen("ifname "))) {
+ pch = pick_tmp + strlen("ifname ");
+ pch2 = strchr(pch, ' ');
+ if (pch && pch2) {
+ strncpy(ifname, pch, pch2-pch);
+ } else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,
+ ifname, apsta_params->apstamode));
+ return -1;
+ }
+ ret = wl_ext_parse_config(cur_if, pick_tmp, &pick_next);
+ if (ret)
+ return -1;
+ pick_tmp = pick_next;
+ } else {
+ ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));
+ return -1;
+ }
+
+ }
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
+{
+ char *pch, *pick_tmp, *param;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ wlc_ssid_t ssid = { 0, {0} };
+ scb_val_t scbval;
+ struct {
+ s32 tmp;
s32 cfg;
s32 val;
- } bss_setbuf;\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
- apstamode_t apstamode = apsta_params->apstamode;\r
- char ifname[IFNAMSIZ+1];\r
- struct wl_if_info *cur_if;\r
- struct dhd_pub *dhd;\r
-\r
- if (!apsta_params->init) {\r
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
- return -1;\r
- }\r
-\r
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
- dhd = dhd_get_pub(dev);\r
-\r
- pick_tmp = command;\r
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- while (param != NULL) {\r
- if (!strcmp(param, "ifname")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- strcpy(ifname, pch);\r
- else {\r
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- }\r
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
- cur_if = &apsta_params->pif;\r
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
- cur_if = &apsta_params->vif;\r
- } else {\r
- ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
- return -1;\r
- }\r
- if (!cur_if->dev) {\r
- ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));\r
- return -1;\r
- }\r
-\r
- if (cur_if->ifmode == ISTA_MODE) {\r
- wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);\r
- } else if (cur_if->ifmode == IAP_MODE) {\r
- // deauthenticate all STA first\r
- memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN);\r
- wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);\r
- }\r
-\r
- if (apstamode == IAPONLY_MODE) {\r
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
- wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid\r
- wl_ext_iovar_setint(dev, "mpc", 1);\r
- } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&\r
- cur_if->ifmode == IAP_MODE) {\r
- // vif is AP mode\r
- bss_setbuf.tmp = 0xffffffff;\r
- bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down\r
- bss_setbuf.val = htod32(0);\r
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- wl_ext_iovar_setint(dev, "mpc", 1);\r
-#ifdef ARP_OFFLOAD_SUPPORT\r
- /* IF SoftAP is disabled, enable arpoe back for STA mode. */\r
- dhd_arp_offload_set(dhd, dhd_arp_mode);\r
- dhd_arp_offload_enable(dhd, TRUE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
- } else if (apstamode == IDUALAP_MODE) {\r
- bss_setbuf.tmp = 0xffffffff;\r
- bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down\r
- bss_setbuf.val = htod32(0);\r
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- }\r
-\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#if defined(BCMSDIO)\r
- if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {\r
- bool enabled;\r
- dhd_wlfc_get_enable(dhd, &enabled);\r
- if (enabled) {\r
- dhd_wlfc_deinit(dhd);\r
- }\r
- }\r
-#endif \r
-#endif /* PROP_TXSTATUS_VSDB */\r
-\r
- cur_if->ifstate = IF_STATE_DISALBE;\r
- printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);\r
-\r
- return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)\r
-{\r
- int ret = 0;\r
- s32 val = 0;\r
- char *pch, *pick_tmp, *param;\r
- s8 iovar_buf[WLC_IOCTL_SMLEN];\r
- wlc_ssid_t ssid = { 0, {0} };\r
- struct {\r
+ } bss_setbuf;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ apstamode_t apstamode = apsta_params->apstamode;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if;
+ struct dhd_pub *dhd;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+ dhd = dhd_get_pub(dev);
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "ifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ if (!cur_if->dev) {
+ ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
+ return -1;
+ }
+
+ if (cur_if->ifmode == ISTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
+ } else if (cur_if->ifmode == IAP_MODE) {
+ // deauthenticate all STA first
+ memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN);
+ wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+ }
+
+ if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid
+ wl_ext_iovar_setint(dev, "mpc", 1);
+ } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&
+ cur_if->ifmode == IAP_MODE) {
+ // vif is AP mode
+ bss_setbuf.tmp = 0xffffffff;
+ bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+ bss_setbuf.val = htod32(0);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ wl_ext_iovar_setint(dev, "mpc", 1);
+#ifdef ARP_OFFLOAD_SUPPORT
+ /* IF SoftAP is disabled, enable arpoe back for STA mode. */
+ dhd_arp_offload_set(dhd, dhd_arp_mode);
+ dhd_arp_offload_enable(dhd, TRUE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ } else if (apstamode == IDUALAP_MODE) {
+ bss_setbuf.tmp = 0xffffffff;
+ bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+ bss_setbuf.val = htod32(0);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+ if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {
+ bool enabled;
+ dhd_wlfc_get_enable(dhd, &enabled);
+ if (enabled) {
+ dhd_wlfc_deinit(dhd);
+ }
+ }
+#endif
+#endif /* PROP_TXSTATUS_VSDB */
+
+ cur_if->ifstate = IF_STATE_DISALBE;
+ printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
+{
+ int ret = 0;
+ s32 val = 0;
+ char *pch, *pick_tmp, *param;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ wlc_ssid_t ssid = { 0, {0} };
+ struct {
s32 cfg;
s32 val;
- } bss_setbuf;\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
- apstamode_t apstamode = apsta_params->apstamode;\r
- char ifname[IFNAMSIZ+1];\r
- struct wl_if_info *cur_if;\r
- char cmd[128] = "iapsta_stop ifname ";\r
- struct dhd_pub *dhd;\r
-\r
- if (!apsta_params->init) {\r
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
- return -1;\r
- }\r
-\r
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
- dhd = dhd_get_pub(dev);\r
-\r
- pick_tmp = command;\r
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- while (param != NULL) {\r
- if (!strcmp(param, "ifname")) {\r
- pch = bcmstrtok(&pick_tmp, " ", 0);\r
- if (pch)\r
- strcpy(ifname, pch);\r
- else {\r
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
- return -1;\r
- }\r
- }\r
- param = bcmstrtok(&pick_tmp, " ", 0);\r
- }\r
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
- cur_if = &apsta_params->pif;\r
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
- cur_if = &apsta_params->vif;\r
- } else {\r
- ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
- return -1;\r
- }\r
- if (!cur_if->dev) {\r
- ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));\r
- return -1;\r
- }\r
- ssid.SSID_len = strlen(cur_if->ssid);\r
- memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);\r
- ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx));\r
-\r
- snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname);\r
- ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd));\r
- if (ret)\r
- goto exit;\r
-\r
- if (cur_if == &apsta_params->vif) {\r
- wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr,\r
- ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- }\r
-\r
- // set ssid for AP\r
- if (cur_if->ifmode == IAP_MODE) {\r
- wl_ext_iovar_setint(dev, "mpc", 0);\r
- if (apstamode == IAPONLY_MODE) {\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) {\r
- wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid),\r
- iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);\r
- }\r
- }\r
-\r
- if (cur_if->ifmode == IAP_MODE) {\r
- wl_ext_set_bgnmode(cur_if);\r
- wl_ext_set_chanspec(cur_if->dev, cur_if->channel);\r
- }\r
- wl_ext_set_amode(cur_if, apsta_params);\r
- wl_ext_set_emode(cur_if, apsta_params);\r
-\r
- if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {\r
- if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) {\r
- printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid);\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1);\r
- }\r
- val = 1;\r
- wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1);\r
- }\r
- if (cur_if->ifmode == IAP_MODE) {\r
- if (cur_if->maxassoc >= 0)\r
- wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc);\r
- printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON");\r
- // terence: fix me, hidden does not work in dualAP mode\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1);\r
- }\r
-\r
- if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
- } else if (apstamode == IAPONLY_MODE) {\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) {\r
- if (cur_if->ifmode == ISTA_MODE) {\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
- } else {\r
- if (FW_SUPPORTED(dhd, rsdb)) {\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
- } else {\r
- bss_setbuf.cfg = htod32(cur_if->bssidx);\r
- bss_setbuf.val = htod32(1);\r
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
- iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
- }\r
+ } bss_setbuf;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ apstamode_t apstamode = apsta_params->apstamode;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if;
+ char cmd[128] = "iapsta_stop ifname ";
+ struct dhd_pub *dhd;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+ dhd = dhd_get_pub(dev);
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "ifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ if (!cur_if->dev) {
+ ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ ssid.SSID_len = strlen(cur_if->ssid);
+ memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);
+ ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx));
+
+ snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname);
+ ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd));
+ if (ret)
+ goto exit;
+
+ if (cur_if == &apsta_params->vif) {
+ wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr,
+ ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+ // set ssid for AP
+ if (cur_if->ifmode == IAP_MODE) {
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) {
+ wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid),
+ iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);
+ }
+ }
+
+ if (cur_if->ifmode == IAP_MODE) {
+ wl_ext_set_bgnmode(cur_if);
+ wl_ext_set_chanspec(cur_if->dev, cur_if->channel);
+ }
+ wl_ext_set_amode(cur_if, apsta_params);
+ wl_ext_set_emode(cur_if, apsta_params);
+
+ if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
+ if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) {
+ printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid);
+ wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1);
+ }
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1);
+ }
+ if (cur_if->ifmode == IAP_MODE) {
+ if (cur_if->maxassoc >= 0)
+ wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc);
+ printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON");
+ // terence: fix me, hidden does not work in dualAP mode
+ wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1);
+ }
+
+ if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) {
+ if (cur_if->ifmode == ISTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else {
+ if (FW_SUPPORTED(dhd, rsdb)) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else {
+ bss_setbuf.cfg = htod32(cur_if->bssidx);
+ bss_setbuf.val = htod32(1);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */\r
- dhd_arp_offload_set(dhd, 0);\r
- dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
- }\r
- }\r
- else if (apstamode == IDUALAP_MODE) {\r
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
- }\r
-\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#if defined(BCMSDIO)\r
- if (cur_if==&apsta_params->vif && !disable_proptx) {\r
- bool enabled;\r
- dhd_wlfc_get_enable(dhd, &enabled);\r
- if (!enabled) {\r
- dhd_wlfc_init(dhd);\r
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
- }\r
- }\r
-#endif
-#endif /* PROP_TXSTATUS_VSDB */\r
-\r
- printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid);\r
-\r
- cur_if->ifstate = IF_STATE_ENABLE;\r
-\r
-exit:\r
- return ret;\r
-}\r
-
-void\r
-wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)\r
-{\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
- struct wl_if_info *cur_if = &apsta_params->vif;\r
- scb_val_t scbval;\r
- int ret;\r
- channel_info_t ci;\r
- struct dhd_pub *dhd;\r
-\r
- if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {\r
- dhd = dhd_get_pub(dev);\r
- if (!FW_SUPPORTED(dhd, vsdb)) {\r
- if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {\r
- if (channel != ci.target_channel) {\r
- printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);\r
- memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN);\r
- wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);\r
- }\r
- }\r
- }\r
- }\r
-}\r
-
-int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)\r
-{\r
- g_apsta_params.vif.dev = net;\r
- g_apsta_params.vif.bssidx = bssidx;\r
- if (strlen(g_apsta_params.vif.ifname)) {\r
- memset(net->name, 0, sizeof(IFNAMSIZ));\r
- strcpy(net->name, g_apsta_params.vif.ifname);\r
- net->name[IFNAMSIZ - 1] = '\0';\r
- }\r
- if (g_apsta_params.pif.dev) {\r
- memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);\r
- net->dev_addr[0] |= 0x02;\r
- }\r
-\r
- return 0;\r
-}\r
-
-int wl_android_ext_dettach_netdev(void)\r
-{\r
- struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-\r
- ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));\r
- memset(apsta_params, 0, sizeof(struct wl_apsta_params));\r
-\r
- return 0;\r
-}\r
-#endif\r
-\r
-#ifdef IDHCP\r
-int wl_ext_ip_dump(int ip, char *buf)\r
-{\r
- unsigned char bytes[4];\r
- int bytes_written=-1;\r
-\r
- bytes[0] = ip & 0xFF;\r
- bytes[1] = (ip >> 8) & 0xFF;\r
- bytes[2] = (ip >> 16) & 0xFF;\r
- bytes[3] = (ip >> 24) & 0xFF; \r
- bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);\r
-\r
- return bytes_written;\r
-}\r
-\r
-/*\r
-terence 20170215:\r
-dhd_priv dhcpc_dump ifname [wlan0|wlan1]\r
-dhd_priv dhcpc_enable [0|1]\r
-*/\r
-int\r
-wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)\r
-{\r
- int enable = -1, ret = -1;\r
- int bytes_written = -1;\r
-\r
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
- sscanf(command, "%*s %d", &enable);\r
-\r
- if (enable >= 0)\r
- ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);\r
- else {\r
- ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);\r
- if (!ret) {\r
- bytes_written = snprintf(command, total_len, "%d", enable);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-int\r
-wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)\r
-{\r
-\r
- int ret = 0;\r
- int bytes_written = 0;\r
- uint32 ip_addr;\r
- char buf[20]="";\r
-\r
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);\r
- if (!ret) {\r
- wl_ext_ip_dump(ip_addr, buf);\r
- bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);\r
- }\r
-\r
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);\r
- if (!ret) {\r
- wl_ext_ip_dump(ip_addr, buf);\r
- bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);\r
- }\r
-\r
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);\r
- if (!ret) {\r
- wl_ext_ip_dump(ip_addr, buf);\r
- bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);\r
- }\r
-\r
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);\r
- if (!ret) {\r
- wl_ext_ip_dump(ip_addr, buf);\r
- bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);\r
- }\r
-\r
- if (!bytes_written)\r
- bytes_written = -1;\r
- \r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-\r
- return bytes_written;\r
-}\r
-#endif\r
-\r
-/*\r
-dhd_priv dhd [string] ==> Not ready\r
-1. Get dhd val:\r
- Ex: dhd_priv dhd bussleep\r
-2. Set dhd val:\r
- Ex: dhd_priv dhd bussleep 1\r
-\r
-dhd_priv wl [WLC_GET_PM] ==> Ready to get int val\r
-dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val\r
-dhd_priv wl [string] ==> Ready to get int val\r
-dhd_priv wl [string] [int] ==> Ready to set int val\r
-Ex: get/set WLC_PM\r
- dhd_priv wl 85\r
- dhd_priv wl 86 1\r
-Ex: get/set mpc\r
- dhd_priv wl mpc\r
- dhd_priv wl mpc 1\r
-*/\r
-int\r
-wl_ext_iovar(struct net_device *dev, char *command, int total_len)\r
-{\r
- int ret = 0;\r
- char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";\r
- int cmd=-1, val=0;\r
- int bytes_written=-1;\r
-\r
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
- sscanf(command, "%s %d %s", wl, &cmd, arg);\r
- if (cmd < 0)\r
- sscanf(command, "%s %s %s", wl, cmd_str, val_str);\r
-\r
- if (!strcmp(wl, "wl")) {\r
- if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {\r
- ret = sscanf(arg, "%d", &val);\r
- if (ret > 0) { // set\r
- ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);\r
- } else { // get\r
- ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);\r
- if (!ret) {\r
- bytes_written = snprintf(command, total_len, "%d", val);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
- } else if (strlen(cmd_str)) {\r
- ret = sscanf(val_str, "%d", &val);\r
- if (ret > 0) { // set\r
- ret = wl_ext_iovar_setint(dev, cmd_str, val);\r
- } else { // get\r
- ret = wl_ext_iovar_getint(dev, cmd_str, &val);\r
- if (!ret) {\r
- bytes_written = snprintf(command, total_len, "%d", val);\r
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
- ret = bytes_written;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return ret;\r
-}\r
-\r
-int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,\r
- int *bytes_written)\r
-{\r
- int ret = 0;\r
-\r
- if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {\r
- *bytes_written = wl_ext_channels(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {\r
- *bytes_written = wl_ext_channel(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {\r
- *bytes_written = wl_ext_roam_trigger(net, command, total_len);\r
- }
- else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {\r
- *bytes_written = wl_ext_keep_alive(net, command, total_len);\r
- }
- else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {\r
- *bytes_written = wl_ext_pm(net, command, total_len);\r
- }\r
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ }
+ }
+ else if (apstamode == IDUALAP_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+ if (cur_if==&apsta_params->vif && !disable_proptx) {
+ bool enabled;
+ dhd_wlfc_get_enable(dhd, &enabled);
+ if (!enabled) {
+ dhd_wlfc_init(dhd);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ }
+ }
+#endif
+#endif /* PROP_TXSTATUS_VSDB */
+
+ printf("%s: ifname=%s, SSID: \"%s\"\n", __FUNCTION__, ifname, cur_if->ssid);
+
+ cur_if->ifstate = IF_STATE_ENABLE;
+
+exit:
+ return ret;
+}
+
+void
+wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)
+{
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ struct wl_if_info *cur_if = &apsta_params->vif;
+ scb_val_t scbval;
+ int ret;
+ channel_info_t ci;
+ struct dhd_pub *dhd;
+
+ if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {
+ dhd = dhd_get_pub(dev);
+ if (!FW_SUPPORTED(dhd, vsdb)) {
+ if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
+ if (channel != ci.target_channel) {
+ printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);
+ memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN);
+ wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+ }
+ }
+ }
+ }
+}
+
+int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)
+{
+ g_apsta_params.vif.dev = net;
+ g_apsta_params.vif.bssidx = bssidx;
+ if (strlen(g_apsta_params.vif.ifname)) {
+ memset(net->name, 0, sizeof(IFNAMSIZ));
+ strcpy(net->name, g_apsta_params.vif.ifname);
+ net->name[IFNAMSIZ - 1] = '\0';
+ }
+ if (g_apsta_params.pif.dev) {
+ memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);
+ net->dev_addr[0] |= 0x02;
+ }
+
+ return 0;
+}
+
+int wl_android_ext_dettach_netdev(void)
+{
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+
+ ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
+ memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+ return 0;
+}
+#endif
+
+#ifdef IDHCP
+int wl_ext_ip_dump(int ip, char *buf)
+{
+ unsigned char bytes[4];
+ int bytes_written=-1;
+
+ bytes[0] = ip & 0xFF;
+ bytes[1] = (ip >> 8) & 0xFF;
+ bytes[2] = (ip >> 16) & 0xFF;
+ bytes[3] = (ip >> 24) & 0xFF;
+ bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
+
+ return bytes_written;
+}
+
+/*
+terence 20170215:
+dhd_priv dhcpc_dump ifname [wlan0|wlan1]
+dhd_priv dhcpc_enable [0|1]
+*/
+int
+wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)
+{
+ int enable = -1, ret = -1;
+ int bytes_written = -1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &enable);
+
+ if (enable >= 0)
+ ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);
+ else {
+ ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", enable);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+int
+wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)
+{
+
+ int ret = 0;
+ int bytes_written = 0;
+ uint32 ip_addr;
+ char buf[20]="";
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);
+ }
+
+ if (!bytes_written)
+ bytes_written = -1;
+
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+
+ return bytes_written;
+}
+#endif
+
+/*
+dhd_priv dhd [string] ==> Not ready
+1. Get dhd val:
+ Ex: dhd_priv dhd bussleep
+2. Set dhd val:
+ Ex: dhd_priv dhd bussleep 1
+
+dhd_priv wl [WLC_GET_PM] ==> Ready to get int val
+dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val
+dhd_priv wl [string] ==> Ready to get int val
+dhd_priv wl [string] [int] ==> Ready to set int val
+Ex: get/set WLC_PM
+ dhd_priv wl 85
+ dhd_priv wl 86 1
+Ex: get/set mpc
+ dhd_priv wl mpc
+ dhd_priv wl mpc 1
+*/
+int
+wl_ext_iovar(struct net_device *dev, char *command, int total_len)
+{
+ int ret = 0;
+ char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";
+ int cmd=-1, val=0;
+ int bytes_written=-1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%s %d %s", wl, &cmd, arg);
+ if (cmd < 0)
+ sscanf(command, "%s %s %s", wl, cmd_str, val_str);
+
+ if (!strcmp(wl, "wl")) {
+ if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {
+ ret = sscanf(arg, "%d", &val);
+ if (ret > 0) { // set
+ ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);
+ } else { // get
+ ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+ } else if (strlen(cmd_str)) {
+ ret = sscanf(val_str, "%d", &val);
+ if (ret > 0) { // set
+ ret = wl_ext_iovar_setint(dev, cmd_str, val);
+ } else { // get
+ ret = wl_ext_iovar_getint(dev, cmd_str, &val);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
+ int *bytes_written)
+{
+ int ret = 0;
+
+ if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {
+ *bytes_written = wl_ext_channels(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {
+ *bytes_written = wl_ext_channel(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {
+ *bytes_written = wl_ext_roam_trigger(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
+ *bytes_written = wl_ext_keep_alive(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {
+ *bytes_written = wl_ext_pm(net, command, total_len);
+ }
else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) {
- *bytes_written = wl_ext_monitor(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) {\r
- int bcn_li_dtim;\r
- bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10);\r
- *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim);\r
- }\r
-#ifdef WL_EXT_IAPSTA\r
- else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) {\r
- *bytes_written = wl_ext_iapsta_init(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) {\r
- *bytes_written = wl_ext_iapsta_config(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) {\r
- *bytes_written = wl_ext_iapsta_enable(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) {\r
- *bytes_written = wl_ext_iapsta_disable(net, command, total_len);\r
- }\r
-#endif\r
-#ifdef IDHCP\r
- else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) {\r
- *bytes_written = wl_ext_dhcpc_enable(net, command, total_len);\r
- }\r
- else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) {\r
- *bytes_written = wl_ext_dhcpc_dump(net, command, total_len);\r
- }\r
-#endif\r
- else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) {\r
- *bytes_written = wl_ext_iovar(net, command, total_len);\r
- }\r
- else\r
- ret = -1;\r
-
- return ret;\r
-}\r
-\r
-#if defined(RSSIAVG)\r
-void\r
-wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
- wl_rssi_cache_t *node, *cur, **rssi_head;\r
- int i=0;\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
- node = *rssi_head;\r
-\r
- for (;node;) {\r
- ANDROID_INFO(("%s: Free %d with BSSID %pM\n",\r
- __FUNCTION__, i, &node->BSSID));\r
- cur = node;\r
- node = cur->next;\r
- kfree(cur);\r
- i++;\r
- }\r
- *rssi_head = NULL;\r
-}\r
-\r
-void\r
-wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
- wl_rssi_cache_t *node, *prev, **rssi_head;\r
- int i = -1, tmp = 0;\r
- struct timeval now;\r
-\r
- do_gettimeofday(&now);\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
- node = *rssi_head;\r
- prev = node;\r
- for (;node;) {\r
- i++;\r
- if (now.tv_sec > node->tv.tv_sec) {\r
- if (node == *rssi_head) {\r
- tmp = 1;\r
- *rssi_head = node->next;\r
- } else {\r
- tmp = 0;\r
- prev->next = node->next;\r
- }\r
- ANDROID_INFO(("%s: Del %d with BSSID %pM\n",\r
- __FUNCTION__, i, &node->BSSID));\r
- kfree(node);\r
- if (tmp == 1) {\r
- node = *rssi_head;\r
- prev = node;\r
- } else {\r
- node = prev->next;\r
- }\r
- continue;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void\r
-wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid)\r
-{\r
- wl_rssi_cache_t *node, *prev, **rssi_head;\r
- int i = -1, tmp = 0;\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
- node = *rssi_head;\r
- prev = node;\r
- for (;node;) {\r
- i++;\r
- if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) {\r
- if (node == *rssi_head) {\r
- tmp = 1;\r
- *rssi_head = node->next;\r
- } else {\r
- tmp = 0;\r
- prev->next = node->next;\r
- }\r
- ANDROID_INFO(("%s: Del %d with BSSID %pM\n",\r
- __FUNCTION__, i, &node->BSSID));\r
- kfree(node);\r
- if (tmp == 1) {\r
- node = *rssi_head;\r
- prev = node;\r
- } else {\r
- node = prev->next;\r
- }\r
- continue;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void\r
-wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
- wl_rssi_cache_t *node, **rssi_head;\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
- /* reset dirty */\r
- node = *rssi_head;\r
- for (;node;) {\r
- node->dirty += 1;\r
- node = node->next;\r
- }\r
-}\r
-\r
-int\r
-wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg)\r
-{\r
- wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;\r
- int j, k=0;\r
- int rssi, error=0;\r
- struct ether_addr bssid;\r
- struct timeval now, timeout;\r
-\r
- if (!g_wifi_on)\r
- return 0;\r
-\r
- error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);\r
- if (error == BCME_NOTASSOCIATED) {\r
- ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error));\r
- return 0;\r
- }\r
- if (error) {\r
- ANDROID_ERROR(("Could not get bssid (%d)\n", error));\r
- }\r
- error = wldev_get_rssi(net, &rssi);\r
- if (error) {\r
- ANDROID_ERROR(("Could not get rssi (%d)\n", error));\r
- return error;\r
- }\r
-\r
- do_gettimeofday(&now);\r
- timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;\r
- if (timeout.tv_sec < now.tv_sec) {\r
- /*\r
- * Integer overflow - assume long enough timeout to be assumed\r
- * to be infinite, i.e., the timeout would never happen.\r
- */\r
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
- __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
- }\r
-\r
- /* update RSSI */\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
- node = *rssi_head;\r
- prev = NULL;\r
- for (;node;) {\r
- if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {\r
- ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n",\r
- __FUNCTION__, k, &bssid, rssi));\r
- for (j=0; j<RSSIAVG_LEN-1; j++)\r
- node->RSSI[j] = node->RSSI[j+1];\r
- node->RSSI[j] = rssi;\r
- node->dirty = 0;\r
- node->tv = timeout;\r
- goto exit;\r
- }\r
- prev = node;\r
- node = node->next;\r
- k++;\r
- }\r
-\r
- leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);\r
- if (!leaf) {\r
- ANDROID_ERROR(("%s: Memory alloc failure %d\n",\r
- __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));\r
- return 0;\r
- }\r
- ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",\r
- __FUNCTION__, k, &bssid, rssi));\r
-\r
- leaf->next = NULL;\r
- leaf->dirty = 0;\r
- leaf->tv = timeout;\r
- memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN);\r
- for (j=0; j<RSSIAVG_LEN; j++)\r
- leaf->RSSI[j] = rssi;\r
-\r
- if (!prev)\r
- *rssi_head = leaf;\r
- else\r
- prev->next = leaf;\r
-\r
-exit:\r
- *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid);\r
-\r
- return error;\r
-}\r
-\r
-void\r
-wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)\r
-{\r
- wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;\r
- wl_bss_info_t *bi = NULL;\r
- int i, j, k;\r
- struct timeval now, timeout;\r
-\r
- if (!ss_list->count)\r
- return;\r
-\r
- do_gettimeofday(&now);\r
- timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;\r
- if (timeout.tv_sec < now.tv_sec) {\r
- /*\r
- * Integer overflow - assume long enough timeout to be assumed\r
- * to be infinite, i.e., the timeout would never happen.\r
- */\r
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
- __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
- }\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
- /* update RSSI */\r
- for (i = 0; i < ss_list->count; i++) {\r
- node = *rssi_head;\r
- prev = NULL;\r
- k = 0;\r
- bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;\r
- for (;node;) {\r
- if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {\r
- ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
- for (j=0; j<RSSIAVG_LEN-1; j++)\r
- node->RSSI[j] = node->RSSI[j+1];\r
- node->RSSI[j] = dtoh16(bi->RSSI);\r
- node->dirty = 0;\r
- node->tv = timeout;\r
- break;\r
- }\r
- prev = node;\r
- node = node->next;\r
- k++;\r
- }\r
-\r
- if (node)\r
- continue;\r
-\r
- leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);\r
- if (!leaf) {\r
- ANDROID_ERROR(("%s: Memory alloc failure %d\n",\r
- __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));\r
- return;\r
- }\r
- ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n",\r
- __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-\r
- leaf->next = NULL;\r
- leaf->dirty = 0;\r
- leaf->tv = timeout;\r
- memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);\r
- for (j=0; j<RSSIAVG_LEN; j++)\r
- leaf->RSSI[j] = dtoh16(bi->RSSI);\r
-\r
- if (!prev)\r
- *rssi_head = leaf;\r
- else\r
- prev->next = leaf;\r
- }\r
-}\r
-\r
-int16\r
-wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)\r
-{\r
- wl_rssi_cache_t *node, **rssi_head;\r
- int j, rssi_sum, rssi=RSSI_MINVAL;\r
-\r
- rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
- node = *rssi_head;\r
- for (;node;) {\r
- if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {\r
- rssi_sum = 0;\r
- rssi = 0;\r
- for (j=0; j<RSSIAVG_LEN; j++)\r
- rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];\r
- rssi = rssi_sum / j;\r
- break;\r
- }\r
- node = node->next;\r
- }\r
- rssi = MIN(rssi, RSSI_MAXVAL);\r
- if (rssi == RSSI_MINVAL) {\r
- ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n",\r
- __FUNCTION__, addr));\r
- }\r
- return (int16)rssi;\r
-}\r
-#endif\r
-\r
-#if defined(RSSIOFFSET)\r
-int\r
-wl_update_rssi_offset(struct net_device *net, int rssi)\r
-{\r
-#if defined(RSSIOFFSET_NEW)\r
- int j;\r
-#endif\r
-\r
- if (!g_wifi_on)\r
- return rssi;\r
-\r
-#if defined(RSSIOFFSET_NEW)\r
- for (j=0; j<RSSI_OFFSET; j++) {\r
- if (rssi - (RSSI_OFFSET_MINVAL+RSSI_OFFSET_INTVAL*(j+1)) < 0)\r
- break;\r
- }\r
- rssi += j;\r
-#else\r
- rssi += RSSI_OFFSET;\r
-#endif\r
- return MIN(rssi, RSSI_MAXVAL);\r
-}\r
-#endif\r
-\r
-#if defined(BSSCACHE)\r
-void\r
-wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
- wl_bss_cache_t *node, *cur, **bss_head;\r
- int i=0;\r
-\r
- ANDROID_TRACE(("%s called\n", __FUNCTION__));\r
-\r
- bss_head = &bss_cache_ctrl->m_cache_head;\r
- node = *bss_head;\r
-\r
- for (;node;) {\r
- ANDROID_TRACE(("%s: Free %d with BSSID %pM\n",\r
- __FUNCTION__, i, &node->results.bss_info->BSSID));\r
- cur = node;\r
- node = cur->next;\r
- kfree(cur);\r
- i++;\r
- }\r
- *bss_head = NULL;\r
-}\r
-\r
-void\r
-wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
- wl_bss_cache_t *node, *prev, **bss_head;\r
- int i = -1, tmp = 0;\r
- struct timeval now;\r
-\r
- do_gettimeofday(&now);\r
-\r
- bss_head = &bss_cache_ctrl->m_cache_head;\r
- node = *bss_head;\r
- prev = node;\r
- for (;node;) {\r
- i++;\r
- if (now.tv_sec > node->tv.tv_sec) {\r
- if (node == *bss_head) {\r
- tmp = 1;\r
- *bss_head = node->next;\r
- } else {\r
- tmp = 0;\r
- prev->next = node->next;\r
- }\r
- ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, i, &node->results.bss_info->BSSID,\r
- dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));\r
- kfree(node);\r
- if (tmp == 1) {\r
- node = *bss_head;\r
- prev = node;\r
- } else {\r
- node = prev->next;\r
- }\r
- continue;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void\r
-wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid)\r
-{\r
- wl_bss_cache_t *node, *prev, **bss_head;\r
- int i = -1, tmp = 0;\r
-\r
- bss_head = &bss_cache_ctrl->m_cache_head;\r
- node = *bss_head;\r
- prev = node;\r
- for (;node;) {\r
- i++;\r
- if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) {\r
- if (node == *bss_head) {\r
- tmp = 1;\r
- *bss_head = node->next;\r
- } else {\r
- tmp = 0;\r
- prev->next = node->next;\r
- }\r
- ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, i, &node->results.bss_info->BSSID,\r
- dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));\r
- kfree(node);\r
- if (tmp == 1) {\r
- node = *bss_head;\r
- prev = node;\r
- } else {\r
- node = prev->next;\r
- }\r
- continue;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void\r
-wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
- wl_bss_cache_t *node, **bss_head;\r
-\r
- bss_head = &bss_cache_ctrl->m_cache_head;\r
-\r
- /* reset dirty */\r
- node = *bss_head;\r
- for (;node;) {\r
- node->dirty += 1;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void dump_bss_cache(\r
-#if defined(RSSIAVG)\r
- wl_rssi_cache_ctrl_t *rssi_cache_ctrl,\r
-#endif\r
- wl_bss_cache_t *node)\r
-{\r
- int k = 0;\r
- int16 rssi;\r
-\r
- for (;node;) {\r
-#if defined(RSSIAVG)\r
- rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);\r
-#else\r
- rssi = dtoh16(node->results.bss_info->RSSI);\r
-#endif\r
- ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID));\r
- k++;\r
- node = node->next;\r
- }\r
-}\r
-\r
-void\r
-wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,\r
-#if defined(RSSIAVG)\r
- wl_rssi_cache_ctrl_t *rssi_cache_ctrl,\r
-#endif\r
- wl_scan_results_t *ss_list)\r
-{\r
- wl_bss_cache_t *node, *prev, *leaf, **bss_head;\r
- wl_bss_info_t *bi = NULL;\r
- int i, k=0;\r
-#if defined(SORT_BSS_BY_RSSI)\r
- int16 rssi, rssi_node;\r
-#endif\r
- struct timeval now, timeout;\r
-\r
- if (!ss_list->count)\r
- return;\r
-\r
- do_gettimeofday(&now);\r
- timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT;\r
- if (timeout.tv_sec < now.tv_sec) {\r
- /*\r
- * Integer overflow - assume long enough timeout to be assumed\r
- * to be infinite, i.e., the timeout would never happen.\r
- */\r
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
- __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
- }\r
-\r
- bss_head = &bss_cache_ctrl->m_cache_head;\r
-\r
- for (i=0; i < ss_list->count; i++) {\r
- node = *bss_head;\r
- prev = NULL;\r
- bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;\r
-\r
- for (;node;) {\r
- if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {\r
- if (node == *bss_head)\r
- *bss_head = node->next;\r
- else {\r
- prev->next = node->next;\r
- }\r
- break;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
-\r
- leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL);\r
- if (!leaf) {\r
- ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__,\r
- dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t)));\r
- return;\r
- }\r
- if (node) {\r
- kfree(node);\r
- node = NULL;\r
- ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
- } else\r
- ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
- __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-\r
- memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));\r
- leaf->next = NULL;\r
- leaf->dirty = 0;\r
- leaf->tv = timeout;\r
- leaf->results.count = 1;\r
- leaf->results.version = ss_list->version;\r
- k++;\r
-\r
- if (*bss_head == NULL)\r
- *bss_head = leaf;\r
- else {\r
-#if defined(SORT_BSS_BY_RSSI)\r
- node = *bss_head;\r
-#if defined(RSSIAVG)\r
- rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID);\r
-#else\r
- rssi = dtoh16(leaf->results.bss_info->RSSI);\r
-#endif\r
- for (;node;) {\r
-#if defined(RSSIAVG)\r
- rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);\r
-#else\r
- rssi_node = dtoh16(node->results.bss_info->RSSI);\r
-#endif\r
- if (rssi > rssi_node) {\r
- leaf->next = node;\r
- if (node == *bss_head)\r
- *bss_head = leaf;\r
- else\r
- prev->next = leaf;\r
- break;\r
- }\r
- prev = node;\r
- node = node->next;\r
- }\r
- if (node == NULL)\r
- prev->next = leaf;\r
-#else\r
- leaf->next = *bss_head;\r
- *bss_head = leaf;\r
-#endif\r
- }\r
- }\r
- dump_bss_cache(\r
-#if defined(RSSIAVG)\r
- rssi_cache_ctrl,\r
-#endif\r
- *bss_head);\r
-}\r
-\r
-void\r
-wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
- ANDROID_TRACE(("%s:\n", __FUNCTION__));\r
- wl_free_bss_cache(bss_cache_ctrl);\r
-}\r
-#endif\r
-\r
-\r
+ *bytes_written = wl_ext_monitor(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) {
+ int bcn_li_dtim;
+ bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10);
+ *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim);
+ }
+#ifdef WL_EXT_IAPSTA
+ else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) {
+ *bytes_written = wl_ext_iapsta_init(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) {
+ *bytes_written = wl_ext_iapsta_config(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) {
+ *bytes_written = wl_ext_iapsta_enable(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) {
+ *bytes_written = wl_ext_iapsta_disable(net, command, total_len);
+ }
+#endif
+#ifdef IDHCP
+ else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) {
+ *bytes_written = wl_ext_dhcpc_enable(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) {
+ *bytes_written = wl_ext_dhcpc_dump(net, command, total_len);
+ }
+#endif
+ else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) {
+ *bytes_written = wl_ext_iovar(net, command, total_len);
+ }
+ else
+ ret = -1;
+
+ return ret;
+}
+
+#if defined(RSSIAVG)
+void
+wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *cur, **rssi_head;
+ int i=0;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+
+ for (;node;) {
+ ANDROID_INFO(("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *rssi_head = NULL;
+}
+
+void
+wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int i = -1, tmp = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (now.tv_sec > node->tv.tv_sec) {
+ if (node == *rssi_head) {
+ tmp = 1;
+ *rssi_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *rssi_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int i = -1, tmp = 0;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) {
+ if (node == *rssi_head) {
+ tmp = 1;
+ *rssi_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *rssi_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *rssi_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+int
+wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg)
+{
+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
+ int j, k=0;
+ int rssi, error=0;
+ struct ether_addr bssid;
+ struct timeval now, timeout;
+
+ if (!g_wifi_on)
+ return 0;
+
+ error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);
+ if (error == BCME_NOTASSOCIATED) {
+ ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error));
+ return 0;
+ }
+ if (error) {
+ ANDROID_ERROR(("Could not get bssid (%d)\n", error));
+ }
+ error = wldev_get_rssi(net, &rssi);
+ if (error) {
+ ANDROID_ERROR(("Could not get rssi (%d)\n", error));
+ return error;
+ }
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ /* update RSSI */
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = NULL;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {
+ ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n",
+ __FUNCTION__, k, &bssid, rssi));
+ for (j=0; j<RSSIAVG_LEN-1; j++)
+ node->RSSI[j] = node->RSSI[j+1];
+ node->RSSI[j] = rssi;
+ node->dirty = 0;
+ node->tv = timeout;
+ goto exit;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+
+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ ANDROID_ERROR(("%s: Memory alloc failure %d\n",
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
+ return 0;
+ }
+ ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",
+ __FUNCTION__, k, &bssid, rssi));
+
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN);
+ for (j=0; j<RSSIAVG_LEN; j++)
+ leaf->RSSI[j] = rssi;
+
+ if (!prev)
+ *rssi_head = leaf;
+ else
+ prev->next = leaf;
+
+exit:
+ *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid);
+
+ return error;
+}
+
+void
+wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)
+{
+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
+ wl_bss_info_t *bi = NULL;
+ int i, j, k;
+ struct timeval now, timeout;
+
+ if (!ss_list->count)
+ return;
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* update RSSI */
+ for (i = 0; i < ss_list->count; i++) {
+ node = *rssi_head;
+ prev = NULL;
+ k = 0;
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
+ ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
+ for (j=0; j<RSSIAVG_LEN-1; j++)
+ node->RSSI[j] = node->RSSI[j+1];
+ node->RSSI[j] = dtoh16(bi->RSSI);
+ node->dirty = 0;
+ node->tv = timeout;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+
+ if (node)
+ continue;
+
+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ ANDROID_ERROR(("%s: Memory alloc failure %d\n",
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
+ return;
+ }
+ ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
+
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);
+ for (j=0; j<RSSIAVG_LEN; j++)
+ leaf->RSSI[j] = dtoh16(bi->RSSI);
+
+ if (!prev)
+ *rssi_head = leaf;
+ else
+ prev->next = leaf;
+ }
+}
+
+int16
+wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+ int j, rssi_sum, rssi=RSSI_MINVAL;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ node = *rssi_head;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {
+ rssi_sum = 0;
+ rssi = 0;
+ for (j=0; j<RSSIAVG_LEN; j++)
+ rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];
+ rssi = rssi_sum / j;
+ break;
+ }
+ node = node->next;
+ }
+ rssi = MIN(rssi, RSSI_MAXVAL);
+ if (rssi == RSSI_MINVAL) {
+ ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n",
+ __FUNCTION__, addr));
+ }
+ return (int16)rssi;
+}
+#endif
+
+#if defined(RSSIOFFSET)
+int
+wl_update_rssi_offset(struct net_device *net, int rssi)
+{
+#if defined(RSSIOFFSET_NEW)
+ int j;
+#endif
+
+ if (!g_wifi_on)
+ return rssi;
+
+#if defined(RSSIOFFSET_NEW)
+ for (j=0; j<RSSI_OFFSET; j++) {
+ if (rssi - (RSSI_OFFSET_MINVAL+RSSI_OFFSET_INTVAL*(j+1)) < 0)
+ break;
+ }
+ rssi += j;
+#else
+ rssi += RSSI_OFFSET;
+#endif
+ return MIN(rssi, RSSI_MAXVAL);
+}
+#endif
+
+#if defined(BSSCACHE)
+void
+wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *cur, **bss_head;
+ int i=0;
+
+ ANDROID_TRACE(("%s called\n", __FUNCTION__));
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+
+ for (;node;) {
+ ANDROID_TRACE(("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID));
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *bss_head = NULL;
+}
+
+void
+wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *prev, **bss_head;
+ int i = -1, tmp = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (now.tv_sec > node->tv.tv_sec) {
+ if (node == *bss_head) {
+ tmp = 1;
+ *bss_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID,
+ dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *bss_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid)
+{
+ wl_bss_cache_t *node, *prev, **bss_head;
+ int i = -1, tmp = 0;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) {
+ if (node == *bss_head) {
+ tmp = 1;
+ *bss_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID,
+ dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *bss_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, **bss_head;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *bss_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+void dump_bss_cache(
+#if defined(RSSIAVG)
+ wl_rssi_cache_ctrl_t *rssi_cache_ctrl,
+#endif
+ wl_bss_cache_t *node)
+{
+ int k = 0;
+ int16 rssi;
+
+ for (;node;) {
+#if defined(RSSIAVG)
+ rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);
+#else
+ rssi = dtoh16(node->results.bss_info->RSSI);
+#endif
+ ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID));
+ k++;
+ node = node->next;
+ }
+}
+
+void
+wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,
+#if defined(RSSIAVG)
+ wl_rssi_cache_ctrl_t *rssi_cache_ctrl,
+#endif
+ wl_scan_results_t *ss_list)
+{
+ wl_bss_cache_t *node, *prev, *leaf, **bss_head;
+ wl_bss_info_t *bi = NULL;
+ int i, k=0;
+#if defined(SORT_BSS_BY_RSSI)
+ int16 rssi, rssi_node;
+#endif
+ struct timeval now, timeout;
+
+ if (!ss_list->count)
+ return;
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ for (i=0; i < ss_list->count; i++) {
+ node = *bss_head;
+ prev = NULL;
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
+
+ for (;node;) {
+ if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
+ if (node == *bss_head)
+ *bss_head = node->next;
+ else {
+ prev->next = node->next;
+ }
+ break;
+ }
+ prev = node;
+ node = node->next;
+ }
+
+ leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__,
+ dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t)));
+ return;
+ }
+ if (node) {
+ kfree(node);
+ node = NULL;
+ ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
+ } else
+ ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
+
+ memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ leaf->results.count = 1;
+ leaf->results.version = ss_list->version;
+ k++;
+
+ if (*bss_head == NULL)
+ *bss_head = leaf;
+ else {
+#if defined(SORT_BSS_BY_RSSI)
+ node = *bss_head;
+#if defined(RSSIAVG)
+ rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID);
+#else
+ rssi = dtoh16(leaf->results.bss_info->RSSI);
+#endif
+ for (;node;) {
+#if defined(RSSIAVG)
+ rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);
+#else
+ rssi_node = dtoh16(node->results.bss_info->RSSI);
+#endif
+ if (rssi > rssi_node) {
+ leaf->next = node;
+ if (node == *bss_head)
+ *bss_head = leaf;
+ else
+ prev->next = leaf;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ }
+ if (node == NULL)
+ prev->next = leaf;
+#else
+ leaf->next = *bss_head;
+ *bss_head = leaf;
+#endif
+ }
+ }
+ dump_bss_cache(
+#if defined(RSSIAVG)
+ rssi_cache_ctrl,
+#endif
+ *bss_head);
+}
+
+void
+wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ ANDROID_TRACE(("%s:\n", __FUNCTION__));
+ wl_free_bss_cache(bss_cache_ctrl);
+}
+#endif
+
+