wifi: update bcmdhd-usb.1.363.110.17 wifi driver to fix some issue
authorRongjun Chen <rongjun.chen@amlogic.com>
Sat, 20 Jan 2018 03:28:42 +0000 (11:28 +0800)
committerRongjun Chen <rongjun.chen@amlogic.com>
Sat, 20 Jan 2018 03:28:42 +0000 (11:28 +0800)
Change-Id: I363728b4b5bab1f482ae8dbbd80f08c3aa6e40d1

12 files changed:
bcmdhd-usb.1.363.110.17.x/Kconfig [changed mode: 0644->0755]
bcmdhd-usb.1.363.110.17.x/Makefile [changed mode: 0644->0755]
bcmdhd-usb.1.363.110.17.x/dhd_config.c
bcmdhd-usb.1.363.110.17.x/dhd_config.h
bcmdhd-usb.1.363.110.17.x/dhd_debug.c
bcmdhd-usb.1.363.110.17.x/dhd_linux.c
bcmdhd-usb.1.363.110.17.x/dhd_wlfc.c
bcmdhd-usb.1.363.110.17.x/include/osl.h
bcmdhd-usb.1.363.110.17.x/linux_osl.c
bcmdhd-usb.1.363.110.17.x/wl_android_ext.c
bcmdhd-usb.1.363.110.17.x/wl_cfg80211.c
bcmdhd-usb.1.363.110.17.x/wl_escan.c

old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 5e5c406..a121350
@@ -4,6 +4,7 @@
 
 CONFIG_BCMDHD := m
 CONFIG_DHD_USE_STATIC_BUF := y
+CONFIG_BCMDHD_PROPTXSTATUS := y
 
 DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER                \
        -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE            \
@@ -13,7 +14,7 @@ DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER                \
        -DEMBEDDED_PLATFORM -DPNO_SUPPORT                                     \
        -DOEM_ANDROID                                                         \
        -DSUPPORT_PM2_ONLY -DWL_EXT_IAPSTA                                    \
-       -DTOE -DBDC -DDHD_BCMEVENTS -DPROP_TXSTATUS                           \
+       -DTOE -DBDC -DDHD_BCMEVENTS                                           \
        -I$(src) -I$(src)/include -I$(src)/common/include
 
 DHDCFLAGS += -DUSBOS_TX_THREAD -DBCMDHDUSB -DBCMDBUS -DBCMTRXV2          \
@@ -28,6 +29,13 @@ DHDOFILES = bcmutils.o bcmwifi_channels.o bcmxtlv.o \
        dhd_debug.o dhd_debug_linux.o                                         \
        dhd_config.o wl_android_ext.o
 
+ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
+DHDCFLAGS += -DPROP_TXSTATUS
+ifneq ($(CONFIG_CFG80211),)
+DHDCFLAGS += -DPROP_TXSTATUS_VSDB
+endif
+endif
+
 obj-$(CONFIG_BCMDHD) += bcmdhd.o
 bcmdhd-objs += $(DHDOFILES)
 
@@ -57,7 +65,7 @@ DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL
 DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
 DHDCFLAGS += -DESCAN_RESULT_PATCH
 DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
-DHDCFLAGS += -DWLTDLS -DWL_SDO -DWL_NAN -DPROP_TXSTATUS_VSDB
+DHDCFLAGS += -DWLTDLS -DWL_SDO -DWL_NAN
 endif
 ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),)
 DHDCFLAGS += -DWL_SCHED_SCAN
index 62d4e34eb7e948cad80029115c8384fd0efff357..cb7558c17fa73a8c4d1fce6f1959add8a6f20f92 100644 (file)
-\r
-#include <typedefs.h>\r
-#include <osl.h>\r
-\r
-#include <bcmutils.h>\r
-\r
-#include <dhd_config.h>\r
-#include <dhd_dbg.h>\r
-\r
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+
+#include <dhd_config.h>
+#include <dhd_dbg.h>
+
 /* message levels */
-#define CONFIG_ERROR_LEVEL     0x0001\r
-#define CONFIG_TRACE_LEVEL     0x0002\r
+#define CONFIG_ERROR_LEVEL     0x0001
+#define CONFIG_TRACE_LEVEL     0x0002
 
-uint config_msg_level = CONFIG_ERROR_LEVEL;\r
+uint config_msg_level = CONFIG_ERROR_LEVEL;
 
-#define CONFIG_ERROR(x) \\r
+#define CONFIG_ERROR(x) \
        do { \
-               if (config_msg_level & CONFIG_ERROR_LEVEL) { \\r
-                       printk(KERN_ERR "CONFIG-ERROR) ");      \\r
+               if (config_msg_level & CONFIG_ERROR_LEVEL) { \
+                       printk(KERN_ERR "CONFIG-ERROR) ");      \
                        printk x; \
                } \
        } while (0)
-#define CONFIG_TRACE(x) \\r
+#define CONFIG_TRACE(x) \
        do { \
-               if (config_msg_level & CONFIG_TRACE_LEVEL) { \\r
-                       printk(KERN_ERR "CONFIG-TRACE) ");      \\r
+               if (config_msg_level & CONFIG_TRACE_LEVEL) { \
+                       printk(KERN_ERR "CONFIG-TRACE) ");      \
                        printk x; \
                } \
-       } while (0)\r
-\r
-#define MAXSZ_BUF              1000\r
-#define        MAXSZ_CONFIG    4096\r
-\r
+       } while (0)
+
+#define MAXSZ_BUF              1000
+#define        MAXSZ_CONFIG    4096
+
 #define htod32(i) i
 #define htod16(i) i
 #define dtoh32(i) i
 #define dtoh16(i) i
 #define htodchanspec(i) i
-#define dtohchanspec(i) i\r
-\r
-void\r
-dhd_conf_set_conf_path_by_fw_path(dhd_pub_t *dhd, char *conf_path, char *fw_path)\r
-{\r
-       int i;\r
-\r
-       if (fw_path[0] == '\0') {\r
-#ifdef CONFIG_BCMDHD_FW_PATH\r
-               bcm_strncpy_s(conf_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);\r
-               if (fw_path[0] == '\0')\r
-#endif\r
-               {\r
-                       printf("fw path is null\n");\r
-                       return;\r
-               }\r
-       } else\r
-               strcpy(conf_path, fw_path);\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(conf_path);\r
+#define dtohchanspec(i) i
+
+void
+dhd_conf_set_conf_path_by_fw_path(dhd_pub_t *dhd, char *conf_path, char *fw_path)
+{
+       int i;
+
+       if (fw_path[0] == '\0') {
+#ifdef CONFIG_BCMDHD_FW_PATH
+               bcm_strncpy_s(conf_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
+               if (fw_path[0] == '\0')
+#endif
+               {
+                       printf("fw path is null\n");
+                       return;
+               }
+       } else
+               strcpy(conf_path, fw_path);
+
+       /* find out the last '/' */
+       i = strlen(conf_path);
        while (i > 0) {
-               if (conf_path[i] == '/') break;\r
-               i--;\r
-       }\r
-       strcpy(&conf_path[i+1], "config.txt");\r
-\r
-       printf("%s: config_path=%s\n", __FUNCTION__, conf_path);\r
-}\r
-\r
-int\r
-dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,\r
-       int def, bool down)\r
-{\r
-       int ret = -1;\r
-       char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */\r
-\r
-       if (val >= def) {\r
-               if (down) {\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
-               }\r
-               if (cmd == WLC_SET_VAR) {\r
-                       printf("%s: set %s %d\n", __FUNCTION__, name, val);\r
-                       bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-               } else {\r
-                       printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,\r
-       int len, bool down)\r
-{\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       int ret = -1;\r
-\r
-       if (down) {\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
-       }\r
-\r
-       if (cmd == WLC_SET_VAR) {\r
-               bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-       } else {\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)\r
-{\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       int ret = -1;\r
-\r
-       if (cmd == WLC_GET_VAR) {\r
-               if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {\r
-                       ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);\r
-                       if (!ret) {\r
-                               memcpy(buf, iovbuf, len);\r
-                       } else {\r
-                               CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
-                       }\r
-               } else {\r
-                       CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));\r
-               }\r
-       } else {\r
-               ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);\r
-               if (ret < 0)\r
-                       CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-uint\r
-dhd_conf_get_band(dhd_pub_t *dhd)\r
-{\r
-       uint band = WLC_BAND_AUTO;\r
-\r
-       if (dhd && dhd->conf)\r
-               band = dhd->conf->band;\r
-       else\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\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
-       int bcmerror = -1;\r
-\r
-       memset(cspec, 0, sizeof(wl_country_t));\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
-{\r
-       int bcmerror = -1, i;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       for (i = 0; i < conf->country_list.count; i++) {\r
-               if (strcmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev) == 0) {\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
-                       printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
-                       return 0;\r
-               }\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-int\r
-dhd_conf_fix_country(dhd_pub_t *dhd)\r
-{\r
-       int bcmerror = -1;\r
-       uint band;\r
-       wl_uint32_list_t *list;\r
-       u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
-\r
-       if (!(dhd && dhd->conf)) {\r
-               return bcmerror;\r
-       }\r
-
-       memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
+               if (conf_path[i] == '/') break;
+               i--;
+       }
+       strcpy(&conf_path[i+1], "config.txt");
+
+       printf("%s: config_path=%s\n", __FUNCTION__, conf_path);
+}
+
+int
+dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,
+       int def, bool down)
+{
+       int ret = -1;
+       char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */
+
+       if (val >= def) {
+               if (down) {
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
+               }
+               if (cmd == WLC_SET_VAR) {
+                       printf("%s: set %s %d\n", __FUNCTION__, name, val);
+                       bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+               } else {
+                       printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+               }
+       }
+
+       return ret;
+}
+
+int
+dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,
+       int len, bool down)
+{
+       char iovbuf[WLC_IOCTL_SMLEN];
+       int ret = -1;
+
+       if (down) {
+               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
+       }
+
+       if (cmd == WLC_SET_VAR) {
+               bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));
+               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+       } else {
+               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+       }
+
+       return ret;
+}
+
+int
+dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)
+{
+       char iovbuf[WLC_IOCTL_SMLEN];
+       int ret = -1;
+
+       if (cmd == WLC_GET_VAR) {
+               if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
+                       ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
+                       if (!ret) {
+                               memcpy(buf, iovbuf, len);
+                       } else {
+                               CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
+                       }
+               } else {
+                       CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));
+               }
+       } else {
+               ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);
+               if (ret < 0)
+                       CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
+       }
+
+       return ret;
+}
+
+uint
+dhd_conf_get_band(dhd_pub_t *dhd)
+{
+       uint band = WLC_BAND_AUTO;
+
+       if (dhd && dhd->conf)
+               band = dhd->conf->band;
+       else
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+
+       return band;
+}
+
+int
+dhd_conf_set_country(dhd_pub_t *dhd)
+{
+       int bcmerror = -1;
+
+       memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
+       printf("%s: set country %s, revision %d\n", __FUNCTION__,
+               dhd->conf->cspec.ccode, dhd->conf->cspec.rev);
+       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+       int bcmerror = -1;
+
+       memset(cspec, 0, sizeof(wl_country_t));
+       bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)
+               CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));
+       else
+               printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+       int bcmerror = -1, i;
+       struct dhd_conf *conf = dhd->conf;
+
+       for (i = 0; i < conf->country_list.count; i++) {
+               if (strcmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev) == 0) {
+                       memcpy(cspec->ccode,
+                               conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);
+                       cspec->rev = conf->country_list.cspec[i].rev;
+                       printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
+                       return 0;
+               }
+       }
+
+       return bcmerror;
+}
+
+int
+dhd_conf_fix_country(dhd_pub_t *dhd)
+{
+       int bcmerror = -1;
+       uint band;
+       wl_uint32_list_t *list;
+       u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+
+       if (!(dhd && dhd->conf)) {
+               return bcmerror;
+       }
+
+       memset(valid_chan_list, 0, sizeof(valid_chan_list));
        list = (wl_uint32_list_t *)(void *) valid_chan_list;
        list->count = htod32(WL_NUMCHANNELS);
-       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {\r
-               CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));\r
-       }\r
-\r
-       band = dhd_conf_get_band(dhd);\r
-\r
-       if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) &&\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
-               }\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-bool\r
-dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)\r
-{\r
-       int i;\r
-       bool match = false;\r
-\r
-       if (dhd && dhd->conf) {\r
-               if (dhd->conf->channels.count == 0)\r
-                       return true;\r
-               for (i=0; i<dhd->conf->channels.count; i++) {\r
-                       if (channel == dhd->conf->channels.channel[i])\r
-                               match = true;\r
-               }\r
-       } else {\r
-               match = true;\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\r
-       }\r
-\r
-       return match;\r
-}\r
-\r
-int\r
-dhd_conf_set_roam(dhd_pub_t *dhd)\r
-{\r
-       int bcmerror = -1;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       dhd_roam_disable = conf->roam_off;\r
-       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);\r
-\r
-       if (!conf->roam_off || !conf->roam_off_suspend) {\r
-               printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",\r
-                               (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);\r
-\r
-               printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",\r
-                               (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);\r
-\r
-               printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",\r
-                               (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);\r
-               \r
-               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-void\r
-dhd_conf_set_bw_cap(dhd_pub_t *dhd)\r
-{\r
-       struct {\r
-               u32 band;\r
-               u32 bw_cap;\r
-       } param = {0, 0};\r
-\r
-       if (dhd->conf->bw_cap_2g >= 0) {\r
-               param.band = WLC_BAND_2G;\r
-               param.bw_cap = (uint)dhd->conf->bw_cap_2g;\r
-               printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
-       }\r
-\r
-       if (dhd->conf->bw_cap_5g >= 0) {\r
-               param.band = WLC_BAND_5G;\r
-               param.bw_cap = (uint)dhd->conf->bw_cap_5g;\r
-               printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
-       }\r
-}\r
-\r
-void\r
-dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp)\r
-{\r
-       int bcmerror = -1;\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       edcf_acparam_t *acparam;\r
-\r
-       bzero(iovbuf, sizeof(iovbuf));\r
-\r
-       /*\r
-        * Get current acparams, using buf as an input buffer.\r
-        * Return data is array of 4 ACs of wme params.\r
-        */\r
-       bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));\r
-       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {\r
-               CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));\r
-               return;\r
-       }\r
-       memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);\r
-\r
-       acparam = &acp[AC_BK];\r
-       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_BE];\r
-       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_VI];\r
-       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_VO];\r
-       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-\r
-       return;\r
-}\r
-\r
-void\r
-dhd_conf_update_wme(dhd_pub_t *dhd, edcf_acparam_t *acparam_cur, int aci)\r
-{\r
-       int aifsn, ecwmin, ecwmax, txop;\r
-       edcf_acparam_t *acp;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       /* Default value */\r
-       aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;\r
-       ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;\r
-       ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;\r
-       txop = acparam_cur->TXOP;\r
-\r
-       /* Modified value */\r
-       if (conf->wme.aifsn[aci] > 0)\r
-               aifsn = conf->wme.aifsn[aci];\r
-       if (conf->wme.ecwmin[aci] > 0)\r
-               ecwmin = conf->wme.ecwmin[aci];\r
-       if (conf->wme.ecwmax[aci] > 0)\r
-               ecwmax = conf->wme.ecwmax[aci];\r
-       if (conf->wme.txop[aci] > 0)\r
-               txop = conf->wme.txop[aci];\r
-\r
-       if (!(conf->wme.aifsn[aci] || conf->wme.ecwmin[aci] ||\r
-                       conf->wme.ecwmax[aci] || conf->wme.txop[aci]))\r
-               return;\r
-\r
-       /* Update */\r
-       acp = acparam_cur;\r
-       acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);\r
-       acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);\r
-       acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));\r
-       acp->TXOP = txop;\r
-\r
-       printf("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acp->ACI, acp->ACI&EDCF_AIFSN_MASK,\r
-               acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acp->TXOP);\r
-\r
-       /*\r
-       * Now use buf as an output buffer.\r
-       * Put WME acparams after "wme_ac\0" in buf.\r
-       * NOTE: only one of the four ACs can be set at a time.\r
-       */\r
-       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
-\r
-}\r
-\r
-void\r
-dhd_conf_set_wme(dhd_pub_t *dhd)\r
-{\r
-       edcf_acparam_t acparam_cur[AC_COUNT];\r
-\r
-       if (dhd && dhd->conf) {\r
-               if (!dhd->conf->force_wme_ac) {\r
-                       CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",\r
-                               __FUNCTION__, dhd->conf->force_wme_ac));\r
-                       return;\r
-               }\r
-\r
-               CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));\r
-               dhd_conf_get_wme(dhd, acparam_cur);\r
-\r
-               dhd_conf_update_wme(dhd, &acparam_cur[AC_BK], AC_BK);\r
-               dhd_conf_update_wme(dhd, &acparam_cur[AC_BE], AC_BE);\r
-               dhd_conf_update_wme(dhd, &acparam_cur[AC_VI], AC_VI);\r
-               dhd_conf_update_wme(dhd, &acparam_cur[AC_VO], AC_VO);\r
-\r
-               CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));\r
-               dhd_conf_get_wme(dhd, acparam_cur);\r
-       } else {\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\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
-#define MACS "%02x%02x%02x%02x%02x%02x"\r
-\r
-       /*\r
-        * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.\r
-        *   1) pkt_filter_mode=0\r
-        *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
-        * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)\r
-        *   1) pkt_filter_mode=1\r
-        *   2) pkt_filter_del=100, 102, 103, 104\r
-        *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E\r
-        * 3. magic pkt: magic_pkt_filter_add=141 0 1 12\r
-        * 4. Filter out netbios pkt:\r
-        *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089\r
-        */\r
-       for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {\r
-               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];\r
-               printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);\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
-               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
-               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
-               dhd->pktfilter_count += 1;\r
-       }\r
-}\r
-\r
-bool\r
-dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)\r
-{\r
-       int i;\r
-\r
-       if (dhd && dhd->conf) {\r
-               for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {\r
-                       if (id == dhd->conf->pkt_filter_del.id[i]) {\r
-                               printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);\r
-                               return true;\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-       return false;\r
-}\r
-\r
-void\r
-dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)\r
-{\r
-       dhd->pktfilter_count = 6;\r
-       dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;\r
-       dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";\r
-       dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";\r
-       dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";\r
-       dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;\r
-       /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/\r
-       dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;\r
-\r
-       /* IPv4 broadcast address XXX.XXX.XXX.255 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";\r
-       dhd->pktfilter_count++;\r
-       /* discard IPv4 multicast address 224.0.0.0/4 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";\r
-       dhd->pktfilter_count++;\r
-       /* discard IPv6 multicast address FF00::/8 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";\r
-       dhd->pktfilter_count++;\r
-       /* discard Netbios pkt */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";\r
-       dhd->pktfilter_count++;\r
-\r
-}\r
-#endif /* PKT_FILTER_SUPPORT */\r
-\r
-int\r
-dhd_conf_get_pm(dhd_pub_t *dhd)\r
-{\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->pm;\r
-       return -1;\r
-}\r
-\r
-unsigned int\r
-process_config_vars(char *varbuf, unsigned int len, char *pickbuf, char *param)\r
-{\r
-       bool findNewline, changenewline=FALSE, pick=FALSE;\r
-       int column;\r
-       unsigned int n, pick_column=0;\r
-\r
-       findNewline = FALSE;\r
-       column = 0;\r
-\r
-       for (n = 0; n < len; n++) {\r
-               if (varbuf[n] == '\r')\r
-                       continue;\r
-               if ((findNewline || changenewline) && varbuf[n] != '\n')\r
-                       continue;\r
-               findNewline = FALSE;\r
-               if (varbuf[n] == '#') {\r
-                       findNewline = TRUE;\r
-                       continue;\r
-               }\r
-               if (varbuf[n] == '\\') {\r
-                       changenewline = TRUE;\r
-                       continue;\r
-               }\r
-               if (!changenewline && varbuf[n] == '\n') {\r
-                       if (column == 0)\r
-                               continue;\r
-                       column = 0;\r
-                       continue;\r
-               }\r
-               if (changenewline && varbuf[n] == '\n') {\r
-                       changenewline = FALSE;\r
-                       continue;\r
-               }\r
-               if (!memcmp(&varbuf[n], param, strlen(param)) && column==0) {\r
-                       pick = TRUE;\r
-                       column = strlen(param);\r
-                       n += column;\r
-                       pick_column = 0;\r
-               } else {\r
-                       if (pick && column==0)\r
-                               pick = FALSE;\r
-                       else\r
-                               column++;\r
-               }\r
-               if (pick) {\r
-                       if (varbuf[n] == 0x9)\r
-                               continue;\r
-                       if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ')\r
-                               continue;\r
-                       pickbuf[pick_column] = varbuf[n];\r
-                       pick_column++;\r
-               }\r
-       }\r
-\r
-       return pick_column;\r
-}\r
-\r
-void\r
-dhd_conf_read_log_level(dhd_pub_t *dhd, char *bufp, uint len)\r
-{\r
-       uint len_val;\r
-       char *pick;\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               return;\r
-       }\r
-\r
-       /* Process dhd_msglevel */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "msglevel=");\r
-       if (len_val) {\r
-               dhd_msg_level = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);\r
-       }\r
-       /* Process dbus_msglevel */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "dbus_msglevel=");\r
-       if (len_val) {\r
-               dbus_msglevel = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: dbus_msglevel = 0x%X\n", __FUNCTION__, dbus_msglevel);\r
-       }\r
-       /* Process android_msg_level */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "android_msg_level=");\r
-       if (len_val) {\r
-               android_msg_level = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);\r
-       }\r
-       /* Process config_msg_level */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "config_msg_level=");\r
-       if (len_val) {\r
-               config_msg_level = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);\r
-       }\r
-#ifdef WL_CFG80211\r
-       /* Process wl_dbg_level */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "wl_dbg_level=");\r
-       if (len_val) {\r
-               wl_dbg_level = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);\r
-       }\r
-#endif\r
-#if defined(WL_WIRELESS_EXT)\r
-       /* Process iw_msg_level */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "iw_msg_level=");\r
-       if (len_val) {\r
-               iw_msg_level = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);\r
-       }\r
-#endif\r
-\r
-#if defined(DHD_DEBUG)\r
-       /* Process dhd_console_ms */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "dhd_console_ms=");\r
-       if (len_val) {\r
-               dhd_console_ms = (int)simple_strtol(pick, NULL, 0);\r
-               printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);\r
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {
+               CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));
+       }
+
+       band = dhd_conf_get_band(dhd);
+
+       if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) &&
+                       dtoh32(list->count)<11)) {
+               CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
+                       __FUNCTION__, bcmerror, dtoh32(list->count)));
+               if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {
+                       strcpy(dhd->conf->cspec.country_abbrev, "US");
+                       dhd->conf->cspec.rev = 0;
+                       strcpy(dhd->conf->cspec.ccode, "US");
+                       dhd_conf_set_country(dhd);
+               }
+       }
+
+       return bcmerror;
+}
+
+bool
+dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)
+{
+       int i;
+       bool match = false;
+
+       if (dhd && dhd->conf) {
+               if (dhd->conf->channels.count == 0)
+                       return true;
+               for (i=0; i<dhd->conf->channels.count; i++) {
+                       if (channel == dhd->conf->channels.channel[i])
+                               match = true;
+               }
+       } else {
+               match = true;
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+       }
+
+       return match;
+}
+
+int
+dhd_conf_set_roam(dhd_pub_t *dhd)
+{
+       int bcmerror = -1;
+       struct dhd_conf *conf = dhd->conf;
+
+       dhd_roam_disable = conf->roam_off;
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);
+
+       if (!conf->roam_off || !conf->roam_off_suspend) {
+               printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",
+                               (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);
+
+               printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",
+                               (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);
+
+               printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",
+                               (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);
+               
+               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);
        }
-#endif\r
-\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-}\r
-\r
-void\r
-dhd_conf_read_wme_ac_value(dhd_pub_t *dhd, char *pick, uint len, int ac_val)\r
-{\r
-       char *pick_tmp, *pch;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       /* Process WMM parameters */\r
-       if (len) {\r
-               pick_tmp = pick;\r
-               pch = bcmstrstr(pick_tmp, "aifsn ");\r
-               if (pch) {\r
-                       conf->wme.aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);\r
-                       printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, conf->wme.aifsn[ac_val]);\r
-               }\r
-               pick_tmp = pick;\r
-               pch = bcmstrstr(pick_tmp, "ecwmin ");\r
-               if (pch) {\r
-                       conf->wme.ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);\r
-                       printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmin[ac_val]);\r
-               }\r
-               pick_tmp = pick;\r
-               pch = bcmstrstr(pick_tmp, "ecwmax ");\r
-               if (pch) {\r
-                       conf->wme.ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);\r
-                       printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmax[ac_val]);\r
-               }\r
-               pick_tmp = pick;\r
-               pch = bcmstrstr(pick_tmp, "txop ");\r
-               if (pch) {\r
-                       conf->wme.txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);\r
-                       printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, conf->wme.txop[ac_val]);\r
-               }\r
-       }\r
-\r
-}\r
-
-void\r
-dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)\r
-{\r
-       uint len_val;\r
-       char *pick;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               return;\r
-       }\r
-       // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e\r
-       // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e\r
-\r
-       /* Process WMM parameters */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "force_wme_ac=");\r
-       if (len_val) {\r
-               conf->force_wme_ac = (int)simple_strtol(pick, NULL, 10);\r
-               printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_be=");\r
-       if (len_val) {\r
-               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BE);\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_bk=");\r
-       if (len_val) {\r
-               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BK);\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vi=");\r
-       if (len_val) {\r
-               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VI);\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vo=");\r
-       if (len_val) {\r
-               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VO);\r
-       }\r
-\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-\r
-}\r
-\r
-void\r
-dhd_conf_read_roam_params(dhd_pub_t *dhd, char *bufp, uint len)\r
-{\r
-       uint len_val;\r
-       char *pick;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               return;\r
-       }\r
-\r
-       /* Process roam */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "roam_off=");\r
-       if (len_val) {\r
-               if (!strncmp(pick, "0", len_val))\r
-                       conf->roam_off = 0;\r
-               else\r
-                       conf->roam_off = 1;\r
-               printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "roam_off_suspend=");\r
-       if (len_val) {\r
-               if (!strncmp(pick, "0", len_val))\r
-                       conf->roam_off_suspend = 0;\r
-               else\r
-                       conf->roam_off_suspend = 1;\r
-               printf("%s: roam_off_suspend = %d\n", __FUNCTION__,\r
-                       conf->roam_off_suspend);\r
-       }\r
-\r
-       if (!conf->roam_off || !conf->roam_off_suspend) {\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "roam_trigger=");\r
-               if (len_val)\r
-                       conf->roam_trigger[0] = (int)simple_strtol(pick, NULL, 10);\r
-               printf("%s: roam_trigger = %d\n", __FUNCTION__,\r
-                       conf->roam_trigger[0]);\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "roam_scan_period=");\r
-               if (len_val)\r
-                       conf->roam_scan_period[0] = (int)simple_strtol(pick, NULL, 10);\r
-               printf("%s: roam_scan_period = %d\n", __FUNCTION__,\r
-                       conf->roam_scan_period[0]);\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "roam_delta=");\r
-               if (len_val)\r
-                       conf->roam_delta[0] = (int)simple_strtol(pick, NULL, 10);\r
-               printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "fullroamperiod=");\r
-               if (len_val)\r
-                       conf->fullroamperiod = (int)simple_strtol(pick, NULL, 10);\r
-               printf("%s: fullroamperiod = %d\n", __FUNCTION__,\r
-                       conf->fullroamperiod);\r
-       }\r
-\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-\r
-}\r
-\r
-void\r
-dhd_conf_read_country_list(dhd_pub_t *dhd, char *bufp, uint len)\r
-{\r
-       uint len_val;\r
-       int i;\r
-       char *pick, *pch, *pick_tmp;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               return;\r
-       }\r
-\r
-       /* Process country_list:\r
-        * country_list=[country1]:[ccode1]/[regrev1],\r
-        * [country2]:[ccode2]/[regrev2] \\r
-        * Ex: country_list=US:US/0, TW:TW/1\r
-        */\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "country_list=");\r
-       if (len_val) {\r
-               pick_tmp = pick;\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
-                       strcpy(conf->country_list.cspec[i].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
-                       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
-                       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
-               }\r
-               printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);\r
-       }\r
-\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-}\r
-\r
-#ifdef IAPSTA_PREINIT\r
-/*\r
- * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]\r
- * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]\r
-                hidden [y|n] maxassoc [x]\r
-                amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\r
-                emode [none|wep|tkip|aes|tkipaes]\r
-                key [xxxxx]\r
- * iapsta_enable=ifname [wlan0|wlan1]\r
-*/\r
-void\r
-dhd_conf_read_iapsta(dhd_pub_t *dhd, char *bufp, uint len)\r
-{\r
-       uint len_val;\r
-       char *pick;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               return;\r
-       }\r
-\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "iapsta_init=");\r
-       if (len_val) {\r
-               sprintf(conf->iapsta_init, "iapsta_init %s", pick);\r
-               printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);\r
-       }\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "iapsta_config=");\r
-       if (len_val) {\r
-               sprintf(conf->iapsta_config, "iapsta_config %s", pick);\r
-               printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);\r
-       }\r
-       memset(pick, 0, MAXSZ_BUF);\r
-       len_val = process_config_vars(bufp, len, pick, "iapsta_enable=");\r
-       if (len_val) {\r
-               sprintf(conf->iapsta_enable, "iapsta_enable %s", pick);\r
-               printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);\r
-       }\r
-\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-}\r
-#endif\r
-\r
-int\r
-dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)\r
-{\r
-       int bcmerror = -1, i;\r
-       uint len, len_val;\r
-       void * image = NULL;\r
-       char * memblock = NULL;\r
-       char *bufp, *pick = NULL, *pch, *pick_tmp;\r
-       bool conf_file_exists;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));\r
-       if (!conf_file_exists) {\r
-               printf("%s: config path %s\n", __FUNCTION__, conf_path);\r
+
+       return bcmerror;
+}
+
+void
+dhd_conf_set_bw_cap(dhd_pub_t *dhd)
+{
+       struct {
+               u32 band;
+               u32 bw_cap;
+       } param = {0, 0};
+
+       if (dhd->conf->bw_cap_2g >= 0) {
+               param.band = WLC_BAND_2G;
+               param.bw_cap = (uint)dhd->conf->bw_cap_2g;
+               printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
+       }
+
+       if (dhd->conf->bw_cap_5g >= 0) {
+               param.band = WLC_BAND_5G;
+               param.bw_cap = (uint)dhd->conf->bw_cap_5g;
+               printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
+       }
+}
+
+void
+dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp)
+{
+       int bcmerror = -1;
+       char iovbuf[WLC_IOCTL_SMLEN];
+       edcf_acparam_t *acparam;
+
+       bzero(iovbuf, sizeof(iovbuf));
+
+       /*
+        * Get current acparams, using buf as an input buffer.
+        * Return data is array of 4 ACs of wme params.
+        */
+       bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
+               CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));
+               return;
+       }
+       memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);
+
+       acparam = &acp[AC_BK];
+       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_BE];
+       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_VI];
+       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_VO];
+       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+
+       return;
+}
+
+void
+dhd_conf_update_wme(dhd_pub_t *dhd, edcf_acparam_t *acparam_cur, int aci)
+{
+       int aifsn, ecwmin, ecwmax, txop;
+       edcf_acparam_t *acp;
+       struct dhd_conf *conf = dhd->conf;
+
+       /* Default value */
+       aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;
+       ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;
+       ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;
+       txop = acparam_cur->TXOP;
+
+       /* Modified value */
+       if (conf->wme.aifsn[aci] > 0)
+               aifsn = conf->wme.aifsn[aci];
+       if (conf->wme.ecwmin[aci] > 0)
+               ecwmin = conf->wme.ecwmin[aci];
+       if (conf->wme.ecwmax[aci] > 0)
+               ecwmax = conf->wme.ecwmax[aci];
+       if (conf->wme.txop[aci] > 0)
+               txop = conf->wme.txop[aci];
+
+       if (!(conf->wme.aifsn[aci] || conf->wme.ecwmin[aci] ||
+                       conf->wme.ecwmax[aci] || conf->wme.txop[aci]))
+               return;
+
+       /* Update */
+       acp = acparam_cur;
+       acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);
+       acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);
+       acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));
+       acp->TXOP = txop;
+
+       printf("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acp->ACI, acp->ACI&EDCF_AIFSN_MASK,
+               acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acp->TXOP);
+
+       /*
+       * Now use buf as an output buffer.
+       * Put WME acparams after "wme_ac\0" in buf.
+       * NOTE: only one of the four ACs can be set at a time.
+       */
+       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);
+
+}
+
+void
+dhd_conf_set_wme(dhd_pub_t *dhd)
+{
+       edcf_acparam_t acparam_cur[AC_COUNT];
+
+       if (dhd && dhd->conf) {
+               if (!dhd->conf->force_wme_ac) {
+                       CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",
+                               __FUNCTION__, dhd->conf->force_wme_ac));
+                       return;
+               }
+
+               CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));
+               dhd_conf_get_wme(dhd, acparam_cur);
+
+               dhd_conf_update_wme(dhd, &acparam_cur[AC_BK], AC_BK);
+               dhd_conf_update_wme(dhd, &acparam_cur[AC_BE], AC_BE);
+               dhd_conf_update_wme(dhd, &acparam_cur[AC_VI], AC_VI);
+               dhd_conf_update_wme(dhd, &acparam_cur[AC_VO], AC_VO);
+
+               CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));
+               dhd_conf_get_wme(dhd, acparam_cur);
+       } else {
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+       }
+
+       return;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+void
+dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
+{
+       int i, j;
+       char str[12];
+#define MACS "%02x%02x%02x%02x%02x%02x"
+
+       /*
+        * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.
+        *   1) dhd_master_mode=0
+        *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
+        * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)
+        *   1) dhd_master_mode=1
+        *   2) pkt_filter_del=100, 102, 103, 104, 105
+        *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E
+        * 3. magic pkt: magic_pkt_filter_add=141 0 1 12
+        * 4. Filter out netbios pkt:
+        *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089
+        */
+       for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {
+               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];
+               printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);
+       }
+       dhd->pktfilter_count += i;
+
+       for(i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               for (j=0; j<16; j++)
+                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
+               for (j=0; j<16; j++)
+                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);
+               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];
+               dhd->pktfilter_count += 1;
+       }
+}
+
+bool
+dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)
+{
+       int i;
+
+       if (dhd && dhd->conf) {
+               for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {
+                       if (id == dhd->conf->pkt_filter_del.id[i]) {
+                               printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);
+                               return true;
+                       }
+               }
+               return false;
+       }
+       return false;
+}
+
+void
+dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
+{
+       dhd->pktfilter_count = 6;
+       dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;
+       dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+       dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";
+       dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";
+       dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
+       /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/
+       dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;
+
+       /* IPv4 broadcast address XXX.XXX.XXX.255 */
+       dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";
+       dhd->pktfilter_count++;
+       /* discard IPv4 multicast address 224.0.0.0/4 */
+       dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";
+       dhd->pktfilter_count++;
+       /* discard IPv6 multicast address FF00::/8 */
+       dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";
+       dhd->pktfilter_count++;
+       /* discard Netbios pkt */
+       dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";
+       dhd->pktfilter_count++;
+
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int
+dhd_conf_get_pm(dhd_pub_t *dhd)
+{
+       if (dhd && dhd->conf)
+               return dhd->conf->pm;
+       return -1;
+}
+
+#ifdef PROP_TXSTATUS
+int
+dhd_conf_get_disable_proptx(dhd_pub_t *dhd)
+{
+       struct dhd_conf *conf = dhd->conf;
+       int disable_proptx = -1;
+       int fw_proptx = 0;
+
+       /* check fw proptx priority:
+         * 1st: check fw support by wl cap
+         * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default
+         *        if you would like to disable it, please set disable_proptx=1 in config.txt
+         * 3th: disable when proptxstatus not support in wl cap
+         */
+       if (FW_SUPPORTED(dhd, proptxstatus)) {
+               fw_proptx = 1;
+       } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
+                       dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+               fw_proptx = 1;
+       } else {
+               fw_proptx = 0;
+       }
+
+       /* returned disable_proptx value:
+         * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)
+         * 0: depend on fw support
+         * 1: always disable proptx
+         */
+       if (conf->disable_proptx == 0) {
+               // check fw support as well
+               if (fw_proptx)
+                       disable_proptx = 0;
+               else
+                       disable_proptx = 1;
+       } else if (conf->disable_proptx >= 1) {
+               disable_proptx = 1;
+       } else {
+               // check fw support as well
+               if (fw_proptx)
+                       disable_proptx = -1;
+               else
+                       disable_proptx = 1;
+       }
+
+       printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);
+
+       return disable_proptx;
+}
+#endif
+
+unsigned int
+process_config_vars(char *varbuf, unsigned int len, char *pickbuf, char *param)
+{
+       bool findNewline, changenewline=FALSE, pick=FALSE;
+       int column;
+       unsigned int n, pick_column=0;
+
+       findNewline = FALSE;
+       column = 0;
+
+       for (n = 0; n < len; n++) {
+               if (varbuf[n] == '\r')
+                       continue;
+               if ((findNewline || changenewline) && varbuf[n] != '\n')
+                       continue;
+               findNewline = FALSE;
+               if (varbuf[n] == '#') {
+                       findNewline = TRUE;
+                       continue;
+               }
+               if (varbuf[n] == '\\') {
+                       changenewline = TRUE;
+                       continue;
+               }
+               if (!changenewline && varbuf[n] == '\n') {
+                       if (column == 0)
+                               continue;
+                       column = 0;
+                       continue;
+               }
+               if (changenewline && varbuf[n] == '\n') {
+                       changenewline = FALSE;
+                       continue;
+               }
+               if (!memcmp(&varbuf[n], param, strlen(param)) && column==0) {
+                       pick = TRUE;
+                       column = strlen(param);
+                       n += column;
+                       pick_column = 0;
+               } else {
+                       if (pick && column==0)
+                               pick = FALSE;
+                       else
+                               column++;
+               }
+               if (pick) {
+                       if (varbuf[n] == 0x9)
+                               continue;
+                       if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ')
+                               continue;
+                       pickbuf[pick_column] = varbuf[n];
+                       pick_column++;
+               }
+       }
+
+       return pick_column;
+}
+
+void
+dhd_conf_read_log_level(dhd_pub_t *dhd, char *bufp, uint len)
+{
+       uint len_val;
+       char *pick;
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               return;
+       }
+
+       /* Process dhd_msglevel */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "msglevel=");
+       if (len_val) {
+               dhd_msg_level = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);
+       }
+       /* Process dbus_msglevel */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "dbus_msglevel=");
+       if (len_val) {
+               dbus_msglevel = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: dbus_msglevel = 0x%X\n", __FUNCTION__, dbus_msglevel);
+       }
+       /* Process android_msg_level */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "android_msg_level=");
+       if (len_val) {
+               android_msg_level = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);
+       }
+       /* Process config_msg_level */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "config_msg_level=");
+       if (len_val) {
+               config_msg_level = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);
+       }
+#ifdef WL_CFG80211
+       /* Process wl_dbg_level */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "wl_dbg_level=");
+       if (len_val) {
+               wl_dbg_level = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);
+       }
+#endif
+#if defined(WL_WIRELESS_EXT)
+       /* Process iw_msg_level */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "iw_msg_level=");
+       if (len_val) {
+               iw_msg_level = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);
+       }
+#endif
+
+#if defined(DHD_DEBUG)
+       /* Process dhd_console_ms */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "dhd_console_ms=");
+       if (len_val) {
+               dhd_console_ms = (int)simple_strtol(pick, NULL, 0);
+               printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);
+       }
+#endif
+
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+}
+
+void
+dhd_conf_read_wme_ac_value(dhd_pub_t *dhd, char *pick, uint len, int ac_val)
+{
+       char *pick_tmp, *pch;
+       struct dhd_conf *conf = dhd->conf;
+
+       /* Process WMM parameters */
+       if (len) {
+               pick_tmp = pick;
+               pch = bcmstrstr(pick_tmp, "aifsn ");
+               if (pch) {
+                       conf->wme.aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);
+                       printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, conf->wme.aifsn[ac_val]);
+               }
+               pick_tmp = pick;
+               pch = bcmstrstr(pick_tmp, "ecwmin ");
+               if (pch) {
+                       conf->wme.ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);
+                       printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmin[ac_val]);
+               }
+               pick_tmp = pick;
+               pch = bcmstrstr(pick_tmp, "ecwmax ");
+               if (pch) {
+                       conf->wme.ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);
+                       printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmax[ac_val]);
+               }
+               pick_tmp = pick;
+               pch = bcmstrstr(pick_tmp, "txop ");
+               if (pch) {
+                       conf->wme.txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);
+                       printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, conf->wme.txop[ac_val]);
+               }
+       }
+
+}
+
+void
+dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)
+{
+       uint len_val;
+       char *pick;
+       struct dhd_conf *conf = dhd->conf;
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               return;
+       }
+       // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e
+       // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e
+
+       /* Process WMM parameters */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "force_wme_ac=");
+       if (len_val) {
+               conf->force_wme_ac = (int)simple_strtol(pick, NULL, 10);
+               printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_be=");
+       if (len_val) {
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BE);
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_bk=");
+       if (len_val) {
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BK);
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vi=");
+       if (len_val) {
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VI);
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vo=");
+       if (len_val) {
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VO);
+       }
+
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+
+}
+
+void
+dhd_conf_read_roam_params(dhd_pub_t *dhd, char *bufp, uint len)
+{
+       uint len_val;
+       char *pick;
+       struct dhd_conf *conf = dhd->conf;
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               return;
+       }
+
+       /* Process roam */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "roam_off=");
+       if (len_val) {
+               if (!strncmp(pick, "0", len_val))
+                       conf->roam_off = 0;
+               else
+                       conf->roam_off = 1;
+               printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "roam_off_suspend=");
+       if (len_val) {
+               if (!strncmp(pick, "0", len_val))
+                       conf->roam_off_suspend = 0;
+               else
+                       conf->roam_off_suspend = 1;
+               printf("%s: roam_off_suspend = %d\n", __FUNCTION__,
+                       conf->roam_off_suspend);
+       }
+
+       if (!conf->roam_off || !conf->roam_off_suspend) {
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "roam_trigger=");
+               if (len_val)
+                       conf->roam_trigger[0] = (int)simple_strtol(pick, NULL, 10);
+               printf("%s: roam_trigger = %d\n", __FUNCTION__,
+                       conf->roam_trigger[0]);
+
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "roam_scan_period=");
+               if (len_val)
+                       conf->roam_scan_period[0] = (int)simple_strtol(pick, NULL, 10);
+               printf("%s: roam_scan_period = %d\n", __FUNCTION__,
+                       conf->roam_scan_period[0]);
+
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "roam_delta=");
+               if (len_val)
+                       conf->roam_delta[0] = (int)simple_strtol(pick, NULL, 10);
+               printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);
+
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "fullroamperiod=");
+               if (len_val)
+                       conf->fullroamperiod = (int)simple_strtol(pick, NULL, 10);
+               printf("%s: fullroamperiod = %d\n", __FUNCTION__,
+                       conf->fullroamperiod);
+       }
+
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+
+}
+
+void
+dhd_conf_read_country_list(dhd_pub_t *dhd, char *bufp, uint len)
+{
+       uint len_val;
+       int i;
+       char *pick, *pch, *pick_tmp;
+       struct dhd_conf *conf = dhd->conf;
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               return;
+       }
+
+       /* Process country_list:
+        * country_list=[country1]:[ccode1]/[regrev1],
+        * [country2]:[ccode2]/[regrev2] \
+        * Ex: country_list=US:US/0, TW:TW/1
+        */
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "country_list=");
+       if (len_val) {
+               pick_tmp = pick;
+               for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
+                       /* Process country code */
+                       pch = bcmstrtok(&pick_tmp, ":", 0);
+                       if (!pch)
+                               break;
+                       strcpy(conf->country_list.cspec[i].country_abbrev, pch);
+                       pch = bcmstrtok(&pick_tmp, "/", 0);
+                       if (!pch)
+                               break;
+                       memcpy(conf->country_list.cspec[i].ccode, pch, 2);
+                       pch = bcmstrtok(&pick_tmp, ", ", 0);
+                       if (!pch)
+                               break;
+                       conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);
+                       conf->country_list.count ++;
+                       CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
+                               conf->country_list.cspec[i].country_abbrev,
+                               conf->country_list.cspec[i].ccode,
+                               conf->country_list.cspec[i].rev));
+               }
+               printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
+       }
+
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+}
+
+#ifdef IAPSTA_PREINIT
+/*
+ * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]
+ * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]
+                hidden [y|n] maxassoc [x]
+                amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]
+                emode [none|wep|tkip|aes|tkipaes]
+                key [xxxxx]
+ * iapsta_enable=ifname [wlan0|wlan1]
+*/
+void
+dhd_conf_read_iapsta(dhd_pub_t *dhd, char *bufp, uint len)
+{
+       uint len_val;
+       char *pick;
+       struct dhd_conf *conf = dhd->conf;
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               return;
+       }
+
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "iapsta_init=");
+       if (len_val) {
+               sprintf(conf->iapsta_init, "iapsta_init %s", pick);
+               printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);
+       }
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "iapsta_config=");
+       if (len_val) {
+               sprintf(conf->iapsta_config, "iapsta_config %s", pick);
+               printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);
+       }
+       memset(pick, 0, MAXSZ_BUF);
+       len_val = process_config_vars(bufp, len, pick, "iapsta_enable=");
+       if (len_val) {
+               sprintf(conf->iapsta_enable, "iapsta_enable %s", pick);
+               printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);
+       }
+
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+}
+#endif
+
+int
+dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
+{
+       int bcmerror = -1, i;
+       uint len, len_val;
+       void * image = NULL;
+       char * memblock = NULL;
+       char *bufp, *pick = NULL, *pch, *pick_tmp;
+       bool conf_file_exists;
+       struct dhd_conf *conf = dhd->conf;
+
+       conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));
+       if (!conf_file_exists) {
+               printf("%s: config path %s\n", __FUNCTION__, conf_path);
                return (0);
-       }\r
-\r
-       if (conf_file_exists) {\r
-               image = dhd_os_open_image(conf_path);\r
-               if (image == NULL) {\r
-                       printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);\r
-                       goto err;\r
-               }\r
-       }\r
-\r
-       memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);\r
-       if (memblock == NULL) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_CONFIG));\r
-               goto err;\r
-       }\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               goto err;\r
-       }\r
-\r
-       /* Read variables */\r
-       if (conf_file_exists) {\r
-               len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);\r
-       }\r
-       if (len > 0 && len < MAXSZ_CONFIG) {\r
-               bufp = (char *)memblock;\r
-               bufp[len] = 0;\r
-\r
-               /* Process log_level */\r
-               dhd_conf_read_log_level(dhd, bufp, len);\r
-               dhd_conf_read_roam_params(dhd, bufp, len);\r
-               dhd_conf_read_wme_ac_params(dhd, bufp, len);\r
-               dhd_conf_read_country_list(dhd, bufp, len);\r
-#ifdef IAPSTA_PREINIT\r
-               dhd_conf_read_iapsta(dhd, bufp, len);\r
-#endif\r
-\r
-               /* Process band:\r
-                * band=a for 5GHz only and band=b for 2.4GHz only\r
-                */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "band=");\r
-               if (len_val) {\r
-                       if (!strncmp(pick, "b", len_val))\r
-                               conf->band = WLC_BAND_2G;\r
-                       else if (!strncmp(pick, "a", len_val))\r
-                               conf->band = WLC_BAND_5G;\r
-                       else\r
-                               conf->band = WLC_BAND_AUTO;\r
-                       printf("%s: band = %d\n", __FUNCTION__, conf->band);\r
-               }\r
-\r
-               /* Process mimo_bw_cap */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "mimo_bw_cap=");\r
-               if (len_val) {\r
-                       conf->mimo_bw_cap = (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);\r
-               }\r
-\r
-               /* Process bw_cap_2g */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bw_cap_2g=");\r
-               if (len_val) {\r
-                       conf->bw_cap_2g = (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);\r
-               }\r
-\r
-               /* Process bw_cap_5g */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bw_cap_5g=");\r
-               if (len_val) {\r
-                       conf->bw_cap_5g = (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: bw_cap_5g = %d\n", __FUNCTION__, conf->bw_cap_5g);\r
-               }\r
-\r
-               /* Process country code */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "ccode=");\r
-               if (len_val) {\r
-                       memset(&conf->cspec, 0, sizeof(wl_country_t));\r
-                       memcpy(conf->cspec.country_abbrev, pick, len_val);\r
-                       memcpy(conf->cspec.ccode, pick, len_val);\r
-                       memset(pick, 0, MAXSZ_BUF);\r
-                       len_val = process_config_vars(bufp, len, pick, "regrev=");\r
-                       if (len_val)\r
-                               conf->cspec.rev = (int32)simple_strtol(pick, NULL, 10);\r
-               }\r
-\r
-               /* Process channels */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "channels=");\r
-               pick_tmp = pick;\r
-               if (len_val) {\r
-                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                       i=0;\r
-                       while (pch != NULL && i<WL_NUMCHANNELS) {\r
-                               conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);\r
-                               pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                               i++;\r
-                       }\r
-                       conf->channels.count = i;\r
-                       printf("%s: channels = ", __FUNCTION__);\r
-                       for (i=0; i<conf->channels.count; i++)\r
-                               printf("%d ", conf->channels.channel[i]);\r
-                       printf("\n");\r
-               }\r
-\r
-               /* Process keep alive period */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "keep_alive_period=");\r
-               if (len_val) {\r
-                       conf->keep_alive_period = (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: keep_alive_period = %d\n", __FUNCTION__,\r
-                               conf->keep_alive_period);\r
-               }\r
-\r
-               /* Process STBC parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "stbc=");\r
-               if (len_val) {\r
-                       conf->stbc = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);\r
-               }\r
-\r
-               /* Process dhd_master_mode parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "dhd_master_mode=");\r
-               if (len_val) {\r
-                       if (!strncmp(pick, "0", len_val))\r
-                               dhd_master_mode = FALSE;\r
-                       else\r
-                               dhd_master_mode = TRUE;\r
-                       printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);\r
-               }\r
-\r
-#ifdef PKT_FILTER_SUPPORT\r
-               /* Process pkt_filter_add:\r
-                * All pkt: pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
-                */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "pkt_filter_add=");\r
-               pick_tmp = pick;\r
-               if (len_val) {\r
-                       pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
-                       i=0;\r
-                       while (pch != NULL && i<DHD_CONF_FILTER_MAX) {\r
-                               strcpy(&conf->pkt_filter_add.filter[i][0], pch);\r
-                               printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);\r
-                               pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
-                               i++;\r
-                       }\r
-                       conf->pkt_filter_add.count = i;\r
-               }\r
-\r
-               /* Process pkt_filter_del */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "pkt_filter_del=");\r
-               pick_tmp = pick;\r
-               if (len_val) {\r
-                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                       i=0;\r
-                       while (pch != NULL && i<DHD_CONF_FILTER_MAX) {\r
-                               conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);\r
-                               pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                               i++;\r
-                       }\r
-                       conf->pkt_filter_del.count = i;\r
-                       printf("%s: pkt_filter_del id = ", __FUNCTION__);\r
-                       for (i=0; i<conf->pkt_filter_del.count; i++)\r
-                               printf("%d ", conf->pkt_filter_del.id[i]);\r
-                       printf("\n");\r
-               }\r
-\r
-               /* Process magic_pkt_filter_add=141 0 1 12\r
-                */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "magic_pkt_filter_add=");\r
-               pick_tmp = pick;\r
-               if (len_val) {\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
-                       }\r
-                       conf->magic_pkt_filter_add.count = i;\r
-               }\r
-#endif\r
-\r
-               /* Process srl parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "srl=");\r
-               if (len_val) {\r
-                       conf->srl = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: srl = %d\n", __FUNCTION__, conf->srl);\r
-               }\r
-\r
-               /* Process lrl parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "lrl=");\r
-               if (len_val) {\r
-                       conf->lrl = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);\r
-               }\r
-\r
-               /* Process beacon timeout parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bcn_timeout=");\r
-               if (len_val) {\r
-                       conf->bcn_timeout= (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);\r
-               }\r
-\r
-               /* Process ampdu_ba_wsize parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "ampdu_ba_wsize=");\r
-               if (len_val) {\r
-                       conf->ampdu_ba_wsize = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);\r
-               }\r
-\r
-               /* Process ampdu_hostreorder parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "ampdu_hostreorder=");\r
-               if (len_val) {\r
-                       conf->ampdu_hostreorder = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);\r
-               }\r
-\r
-               /* Process spect parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "spect=");\r
-               if (len_val) {\r
-                       conf->spect = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: spect = %d\n", __FUNCTION__, conf->spect);\r
-               }\r
-\r
-               /* Process txbf parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "txbf=");\r
-               if (len_val) {\r
-                       conf->txbf = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);\r
-               }\r
-\r
-               /* Process frameburst parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "frameburst=");\r
-               if (len_val) {\r
-                       conf->frameburst = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);\r
-               }\r
-\r
-               /* Process lpc parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "lpc=");\r
-               if (len_val) {\r
-                       conf->lpc = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);\r
-               }\r
-\r
-               /* Process disable_proptx parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "disable_proptx=");\r
-               if (len_val) {\r
+       }
+
+       if (conf_file_exists) {
+               image = dhd_os_open_image(conf_path);
+               if (image == NULL) {
+                       printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);
+                       goto err;
+               }
+       }
+
+       memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);
+       if (memblock == NULL) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_CONFIG));
+               goto err;
+       }
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               goto err;
+       }
+
+       /* Read variables */
+       if (conf_file_exists) {
+               len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);
+       }
+       if (len > 0 && len < MAXSZ_CONFIG) {
+               bufp = (char *)memblock;
+               bufp[len] = 0;
+
+               /* Process log_level */
+               dhd_conf_read_log_level(dhd, bufp, len);
+               dhd_conf_read_roam_params(dhd, bufp, len);
+               dhd_conf_read_wme_ac_params(dhd, bufp, len);
+               dhd_conf_read_country_list(dhd, bufp, len);
+#ifdef IAPSTA_PREINIT
+               dhd_conf_read_iapsta(dhd, bufp, len);
+#endif
+
+               /* Process band:
+                * band=a for 5GHz only and band=b for 2.4GHz only
+                */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "band=");
+               if (len_val) {
+                       if (!strncmp(pick, "b", len_val))
+                               conf->band = WLC_BAND_2G;
+                       else if (!strncmp(pick, "a", len_val))
+                               conf->band = WLC_BAND_5G;
+                       else
+                               conf->band = WLC_BAND_AUTO;
+                       printf("%s: band = %d\n", __FUNCTION__, conf->band);
+               }
+
+               /* Process mimo_bw_cap */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "mimo_bw_cap=");
+               if (len_val) {
+                       conf->mimo_bw_cap = (uint)simple_strtol(pick, NULL, 10);
+                       printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);
+               }
+
+               /* Process bw_cap_2g */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "bw_cap_2g=");
+               if (len_val) {
+                       conf->bw_cap_2g = (uint)simple_strtol(pick, NULL, 10);
+                       printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);
+               }
+
+               /* Process bw_cap_5g */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "bw_cap_5g=");
+               if (len_val) {
+                       conf->bw_cap_5g = (uint)simple_strtol(pick, NULL, 10);
+                       printf("%s: bw_cap_5g = %d\n", __FUNCTION__, conf->bw_cap_5g);
+               }
+
+               /* Process country code */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "ccode=");
+               if (len_val) {
+                       memset(&conf->cspec, 0, sizeof(wl_country_t));
+                       memcpy(conf->cspec.country_abbrev, pick, len_val);
+                       memcpy(conf->cspec.ccode, pick, len_val);
+                       memset(pick, 0, MAXSZ_BUF);
+                       len_val = process_config_vars(bufp, len, pick, "regrev=");
+                       if (len_val)
+                               conf->cspec.rev = (int32)simple_strtol(pick, NULL, 10);
+               }
+
+               /* Process channels */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "channels=");
+               pick_tmp = pick;
+               if (len_val) {
+                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                       i=0;
+                       while (pch != NULL && i<WL_NUMCHANNELS) {
+                               conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);
+                               pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                               i++;
+                       }
+                       conf->channels.count = i;
+                       printf("%s: channels = ", __FUNCTION__);
+                       for (i=0; i<conf->channels.count; i++)
+                               printf("%d ", conf->channels.channel[i]);
+                       printf("\n");
+               }
+
+               /* Process keep alive period */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "keep_alive_period=");
+               if (len_val) {
+                       conf->keep_alive_period = (uint)simple_strtol(pick, NULL, 10);
+                       printf("%s: keep_alive_period = %d\n", __FUNCTION__,
+                               conf->keep_alive_period);
+               }
+
+               /* Process STBC parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "stbc=");
+               if (len_val) {
+                       conf->stbc = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);
+               }
+
+               /* Process dhd_master_mode parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "dhd_master_mode=");
+               if (len_val) {
+                       if (!strncmp(pick, "0", len_val))
+                               dhd_master_mode = FALSE;
+                       else
+                               dhd_master_mode = TRUE;
+                       printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);
+               }
+
+#ifdef PKT_FILTER_SUPPORT
+               /* Process pkt_filter_add:
+                * All pkt: pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
+                */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "pkt_filter_add=");
+               pick_tmp = pick;
+               if (len_val) {
+                       pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                       i=0;
+                       while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                               strcpy(&conf->pkt_filter_add.filter[i][0], pch);
+                               printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);
+                               pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                               i++;
+                       }
+                       conf->pkt_filter_add.count = i;
+               }
+
+               /* Process pkt_filter_del */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "pkt_filter_del=");
+               pick_tmp = pick;
+               if (len_val) {
+                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                       i=0;
+                       while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                               conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);
+                               pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                               i++;
+                       }
+                       conf->pkt_filter_del.count = i;
+                       printf("%s: pkt_filter_del id = ", __FUNCTION__);
+                       for (i=0; i<conf->pkt_filter_del.count; i++)
+                               printf("%d ", conf->pkt_filter_del.id[i]);
+                       printf("\n");
+               }
+
+               /* Process magic_pkt_filter_add=141 0 1 12
+                */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "magic_pkt_filter_add=");
+               pick_tmp = pick;
+               if (len_val) {
+                       pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                       i=0;
+                       while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                               strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);
+                               printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);
+                               pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                               i++;
+                       }
+                       conf->magic_pkt_filter_add.count = i;
+               }
+#endif
+
+               /* Process srl parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "srl=");
+               if (len_val) {
+                       conf->srl = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: srl = %d\n", __FUNCTION__, conf->srl);
+               }
+
+               /* Process lrl parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "lrl=");
+               if (len_val) {
+                       conf->lrl = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);
+               }
+
+               /* Process beacon timeout parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "bcn_timeout=");
+               if (len_val) {
+                       conf->bcn_timeout= (uint)simple_strtol(pick, NULL, 10);
+                       printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);
+               }
+
+               /* Process ampdu_ba_wsize parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "ampdu_ba_wsize=");
+               if (len_val) {
+                       conf->ampdu_ba_wsize = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);
+               }
+
+               /* Process ampdu_hostreorder parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "ampdu_hostreorder=");
+               if (len_val) {
+                       conf->ampdu_hostreorder = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);
+               }
+
+               /* Process spect parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "spect=");
+               if (len_val) {
+                       conf->spect = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: spect = %d\n", __FUNCTION__, conf->spect);
+               }
+
+               /* Process txbf parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "txbf=");
+               if (len_val) {
+                       conf->txbf = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);
+               }
+
+               /* Process frameburst parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "frameburst=");
+               if (len_val) {
+                       conf->frameburst = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);
+               }
+
+               /* Process lpc parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "lpc=");
+               if (len_val) {
+                       conf->lpc = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);
+               }
+
+               /* Process disable_proptx parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "disable_proptx=");
+               if (len_val) {
                        conf->disable_proptx = (int)simple_strtol(pick, NULL, 10);
                        printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);
-               }\r
-\r
-               /* Process dpc_cpucore parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "dpc_cpucore=");\r
-               if (len_val) {\r
-                       conf->dpc_cpucore = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);\r
-               }\r
-\r
-               /* Process deepsleep parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "deepsleep=");\r
-               if (len_val) {\r
-                       if (!strncmp(pick, "1", len_val))\r
-                               conf->deepsleep = TRUE;\r
-                       else\r
-                               conf->deepsleep = FALSE;\r
-                       printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);\r
-               }\r
-\r
-               /* Process PM parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "PM=");\r
-               if (len_val) {\r
-                       conf->pm = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: PM = %d\n", __FUNCTION__, conf->pm);\r
-               }\r
-\r
-               /* Process pm_in_suspend parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "pm_in_suspend=");\r
-               if (len_val) {\r
-                       conf->pm_in_suspend = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);\r
-               }\r
-\r
-               /* Process pm2_sleep_ret parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "pm2_sleep_ret=");\r
-               if (len_val) {\r
-                       conf->pm2_sleep_ret = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);\r
-               }\r
-\r
-               /* Process pktprio8021x parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "pktprio8021x=");\r
-               if (len_val) {\r
-                       conf->pktprio8021x = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);\r
-               }\r
-\r
-               /* Process vhtmode parameters */\r
+               }
+
+               /* Process dpc_cpucore parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "dpc_cpucore=");
+               if (len_val) {
+                       conf->dpc_cpucore = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);
+               }
+
+               /* Process deepsleep parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "deepsleep=");
+               if (len_val) {
+                       if (!strncmp(pick, "1", len_val))
+                               conf->deepsleep = TRUE;
+                       else
+                               conf->deepsleep = FALSE;
+                       printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);
+               }
+
+               /* Process PM parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "PM=");
+               if (len_val) {
+                       conf->pm = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: PM = %d\n", __FUNCTION__, conf->pm);
+               }
+
+               /* Process pm_in_suspend parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "pm_in_suspend=");
+               if (len_val) {
+                       conf->pm_in_suspend = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);
+               }
+
+               /* Process pm2_sleep_ret parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "pm2_sleep_ret=");
+               if (len_val) {
+                       conf->pm2_sleep_ret = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);
+               }
+
+               /* Process pktprio8021x parameters */
                memset(pick, 0, MAXSZ_BUF);
-               len_val = process_config_vars(bufp, len, pick, "vhtmode=");\r
+               len_val = process_config_vars(bufp, len, pick, "pktprio8021x=");
+               if (len_val) {
+                       conf->pktprio8021x = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);
+               }
+
+               /* Process vhtmode parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "vhtmode=");
                if (len_val) {
                        if (!strncmp(pick, "0", len_val))
-                               conf->vhtmode = 0;\r
+                               conf->vhtmode = 0;
                        else
-                               conf->vhtmode = 1;\r
-                       printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);\r
-               }\r
-\r
-               /* Process num_different_channels parameters */\r
+                               conf->vhtmode = 1;
+                       printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);
+               }
+
+               /* Process num_different_channels parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "num_different_channels=");
+               if (len_val) {
+                       conf->num_different_channels = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);
+               }
+
+#ifdef IDHCPC
+               /* Process dhcpc_enable parameters */
                memset(pick, 0, MAXSZ_BUF);
-               len_val = process_config_vars(bufp, len, pick, "num_different_channels=");\r
-               if (len_val) {\r
-                       conf->num_different_channels = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);\r
-               }\r
-\r
-               bcmerror = 0;\r
-       } else {\r
-               CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));\r
-               bcmerror = BCME_SDIO_ERROR;\r
-       }\r
-\r
-err:\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-\r
-       if (memblock)\r
-               MFREE(dhd->osh, memblock, MAXSZ_CONFIG);\r
-\r
-       if (image)\r
-               dhd_os_close_image(image);\r
-\r
-       return bcmerror;\r
-}\r
-\r
-int\r
-dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)\r
-{\r
-       printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);\r
-       dhd->conf->chip = chip;\r
-       dhd->conf->chiprev = chiprev;\r
-       return 0;\r
-}\r
-\r
-uint\r
-dhd_conf_get_chiprev(void *context)\r
-{\r
-       dhd_pub_t *dhd = context;\r
-\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->chiprev;\r
-       return 0;\r
-}\r
-\r
-int\r
-dhd_conf_preinit(dhd_pub_t *dhd)\r
-{\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-       if(!conf) {\r
-               CONFIG_ERROR(("%s: conf not attached\n", __FUNCTION__));\r
-       }\r
-\r
-       memset(&conf->country_list, 0, sizeof(conf_country_list_t));\r
-       conf->band = WLC_BAND_AUTO;\r
-       conf->mimo_bw_cap = -1;\r
-       conf->bw_cap_2g = -1;\r
-       conf->bw_cap_5g = -1;\r
-       if (conf->chip == BCM43569_CHIP_ID) {\r
-               strcpy(conf->cspec.country_abbrev, "CN");\r
-               strcpy(conf->cspec.ccode, "CN");\r
-               conf->cspec.rev = 38;\r
-       } else {\r
-               strcpy(conf->cspec.country_abbrev, "CN");\r
-               strcpy(conf->cspec.ccode, "CN");\r
-               conf->cspec.rev = 0;\r
-       }\r
-       memset(&conf->channels, 0, sizeof(wl_channel_list_t));\r
-       conf->roam_off = 1;\r
-       conf->roam_off_suspend = 1;\r
-#ifdef CUSTOM_ROAM_TRIGGER_SETTING\r
-       conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;\r
-#else\r
-       conf->roam_trigger[0] = -65;\r
-#endif\r
-       conf->roam_trigger[1] = WLC_BAND_ALL;\r
-       conf->roam_scan_period[0] = 10;\r
-       conf->roam_scan_period[1] = WLC_BAND_ALL;\r
-#ifdef CUSTOM_ROAM_DELTA_SETTING\r
-       conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;\r
-#else\r
-       conf->roam_delta[0] = 15;\r
-#endif\r
-       conf->roam_delta[1] = WLC_BAND_ALL;\r
+               len_val = process_config_vars(bufp, len, pick, "dhcpc_enable=");
+               if (len_val) {
+                       conf->dhcpc_enable = (int)simple_strtol(pick, NULL, 10);
+                       printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);
+               }
+#endif
+
+               bcmerror = 0;
+       } else {
+               CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));
+               bcmerror = BCME_SDIO_ERROR;
+       }
+
+err:
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+
+       if (memblock)
+               MFREE(dhd->osh, memblock, MAXSZ_CONFIG);
+
+       if (image)
+               dhd_os_close_image(image);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)
+{
+       printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);
+       dhd->conf->chip = chip;
+       dhd->conf->chiprev = chiprev;
+       return 0;
+}
+
+uint
+dhd_conf_get_chip(void *context)
+{
+       dhd_pub_t *dhd = context;
+
+       if (dhd && dhd->conf)
+               return dhd->conf->chip;
+       return 0;
+}
+
+uint
+dhd_conf_get_chiprev(void *context)
+{
+       dhd_pub_t *dhd = context;
+
+       if (dhd && dhd->conf)
+               return dhd->conf->chiprev;
+       return 0;
+}
+
+int
+dhd_conf_preinit(dhd_pub_t *dhd)
+{
+       struct dhd_conf *conf = dhd->conf;
+
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+       if(!conf) {
+               CONFIG_ERROR(("%s: conf not attached\n", __FUNCTION__));
+       }
+
+       memset(&conf->country_list, 0, sizeof(conf_country_list_t));
+       conf->band = WLC_BAND_AUTO;
+       conf->mimo_bw_cap = -1;
+       conf->bw_cap_2g = -1;
+       conf->bw_cap_5g = -1;
+       if (conf->chip == BCM43569_CHIP_ID) {
+               strcpy(conf->cspec.country_abbrev, "CN");
+               strcpy(conf->cspec.ccode, "CN");
+               conf->cspec.rev = 38;
+       } else {
+               strcpy(conf->cspec.country_abbrev, "CN");
+               strcpy(conf->cspec.ccode, "CN");
+               conf->cspec.rev = 0;
+       }
+       memset(&conf->channels, 0, sizeof(wl_channel_list_t));
+       conf->roam_off = 1;
+       conf->roam_off_suspend = 1;
+#ifdef CUSTOM_ROAM_TRIGGER_SETTING
+       conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;
+#else
+       conf->roam_trigger[0] = -65;
+#endif
+       conf->roam_trigger[1] = WLC_BAND_ALL;
+       conf->roam_scan_period[0] = 10;
+       conf->roam_scan_period[1] = WLC_BAND_ALL;
+#ifdef CUSTOM_ROAM_DELTA_SETTING
+       conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;
+#else
+       conf->roam_delta[0] = 15;
+#endif
+       conf->roam_delta[1] = WLC_BAND_ALL;
 #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
-       conf->fullroamperiod = 60;\r
+       conf->fullroamperiod = 60;
 #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
-       conf->fullroamperiod = 120;\r
-#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */\r
-#ifdef CUSTOM_KEEP_ALIVE_SETTING\r
-       conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;\r
-#else\r
-       conf->keep_alive_period = 28000;\r
-#endif\r
-       conf->force_wme_ac = 0;\r
-       conf->stbc = -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->bcn_timeout = 15;\r
-       conf->spect = -1;\r
-       conf->txbf = -1;\r
-       conf->lpc = -1;\r
-       conf->disable_proptx = 1;\r
-       conf->ampdu_ba_wsize = 0;\r
-       conf->ampdu_hostreorder = -1;\r
-       conf->dpc_cpucore = -1;\r
-       conf->frameburst = -1;\r
-       conf->deepsleep = FALSE;\r
-       conf->pm = -1;\r
-       conf->pm_in_suspend = -1;\r
-       conf->pm2_sleep_ret = -1;\r
-       conf->num_different_channels = -1;\r
-       conf->pktprio8021x = -1;\r
-       conf->vhtmode = -1;\r
-\r
-       return 0;\r
-}\r
-\r
-int\r
-dhd_conf_reset(dhd_pub_t *dhd)\r
-{\r
-       memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
-       return 0;\r
-}\r
-\r
-int\r
-dhd_conf_attach(dhd_pub_t *dhd)\r
-{\r
-       dhd_conf_t *conf;\r
-\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-       if (dhd->conf != NULL) {\r
-               printf("%s: config is attached before!\n", __FUNCTION__);\r
-               return 0;\r
-       }\r
-       /* Allocate private bus interface state */\r
-       if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {\r
-               CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));\r
-               goto fail;\r
-       }\r
-       memset(conf, 0, sizeof(dhd_conf_t));\r
-\r
-       dhd->conf = conf;\r
-\r
-       return 0;\r
-\r
-fail:\r
-       if (conf != NULL)\r
-               MFREE(dhd->osh, conf, sizeof(dhd_conf_t));\r
-       return BCME_NOMEM;\r
-}\r
-\r
-void\r
-dhd_conf_detach(dhd_pub_t *dhd)\r
-{\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-       if (dhd->conf) {\r
-               MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
-       }\r
-       dhd->conf = NULL;\r
-}\r
+       conf->fullroamperiod = 120;
+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+#ifdef CUSTOM_KEEP_ALIVE_SETTING
+       conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;
+#else
+       conf->keep_alive_period = 28000;
+#endif
+       conf->force_wme_ac = 0;
+       conf->stbc = -1;
+#ifdef PKT_FILTER_SUPPORT
+       memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
+       memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
+       memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));
+#endif
+       conf->srl = -1;
+       conf->lrl = -1;
+       conf->bcn_timeout = 15;
+       conf->spect = -1;
+       conf->txbf = -1;
+       conf->lpc = -1;
+       conf->disable_proptx = -1;
+       conf->ampdu_ba_wsize = 0;
+       conf->ampdu_hostreorder = -1;
+       conf->dpc_cpucore = -1;
+       conf->frameburst = -1;
+       conf->deepsleep = FALSE;
+       conf->pm = -1;
+       conf->pm_in_suspend = -1;
+       conf->pm2_sleep_ret = -1;
+       conf->num_different_channels = -1;
+#ifdef IDHCPC
+       conf->dhcpc_enable = -1;
+#endif
+       conf->pktprio8021x = -1;
+       conf->vhtmode = -1;
+
+       return 0;
+}
+
+int
+dhd_conf_reset(dhd_pub_t *dhd)
+{
+       memset(dhd->conf, 0, sizeof(dhd_conf_t));
+       return 0;
+}
+
+int
+dhd_conf_attach(dhd_pub_t *dhd)
+{
+       dhd_conf_t *conf;
+
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+       if (dhd->conf != NULL) {
+               printf("%s: config is attached before!\n", __FUNCTION__);
+               return 0;
+       }
+       /* Allocate private bus interface state */
+       if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {
+               CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));
+               goto fail;
+       }
+       memset(conf, 0, sizeof(dhd_conf_t));
+
+       dhd->conf = conf;
+
+       return 0;
+
+fail:
+       if (conf != NULL)
+               MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
+       return BCME_NOMEM;
+}
+
+void
+dhd_conf_detach(dhd_pub_t *dhd)
+{
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+       if (dhd->conf) {
+               MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));
+       }
+       dhd->conf = NULL;
+}
index 26178debc76fcaa6b7aa2ad80bc523eee64d3fcc..e2e7f02f54a215eac8df7a8490942349edb7d85a 100644 (file)
-\r
-#ifndef _dhd_config_\r
-#define _dhd_config_\r
-\r
-#include <bcmdevs.h>\r
-#include <dngl_stats.h>\r
-#include <dhd.h>\r
-#include <wlioctl.h>\r
-#include <proto/802.11.h>\r
-\r
-#define FW_PATH_AUTO_SELECT 1\r
-extern char firmware_path[MOD_PARAM_PATHLEN];\r
-\r
-/* channel list */\r
-typedef struct wl_channel_list {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length channel list */\r
-       uint32 channel[WL_NUMCHANNELS];\r
-} wl_channel_list_t;\r
-\r
-typedef struct wmes_param {\r
-       int aifsn[AC_COUNT];\r
-       int ecwmin[AC_COUNT];\r
-       int ecwmax[AC_COUNT];\r
-       int txop[AC_COUNT];\r
-} wme_param_t;\r
-\r
-#ifdef PKT_FILTER_SUPPORT\r
-#define DHD_CONF_FILTER_MAX    8\r
-/* filter list */\r
-#define PKT_FILTER_LEN 300\r
-typedef struct conf_pkt_filter_add {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length filter list */\r
-       char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];\r
-} conf_pkt_filter_add_t;\r
-\r
-/* pkt_filter_del list */\r
-typedef struct conf_pkt_filter_del {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length filter list */\r
-       uint32 id[DHD_CONF_FILTER_MAX];\r
-} conf_pkt_filter_del_t;\r
-#endif\r
-\r
-#define CONFIG_COUNTRY_LIST_SIZE 100\r
-/* country list */\r
-typedef struct conf_country_list {\r
-       uint32 count;\r
-       wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];\r
-} conf_country_list_t;\r
-\r
-typedef struct dhd_conf {\r
+
+#ifndef _dhd_config_
+#define _dhd_config_
+
+#include <bcmdevs.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <wlioctl.h>
+#include <proto/802.11.h>
+
+#define FW_PATH_AUTO_SELECT 1
+extern char firmware_path[MOD_PARAM_PATHLEN];
+
+/* channel list */
+typedef struct wl_channel_list {
+       /* in - # of channels, out - # of entries */
+       uint32 count;
+       /* variable length channel list */
+       uint32 channel[WL_NUMCHANNELS];
+} wl_channel_list_t;
+
+typedef struct wmes_param {
+       int aifsn[AC_COUNT];
+       int ecwmin[AC_COUNT];
+       int ecwmax[AC_COUNT];
+       int txop[AC_COUNT];
+} wme_param_t;
+
+#ifdef PKT_FILTER_SUPPORT
+#define DHD_CONF_FILTER_MAX    8
+/* filter list */
+#define PKT_FILTER_LEN 300
+typedef struct conf_pkt_filter_add {
+       /* in - # of channels, out - # of entries */
+       uint32 count;
+       /* variable length filter list */
+       char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];
+} conf_pkt_filter_add_t;
+
+/* pkt_filter_del list */
+typedef struct conf_pkt_filter_del {
+       /* in - # of channels, out - # of entries */
+       uint32 count;
+       /* variable length filter list */
+       uint32 id[DHD_CONF_FILTER_MAX];
+} conf_pkt_filter_del_t;
+#endif
+
+#define CONFIG_COUNTRY_LIST_SIZE 100
+/* country list */
+typedef struct conf_country_list {
+       uint32 count;
+       wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];
+} conf_country_list_t;
+
+typedef struct dhd_conf {
        uint    chip;                   /* chip number */
-       uint    chiprev;                /* chip revision */\r
-       conf_country_list_t country_list; /* Country list */\r
-       int band;                       /* Band, b:2.4G only, otherwise for auto */\r
-       int mimo_bw_cap;                        /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */\r
-       int bw_cap_2g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */\r
-       int bw_cap_5g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */\r
-       wl_country_t cspec;             /* Country */\r
-       wl_channel_list_t channels;     /* Support channels */\r
-       uint roam_off;          /* Roaming, 0:enable, 1:disable */\r
-       uint roam_off_suspend;          /* Roaming in suspend, 0:enable, 1:disable */\r
-       int roam_trigger[2];            /* The RSSI threshold to trigger roaming */\r
-       int roam_scan_period[2];        /* Roaming scan period */\r
-       int roam_delta[2];                      /* Roaming candidate qualification delta */\r
-       int fullroamperiod;                     /* Full Roaming period */\r
-       uint keep_alive_period;         /* The perioid in ms to send keep alive packet */\r
-       int force_wme_ac;\r
-       wme_param_t wme;        /* WME parameters */\r
-       int stbc;                       /* STBC for Tx/Rx */\r
-#ifdef PKT_FILTER_SUPPORT\r
-       conf_pkt_filter_add_t pkt_filter_add;           /* Packet filter add */\r
-       conf_pkt_filter_del_t pkt_filter_del;           /* Packet filter add */\r
-       conf_pkt_filter_add_t magic_pkt_filter_add;             /* Magic Packet filter add */\r
-#endif\r
-       int srl;        /* short retry limit */\r
-       int lrl;        /* long retry limit */\r
-       uint bcn_timeout;       /* beacon timeout */\r
-       int spect;\r
-       int txbf;\r
-       int lpc;\r
-       int disable_proptx;\r
-       int ampdu_ba_wsize;\r
-       int ampdu_hostreorder;\r
-       int dpc_cpucore;\r
-       int frameburst;\r
-       bool deepsleep;\r
-       int pm;\r
-       int pm_in_suspend;\r
-       int pm2_sleep_ret;\r
-       int pktprio8021x;\r
-       int vhtmode;\r
-       int num_different_channels;\r
-#ifdef IAPSTA_PREINIT\r
-       char iapsta_init[50];\r
-       char iapsta_config[300];\r
-       char iapsta_enable[50];\r
-#endif\r
-} dhd_conf_t;\r
-\r
-void dhd_conf_set_conf_path_by_fw_path(dhd_pub_t *dhd, char *conf_path, char *fw_path);\r
-int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down);\r
-int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx);\r
-uint dhd_conf_get_band(dhd_pub_t *dhd);\r
-int dhd_conf_set_country(dhd_pub_t *dhd);\r
-int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);\r
-int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);\r
-int dhd_conf_fix_country(dhd_pub_t *dhd);\r
-bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);\r
-int dhd_conf_set_roam(dhd_pub_t *dhd);\r
-void dhd_conf_set_bw_cap(dhd_pub_t *dhd);\r
-void dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp);\r
-void dhd_conf_set_wme(dhd_pub_t *dhd);\r
-void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);\r
-bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);\r
-void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);\r
-int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);\r
-int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);\r
-uint dhd_conf_get_chiprev(void *context);\r
-int dhd_conf_get_pm(dhd_pub_t *dhd);\r
-int dhd_conf_preinit(dhd_pub_t *dhd);\r
-int dhd_conf_reset(dhd_pub_t *dhd);\r
-int dhd_conf_attach(dhd_pub_t *dhd);\r
-void dhd_conf_detach(dhd_pub_t *dhd);\r
-void *dhd_get_pub(struct net_device *dev);\r
-void *dhd_get_conf(struct net_device *dev);\r
-#endif /* _dhd_config_ */\r
+       uint    chiprev;                /* chip revision */
+       conf_country_list_t country_list; /* Country list */
+       int band;                       /* Band, b:2.4G only, otherwise for auto */
+       int mimo_bw_cap;                        /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */
+       int bw_cap_2g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */
+       int bw_cap_5g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */
+       wl_country_t cspec;             /* Country */
+       wl_channel_list_t channels;     /* Support channels */
+       uint roam_off;          /* Roaming, 0:enable, 1:disable */
+       uint roam_off_suspend;          /* Roaming in suspend, 0:enable, 1:disable */
+       int roam_trigger[2];            /* The RSSI threshold to trigger roaming */
+       int roam_scan_period[2];        /* Roaming scan period */
+       int roam_delta[2];                      /* Roaming candidate qualification delta */
+       int fullroamperiod;                     /* Full Roaming period */
+       uint keep_alive_period;         /* The perioid in ms to send keep alive packet */
+       int force_wme_ac;
+       wme_param_t wme;        /* WME parameters */
+       int stbc;                       /* STBC for Tx/Rx */
+#ifdef PKT_FILTER_SUPPORT
+       conf_pkt_filter_add_t pkt_filter_add;           /* Packet filter add */
+       conf_pkt_filter_del_t pkt_filter_del;           /* Packet filter add */
+       conf_pkt_filter_add_t magic_pkt_filter_add;             /* Magic Packet filter add */
+#endif
+       int srl;        /* short retry limit */
+       int lrl;        /* long retry limit */
+       uint bcn_timeout;       /* beacon timeout */
+       int spect;
+       int txbf;
+       int lpc;
+       int disable_proptx;
+       int ampdu_ba_wsize;
+       int ampdu_hostreorder;
+       int dpc_cpucore;
+       int frameburst;
+       bool deepsleep;
+       int pm;
+       int pm_in_suspend;
+       int pm2_sleep_ret;
+       int pktprio8021x;
+       int vhtmode;
+       int num_different_channels;
+#ifdef IDHCPC
+       int dhcpc_enable;
+#endif
+#ifdef IAPSTA_PREINIT
+       char iapsta_init[50];
+       char iapsta_config[300];
+       char iapsta_enable[50];
+#endif
+} dhd_conf_t;
+
+void dhd_conf_set_conf_path_by_fw_path(dhd_pub_t *dhd, char *conf_path, char *fw_path);
+int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down);
+int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx);
+uint dhd_conf_get_band(dhd_pub_t *dhd);
+int dhd_conf_set_country(dhd_pub_t *dhd);
+int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);
+int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);
+int dhd_conf_fix_country(dhd_pub_t *dhd);
+bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);
+int dhd_conf_set_roam(dhd_pub_t *dhd);
+void dhd_conf_set_bw_cap(dhd_pub_t *dhd);
+void dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp);
+void dhd_conf_set_wme(dhd_pub_t *dhd);
+void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);
+bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);
+void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);
+int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);
+int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
+uint dhd_conf_get_chip(void *context);
+uint dhd_conf_get_chiprev(void *context);
+int dhd_conf_get_pm(dhd_pub_t *dhd);
+#ifdef PROP_TXSTATUS
+int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
+#endif
+int dhd_conf_preinit(dhd_pub_t *dhd);
+int dhd_conf_reset(dhd_pub_t *dhd);
+int dhd_conf_attach(dhd_pub_t *dhd);
+void dhd_conf_detach(dhd_pub_t *dhd);
+void *dhd_get_pub(struct net_device *dev);
+void *dhd_get_conf(struct net_device *dev);
+#endif /* _dhd_config_ */
index e7071448d08cfa26cced5fc5c22d699f04448fa5..78c80c5b20ec525ed3745ea7561eb7a8b84e3601 100644 (file)
@@ -437,6 +437,7 @@ dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
 {
        void *buf;
        unsigned long flags;
+
 #ifdef CONFIG_DHD_USE_STATIC_BUF
        buf = dhd_wlan_mem_prealloc(section, ring_sz);
 #else
@@ -485,6 +486,7 @@ dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
        dhd_os_spin_unlock(ring->lock, flags);
 
        dhd_os_spin_lock_deinit(dhdp->osh, ring->lock);
+
 #ifndef CONFIG_DHD_USE_STATIC_BUF
        MFREE(dhdp->osh, buf, ring_sz);
 #endif
index 64d3aa26bd39088abb928b68a91232595b8a8d57..0b734f5200edddc40588fa6baa1322c6d5ad6562 100644 (file)
@@ -7208,8 +7208,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(BCMDBUS)
 #ifdef PROP_TXSTATUS
        int wlfc_enable = TRUE;
-       /* terence 20161229: we should set ampdu_hostreorder=0 if proptx not support in fw */
-       uint32 fw_caps;
 #ifndef DISABLE_11N
        uint32 hostreorder = 1;
        uint wl_down = 1;
@@ -7616,8 +7614,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "stbc_rx", dhd->conf->stbc, 0, FALSE);
        dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", dhd->conf->srl, 0, TRUE);
        dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", dhd->conf->lrl, 0, FALSE);
-       dhd_conf_set_intiovar(dhd, WLC_SET_SPECT_MANAGMENT, "WLC_SET_SPECT_MANAGMENT", dhd->conf->spect, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_SPECT_MANAGMENT, "WLC_SET_SPECT_MANAGMENT", dhd->conf->spect, 0, TRUE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "vhtmode", dhd->conf->vhtmode, 0, TRUE);
+#ifdef IDHCPC
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpc_enable", dhd->conf->dhcpc_enable, 0, FALSE);
+#endif
        dhd_conf_set_bw_cap(dhd);
 
 #if defined(OEM_ANDROID) && defined(SOFTAP)
@@ -8031,16 +8032,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 
 #if defined(BCMDBUS)
 #ifdef PROP_TXSTATUS
-       /* terence 20161229: we should set ampdu_hostreorder=0 if proptx not support in fw or disabled */
-       ret = dhd_conf_get_iovar(dhd, WLC_GET_VAR, "wlfc_mode", (char *)&fw_caps, sizeof(fw_caps), 0);
-       ret = 0; // terence 20161229: for short term fix for some old chip not support wlfc_mode, but proptxstatus supported
-       if (ret || dhd->conf->disable_proptx) {
-               printf("%s: set disable_proptx=1 and ampdu_hostreorder=0\n", __FUNCTION__);
-               disable_proptx = 1;
-#ifndef DISABLE_11N
-               hostreorder = 0;
-#endif
-       }
        if (disable_proptx ||
 #ifdef PROP_TXSTATUS_VSDB
                /* enable WLFC only if the firmware is VSDB when it is in STA mode */
@@ -8050,6 +8041,16 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                FALSE) {
                wlfc_enable = FALSE;
        }
+       ret = dhd_conf_get_disable_proptx(dhd);
+       if (ret == 0){
+               disable_proptx = 0;
+               wlfc_enable = TRUE;
+       } else if (ret >= 1) {
+               disable_proptx = 1;
+               wlfc_enable = FALSE;
+               /* terence 20161229: we should set ampdu_hostreorder=0 when disalbe_proptx=1 */
+               hostreorder = 0;
+       }
 
 #if defined(PROP_TXSTATUS)
 #endif /* PROP_TXSTATUS */
@@ -8070,8 +8071,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_preinit_config(dhd, 0);
 #endif /* READ_CONFIG_FROM_FILE */
 
-       if (wlfc_enable)
+       if (wlfc_enable) {
                dhd_wlfc_init(dhd);
+               /* terence 20161229: enable ampdu_hostreorder if tlv enabled */
+               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);
+       }
 #ifndef DISABLE_11N
        else if (hostreorder)
                dhd_wlfc_hostreorder_init(dhd);
index 33a3aab27c8e135309c19fccfb7c034919b3db11..b0419554eb55cab2b4a533773eef4f02ce3bf680 100644 (file)
@@ -3523,8 +3523,6 @@ dhd_wlfc_init(dhd_pub_t *dhd)
                */
                DHD_ERROR(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
                        dhd->wlfc_enabled?"enabled":"disabled", tlv));
-               /* terence 20161229: enable ampdu_hostreorder if tlv enable hostreorder */
-               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);
        }
 
        mode = 0;
index 1a45fb31bef49e44a1b886a356f16b526571e647..1f8ea6f411ee2c96bee91ee55b7aabc873316d4c 100644 (file)
@@ -115,6 +115,7 @@ MAKE_PREFETCH_RANGE_FN(PREF_STORE_RETAINED)
 #ifdef CONFIG_DHD_USE_STATIC_BUF
 void* dhd_wlan_mem_prealloc(int section, unsigned long size);
 #endif
+
 #if !defined(OSL_SYSUPTIME)
 #define OSL_SYSUPTIME() (0)
 #define OSL_SYSUPTIME_SUPPORT FALSE
index d35b4fbb4b3fda0d12059960756130e50a90b793..efb84df585ca57b6939304d3623e398f45aab05b 100644 (file)
@@ -33,6 +33,7 @@
 #include <bcmendian.h>
 #include <linuxver.h>
 #include <bcmdefs.h>
+
 #ifdef mips
 #include <asm/paccess.h>
 #include <asm/cache.h>
index 284dd1aacfcb46e5a37eba17cacb428c05e40f05..2fc0d03e498d30b6a115d1d0dea647ff12c1bf1d 100644 (file)
 #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_GET_CHANNEL                        "GET_CHANNEL"\r
-#define CMD_SET_CHANNEL                        "SET_CHANNEL"\r
-#define CMD_SET_ROAM                   "SET_ROAM_TRIGGER"\r
-#define CMD_GET_ROAM                   "GET_ROAM_TRIGGER"\r
-#define CMD_GET_KEEP_ALIVE             "GET_KEEP_ALIVE"\r
-#define CMD_GET_PM                             "GET_PM"\r
-#define CMD_SET_PM                             "SET_PM"\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
 #define CMD_IAPSTA_CONFIG              "IAPSTA_CONFIG"\r
 #define CMD_IAPSTA_ENABLE              "IAPSTA_ENABLE"\r
 #define CMD_IAPSTA_DISABLE             "IAPSTA_DISABLE"\r
-\r
-#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))\r
 #endif\r
-#ifdef WL_EXT_DHCPC\r
+#ifdef IDHCPC\r
 #define CMD_DHCPC_ENABLE       "DHCPC_ENABLE"\r
 #define CMD_DHCPC_DUMP         "DHCPC_DUMP"\r
 #endif\r
@@ -79,7 +76,18 @@ int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)
        return ret;\r
 }\r
 \r
-#ifdef WL_EXT_IAPSTA\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
@@ -92,6 +100,7 @@ int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,
        return ret;\r
 }\r
 \r
+#ifdef WL_EXT_IAPSTA\r
 int wl_ext_iovar_setint_bsscfg(struct net_device *dev, s8 *iovar,\r
        s32 val, s32 bssidx)\r
 {\r
@@ -216,30 +225,10 @@ wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)
                return BCME_VERSION;\r
        }\r
        *ioctl_ver = val;\r
-       printf("%s: ioctl_ver=%d\n", __FUNCTION__, val);\r
 \r
        return ret;\r
 }\r
 \r
-int\r
-wl_ext_get_channel(\r
-struct net_device *dev, char* command, int total_len)\r
-{\r
-       int ret;\r
-       channel_info_t ci;\r
-       int bytes_written = 0;\r
-\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
-       }\r
-\r
-       return bytes_written;\r
-}\r
-\r
 static int\r
 wl_ext_set_chanspec(struct net_device *dev, uint16 channel)\r
 {\r
@@ -328,163 +317,246 @@ change_bw:
 }\r
 \r
 int\r
-wl_ext_set_channel(\r
-struct net_device *dev, char* command, int total_len)\r
+wl_ext_channel(struct net_device *dev, char* command, int total_len)\r
 {\r
        int ret;\r
-       int channel;\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
-       ret = wl_ext_set_chanspec(dev, channel);\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_set_roam_trigger(\r
-struct net_device *dev, char* command, int total_len)\r
+wl_ext_channels(struct net_device *dev, char* command, int total_len)\r
 {\r
-       int ret = 0;\r
-       int roam_trigger[2];\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
-       sscanf(command, "%*s %10d", &roam_trigger[0]);\r
-       roam_trigger[1] = WLC_BAND_ALL;\r
+       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
 \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
+       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_get_roam_trigger(\r
-struct net_device *dev, char *command, int total_len)\r
+wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)\r
 {\r
-       int ret;\r
-       int bytes_written;\r
+       int ret = 0;\r
        int roam_trigger[2] = {0, 0};\r
        int trigger[2]= {0, 0};\r
+       int bytes_written=-1;\r
 \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
+       sscanf(command, "%*s %10d", &roam_trigger[0]);\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
+       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
-       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
+               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
-       return bytes_written;\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
-s32\r
-wl_ext_get_keep_alive(struct net_device *dev, char *command, int total_len) {\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
-       int res = -1, len, i = 0;\r
-       char* str = "mkeep_alive";\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
-       len = WLC_IOCTL_MEDLEN;\r
-       mkeep_alive_pktp = kmalloc(len, GFP_KERNEL);\r
-       memset(mkeep_alive_pktp, 0, len);\r
-       strcpy((char*)mkeep_alive_pktp, str);\r
-\r
-       if ((res = wldev_ioctl(dev, WLC_GET_VAR, mkeep_alive_pktp, len, FALSE))<0) {\r
-               ANDROID_ERROR(("%s: GET mkeep_alive ERROR %d\n", __FUNCTION__, res));\r
-               goto exit;\r
+               ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,\r
+                       iovar_buf, sizeof(iovar_buf), NULL);\r
        } else {\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
+               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
-                       printf("%02x", mkeep_alive_pktp->data[i]);\r
+                       bytes_written += snprintf(command+bytes_written, total_len, "%x", 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
+               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
+               ret = bytes_written;\r
        }\r
-       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-\r
+       \r
 exit:\r
-       kfree(mkeep_alive_pktp);\r
-       return bytes_written;\r
+       return ret;\r
 }\r
 \r
 int\r
-wl_ext_set_pm(struct net_device *dev, char *command, int total_len)\r
+wl_ext_pm(struct net_device *dev, char *command, int total_len)\r
 {\r
-       int pm, ret = -1;\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
-       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
+       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
-int\r
-wl_ext_get_pm(struct net_device *dev, char *command, int total_len)\r
+static int\r
+wl_ext_monitor(struct net_device *dev, char *command, int total_len)\r
 {\r
-\r
-       int ret = 0;\r
-       int pm_local;\r
-       char *pm;\r
+       int val, ret = -1;\r
        int bytes_written=-1;\r
 \r
-       ret = wldev_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local), FALSE);\r
-       if (!ret) {\r
-               ANDROID_TRACE(("%s: PM = %d\n", __func__, pm_local));\r
-               if (pm_local == PM_OFF)\r
-                       pm = "PM_OFF";\r
-               else if(pm_local == PM_MAX)\r
-                       pm = "PM_MAX";\r
-               else if(pm_local == PM_FAST)\r
-                       pm = "PM_FAST";\r
-               else {\r
-                       pm_local = 0;\r
-                       pm = "Invalid";\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
-               bytes_written = snprintf(command, total_len, "PM %s", pm);\r
-               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
        }\r
-       return bytes_written;\r
-}\r
-\r
-static int\r
-wl_ext_set_monitor(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int val, ret = -1;\r
 \r
-       sscanf(command, "%*s %d", &val);\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
        return ret;\r
 }\r
 \r
@@ -568,31 +640,31 @@ wl_ext_set_bgnmode(struct wl_if_info *cur_if)
                wl_ext_iovar_setint(dev, "nmode", 0);\r
                val = 0;\r
                wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               printf("%s: Network mode: B only\n", __FUNCTION__);\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
-               printf("%s: Network mode: G only\n", __FUNCTION__);\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
-               printf("%s: Network mode: : B/G mixed\n", __FUNCTION__);\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
-               printf("%s: Network mode: : B/G/N mixed\n", __FUNCTION__);\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
-               printf("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__);\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
@@ -610,33 +682,41 @@ wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params
                auth = 0;\r
                sup_wpa = 0;\r
                wpa_auth = 0;\r
-               printf("%s: Authentication: Open System\n", __FUNCTION__);\r
+               ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));\r
        } else if (amode == AUTH_SHARED) {\r
                sup_wpa = 1;\r
                auth = 1;\r
                wpa_auth = 0;\r
-               printf("%s: Authentication: Shared Key\n", __FUNCTION__);\r
+               ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));\r
        } else if (amode == AUTH_WPAPSK) {\r
                sup_wpa = 1;\r
                auth = 0;\r
                wpa_auth = 4;\r
-               printf("%s: Authentication: WPA-PSK\n", __FUNCTION__);\r
+               ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));\r
        } else if (amode == AUTH_WPA2PSK) {\r
                sup_wpa = 1;\r
                auth = 0;\r
                wpa_auth = 128;\r
-               printf("%s: Authentication: WPA2-PSK\n", __FUNCTION__);\r
+               ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));\r
        } else if (amode == AUTH_WPAWPA2PSK) {\r
                sup_wpa = 1;\r
                auth = 0;\r
                wpa_auth = 132;\r
-               printf("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__);\r
+               ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));\r
        }\r
-       wl_ext_iovar_setint_bsscfg(dev, "auth", auth, cur_if->bssidx);\r
+       if (apsta_params->apstamode == IDUALAP_MODE)\r
+               wl_ext_iovar_setint(dev, "auth", auth);\r
+       else\r
+               wl_ext_iovar_setint_bsscfg(dev, "auth", auth, cur_if->bssidx);\r
 \r
        if (apsta_params->apstamode == IAP_MODE) // fix for 43455\r
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-       wl_ext_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, cur_if->bssidx);\r
+\r
+       if (apsta_params->apstamode == IDUALAP_MODE)\r
+               wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);\r
+       else\r
+               wl_ext_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, cur_if->bssidx);\r
+\r
        if (apsta_params->apstamode == IAP_MODE) // fix for 43455\r
                wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);;\r
 \r
@@ -655,48 +735,64 @@ wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params
        wsec_pmk_t psk;\r
        encmode_t emode = cur_if->emode;\r
        char *key = cur_if->key;\r
-       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
 \r
        memset(&wsec_key, 0, sizeof(wsec_key));\r
        memset(&psk, 0, sizeof(psk));\r
        if (emode == ENC_NONE) {\r
                wsec = 0;\r
-               printf("%s: Encryption: No securiy\n", __FUNCTION__);\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
-               printf("%s: Encryption: WEP\n", __FUNCTION__);\r
-               printf("%s: Key: %s\n", __FUNCTION__, wsec_key.data);\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
-               printf("%s: Encryption: TKIP\n", __FUNCTION__);\r
-               printf("%s: Key: %s\n", __FUNCTION__, psk.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
-               printf("%s: Encryption: AES\n", __FUNCTION__);\r
-               printf("%s: Key: %s\n", __FUNCTION__, psk.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
-               printf("%s: Encryption: TKIP/AES\n", __FUNCTION__);\r
-               printf("%s: Key: %s\n", __FUNCTION__, psk.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_bsscfg(dev, "wsec", wsec, cur_if->bssidx);\r
+       if (apsta_params->apstamode == IDUALAP_MODE)\r
+               wl_ext_iovar_setint(dev, "wsec", wsec);\r
+       else\r
+               wl_ext_iovar_setint_bsscfg(dev, "wsec", wsec, cur_if->bssidx);\r
 \r
        if (wsec == 1) {\r
-               wl_ext_iovar_setbuf_bsscfg(dev, "wsec_key", &wsec_key, sizeof(wsec_key),\r
-                       iovar_buf, WLC_IOCTL_MAXLEN, cur_if->bssidx, NULL);\r
+               /* 43438a1: wl0: Feb 23 2017 11:24:58 version 7.46.57.8 (r1174) FWID 01-62ddbfa1\r
+                 * sta wlan0 TBD\r
+                 * ap wlan0 OK\r
+                 * apsta wlan0 TBD, wlan1 OK\r
+                 */\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
+                       /* 43438a1: wl0: Feb 23 2017 11:24:58 version 7.46.57.8 (r1174) FWID 01-62ddbfa1\r
+                         * sta wlan0 OK\r
+                         * ap wlan0 OK\r
+                         * apsta wlan0 NG, wlan1 NG(condigured ok, ping NG, same as dhd_helper)\r
+                         */\r
+                       /* 4359c0: wl0: Mar  6 2017 10:16:06 version 9.87.51.7 (r686312) FWID 01-4dcc75d9\r
+                         * sta wlan0 OK\r
+                         * ap wlan0 OK, but wl rate only 433Mbps\r
+                         * dualap: wlan0 and wlan1 ok\r
+                         */\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
@@ -727,7 +823,7 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
        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_conf *conf;\r
+       struct dhd_pub *dhd;\r
 \r
        if (apsta_params->action >= ACTION_INIT) {\r
                ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));\r
@@ -736,7 +832,7 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
 \r
        memset(apsta_params, 0, sizeof(struct wl_apsta_params));\r
 \r
-       printf("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len);\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
@@ -770,6 +866,11 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
                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
@@ -783,19 +884,8 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
 \r
        if (apsta_params->apstamode == ISTA_MODE) {\r
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 0);\r
-               val = 0;\r
-               wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);\r
-               // bcn_timeout is reset to 8 in WLC_SET_AP\r
-               conf = dhd_get_conf(dev);\r
-               if (conf) {\r
-                       wl_ext_iovar_setint(dev, "bcn_timeout", conf->bcn_timeout);\r
-                       if (conf->pm >= 0)\r
-                               val = conf->pm;\r
-                       else\r
-                               val = PM_FAST;\r
-                       wl_ext_ioctl(dev, WLC_SET_PM, &val, sizeof(val), 1);\r
-               }\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 == IAP_MODE) {\r
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
@@ -807,14 +897,29 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
                wl_ext_iovar_setint(dev, "mpc", 0);\r
                val = 0;\r
                wl_ext_ioctl(dev, WLC_SET_PM, &val, sizeof(val), 1);\r
-               wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,\r
-                       WLC_IOCTL_SMLEN, 1, NULL);\r
+               dhd = dhd_get_pub(dev);\r
+               if (FW_SUPPORTED(dhd, rsdb)) {\r
+                       /* IF SoftAP is enabled, disable arpoe or wlan1 ping fail */\r
+                       wl_ext_iovar_setint(dev, "arp_ol", 0);\r
+                       wl_ext_iovar_setint(dev, "arpoe", 0);\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
        } else if (apsta_params->apstamode == IDUALAP_MODE) {\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 ping fail */\r
+               wl_ext_iovar_setint(dev, "arp_ol", 0);\r
+               wl_ext_iovar_setint(dev, "arpoe", 0);\r
                bzero(&iface, sizeof(wl_interface_create_t));\r
                iface.ver = WL_INTERFACE_CREATE_VER;\r
                iface.flags = WL_INTERFACE_CREATE_AP;\r
@@ -824,6 +929,7 @@ wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
 \r
        apsta_params->action = ACTION_INIT;\r
        ret = wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);\r
+       printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);\r
 \r
        return ret;\r
 }\r
@@ -842,7 +948,7 @@ wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)
                return -1;\r
        }\r
 \r
-       printf("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len);\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
@@ -861,13 +967,14 @@ wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)
        }\r
        if (!strcmp(apsta_params->pif.dev->name, ifname) &&\r
                        (apsta_params->apstamode == ISTA_MODE || apsta_params->apstamode == IAP_MODE ||\r
-                       apsta_params->apstamode == IDUALAP_MODE)) {\r
+                       apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->pif;\r
        } else if (!strcmp(apsta_params->vif.ifname, ifname) &&\r
                        (apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->vif;\r
        } else {\r
-               printf("%s: wrong ifname=%s for apstamode=%d\n", __FUNCTION__, ifname, apsta_params->apstamode);\r
+               ANDROID_ERROR(("%s: wrong ifname=%s for apstamode=%d\n", __FUNCTION__,\r
+                       ifname, apsta_params->apstamode));\r
                return -1;\r
        }\r
 \r
@@ -977,19 +1084,21 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
        char *pch, *pick_tmp, *param;\r
        s8 iovar_buf[WLC_IOCTL_SMLEN];\r
        struct {
+               s32 tmp;\r
                s32 cfg;
                s32 val;
        } bss_setbuf;\r
        struct wl_apsta_params *apsta_params = &g_apsta_params;\r
        char ifname[IFNAMSIZ+1];\r
        struct wl_if_info *cur_if;\r
+       struct dhd_pub *dhd;\r
 \r
        if (apsta_params->action < ACTION_INIT) {\r
                ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
                return -1;\r
        }\r
 \r
-       printf("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len);\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_disable\r
@@ -1008,13 +1117,13 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
        }\r
        if (!strcmp(apsta_params->pif.dev->name, ifname) &&\r
                        (apsta_params->apstamode == ISTA_MODE || apsta_params->apstamode == IAP_MODE ||\r
-                       apsta_params->apstamode == IDUALAP_MODE)) {\r
+                       apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->pif;\r
        } else if (!strcmp(apsta_params->vif.ifname, ifname) &&\r
                        (apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->vif;\r
        } else {\r
-               printf("%s: wrong ifname=%s\n", __FUNCTION__, ifname);\r
+               ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
                return -1;\r
        }\r
 \r
@@ -1024,19 +1133,36 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
                wl_ext_iovar_setint(dev, "mpc", 1);\r
        } else if (apsta_params->apstamode == IAPSTA_MODE) {\r
-               bss_setbuf.cfg = htod32(cur_if->bssidx);\r
-               bss_setbuf.val = htod32(0);\r
-               wl_ext_iovar_setbuf(dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-               wl_ext_iovar_setint(dev, "mpc", 1);\r
+               if (cur_if == &apsta_params->pif) {\r
+                       // pif is STA mode\r
+                       wl_ext_ioctl(dev, WLC_DISASSOC, NULL, 0, 1);\r
+               } else {\r
+                       // vif is AP mode\r
+                       dhd = dhd_get_pub(dev);\r
+                       if (FW_SUPPORTED(dhd, rsdb)) {\r
+                               bss_setbuf.tmp = 0xffffffff; // must be 0, or wlan1 can not be down\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
+                       } else {\r
+                               bss_setbuf.cfg = htod32(cur_if->bssidx);\r
+                               bss_setbuf.val = htod32(0);\r
+                               wl_ext_iovar_setbuf(dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
+                                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
+                       }\r
+                       wl_ext_iovar_setint(dev, "mpc", 1);\r
+               }\r
        } else if (apsta_params->apstamode == IDUALAP_MODE) {\r
-               bss_setbuf.cfg = cur_if->bssidx;\r
+               bss_setbuf.tmp = 0xffffffff; // must be 0, or wlan1 can not be down\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
        apsta_params->action = ACTION_DISABLE;\r
+       printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apsta_params->apstamode, ifname);\r
 \r
        return ret;\r
 }\r
@@ -1058,13 +1184,14 @@ wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
        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->action < ACTION_INIT) {\r
                ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
                return -1;\r
        }\r
 \r
-       printf("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len);\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_enable\r
@@ -1083,19 +1210,19 @@ wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
        }\r
        if (!strcmp(apsta_params->pif.dev->name, ifname) &&\r
                        (apsta_params->apstamode == ISTA_MODE || apsta_params->apstamode == IAP_MODE ||\r
-                       apsta_params->apstamode == IDUALAP_MODE)) {\r
+                       apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->pif;\r
        } else if (!strcmp(apsta_params->vif.ifname, ifname) &&\r
                        (apsta_params->apstamode == IAPSTA_MODE || apsta_params->apstamode == IDUALAP_MODE)) {\r
                cur_if = &apsta_params->vif;\r
        } else {\r
-               printf("%s: wrong ifname=%s\n", __FUNCTION__, ifname);\r
+               ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
                return -1;\r
        }\r
 \r
        ssid.SSID_len = strlen(cur_if->ssid);\r
        memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);\r
-       printf("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx);\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
@@ -1156,14 +1283,25 @@ wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
                wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
                wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
        } else if (apstamode == IAPSTA_MODE) {\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
+               if (cur_if == &apsta_params->pif) {\r
+                       // pif is STA mode\r
+                       wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
+               } else {\r
+                       // vif is AP mode\r
+                       dhd = dhd_get_pub(dev);\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
+               }\r
        } else if (apstamode == IDUALAP_MODE) {\r
                wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
        }\r
-       printf("%s: SSID: %s\n", __FUNCTION__, cur_if->ssid);\r
+       printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid);\r
 \r
 exit:\r
        return ret;\r
@@ -1190,14 +1328,14 @@ int wl_android_ext_dettach_netdev(void)
 {\r
        struct wl_apsta_params *apsta_params = &g_apsta_params;\r
 \r
-       printf("%s: Enter\n", __FUNCTION__);\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 WL_EXT_DHCPC\r
+#ifdef IDHCPC\r
 int wl_ext_ip_dump(int ip, char *buf)\r
 {\r
        unsigned char bytes[4];\r
@@ -1287,30 +1425,23 @@ int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len
 {\r
        int ret = 0;\r
 \r
-       if(strnicmp(command, CMD_GET_CHANNEL, strlen(CMD_GET_CHANNEL)) == 0) {\r
-               *bytes_written = wl_ext_get_channel(net, command, total_len);\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_SET_CHANNEL, strlen(CMD_SET_CHANNEL)) == 0) {\r
-               *bytes_written = wl_ext_set_channel(net, command, total_len);\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_SET_ROAM, strlen(CMD_SET_ROAM)) == 0) {
-               *bytes_written = wl_ext_set_roam_trigger(net, command, total_len);\r
-       }
-       else if (strnicmp(command, CMD_GET_ROAM, strlen(CMD_GET_ROAM)) == 0) {
-               *bytes_written = wl_ext_get_roam_trigger(net, command, total_len);\r
-       }
-       else if (strnicmp(command, CMD_GET_KEEP_ALIVE, strlen(CMD_GET_KEEP_ALIVE)) == 0) {
-               int skip = strlen(CMD_GET_KEEP_ALIVE) + 1;
-               *bytes_written = wl_ext_get_keep_alive(net, command+skip, total_len-skip);\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_GET_PM, strlen(CMD_GET_PM)) == 0) {
-               *bytes_written = wl_ext_get_pm(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_SET_PM, strlen(CMD_SET_PM)) == 0) {
-               *bytes_written = wl_ext_set_pm(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
        else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) {
-               *bytes_written = wl_ext_set_monitor(net, command, total_len);\r
+               *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
@@ -1331,7 +1462,7 @@ int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len
                *bytes_written = wl_ext_iapsta_disable(net, command, total_len);\r
        }\r
 #endif\r
-#ifdef WL_EXT_DHCPC\r
+#ifdef IDHCPC\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
index 882e5d668da41024f32ae34fdc6959c46730e11b..1f4433216855eb2ba625797ef50826b399255960 100644 (file)
@@ -9613,6 +9613,9 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
                brcm_wowlan_config->patterns = NULL;
                brcm_wowlan_config->n_patterns = 0;
                brcm_wowlan_config->tcp = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+               brcm_wowlan_config->nd_config = NULL;
+#endif
        } else {
                WL_ERR(("Can not allocate memory for brcm_wowlan_config,"
                                        " So wiphy->wowlan_config is set to NULL\n"));
@@ -9677,7 +9680,6 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg)
                /* Reset wowlan & wowlan_config before Unregister to avoid  Kernel Panic */
                WL_DBG(("wl_free_wdev Clearing wowlan Config \n"));
                wdev->wiphy->wowlan = NULL;
-               wdev->wiphy->wowlan_config = NULL;
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */
 #endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */
                wiphy_unregister(wdev->wiphy);
@@ -12053,24 +12055,22 @@ static void wl_deinit_priv_mem(struct bcm_cfg80211 *cfg)
 static s32 wl_create_event_handler(struct bcm_cfg80211 *cfg)
 {
        int ret = 0;
+       WL_DBG(("Enter \n"));
 
        /* Do not use DHD in cfg driver */
-       if (!cfg->event_tsk.thr_pid) {
-               WL_DBG(("Enter \n"));
-               cfg->event_tsk.thr_pid = -1;
+
+       if (cfg->event_tsk.thr_pid < 0) {
                PROC_START(wl_event_handler, cfg, &cfg->event_tsk, 0, "wl_event_handler");
+               if (cfg->event_tsk.thr_pid < 0)
+                       ret = -ENOMEM;
        }
-       if (cfg->event_tsk.thr_pid < 0)
-               ret = -ENOMEM;
        return ret;
 }
 
 static void wl_destroy_event_handler(struct bcm_cfg80211 *cfg)
 {
-       if (cfg->event_tsk.thr_pid >= 0) {
-               WL_DBG(("Enter \n"));
+       if (cfg->event_tsk.thr_pid >= 0)
                PROC_STOP(&cfg->event_tsk);
-       }
 }
 
 void wl_terminate_event_handler(void)
@@ -13179,6 +13179,7 @@ static s32 wl_init_priv(struct bcm_cfg80211 *cfg)
        err = wl_init_priv_mem(cfg);
        if (err)
                return err;
+       cfg->event_tsk.thr_pid = -1;
        if (wl_create_event_handler(cfg))
                return -ENOMEM;
        wl_init_event_handler(cfg);
@@ -16255,6 +16256,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
        s32 ret = BCME_ERROR;
        int chosen = 0;
        int retry = 0;
+       uint chip;
 
        /* Start auto channel selection scan. */
        ret = wldev_ioctl(ndev, WLC_START_CHANNEL_SEL, buf, buflen, true);
@@ -16273,7 +16275,17 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
                ret = wldev_ioctl(ndev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen),
                        false);
                if ((ret == 0) && (dtoh32(chosen) != 0)) {
-                       *channel = (u16)(chosen & 0x00FF);
+                       chip = dhd_conf_get_chip(dhd_get_pub(ndev));
+                       if (chip != BCM43143_CHIP_ID) {
+                               u32 chanspec = 0;
+                               int ctl_chan;
+                               chanspec = wl_chspec_driver_to_host(chosen);
+                               printf("selected chanspec = 0x%x\n", chanspec);
+                               ctl_chan = wf_chspec_ctlchan(chanspec);
+                               printf("selected ctl_chan = 0x%x\n", ctl_chan);
+                               *channel = (u16)(ctl_chan & 0x00FF);
+                       } else
+                               *channel = (u16)(chosen & 0x00FF);
                        WL_INFORM(("selected channel = %d\n", *channel));
                        break;
                }
index 25d5d98cc5a73a1fd968ff5edbd5c48ac7f30222..09254775d30d865082ffacfc76d1688f0c2be424 100644 (file)
@@ -1411,6 +1411,7 @@ void wl_escan_detach(void)
                kfree(escan->escan_ioctl_buf);
                escan->escan_ioctl_buf = NULL;
        }
+
 #ifndef CONFIG_DHD_USE_STATIC_BUF
        kfree(escan);
 #endif
@@ -1426,6 +1427,7 @@ wl_escan_attach(struct net_device *dev, void * dhdp)
 
        if (!dev)
                return 0;
+
 #ifdef CONFIG_DHD_USE_STATIC_BUF
        escan = dhd_wlan_mem_prealloc(DHD_PREALLOC_WL_ESCAN_INFO, sizeof(struct wl_escan_info));
 #else