WIFI: fix ap62x8 cts test fail issue [1/5]
authorRongjun Chen <rongjun.chen@amlogic.com>
Fri, 4 Jan 2019 02:00:48 +0000 (10:00 +0800)
committerRongjun Chen <rongjun.chen@amlogic.com>
Mon, 7 Jan 2019 11:02:03 +0000 (19:02 +0800)
PD#SWPL-3773

Problem:
CtsNetTestCases Module 3 Fails

Solution:
update driver to fix cts test fail issue

Verify:
r311

Change-Id: Ibea9da241061f1ce2771ba2c39f78952bd201976
Signed-off-by: Rongjun Chen <rongjun.chen@amlogic.com>
25 files changed:
bcmdhd.1.579.77.41.1.cn/dhd_config.c
bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c
bcmdhd.100.10.315.x/Makefile
bcmdhd.100.10.315.x/bcmsdh_sdmmc.c
bcmdhd.100.10.315.x/dhd_config.c
bcmdhd.100.10.315.x/dhd_config.h
bcmdhd.100.10.315.x/dhd_linux.c
bcmdhd.100.10.315.x/dhd_msgbuf.c
bcmdhd.100.10.315.x/dhd_pcie_linux.c
bcmdhd.100.10.315.x/dhd_sdio.c
bcmdhd.100.10.315.x/dhd_static_buf.c
bcmdhd.100.10.315.x/include/epivers.h
bcmdhd.100.10.315.x/linux_osl.c
bcmdhd.100.10.315.x/linux_osl_priv.h
bcmdhd.100.10.315.x/wl_android.c
bcmdhd.100.10.315.x/wl_android.h
bcmdhd.100.10.315.x/wl_android_ext.c
bcmdhd.100.10.315.x/wl_cfg80211.c
bcmdhd.100.10.315.x/wl_escan.c
bcmdhd.100.10.315.x/wl_escan.h
bcmdhd.100.10.315.x/wl_iw.c
bcmdhd.100.10.315.x/wl_iw.h
bcmdhd.100.10.315.x/wldev_common.c

index 27d0e9db91426349084d7808c40db69a8e3feec8..8aa7a9ae2f38b3c87f36039edb514e4fdf8188e5 100644 (file)
@@ -2740,7 +2740,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->txglom_ext = FALSE;\r
        conf->tx_max_offset = 0;\r
        conf->txglomsize = SDPCM_DEFGLOM_SIZE;\r
-       conf->txctl_tmo_fix = -1;\r
+       conf->txctl_tmo_fix = 300;\r
        conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
        conf->deferred_tx_len = 0;\r
        conf->dhd_txminmax = 1;\r
index fb6150facbd2b41779b120cccee09bfaf5dda1ab..53e9eafc49fb96a704a593e57494706747f678a6 100644 (file)
@@ -6610,7 +6610,7 @@ dhdsdio_dpc(dhd_bus_t *bus)
                goto clkwait;
 
        /* Pending interrupt indicates new device status */
-       if (bus->ipend || (bus->ctrl_frame_stat && bus->dhd->conf->txctl_tmo_fix)) {
+       if (bus->ipend) {
                bus->ipend = FALSE;
 #if defined(BT_OVER_SDIO)
        bcmsdh_btsdio_process_f3_intr();
@@ -7552,6 +7552,11 @@ dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen)
        if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0)
                goto done;
 
+       if (!DATAOK(bus)) {
+               rv = BCME_NOTREADY;
+               goto done;
+       }
+
        /* Bump dongle by sending an empty packet on the event channel.
         * sdpcm_sendup (RX) checks for virtual console input.
         */
index 777ac49df7ff89d6e3933b9414b42645e284b099..34cedee46455db65ae1096d0a97bab3633917324 100644 (file)
@@ -2948,10 +2948,13 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        }
 exit:
        if (unlikely(err)) {
+               int suppressed = 0;
+               wldev_ioctl(dev, WLC_GET_SCANSUPPRESS, &suppressed, sizeof(int), false);
                /* Don't print Error incase of Scan suppress */
-               if ((err == BCME_EPERM) && cfg->scan_suppressed)
+               if ((err == BCME_EPERM) && (cfg->scan_suppressed || suppressed)) {
+                       cnt = 0;
                        WL_DBG(("Escan failed: Scan Suppressed \n"));
-               else {
+               else {
                        cnt++;
                        WL_ERR(("error (%d), cnt=%d\n", err, cnt));
                        // terence 20140111: send disassoc to firmware
index c5b4b2b0562020f2a95363607061f4254f65ebd5..d0fd9f9f19408221fe6dc012ad2360ee6d8b296c 100644 (file)
@@ -2513,6 +2513,7 @@ wl_cfgvendor_dbg_trigger_mem_dump(struct wiphy *wiphy,
        if (ret) {
                WL_ERR(("Vendor Command reply failed ret:%d \n", ret));
        }
+       printk("wl_cfgvendor_dbg_trigger_mem_dump ===================ret : %d\n", ret);
 
 exit:
        return ret;
index 3c964b1cb2b6e8fbbb97dfb0c99b35e2aec7fcbc..9884970c0b4d09efbe78b678c68a3aa7020ebfb7 100644 (file)
@@ -101,7 +101,7 @@ ifeq ($(CONFIG_VTS_SUPPORT),y)
 ifneq ($(CONFIG_CFG80211),)
 DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG      \
        -DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DPKT_FILTER_SUPPORT  \
-       -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS                     \
+       -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS   \
        -DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DEXPLICIT_DISCIF_CLEANUP
 
 DHDOFILES += dhd_rtt.o bcm_app_utils.o
index 04111dc0269c0d95784aebe39833f8ab31f625ea..338ec0ee1a06a0c5f1e5e95b23b37a77422f0f43 100644 (file)
@@ -1244,10 +1244,10 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
                                        goto txglomfail;
                                }
                        }
-                       
+
                        bcopy(buf, (localbuf + local_plen), pkt_len);
                        local_plen += pkt_len;
-                       if (PKTNEXT(sd->osh, pnext))    
+                       if (PKTNEXT(sd->osh, pnext))
                                continue;
 
                        buf = localbuf;
index eedac09da04197fcfa67faf3e7c4f04f80013f40..fed007f6372ced5a0ac22a3708c9908fca1af8cb 100644 (file)
@@ -46,6 +46,15 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define htodchanspec(i) i\r
 #define dtohchanspec(i) i\r
 \r
+#define MAX_EVENT_BUF_NUM 16\r
+typedef struct eventmsg_buf {\r
+       u16 num;\r
+       struct {\r
+               u16 type;\r
+               bool set;\r
+       } event [MAX_EVENT_BUF_NUM];\r
+} eventmsg_buf_t;\r
+\r
 typedef struct cihp_name_map_t {\r
        uint chip;\r
        uint chiprev;\r
@@ -792,7 +801,8 @@ dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec)
        memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
 \r
        printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
-       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);\r
+       bcmerror = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec,\r
+               sizeof(wl_country_t), FALSE);\r
        dhd_conf_get_country(dhd, cspec);\r
        printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
 \r
@@ -887,6 +897,85 @@ dhd_conf_set_roam(dhd_pub_t *dhd)
        return bcmerror;\r
 }\r
 \r
+void\r
+dhd_conf_add_to_eventbuffer(struct eventmsg_buf *ev, u16 event, bool set)\r
+{\r
+       if (!ev || (event > WLC_E_LAST))\r
+               return;\r
+\r
+       if (ev->num < MAX_EVENT_BUF_NUM) {\r
+               ev->event[ev->num].type = event;\r
+               ev->event[ev->num].set = set;\r
+               ev->num++;\r
+       } else {\r
+               CONFIG_ERROR(("evenbuffer doesn't support > %u events. Update"\r
+                       " the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM));\r
+               ASSERT(0);\r
+       }\r
+}\r
+\r
+s32\r
+dhd_conf_apply_eventbuffer(dhd_pub_t *dhd, eventmsg_buf_t *ev)\r
+{\r
+       char eventmask[WL_EVENTING_MASK_LEN];\r
+       int i, ret = 0;\r
+\r
+       if (!ev || (!ev->num))\r
+               return -EINVAL;\r
+\r
+       /* Read event_msgs mask */\r
+       ret = dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs", eventmask, sizeof(eventmask), 0);\r
+       if (unlikely(ret)) {\r
+               CONFIG_ERROR(("Get event_msgs error (%d)\n", ret));\r
+               goto exit;\r
+       }\r
+\r
+       /* apply the set bits */\r
+       for (i = 0; i < ev->num; i++) {\r
+               if (ev->event[i].set)\r
+                       setbit(eventmask, ev->event[i].type);\r
+               else\r
+                       clrbit(eventmask, ev->event[i].type);\r
+       }\r
+\r
+       /* Write updated Event mask */\r
+       ret = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask,\r
+               sizeof(eventmask), FALSE);\r
+       if (unlikely(ret)) {\r
+               CONFIG_ERROR(("Set event_msgs error (%d)\n", ret));\r
+       }\r
+\r
+exit:\r
+       return ret;\r
+}\r
+\r
+int\r
+dhd_conf_enable_roam_offload(dhd_pub_t *dhd, int enable)\r
+{\r
+       int err;\r
+       eventmsg_buf_t ev_buf;\r
+\r
+       if (dhd->conf->roam_off_suspend)\r
+               return 0;\r
+\r
+       err = dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_offload", enable, 0, FALSE);\r
+       if (err)\r
+               return err;\r
+\r
+       bzero(&ev_buf, sizeof(eventmsg_buf_t));\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_PSK_SUP, !enable);\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_REQ_IE, !enable);\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_RESP_IE, !enable);\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_REASSOC, !enable);\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_JOIN, !enable);\r
+       dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ROAM, !enable);\r
+       err = dhd_conf_apply_eventbuffer(dhd, &ev_buf);\r
+\r
+       CONFIG_TRACE(("%s: roam_offload %d\n", __FUNCTION__, enable));\r
+\r
+       return err;\r
+}\r
+\r
 void\r
 dhd_conf_set_bw_cap(dhd_pub_t *dhd)\r
 {\r
@@ -1160,59 +1249,87 @@ dhd_conf_get_pm(dhd_pub_t *dhd)
        return -1;\r
 }\r
 \r
-#define AP_IN_SUSPEND 1\r
-#define AP_DOWN_IN_SUSPEND 2\r
-int\r
-dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd)\r
+uint\r
+dhd_conf_get_insuspend(dhd_pub_t *dhd)\r
 {\r
-       int mode = 0;\r
+       uint mode = 0;\r
 \r
-       /* returned ap_in_suspend value:\r
-        * 0: nothing\r
-        * 1: ap enabled in suspend\r
-        * 2: ap enabled, but down in suspend\r
-        */\r
-       if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
-               mode = dhd->conf->ap_in_suspend;\r
+       if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+               mode = dhd->conf->insuspend &\r
+                       (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | ROAM_OFFLOAD_IN_SUSPEND);\r
+       } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+               mode = dhd->conf->insuspend &\r
+                       (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | AP_DOWN_IN_SUSPEND);\r
        }\r
 \r
        return mode;\r
 }\r
 \r
 int\r
-dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend)\r
+dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend)\r
 {\r
-       int mode = 0;\r
-       uint wl_down = 1;\r
+       uint mode = 0, wl_down = 1;\r
+       struct dhd_conf *conf = dhd->conf;\r
 \r
-       mode = dhd_conf_get_ap_mode_in_suspend(dhd);\r
+       mode = dhd_conf_get_insuspend(dhd);\r
        if (mode)\r
-               printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode);\r
+               printf("%s: op_mode %d, suspend %d, mode 0x%x\n", __FUNCTION__,\r
+                       dhd->op_mode, suspend, mode);\r
+\r
        if (suspend) {\r
-               if (mode == AP_IN_SUSPEND) {\r
+               if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+                       if (mode & ROAM_OFFLOAD_IN_SUSPEND)\r
+                               dhd_conf_enable_roam_offload(dhd, 1);\r
+               } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+                       if (mode & AP_DOWN_IN_SUSPEND) {\r
+                               dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down,\r
+                                       sizeof(wl_down), TRUE, 0);\r
+                       }\r
+               }\r
 #ifdef SUSPEND_EVENT\r
-                       if (dhd->conf->suspend_eventmask_enable) {\r
-                               char *eventmask = dhd->conf->suspend_eventmask;\r
-                               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);\r
+               if (mode & NO_EVENT_IN_SUSPEND) {\r
+                       char suspend_eventmask[WL_EVENTING_MASK_LEN];\r
+                       if (!conf->suspended) {\r
+                               dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs",\r
+                                       conf->resume_eventmask, sizeof(conf->resume_eventmask), 0);\r
                        }\r
+                       memset(suspend_eventmask, 0, sizeof(suspend_eventmask));\r
+                       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",\r
+                               suspend_eventmask, sizeof(suspend_eventmask), FALSE);\r
+               }\r
 #endif\r
-               } else if (mode == AP_DOWN_IN_SUSPEND)\r
-                       dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);\r
+               conf->suspended = TRUE;\r
        } else {\r
-               if (mode == AP_IN_SUSPEND) {\r
 #ifdef SUSPEND_EVENT\r
-                       if (dhd->conf->suspend_eventmask_enable) {\r
-                               char *eventmask = dhd->conf->resume_eventmask;\r
-                               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);\r
+               if (mode & NO_EVENT_IN_SUSPEND) {\r
+                       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",\r
+                               conf->resume_eventmask, sizeof(conf->resume_eventmask), FALSE);\r
+                       if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+                               struct ether_addr bssid;\r
+                               int ret = 0;\r
+                               ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, &bssid,\r
+                                       sizeof(struct ether_addr), FALSE, 0);\r
+                               if (ret != BCME_NOTASSOCIATED && !memcmp(&ether_null, &bssid, ETHER_ADDR_LEN)) {\r
+                                       CONFIG_TRACE(("%s: send disassoc\n", __FUNCTION__));\r
+                                       dhd_conf_set_intiovar(dhd, WLC_DISASSOC, "WLC_DISASSOC", 0, 0, FALSE);\r
+                               }\r
                        }\r
+               }\r
 #endif\r
-               } else if (mode == AP_DOWN_IN_SUSPEND) {\r
-                       wl_down = 0;\r
-                       dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0);\r
+               if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+                       if (mode & ROAM_OFFLOAD_IN_SUSPEND)\r
+                               dhd_conf_enable_roam_offload(dhd, 0);\r
+               } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+                       if (mode & AP_DOWN_IN_SUSPEND) {\r
+                               wl_down = 0;\r
+                               dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down,\r
+                                       sizeof(wl_down), TRUE, 0);\r
+                       }\r
                }\r
+               conf->suspended = FALSE;\r
        }\r
 \r
-       return mode;\r
+       return 0;\r
 }\r
 \r
 #ifdef PROP_TXSTATUS\r
@@ -2099,24 +2216,15 @@ dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
        }\r
        else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {\r
                if (!strncmp(data, "1", 1))\r
-                       conf->xmit_in_suspend = TRUE;\r
+                       conf->insuspend &= ~NO_TXDATA_IN_SUSPEND;\r
                else\r
-                       conf->xmit_in_suspend = FALSE;\r
-               printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);\r
-       }\r
-       else if (!strncmp("ap_in_suspend=", full_param, len_param)) {\r
-               conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);\r
+                       conf->insuspend |= NO_TXDATA_IN_SUSPEND;\r
+               printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);\r
        }\r
-#ifdef SUSPEND_EVENT\r
-       else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {\r
-               if (!strncmp(data, "1", 1))\r
-                       conf->suspend_eventmask_enable = TRUE;\r
-               else\r
-                       conf->suspend_eventmask_enable = FALSE;\r
-               printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);\r
+       else if (!strncmp("insuspend=", full_param, len_param)) {\r
+               conf->insuspend = (int)simple_strtol(data, NULL, 0);\r
+               printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);\r
        }\r
-#endif\r
        else\r
                return false;\r
 \r
@@ -2582,7 +2690,7 @@ dhd_conf_postinit_ioctls(dhd_pub_t *dhd)
        dhd_conf_set_intiovar(dhd, WLC_SET_BAND, "WLC_SET_BAND", conf->band, 0, FALSE);\r
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bcn_timeout", conf->bcn_timeout, 0, FALSE);\r
        dhd_conf_set_intiovar(dhd, WLC_SET_PM, "PM", conf->pm, 0, FALSE);\r
-       dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, TRUE);\r
+       dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, FALSE);\r
        dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", conf->lrl, 0, FALSE);\r
        dhd_conf_set_bw_cap(dhd);\r
        dhd_conf_set_roam(dhd);\r
@@ -2728,11 +2836,8 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->pm = -1;\r
        conf->pm_in_suspend = -1;\r
        conf->suspend_bcn_li_dtim = -1;\r
-       conf->xmit_in_suspend = TRUE;\r
-       conf->ap_in_suspend = 0;\r
+       conf->insuspend = 0;\r
 #ifdef SUSPEND_EVENT\r
-       conf->suspend_eventmask_enable = FALSE;\r
-       memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));\r
        memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));\r
 #endif\r
 #ifdef IDHCP\r
index d7ad3c8b1207cd83d30311902b39faa12a199816..1830c5fa03855ba6bdfff324db4f1c7645fd4d27 100644 (file)
@@ -109,6 +109,13 @@ enum in4way_flags {
        WAIT_DISCONNECTED       = (1 << (3)),
 };
 
+enum in_suspend_flags {
+       NO_EVENT_IN_SUSPEND     = (1 << (0)),
+       NO_TXDATA_IN_SUSPEND    = (1 << (1)),
+       AP_DOWN_IN_SUSPEND      = (1 << (2)),
+       ROAM_OFFLOAD_IN_SUSPEND = (1 << (3)),
+};
+
 enum eapol_status {
        EAPOL_STATUS_NONE = 0,
        EAPOL_STATUS_WPS_REQID,
@@ -204,11 +211,9 @@ typedef struct dhd_conf {
        uint8 tcpack_sup_mode;
 #endif
        int pktprio8021x;
-       int xmit_in_suspend;
-       int ap_in_suspend;
+       uint insuspend;
+       bool suspended;
 #ifdef SUSPEND_EVENT
-       bool suspend_eventmask_enable;
-       char suspend_eventmask[WL_EVENTING_MASK_LEN];
        char resume_eventmask[WL_EVENTING_MASK_LEN];
 #endif
 #ifdef IDHCP
@@ -273,8 +278,8 @@ 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_get_ap_mode_in_suspend(dhd_pub_t *dhd);
-int dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend);
+uint dhd_conf_get_insuspend(dhd_pub_t *dhd);
+int dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend);
 void dhd_conf_postinit_ioctls(dhd_pub_t *dhd);
 int dhd_conf_preinit(dhd_pub_t *dhd);
 int dhd_conf_reset(dhd_pub_t *dhd);
index e8914db9fe3c8f1bc90e3279b6fbdb43e673ee94..18a3684222d9c4f5ee13e53a2d2f4df51a130c29 100644 (file)
@@ -3587,7 +3587,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        if (dhd->conf->pm_in_suspend >= 0)
                                power_mode = dhd->conf->pm_in_suspend;
                        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
-                                        sizeof(power_mode), TRUE, 0);
+                               sizeof(power_mode), TRUE, 0);
 
 #ifdef PKT_FILTER_SUPPORT
                        /* Enable packet filter,
@@ -3768,9 +3768,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        }
 #endif /* CUSTOM_EVENT_PM_WAKE */
 #endif /* DHD_USE_EARLYSUSPEND */
-                       dhd_conf_set_ap_in_suspend(dhd, value);
+                       dhd_conf_set_suspend_resume(dhd, value);
                } else {
-                       dhd_conf_set_ap_in_suspend(dhd, value);
+                       dhd_conf_set_suspend_resume(dhd, value);
 #ifdef PKT_FILTER_SUPPORT
                        dhd->early_suspended = 0;
 #endif // endif
@@ -3784,11 +3784,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                DHD_ERROR(("failed to set intr_width (%d)\n", ret));
                        }
 #endif /* DYNAMIC_SWOOB_DURATION */
-#ifndef SUPPORT_PM2_ONLY
-                       power_mode = PM_FAST;
                        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
-                                        sizeof(power_mode), TRUE, 0);
-#endif /* SUPPORT_PM2_ONLY */
+                               sizeof(power_mode), TRUE, 0);
 #if defined(WL_CFG80211) && defined(WL_BCNRECV)
                        ret = wl_android_bcnrecv_resume(dhd_linux_get_primary_netdev(dhd));
                        if (ret != BCME_OK) {
@@ -3929,7 +3926,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #endif /* DHD_LB_IRQSET */
 
                        /* terence 2017029: Reject in early suspend */
-                       if (!dhd->conf->xmit_in_suspend) {
+                       if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
                                dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
                        }
                }
@@ -3950,7 +3947,7 @@ static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force)
        /* Set flag when early suspend was called */
        dhdp->in_suspend = val;
        if ((force || !dhdp->suspend_disable_flag) &&
-               (dhd_support_sta_mode(dhdp) || dhd_conf_get_ap_mode_in_suspend(dhdp)))
+               (dhd_support_sta_mode(dhdp) || dhd_conf_get_insuspend(dhdp)))
        {
                ret = dhd_set_suspend(val, dhdp);
        }
@@ -5271,7 +5268,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
        }
 
        /* terence 2017029: Reject in early suspend */
-       if (!dhd->pub.conf->xmit_in_suspend && dhd->pub.early_suspended) {
+       if ((dhd->pub.conf->insuspend & NO_TXDATA_IN_SUSPEND) && dhd->pub.early_suspended) {
                dhd_txflowcontrol(&dhd->pub, ALL_INTERFACES, ON);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
                return -ENODEV;
@@ -8549,6 +8546,15 @@ dhd_stop(struct net_device *net)
 
        OLD_MOD_DEC_USE_COUNT;
 exit:
+#if defined(WL_WIRELESS_EXT)
+       if (ifidx == 0) {
+#ifdef WL_ESCAN
+               wl_escan_down(&dhd->pub);
+#else
+               wl_iw_down(&dhd->pub);
+#endif /* WL_ESCAN */
+       }
+#endif /* defined(WL_WIRELESS_EXT) */
        if (skip_reset == false) {
                if (ifidx == 0 && !dhd_download_fw_on_driverload) {
 #if defined(BT_OVER_SDIO)
@@ -8766,14 +8772,6 @@ dhd_open(struct net_device *net)
                                ret = -1;
                                goto exit;
                        }
-#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
-                       conf = dhd_get_conf(net);
-                       if (conf) {
-                               wl_android_ext_priv_cmd(net, conf->isam_init, 0, &bytes_written);
-                               wl_android_ext_priv_cmd(net, conf->isam_config, 0, &bytes_written);
-                               wl_android_ext_priv_cmd(net, conf->isam_enable, 0, &bytes_written);
-                       }
-#endif
                }
 #ifdef SUPPORT_DEEP_SLEEP
                else {
@@ -8924,6 +8922,25 @@ dhd_open(struct net_device *net)
                dhd_set_scb_probe(&dhd->pub);
 #endif /* NUM_SCB_MAX_PROBE */
 #endif /* WL_CFG80211 */
+#if defined(WL_WIRELESS_EXT)
+#ifdef WL_ESCAN
+               if (unlikely(wl_escan_up(net, &dhd->pub))) {
+                       DHD_ERROR(("%s: failed to bring up escan\n", __FUNCTION__));
+                       ret = -1;
+                       goto exit;
+               }
+#endif
+#endif
+#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
+               if (!dhd_download_fw_on_driverload) {
+                       conf = dhd_get_conf(net);
+                       if (conf) {
+                               wl_android_ext_priv_cmd(net, conf->isam_init, 0, &bytes_written);
+                               wl_android_ext_priv_cmd(net, conf->isam_config, 0, &bytes_written);
+                               wl_android_ext_priv_cmd(net, conf->isam_enable, 0, &bytes_written);
+                       }
+               }
+#endif
        }
 
        /* Allow transmit calls */
@@ -12391,9 +12408,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
 #endif /* defined(BCMPCIE) && defined(EAPOL_PKT_PRIO) */
 
-#ifdef SUSPEND_EVENT
-       bcopy(eventmask, dhd->conf->resume_eventmask, WL_EVENTING_MASK_LEN);
-#endif
        /* Write updated Event mask */
        ret = dhd_iovar(dhd, 0, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, NULL, 0, TRUE);
        if (ret < 0) {
@@ -13494,6 +13508,11 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
                        dhd->bus_user_count--;
 #endif /* BT_OVER_SDIO */
                }
+#if defined(WL_WIRELESS_EXT)
+#ifdef WL_ESCAN
+               wl_escan_down(&dhd->pub);
+#endif /* WL_ESCAN */
+#endif /* defined(WL_WIRELESS_EXT) */
        }
 #endif /* OEM_ANDROID && (BCMPCIE || (BCMLXSDMMC && KERNEL_VERSION >= 2.6.27)) */
        return 0;
@@ -16656,6 +16675,8 @@ static void dhd_hang_process(void *dhd_info, void *event_info, u8 event)
        struct net_device *dev;
 
        dhd = (dhd_info_t *)dhd_info;
+       if (!dhd || !dhd->iflist[0])
+               return;
        dev = dhd->iflist[0]->net;
 
        if (dev) {
index 408cf89fefcf72441255b0cf6cd05059738825d9..8eb0b8aa6c5a66b3f33352b30aed9f98553dcb20 100644 (file)
@@ -6834,6 +6834,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
                        if (intstatus) {
                                DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, intstatus=0x%x, intmask=0x%x\n",
                                        __FUNCTION__, cnt, intstatus, intmask));
+                               dhd->bus->intstatus = intstatus;
                                dhd->bus->ipend = TRUE;
                                dhd->bus->dpc_sched = TRUE;
                                dhd_sched_dpc(dhd);
index 3033dfd69a4caf1d1f9c539318dba800828b4e95..8885b0997a09093b58668e55e0da7977ea173044 100644 (file)
@@ -1140,7 +1140,8 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        if (dhdpcie_chipmatch (pdev->vendor, pdev->device)) {
                DHD_ERROR(("%s: chipmatch failed!!\n", __FUNCTION__));
-                       return -ENODEV;
+               DHD_MUTEX_UNLOCK();
+               return -ENODEV;
        }
        printf("PCI_PROBE:  bus %X, slot %X,vendor %X, device %X"
                "(good PCI location)\n", pdev->bus->number,
@@ -1148,6 +1149,7 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        if (dhdpcie_init (pdev)) {
                DHD_ERROR(("%s: PCIe Enumeration failed\n", __FUNCTION__));
+               DHD_MUTEX_UNLOCK();
                return -ENODEV;
        }
 
@@ -1845,7 +1847,7 @@ dhdpcie_enable_irq(dhd_bus_t *bus)
 int
 dhdpcie_irq_disabled(dhd_bus_t *bus)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
        struct irq_desc *desc = irq_to_desc(bus->dev->irq);
        /* depth will be zero, if enabled */
        return desc->depth;
index 3c3b3ba090656008fa2fbec7fe67c30201f67142..4a52e87f6215a206cda664386049c0ac76f38fcb 100644 (file)
@@ -7829,6 +7829,18 @@ dhd_dump_cis(uint fn, uint8 *cis)
 static bool
 dhdsdio_chipmatch(uint16 chipid)
 {
+       if (chipid == BCM4330_CHIP_ID)
+               return TRUE;
+       if (chipid == BCM43362_CHIP_ID)
+               return TRUE;
+       if (chipid == BCM43340_CHIP_ID)
+               return TRUE;
+       if (chipid == BCM43341_CHIP_ID)
+               return TRUE;
+       if (chipid == BCM4334_CHIP_ID)
+               return TRUE;
+       if (chipid == BCM4324_CHIP_ID)
+               return TRUE;
        if (chipid == BCM4335_CHIP_ID)
                return TRUE;
        if (chipid == BCM4339_CHIP_ID)
index 2e29474d1ab98eda9376d79737474f10e4a52cf5..2352ba80262332554c4d42cefbb7d062cc92fa6d 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/err.h>\r
 #include <linux/skbuff.h>\r
 \r
-#define        DHD_STATIC_VERSION_STR          "100.10.315.1"\r
+#define        DHD_STATIC_VERSION_STR          "100.10.315.2"\r
 \r
 #define BCMDHD_SDIO\r
 #define BCMDHD_PCIE\r
@@ -52,7 +52,7 @@ enum dhd_prealloc_index {
 #define DHD_PREALLOC_OSL_BUF_SIZE      (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)\r
 #define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)\r
 #define DHD_PREALLOC_DHD_INFO_SIZE     (32 * 1024)\r
-#define DHD_PREALLOC_MEMDUMP_RAM_SIZE  (810 * 1024)\r
+#define DHD_PREALLOC_MEMDUMP_RAM_SIZE  (1290 * 1024)\r
 #define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE      (73 * 1024)\r
 #define DHD_PREALLOC_WL_ESCAN_INFO_SIZE        (66 * 1024)\r
 #ifdef CONFIG_64BIT\r
@@ -416,7 +416,7 @@ err_mem_alloc:
 \r
        if (wlan_static_wl_escan_info_buf)\r
                kfree(wlan_static_wl_escan_info_buf);\r
-       \r
+\r
 #ifdef BCMDHD_PCIE\r
        if (wlan_static_fw_verbose_ring_buf)\r
                kfree(wlan_static_fw_verbose_ring_buf);\r
@@ -512,7 +512,7 @@ dhd_static_buf_exit(void)
 \r
        if (wlan_static_wl_escan_info_buf)\r
                kfree(wlan_static_wl_escan_info_buf);\r
-       \r
+\r
 #ifdef BCMDHD_PCIE\r
        if (wlan_static_fw_verbose_ring_buf)\r
                kfree(wlan_static_fw_verbose_ring_buf);\r
index c99ea904ab319a441217bdc8af817d3c7c28f4e5..0edcbdddf31c16dcf8e4d7596f5ed019de28b381 100644 (file)
@@ -46,6 +46,6 @@
 #define EPI_VERSION_DEV                100.10.315
 
 /* Driver Version String, ASCII, 32 chars max */
-#define        EPI_VERSION_STR         "100.10.315.2 (r771911)"
+#define        EPI_VERSION_STR         "100.10.315.3 (r771911)"
 
 #endif /* _epivers_h_ */
index 6105a2fb4a25b46fab2cec1498dc69dede038cb7..f702c8949ec9781bfc8ce66c1d20fc887b741e70 100644 (file)
@@ -115,9 +115,12 @@ static int secdma_found = 0;
 #endif /* BCM_SECURE_DMA */
 
 #ifdef USE_DMA_LOCK
-#define DMA_LOCK(osh)          spin_lock_bh(&(osh)->dma_lock)
-#define DMA_UNLOCK(osh)                spin_unlock_bh(&(osh)->dma_lock)
-#define DMA_LOCK_INIT(osh)     spin_lock_init(&(osh)->dma_lock)
+static void osl_dma_lock(osl_t *osh);
+static void osl_dma_unlock(osl_t *osh);
+static void osl_dma_lock_init(osl_t *osh);
+#define DMA_LOCK(osh)          osl_dma_lock(osh)
+#define DMA_UNLOCK(osh)                osl_dma_unlock(osh)
+#define DMA_LOCK_INIT(osh)     osl_dma_lock_init(osh);
 #else
 #define DMA_LOCK(osh)          do { /* noop */ } while(0)
 #define DMA_UNLOCK(osh)                do { /* noop */ } while(0)
@@ -1901,3 +1904,42 @@ osl_timer_del(osl_t *osh, osl_timer_t *t)
        return (TRUE);
 }
 #endif
+
+#ifdef USE_DMA_LOCK
+static void
+osl_dma_lock(osl_t *osh)
+{
+       /* XXX: The conditional check is to avoid the scheduling bug.
+        * If the spin_lock_bh is used under the spin_lock_irqsave,
+        * Kernel triggered the warning message as the spin_lock_irqsave
+        * disables the interrupt and the spin_lock_bh doesn't use in case
+        * interrupt is disabled.
+        * Please refer to the __local_bh_enable_ip() function
+        * in kernel/softirq.c to understand the condtion.
+        */
+       if (likely(in_irq() || irqs_disabled())) {
+               spin_lock(&osh->dma_lock);
+       } else {
+               spin_lock_bh(&osh->dma_lock);
+               osh->dma_lock_bh = TRUE;
+       }
+}
+
+static void
+osl_dma_unlock(osl_t *osh)
+{
+       if (unlikely(osh->dma_lock_bh)) {
+               osh->dma_lock_bh = FALSE;
+               spin_unlock_bh(&osh->dma_lock);
+       } else {
+               spin_unlock(&osh->dma_lock);
+       }
+}
+
+static void
+osl_dma_lock_init(osl_t *osh)
+{
+       spin_lock_init(&osh->dma_lock);
+       osh->dma_lock_bh = FALSE;
+}
+#endif /* USE_DMA_LOCK */
\ No newline at end of file
index 0b602cd9035e42950a6e532854e4698d1dd5c011..7ae18c27054667796e3593c508d4d654604e28b8 100644 (file)
@@ -173,6 +173,7 @@ struct osl_info {
 #endif /* BCM_BACKPLANE_TIMEOUT */
 #ifdef USE_DMA_LOCK
        spinlock_t dma_lock;
+       bool dma_lock_bh;
 #endif /* USE_DMA_LOCK */
 };
 
index 4e4b9276cb91dd97265e5d342e54f50508512e30..4fb7ab9471e702e2e97e7bc3257755dca77f24af 100644 (file)
@@ -5256,7 +5256,7 @@ int wl_android_init(void)
 {
        int ret = 0;
 
-#ifdef ENABLE_INSMOD_NO_FW_LOAD
+#if defined(ENABLE_INSMOD_NO_FW_LOAD) || defined(BUS_POWER_RESTORE)
        dhd_download_fw_on_driverload = FALSE;
 #endif /* ENABLE_INSMOD_NO_FW_LOAD */
        if (!iface_name[0]) {
index 4fe94bcbaa8cf1a1bdad82bccda214d1591cf694..e035aa7897900aff721d4a6e9e2aca87fd78839b 100644 (file)
@@ -73,6 +73,13 @@ typedef struct _compat_android_wifi_priv_cmd {
 #define ANDROID_INFO_LEVEL     0x0004
 #define ANDROID_EVENT_LEVEL    0x0008
 
+#define ANDROID_MSG(x) \
+       do { \
+               if (android_msg_level & ANDROID_ERROR_LEVEL) { \
+                       printk(KERN_ERR "ANDROID-MSG) ");       \
+                       printk x; \
+               } \
+       } while (0)
 #define ANDROID_ERROR(x) \
        do { \
                if (android_msg_level & ANDROID_ERROR_LEVEL) { \
@@ -123,8 +130,15 @@ int wl_ext_iapsta_alive_postinit(struct net_device *dev);
 int wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data);
 int wl_ext_iapsta_attach(dhd_pub_t *pub);
 void wl_ext_iapsta_dettach(dhd_pub_t *pub);
+bool wl_ext_check_mesh_creating(struct net_device *net);
 extern int op_mode;
 #endif
+typedef struct bcol_gtk_para {
+       int enable;
+       int ptk_len;
+       char ptk[64];
+       char replay[8];
+} bcol_gtk_para_t;
 int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
        int *bytes_written);
 enum wl_ext_status {
@@ -141,12 +155,20 @@ enum wl_ext_status {
        WL_EXT_STATUS_AP_DISABLED
 };
 typedef struct wl_conn_info {
+       struct net_device *dev;
+       dhd_pub_t *dhd;
        uint8 bssidx;
        wlc_ssid_t ssid;
        struct ether_addr bssid;
        uint16 channel;
+       struct delayed_work pm_enable_work;
+       struct mutex pm_sync;
 } wl_conn_info_t;
+#if defined(WL_WIRELESS_EXT)
 s32 wl_ext_connect(struct net_device *dev, wl_conn_info_t *conn_info);
+void wl_ext_pm_work_handler(struct work_struct * work);
+void wl_ext_add_remove_pm_enable_work(struct wl_conn_info *conn_info, bool add);
+#endif /* defined(WL_WIRELESS_EXT) */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
 #define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
 #endif
index d247d7e31d37f5bdd1ffa5637bc0aa011652f65d..fe00236575c98fb02a9be4dba9ab9988b5e6ed33 100644 (file)
 #include <wl_escan.h>
 #endif
 
+#if defined(WL_WIRELESS_EXT)
+#define WL_PM_ENABLE_TIMEOUT 10000
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+       4 && __GNUC_MINOR__ >= 6))
+#define BCM_SET_CONTAINER_OF(entry, ptr, type, member) \
+_Pragma("GCC diagnostic push") \
+_Pragma("GCC diagnostic ignored \"-Wcast-qual\"") \
+entry = container_of((ptr), type, member); \
+_Pragma("GCC diagnostic pop")
+#else
+#define BCM_SET_CONTAINER_OF(entry, ptr, type, member) \
+entry = container_of((ptr), type, member);
+#endif /* STRICT_GCC_WARNINGS */
+#endif /* defined(WL_WIRELESS_EXT) */
+
 #ifndef WL_CFG80211
 #define htod32(i) i
 #define htod16(i) i
@@ -252,6 +267,7 @@ typedef struct wl_apsta_params {
        uint csa;
        apstamode_t apstamode;
        bool netif_change;
+       bool mesh_creating;
        wait_queue_head_t netif_change_event;
 } wl_apsta_params_t;
 
@@ -487,13 +503,13 @@ set_channel:
                                if (bw == WL_CHANSPEC_BW_80)
                                        goto change_bw;
                                wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);
-                               printf("%s: channel %d\n", __FUNCTION__, _chan);
+                               ANDROID_MSG(("%s: channel %d\n", __FUNCTION__, _chan));
                        } else if (err) {
                                ANDROID_ERROR(("%s: failed to set chanspec error %d\n",
                                        __FUNCTION__, err));
                        } else
-                               printf("%s: %s channel %d, 0x%x\n", __FUNCTION__,
-                                       dev->name, channel, chspec);
+                               ANDROID_MSG(("%s: %s channel %d, 0x%x\n", __FUNCTION__,
+                                       dev->name, channel, chspec));
                } else {
                        ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n",
                                __FUNCTION__));
@@ -572,9 +588,8 @@ wl_ext_channels(struct net_device *dev, char* command, int total_len)
                for (i = 0; i < dtoh32(list->count); i++) {
                        bytes_written += snprintf(command+bytes_written, total_len, " %d",
                                dtoh32(list->element[i]));
-                       printf("%d ", dtoh32(list->element[i]));
                }
-               printf("\n");
+               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
                ret = bytes_written;
        }
 
@@ -678,23 +693,25 @@ wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)
                        goto exit;
                } else {
                        mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;
-                       printf("Id            :%d\n"
-                                       "Period (msec) :%d\n"
-                                       "Length        :%d\n"
-                                       "Packet        :0x",
-                                       mkeep_alive_pktp->keep_alive_id,
-                                       dtoh32(mkeep_alive_pktp->period_msec),
-                                       dtoh16(mkeep_alive_pktp->len_bytes));
-                       for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
-                               printf("%02x", mkeep_alive_pktp->data[i]);
+                       if (android_msg_level & ANDROID_INFO_LEVEL) {
+                               printf("Id            :%d\n"
+                                               "Period (msec) :%d\n"
+                                               "Length        :%d\n"
+                                               "Packet        :0x",
+                                               mkeep_alive_pktp->keep_alive_id,
+                                               dtoh32(mkeep_alive_pktp->period_msec),
+                                               dtoh16(mkeep_alive_pktp->len_bytes));
+                               for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+                                       printf("%02x", mkeep_alive_pktp->data[i]);
+                               }
+                               printf("\n");
                        }
-                       printf("\n");
                }
                bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ",
                        dtoh32(mkeep_alive_pktp->period_msec));
                bytes_written += snprintf(command+bytes_written, total_len, "0x");
                for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
-                       bytes_written += snprintf(command+bytes_written, total_len, "%x",
+                       bytes_written += snprintf(command+bytes_written, total_len, "%02x",
                                mkeep_alive_pktp->data[i]);
                }
                ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
@@ -830,9 +847,9 @@ wl_ext_connect(struct net_device *dev, struct wl_conn_info *conn_info)
        err = wl_ext_iovar_setbuf_bsscfg(dev, "join", ext_join_params,
                join_params_size, iovar_buf, WLC_IOCTL_SMLEN, conn_info->bssidx, NULL);
 
-       printf("Connecting with " MACDBG " channel (%d) ssid \"%s\", len (%d)\n\n",
+       ANDROID_MSG(("Connecting with " MACDBG " channel (%d) ssid \"%s\", len (%d)\n\n",
                MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)), conn_info->channel,
-               ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len);
+               ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len));
 
        kfree(ext_join_params);
        if (err) {
@@ -872,6 +889,79 @@ exit:
 
 }
 
+#if defined(WL_WIRELESS_EXT)
+void wl_ext_pm_work_handler(struct work_struct * work)
+{
+       struct wl_conn_info *conn_info;
+       s32 pm = PM_FAST;
+       dhd_pub_t *dhd;
+       BCM_SET_CONTAINER_OF(conn_info, work, struct wl_conn_info, pm_enable_work.work);
+
+       ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+       4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
+#endif
+
+       dhd = (dhd_pub_t *)(conn_info->dhd);
+       if (!dhd || !conn_info->dhd->up) {
+               ANDROID_TRACE(("%s: dhd is null or not up\n", __FUNCTION__));
+               return;
+       }
+       if (dhd_conf_get_pm(dhd) >= 0)
+               pm = dhd_conf_get_pm(dhd);
+       wl_ext_ioctl(conn_info->dev, WLC_SET_PM, &pm, sizeof(pm), 1);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+       4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic pop")
+#endif
+       DHD_PM_WAKE_UNLOCK(conn_info->dhd);
+
+}
+
+void wl_ext_add_remove_pm_enable_work(struct wl_conn_info *conn_info,
+       bool add)
+{
+       u16 wq_duration = 0;
+       s32 pm = PM_OFF;
+
+       if (conn_info == NULL || conn_info->dhd == NULL)
+               return;
+
+       mutex_lock(&conn_info->pm_sync);
+       /*
+        * Make cancel and schedule work part mutually exclusive
+        * so that while cancelling, we are sure that there is no
+        * work getting scheduled.
+        */
+
+       if (delayed_work_pending(&conn_info->pm_enable_work)) {
+               cancel_delayed_work_sync(&conn_info->pm_enable_work);
+               DHD_PM_WAKE_UNLOCK(conn_info->dhd);
+       }
+
+       if (add) {
+               wq_duration = (WL_PM_ENABLE_TIMEOUT);
+       }
+
+       /* It should schedule work item only if driver is up */
+       if (wq_duration && conn_info->dhd->up) {
+               if (dhd_conf_get_pm(conn_info->dhd) >= 0)
+                       pm = dhd_conf_get_pm(conn_info->dhd);
+               wl_ext_ioctl(conn_info->dev, WLC_SET_PM, &pm, sizeof(pm), 1);
+               if (schedule_delayed_work(&conn_info->pm_enable_work,
+                               msecs_to_jiffies((const unsigned int)wq_duration))) {
+                       DHD_PM_WAKE_LOCK_TIMEOUT(conn_info->dhd, wq_duration);
+               } else {
+                       ANDROID_ERROR(("%s: Can't schedule pm work handler\n", __FUNCTION__));
+               }
+       }
+       mutex_unlock(&conn_info->pm_sync);
+
+}
+#endif /* defined(WL_WIRELESS_EXT) */
+
 #ifdef WL_EXT_IAPSTA
 static int
 wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)
@@ -1299,6 +1389,17 @@ wl_ext_wait_netif_change(struct wl_apsta_params *apsta_params,
                rtnl_lock();
 }
 
+bool
+wl_ext_check_mesh_creating(struct net_device *net)
+{
+       struct dhd_pub *dhd = dhd_get_pub(net);
+       struct wl_apsta_params *apsta_params = dhd->iapsta_params;
+
+       if (apsta_params)
+               return apsta_params->mesh_creating;
+       return FALSE;
+}
+
 static void
 wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_params)
 {
@@ -1372,7 +1473,7 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
                        wl_config_t rsdb_mode_cfg = {0, 0};
                        if (apsta_params->rsdb)
                                rsdb_mode_cfg.config = 1;
-                       printf("%s: set rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config);
+                       ANDROID_MSG(("%s: set rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config));
                        wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
                        wl_ext_iovar_setbuf(dev, "rsdb_mode", &rsdb_mode_cfg,
                                sizeof(rsdb_mode_cfg), iovar_buf, sizeof(iovar_buf), NULL);
@@ -1503,9 +1604,11 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
                iface.ver = WL_INTERFACE_CREATE_VER;
                iface.flags = WL_INTERFACE_CREATE_STA;
                apsta_params->netif_change = FALSE;
+               apsta_params->mesh_creating = TRUE;
                wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
                        iovar_buf, WLC_IOCTL_SMLEN, NULL);
                wl_ext_wait_netif_change(apsta_params, TRUE);
+               apsta_params->mesh_creating = FALSE;
        }
        else if (apstamode == IMESHAP_MODE) {
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1516,11 +1619,13 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
                // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
                bzero(&iface, sizeof(wl_interface_create_t));
                iface.ver = WL_INTERFACE_CREATE_VER;
-               iface.flags = WL_INTERFACE_CREATE_AP;
+               iface.flags = WL_INTERFACE_CREATE_STA;
                apsta_params->netif_change = FALSE;
+               apsta_params->mesh_creating = TRUE;
                wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
                        iovar_buf, WLC_IOCTL_SMLEN, NULL);
                wl_ext_wait_netif_change(apsta_params, TRUE);
+               apsta_params->mesh_creating = FALSE;
        }
        else if (apstamode == IMESHAPSTA_MODE) {
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1540,9 +1645,11 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
                iface.ver = WL_INTERFACE_CREATE_VER;
                iface.flags = WL_INTERFACE_CREATE_STA;
                apsta_params->netif_change = FALSE;
+               apsta_params->mesh_creating = TRUE;
                wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
                        iovar_buf, WLC_IOCTL_SMLEN, NULL);
                wl_ext_wait_netif_change(apsta_params, TRUE);
+               apsta_params->mesh_creating = FALSE;
        }
        else if (apstamode == IMESHAPAP_MODE) {
                wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1582,7 +1689,7 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
        wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
        apsta_params->init = TRUE;
 
-       printf("%s: apstamode=%d\n", __FUNCTION__, apstamode);
+       ANDROID_MSG(("%s: apstamode=%d\n", __FUNCTION__, apstamode));
 }
 
 static int
@@ -2062,9 +2169,9 @@ wl_mesh_print_peer_info(mesh_peer_info_ext_t *mpi_ext,
                                mpi_ext->rssi);
                } else {
                        bytes_written += snprintf(command+bytes_written, total_len,
-                               "\n%d: %pM : %6s : %5s : %6s :"
+                               "\n%2d: %pM : %6s : %5s : %6s :"
                                " %5s : %4s : %4s : %11s : %4s",
-                               count, &mpi_ext->ea, "  NA  ", "  NA ", "  NA  ",
+                               count, &mpi_ext->ea, "  NA  ", "  NA  ", "  NA  ",
                                "  NA ", " NA ", " NA ", "  TIMEDOUT ", " NA ");
                }
                mpi_ext++;
@@ -2138,7 +2245,8 @@ wl_ext_if_down(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if)
        } bss_setbuf;
        apstamode_t apstamode = apsta_params->apstamode;
 
-       printf("%s: %s[%c] Turning off\n", __FUNCTION__, cur_if->ifname, cur_if->prefix);
+       ANDROID_MSG(("%s: %s[%c] Turning off\n", __FUNCTION__,
+               cur_if->ifname, cur_if->prefix));
 
        if (cur_if->ifmode == ISTA_MODE) {
                wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
@@ -2178,12 +2286,13 @@ wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if)
        }
 
        if (cur_if->channel >= 52 && cur_if->channel <= 148) {
-               printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
-                       cur_if->ifname, cur_if->prefix, cur_if->channel);
+               ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+                       cur_if->ifname, cur_if->prefix, cur_if->channel));
                return 0;
        }
 
-       printf("%s: %s[%c] Turning on\n", __FUNCTION__, cur_if->ifname, cur_if->prefix);
+       ANDROID_MSG(("%s: %s[%c] Turning on\n", __FUNCTION__,
+               cur_if->ifname, cur_if->prefix));
 
        wl_ext_set_chanspec(cur_if->dev, apsta_params->ioctl_ver, cur_if->channel,
                &fw_chspec);
@@ -2256,7 +2365,7 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
                return -1;
        }
 
-       printf("%s: %s[%c] Disabling\n", __FUNCTION__, ifname, cur_if->prefix);
+       ANDROID_MSG(("%s: %s[%c] Disabling\n", __FUNCTION__, ifname, cur_if->prefix));
 
        if (cur_if->ifmode == ISTA_MODE) {
                wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
@@ -2327,7 +2436,7 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
 
        cur_if->ifstate = IF_STATE_DISALBE;
 
-       printf("%s: %s[%c] disabled\n", __FUNCTION__, ifname, cur_if->prefix);
+       ANDROID_MSG(("%s: %s[%c] disabled\n", __FUNCTION__, ifname, cur_if->prefix));
 
        return 0;
 }
@@ -2372,11 +2481,11 @@ wl_ext_triger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_i
        if (apsta_params->csa & CSA_DRV_BIT &&
                        (cur_if->ifmode == IAP_MODE || cur_if->ifmode == IMESH_MODE)) {
                if (!cur_if->channel) {
-                       printf("%s: %s[%c] skip channel %d\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, cur_if->channel);
+                       ANDROID_MSG(("%s: %s[%c] skip channel %d\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, cur_if->channel));
                } else if (cur_if->channel >= 52 && cur_if->channel <= 148) {
-                       printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, cur_if->channel);
+                       ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, cur_if->channel));
                        wl_ext_if_down(apsta_params, cur_if);
                } else {
                        wl_chan_switch_t csa_arg;
@@ -2386,14 +2495,14 @@ wl_ext_triger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_i
                        csa_arg.chspec = wl_ext_get_chanspec(apsta_params, cur_if->dev,
                                cur_if->channel);
                        if (csa_arg.chspec) {
-                               printf("%s: Trigger CSA to channel %d(0x%x)\n", __FUNCTION__,
-                                       cur_if->channel, csa_arg.chspec);
+                               ANDROID_MSG(("%s: Trigger CSA to channel %d(0x%x)\n", __FUNCTION__,
+                                       cur_if->channel, csa_arg.chspec));
                                wl_ext_iovar_setbuf(cur_if->dev, "csa", &csa_arg, sizeof(csa_arg),
                                        iovar_buf, sizeof(iovar_buf), NULL);
                                OSL_SLEEP(500);
                                wl_ext_isam_status(cur_if->dev, NULL, 0);
                        } else {
-                               printf("%s: fail to get chanspec\n", __FUNCTION__);
+                               ANDROID_ERROR(("%s: fail to get chanspec\n", __FUNCTION__));
                        }
                }
        }
@@ -2433,21 +2542,21 @@ wl_ext_move_cur_channel(struct wl_apsta_params *apsta_params,
                tmp_chan = wl_ext_get_chan(apsta_params, cur_if->dev);
                if (apsta_params->rsdb && tmp_chan &&
                                wl_ext_diff_band(tmp_chan, target_chan)) {
-                       printf("%s: %s[%c] keep on current channel %d\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, tmp_chan);
+                       ANDROID_MSG(("%s: %s[%c] keep on current channel %d\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, tmp_chan));
                        cur_if->channel = 0;
                } else {
-                       printf("%s: %s[%c] channel=%d => %s[%c] channel=%d\n", __FUNCTION__,
+                       ANDROID_MSG(("%s: %s[%c] channel=%d => %s[%c] channel=%d\n", __FUNCTION__,
                                cur_if->ifname, cur_if->prefix, cur_if->channel,
-                               target_if->ifname, target_if->prefix, target_chan);
+                               target_if->ifname, target_if->prefix, target_chan));
                        cur_if->channel = target_chan;
                }
        }
 exit:
        if ((cur_if->ifmode == IAP_MODE || cur_if->ifmode == IMESH_MODE) &&
                        (cur_if->channel >= 52 && cur_if->channel <= 148)) {
-               printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
-                       cur_if->ifname, cur_if->prefix, cur_if->channel);
+               ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+                       cur_if->ifname, cur_if->prefix, cur_if->channel));
                cur_if->channel = 0;
        }
 
@@ -2483,8 +2592,8 @@ wl_ext_move_other_channel(struct wl_apsta_params *apsta_params,
        }
 
        if (target_if) {
-               printf("%s: %s channel=%d => %s channel=%d\n", __FUNCTION__,
-                       target_if->ifname, target_chan, cur_if->ifname, cur_if->channel);
+               ANDROID_MSG(("%s: %s channel=%d => %s channel=%d\n", __FUNCTION__,
+                       target_if->ifname, target_chan, cur_if->ifname, cur_if->channel));
                target_if->channel = cur_if->channel;
                if (apsta_params->csa == 0) {
                        wl_ext_if_down(apsta_params, target_if);
@@ -2531,9 +2640,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
                return -1;
        }
 
-       printf("%s: %s[%c] Enabling\n", __FUNCTION__, ifname, cur_if->prefix);
-
        wl_ext_isam_status(cur_if->dev, NULL, 0);
+       ANDROID_MSG(("%s: %s[%c] Enabling\n", __FUNCTION__, ifname, cur_if->prefix));
 
        wl_ext_move_cur_channel(apsta_params, dev, cur_if);
        if (!cur_if->channel && cur_if->ifmode != ISTA_MODE) {
@@ -2615,8 +2723,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
                if (cur_if->hidden > 0) {
                        wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden,
                                sizeof(cur_if->hidden), 1);
-                       printf("%s: Broadcast SSID: %s\n", __FUNCTION__,
-                               cur_if->hidden ? "OFF":"ON");
+                       ANDROID_MSG(("%s: Broadcast SSID: %s\n", __FUNCTION__,
+                               cur_if->hidden ? "OFF":"ON"));
                }
        }
 
@@ -2664,7 +2772,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
                } else if (cur_if->ifmode == IAP_MODE) {
                        wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
                } else {
-                       printf("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode);
+                       ANDROID_ERROR(("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode));
                }
 #ifdef WLMESH
        } else if (apstamode == IMESHONLY_MODE ||
@@ -2684,7 +2792,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
                        join_params.params.chanspec_num = 1;
                        wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &join_params, sizeof(join_params), 1);
                } else {
-                       printf("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode);
+                       ANDROID_ERROR(("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode));
                }
 #endif
        }
@@ -2705,8 +2813,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
 #endif
 
        OSL_SLEEP(500);
-       printf("%s: %s[%c] enabled with SSID: \"%s\"\n", __FUNCTION__,
-               ifname, cur_if->prefix, cur_if->ssid);
+       ANDROID_MSG(("%s: %s[%c] enabled with SSID: \"%s\"\n", __FUNCTION__,
+               ifname, cur_if->prefix, cur_if->ssid));
        wl_ext_isam_status(cur_if->dev, NULL, 0);
 
        cur_if->ifstate = IF_STATE_ENABLE;
@@ -2824,7 +2932,7 @@ wl_ext_iapsta_alive_postinit(struct net_device *dev)
        // fix me: how to check it's IAPSTA_MODE or IDUALAP_MODE?
 
        wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
-       printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);
+       ANDROID_MSG(("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode));
 
        return op_mode;
 }
@@ -2957,15 +3065,14 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
 #if defined(WL_WIRELESS_EXT)
        char extra[IW_CUSTOM_MAX];
        union iwreq_data wrqu;
+       uint32 datalen = ntoh32(e->datalen);
 #endif
        uint32 event_type = ntoh32(e->event_type);
        uint32 status =  ntoh32(e->status);
        uint32 reason =  ntoh32(e->reason);
        uint16 flags =  ntoh16(e->flags);
-       uint32 datalen = ntoh32(e->datalen);
 
        if (!apsta_params->init) {
-               ANDROID_TRACE(("%s: please init first\n", __FUNCTION__));
                return -1;
        }
 
@@ -2984,11 +3091,11 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        if (cur_if->ifmode == ISTA_MODE) {
                if (event_type == WLC_E_LINK) {
                        if (!(flags & WLC_EVENT_MSG_LINK)) {
-                               printf("%s: %s[%c] Link Down with %pM\n", __FUNCTION__,
-                                       cur_if->ifname, cur_if->prefix, &e->addr);
+                               ANDROID_MSG(("%s: %s[%c] Link Down with %pM\n", __FUNCTION__,
+                                       cur_if->ifname, cur_if->prefix, &e->addr));
                        } else {
-                               printf("%s: %s[%c] Link UP with %pM\n", __FUNCTION__,
-                                       cur_if->ifname, cur_if->prefix, &e->addr);
+                               ANDROID_MSG(("%s: %s[%c] Link UP with %pM\n", __FUNCTION__,
+                                       cur_if->ifname, cur_if->prefix, &e->addr));
                        }
                }
        }
@@ -2996,25 +3103,25 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                if ((event_type == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
                                (event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
                                reason == WLC_E_REASON_INITIAL_ASSOC)) {
-                       printf("%s: %s[%c] Link up\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix);
+                       ANDROID_MSG(("%s: %s[%c] Link up\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix));
                } else if ((event_type == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
                                (event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
                                reason == WLC_E_REASON_DEAUTH)) {
-                       printf("%s: %s[%c] Link down\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix);
+                       ANDROID_MSG(("%s: %s[%c] Link down\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix));
                }
                else if ((event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) &&
                                reason == DOT11_SC_SUCCESS) {
-                       printf("%s: %s[%c] connected device %pM\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, &e->addr);
+                       ANDROID_MSG(("%s: %s[%c] connected device %pM\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, &e->addr));
                } else if (event_type == WLC_E_DISASSOC_IND) {
-                       printf("%s: %s[%c] disassociated device %pM\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, &e->addr);
+                       ANDROID_MSG(("%s: %s[%c] disassociated device %pM\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, &e->addr));
                } else if (event_type == WLC_E_DEAUTH_IND ||
                                (event_type == WLC_E_DEAUTH && reason != DOT11_RC_RESERVED)) {
-                       printf("%s: %s[%c] deauthenticated device %pM\n", __FUNCTION__,
-                               cur_if->ifname, cur_if->prefix, &e->addr);
+                       ANDROID_MSG(("%s: %s[%c] deauthenticated device %pM\n", __FUNCTION__,
+                               cur_if->ifname, cur_if->prefix, &e->addr));
                }
        }
 
@@ -3103,7 +3210,7 @@ wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx)
        struct wl_apsta_params *apsta_params = dhd->iapsta_params;
        struct wl_if_info *cur_if = NULL, *primary_if;
 
-       printf("%s: ifidx=%d, bssidx=%d\n", __FUNCTION__, ifidx, bssidx);
+       ANDROID_MSG(("%s: ifidx=%d, bssidx=%d\n", __FUNCTION__, ifidx, bssidx));
        if (ifidx < MAX_IF_NUM) {
                cur_if = &apsta_params->if_info[ifidx];
        }
@@ -3159,7 +3266,7 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx)
        if (!apsta_params)
                return 0;
 
-       printf("%s: ifidx=%d\n", __FUNCTION__, ifidx);
+       ANDROID_MSG(("%s: ifidx=%d\n", __FUNCTION__, ifidx));
        if (ifidx < MAX_IF_NUM) {
                cur_if = &apsta_params->if_info[ifidx];
        }
@@ -3179,7 +3286,7 @@ int wl_ext_iapsta_attach(dhd_pub_t *pub)
 
        iapsta_params = kzalloc(sizeof(struct wl_apsta_params), GFP_KERNEL);
        if (unlikely(!iapsta_params)) {
-               printf("%s: Could not allocate apsta_params\n", __FUNCTION__);
+               ANDROID_ERROR(("%s: Could not allocate apsta_params\n", __FUNCTION__));
                return -ENOMEM;
        }
        pub->iapsta_params = (void *)iapsta_params;
@@ -3296,7 +3403,7 @@ wl_ext_rsdb_mode(struct net_device *dev, char *data, char *command,
                rsdb_mode_cfg.config = (int)simple_strtol(data, NULL, 0);
                ret = wl_ext_iovar_setbuf(dev, "rsdb_mode", (char *)&rsdb_mode_cfg,
                        sizeof(rsdb_mode_cfg), iovar_buf, WLC_IOCTL_SMLEN, NULL);
-               printf("%s: rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config);
+               ANDROID_MSG(("%s: rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config));
        } else {
                ret = wl_ext_iovar_getbuf(dev, "rsdb_mode", NULL, 0,
                        iovar_buf, WLC_IOCTL_SMLEN, NULL);
@@ -3311,9 +3418,41 @@ wl_ext_rsdb_mode(struct net_device *dev, char *data, char *command,
        return ret;
 }
 
-#ifdef SENDPROB
-int
-wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
+static s32
+wl_ext_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
+{
+       s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
+       s8 eventmask[WL_EVENTING_MASK_LEN];
+       s32 err = 0;
+
+       if (!ndev)
+               return -ENODEV;
+
+       /* Setup event_msgs */
+       err = wldev_iovar_getbuf(ndev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+       if (unlikely(err)) {
+               ANDROID_ERROR(("Get event_msgs error (%d)\n", err));
+               goto eventmsg_out;
+       }
+       memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+       if (add) {
+               setbit(eventmask, event);
+       } else {
+               clrbit(eventmask, event);
+       }
+       err = wldev_iovar_setbuf(ndev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+                       sizeof(iovbuf), NULL);
+       if (unlikely(err)) {
+               ANDROID_ERROR(("Set event_msgs error (%d)\n", err));
+               goto eventmsg_out;
+       }
+
+eventmsg_out:
+       return err;
+}
+
+static int
+wl_ext_event_msg(struct net_device *dev, char *data,
        char *command, int total_len)
 {
        s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
@@ -3329,7 +3468,8 @@ wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
                ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, data));
                sscanf(data, "%d %d", &event, &add);
                /* Setup event_msgs */
-               bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+               bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf,
+                       sizeof(iovbuf), NULL);
                if (unlikely(bytes_written)) {
                        ANDROID_ERROR(("Get event_msgs error (%d)\n", bytes_written));
                        goto eventmsg_out;
@@ -3343,21 +3483,12 @@ wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
                        ANDROID_INFO(("%s\n", command));
                        goto eventmsg_out;
                }
-               if (add) {
-                       setbit(eventmask, event);
-               } else {
-                       clrbit(eventmask, event);
-               }
-               bytes_written = wl_ext_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
-                               sizeof(iovbuf), NULL);
-               if (unlikely(bytes_written)) {
-                       ANDROID_ERROR(("Set event_msgs error (%d)\n", bytes_written));
-                       goto eventmsg_out;
-               }
+               bytes_written = wl_ext_add_remove_eventmsg(dev, event, add);
        }
        else {
                /* Setup event_msgs */
-               bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+               bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf,
+                       sizeof(iovbuf), NULL);
                if (bytes_written) {
                        ANDROID_ERROR(("Get event_msgs error (%d)\n", bytes_written));
                        goto eventmsg_out;
@@ -3379,6 +3510,7 @@ eventmsg_out:
        return bytes_written;
 }
 
+#ifdef SENDPROB
 static int
 wl_ext_send_probresp(struct net_device *dev, char *data, char *command, int total_len)
 {
@@ -3443,6 +3575,47 @@ exit:
 }
 #endif
 
+static int
+wl_ext_gtk_key_info(struct net_device *dev, char *data, char *command, int total_len)
+{
+       int err = 0;
+       char iovar_buf[WLC_IOCTL_SMLEN]="\0";
+       gtk_keyinfo_t keyinfo;
+       bcol_gtk_para_t bcol_keyinfo;
+
+       /* wl gtk_key_info [kck kek replay_ctr] */
+       /* wl gtk_key_info 001122..FF001122..FF00000000000001 */
+       if (data) {
+               memset(&keyinfo, 0, sizeof(keyinfo));
+               memcpy(&keyinfo, data, RSN_KCK_LENGTH+RSN_KEK_LENGTH+RSN_REPLAY_LEN);
+               if (android_msg_level & ANDROID_INFO_LEVEL) {
+                       prhex("kck", (uchar *)keyinfo.KCK, RSN_KCK_LENGTH);
+                       prhex("kek", (uchar *)keyinfo.KEK, RSN_KEK_LENGTH);
+                       prhex("replay_ctr", (uchar *)keyinfo.ReplayCounter, RSN_REPLAY_LEN);
+               }
+
+               memset(&bcol_keyinfo, 0, sizeof(bcol_keyinfo));
+               bcol_keyinfo.enable = 1;
+               bcol_keyinfo.ptk_len = 64;
+               memcpy(&bcol_keyinfo.ptk, data, RSN_KCK_LENGTH+RSN_KEK_LENGTH);
+               err = wl_ext_iovar_setbuf(dev, "bcol_gtk_rekey_ptk", &bcol_keyinfo,
+                       sizeof(bcol_keyinfo), iovar_buf, sizeof(iovar_buf), NULL);
+               if (!err) {
+                       goto exit;
+               }
+
+               err = wl_ext_iovar_setbuf(dev, "gtk_key_info", &keyinfo, sizeof(keyinfo),
+                       iovar_buf, sizeof(iovar_buf), NULL);
+               if (err) {
+                       ANDROID_ERROR(("%s: failed to set gtk_key_info\n", __FUNCTION__));
+                       goto exit;
+               }
+       }
+
+exit:
+    return err;
+}
+
 typedef int (wl_ext_tpl_parse_t)(struct net_device *dev, char *data, char *command,
        int total_len);
 
@@ -3458,10 +3631,11 @@ const wl_ext_iovar_tpl_t wl_ext_iovar_tpl_list[] = {
 #ifdef WLMESH
        {WLC_GET_VAR,   WLC_SET_VAR,    "mesh_peer_status",     wl_ext_mesh_peer_status},
 #endif
+       {WLC_GET_VAR,   WLC_SET_VAR,    "event_msg",    wl_ext_event_msg},
 #ifdef SENDPROB
-       {WLC_GET_VAR,   WLC_SET_VAR,    "event_msg",    wl_ext_add_remove_eventmsg},
        {WLC_GET_VAR,   WLC_SET_VAR,    "send_probresp",        wl_ext_send_probresp},
 #endif
+       {WLC_GET_VAR,   WLC_SET_VAR,    "gtk_key_info", wl_ext_gtk_key_info},
 };
 
 /*
@@ -3796,7 +3970,7 @@ wl_ext_get_best_channel(struct net_device *net,
                }
        }
 
-       if (android_msg_level&ANDROID_INFO_LEVEL) {
+       if (android_msg_level & ANDROID_INFO_LEVEL) {
                printf("%s: b_band: ", __FUNCTION__);
                for (j=0; j<ARRAYSIZE(b_band); j++)
                        printf("%d, ", b_band[j]);
index 7138d7d84715cab414ac109b3ca59659d07916bb..a15d01995f4a04ebc8527014b839df73760b0fcf 100644 (file)
@@ -3457,10 +3457,13 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        }
 exit:
        if (unlikely(err)) {
+               int suppressed = 0;
+               wldev_ioctl(dev, WLC_GET_SCANSUPPRESS, &suppressed, sizeof(int), false);
                /* Don't print Error incase of Scan suppress */
-               if ((err == BCME_EPERM) && cfg->scan_suppressed)
+               if ((err == BCME_EPERM) && (cfg->scan_suppressed || suppressed)) {
+                       cnt = 0;
                        WL_DBG(("Escan failed: Scan Suppressed \n"));
-               else {
+               else {
                        cnt++;
                        WL_ERR(("error (%d), cnt=%d\n", err, cnt));
                        // terence 20140111: send disassoc to firmware
@@ -4686,6 +4689,13 @@ wl_cfg80211_post_ifcreate(struct net_device *ndev,
                return NULL;
        }
 
+#ifdef WL_EXT_IAPSTA
+       if (wl_ext_check_mesh_creating(ndev)) {
+               printf("%s: change iface_type to NL80211_IFTYPE_MESH_POINT\n", __FUNCTION__);
+               iface_type = NL80211_IFTYPE_MESH_POINT;
+       }
+#endif
+
        WL_DBG(("mac_ptr:%p name:%s role:%d nl80211_iftype:%d " MACDBG "\n",
                addr, name, event->role, iface_type, MAC2STRDBG(event->mac)));
        if (!name) {
@@ -10640,6 +10650,31 @@ wl_cfg80211_parse_ies(const u8 *ptr, u32 len, struct parsed_ies *ies)
        return err;
 
 }
+
+bool
+wl_legacy_chip_check(struct bcm_cfg80211 *cfg)
+{
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+       uint chip;
+
+       chip = dhd_conf_get_chip(dhd);
+
+       if (chip == BCM43362_CHIP_ID || chip == BCM4330_CHIP_ID ||
+               chip == BCM43430_CHIP_ID || chip == BCM43012_CHIP_ID ||
+               chip == BCM4334_CHIP_ID || chip == BCM43340_CHIP_ID ||
+               chip == BCM43341_CHIP_ID || chip == BCM4324_CHIP_ID ||
+               chip == BCM4335_CHIP_ID || chip == BCM4339_CHIP_ID ||
+               chip == BCM4345_CHIP_ID || chip == BCM43454_CHIP_ID ||
+               chip == BCM4354_CHIP_ID || chip == BCM4356_CHIP_ID ||
+               chip == BCM4371_CHIP_ID || chip == BCM4359_CHIP_ID ||
+               chip == BCM43143_CHIP_ID || chip == BCM43242_CHIP_ID ||
+               chip == BCM43569_CHIP_ID) {
+               return true;
+       }
+
+       return false;
+}
+
 static s32
 wl_cfg80211_set_ap_role(
        struct bcm_cfg80211 *cfg,
@@ -10651,6 +10686,9 @@ wl_cfg80211_set_ap_role(
        s32 pm;
        s32 bssidx;
        s32 apsta = 0;
+       bool legacy_chip;
+
+       legacy_chip = wl_legacy_chip_check(cfg);
 
        if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) {
                WL_ERR(("Find p2p index from wdev(%p) failed\n", dev->ieee80211_ptr));
@@ -10659,10 +10697,12 @@ wl_cfg80211_set_ap_role(
 
        WL_INFORM_MEM(("[%s] Bringup SoftAP on bssidx:%d \n", dev->name, bssidx));
 
-       if ((err = wl_cfg80211_add_del_bss(cfg, dev, bssidx,
-                       WL_IF_TYPE_AP, 0, NULL)) < 0) {
-               WL_ERR(("wl add_del_bss returned error:%d\n", err));
-               return err;
+       if (bssidx != 0 || !legacy_chip) {
+               if ((err = wl_cfg80211_add_del_bss(cfg, dev, bssidx,
+                               WL_IF_TYPE_AP, 0, NULL)) < 0) {
+                       WL_ERR(("wl add_del_bss returned error:%d\n", err));
+                       return err;
+               }
        }
 
        /*
@@ -10710,6 +10750,21 @@ wl_cfg80211_set_ap_role(
                                return err;
                        }
                }
+       } else if (bssidx == 0 && legacy_chip) {
+               err = wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32));
+               if (err < 0) {
+                       WL_ERR(("WLC_DOWN error %d\n", err));
+                       return err;
+               }
+               err = wldev_iovar_setint(dev, "apsta", 0);
+               if (err < 0) {
+                       WL_ERR(("wl apsta 0 error %d\n", err));
+                       return err;
+               }
+               if ((err = wldev_ioctl_set(dev, WLC_SET_AP, &ap, sizeof(s32))) < 0) {
+                       WL_ERR(("setting AP mode failed %d \n", err));
+                       return err;
+               }
        }
 
        if (bssidx == 0) {
@@ -10796,7 +10851,7 @@ wl_cfg80211_bcn_bringup_ap(
                        WL_DBG(("Bss is already up\n"));
        } else if (dev_role == NL80211_IFTYPE_AP) {
 
-               if (!wl_get_drv_status(cfg, AP_CREATING, dev)) {
+               if (!wl_get_drv_status(cfg, AP_CREATED, dev)) {
                        /* Make sure fw is in proper state */
                        err = wl_cfg80211_set_ap_role(cfg, dev);
                        if (unlikely(err)) {
@@ -22109,6 +22164,7 @@ wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
        s32 err = 0;
        gtk_keyinfo_t keyinfo;
+       bcol_gtk_para_t bcol_keyinfo;
 
        WL_DBG(("Enter\n"));
        if (data == NULL || cfg->p2p_net == dev) {
@@ -22123,11 +22179,23 @@ wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
        bcopy(data->kek, keyinfo.KEK, RSN_KEK_LENGTH);
        bcopy(data->replay_ctr, keyinfo.ReplayCounter, RSN_REPLAY_LEN);
 
+       memset(&bcol_keyinfo, 0, sizeof(bcol_keyinfo));
+       bcol_keyinfo.enable = 1;
+       bcol_keyinfo.ptk_len = 64;
+       memcpy(&bcol_keyinfo.ptk[0], data->kck, RSN_KCK_LENGTH);
+       memcpy(&bcol_keyinfo.ptk[RSN_KCK_LENGTH], data->kek, RSN_KEK_LENGTH);
+       err = wldev_iovar_setbuf(dev, "bcol_gtk_rekey_ptk", &bcol_keyinfo,
+               sizeof(bcol_keyinfo), cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
+       if (!err) {
+               return err;
+       }
+
        if ((err = wldev_iovar_setbuf(dev, "gtk_key_info", &keyinfo, sizeof(keyinfo),
                cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync)) < 0) {
                WL_ERR(("seting gtk_key_info failed code=%d\n", err));
                return err;
        }
+
        WL_DBG(("Exit\n"));
        return err;
 }
index ef1dde1c6aa05e780b15ef6a241338eb3fcac095..a612957a16e1a43a4489facd2ec6a50407fc64f4 100644 (file)
@@ -1072,17 +1072,21 @@ wl_escan_set_scan(
                ESCAN_ERROR(("device is not ready\n"));
                return -EIO;
        }
+       if (escan->escan_state == ESCAN_STATE_DOWN) {
+               ESCAN_ERROR(("STATE is down\n"));
+               return -EIO;
+       }
        mutex_lock(&escan->usr_sync);
 
        if (!escan->ioctl_ver) {
                val = 1;
                if ((err = wldev_ioctl(dev, WLC_GET_VERSION, &val, sizeof(int), false) < 0)) {
-                       ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", err));
+                       ESCAN_ERROR(("WLC_GET_VERSION failed, err=%d\n", err));
                        goto exit;
                }
                val = dtoh32(val);
                if (val != WLC_IOCTL_VERSION && val != 1) {
-                       ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+                       ESCAN_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
                                val, WLC_IOCTL_VERSION));
                        goto exit;
                }
@@ -1415,7 +1419,7 @@ s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len)
        } else if (escan->autochannel == 2) {
                bytes_written = snprintf(command, total_len, "2g=%d 5g=%d",
                        escan->best_2g_ch, escan->best_5g_ch);
-               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+               ESCAN_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
                ret = bytes_written;
        }
 
@@ -1452,7 +1456,7 @@ static void wl_escan_deinit(struct wl_escan_info *escan)
        wl_destroy_event_handler(escan);
        wl_flush_eq(escan);
        del_timer_sync(&escan->scan_timeout);
-       escan->escan_state = ESCAN_STATE_IDLE;
+       escan->escan_state = ESCAN_STATE_DOWN;
 
 #if defined(RSSIAVG)
        wl_free_rssi_cache(&escan->g_rssi_cache_ctrl);
@@ -1460,6 +1464,7 @@ static void wl_escan_deinit(struct wl_escan_info *escan)
 #if defined(BSSCACHE)
        wl_free_bss_cache(&escan->g_bss_cache_ctrl);
 #endif
+       wl_ext_add_remove_pm_enable_work(&escan->conn_info, FALSE);
 }
 
 static s32 wl_escan_init(struct wl_escan_info *escan)
@@ -1482,6 +1487,7 @@ static s32 wl_escan_init(struct wl_escan_info *escan)
 #endif
 
        if (wl_create_event_handler(escan)) {
+               ESCAN_ERROR(("device is not ready\n"));
                err = -ENOMEM;
                goto err;
        }
@@ -1490,14 +1496,33 @@ static s32 wl_escan_init(struct wl_escan_info *escan)
        escan->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
        escan->escan_state = ESCAN_STATE_IDLE;
 
-       mutex_init(&escan->usr_sync);
-
        return 0;
 err:
        wl_escan_deinit(escan);
        return err;
 }
 
+void wl_escan_down(dhd_pub_t *dhdp)
+{
+       struct wl_escan_info *escan = dhdp->escan;
+
+       wl_escan_deinit(escan);
+}
+
+int wl_escan_up(struct net_device *net, dhd_pub_t *dhdp)
+{
+       struct wl_escan_info *escan = dhdp->escan;
+       int err;
+
+       err = wl_escan_init(escan);
+       if (err) {
+               ESCAN_ERROR(("wl_escan_init err %d\n", err));
+               return err;
+       }
+
+       return 0;
+}
+
 void wl_escan_detach(dhd_pub_t *dhdp)
 {
        struct wl_escan_info *escan = dhdp->escan;
@@ -1523,6 +1548,7 @@ int
 wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
 {
        struct wl_escan_info *escan = NULL;
+       int err = 0;
 
        printf("%s: Enter\n", __FUNCTION__);
 
@@ -1537,7 +1563,9 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
        /* we only care about main interface so save a global here */
        escan->dev = dev;
        escan->pub = dhdp;
-       escan->escan_state = ESCAN_STATE_IDLE;
+       escan->conn_info.dev = dev;
+       escan->conn_info.dhd = dhdp;
+       escan->escan_state = ESCAN_STATE_DOWN;
 
        escan->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
        if (unlikely(!escan->escan_ioctl_buf)) {
@@ -1545,7 +1573,14 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
                goto err ;
        }
        wl_init_eq(escan);
-       wl_escan_init(escan);
+       err = wl_escan_init(escan);
+       if (err) {
+               ESCAN_ERROR(("wl_escan_init err %d\n", err));
+               return err;
+       }
+       mutex_init(&escan->usr_sync);
+       mutex_init(&escan->conn_info.pm_sync);
+       INIT_DELAYED_WORK(&escan->conn_info.pm_enable_work, wl_ext_pm_work_handler);
 
        return 0;
 err:
index 1cb74282b315adb47b42f1a04f7f4ff022bc3a2e..86cde6290ccf3ff5acc5a79d51e1092027e53639 100644 (file)
@@ -34,6 +34,7 @@ struct pmk_list {
 \r
 /* donlge escan state */\r
 enum escan_state {\r
+       ESCAN_STATE_DOWN,\r
        ESCAN_STATE_IDLE,\r
        ESCAN_STATE_SCANING\r
 };\r
@@ -47,7 +48,7 @@ typedef struct wl_escan_info {
        struct net_device *dev;\r
        dhd_pub_t *pub;\r
        struct timer_list scan_timeout;   /* Timer for catch scan event timeout */\r
-       int    escan_state;\r
+       int escan_state;\r
        int ioctl_ver;\r
 \r
        char ioctlbuf[WLC_IOCTL_SMLEN];\r
@@ -88,6 +89,8 @@ int wl_escan_get_scan(struct net_device *dev, struct iw_request_info *info,
 s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len);\r
 int wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp);\r
 void wl_escan_detach(dhd_pub_t *dhdp);\r
+int wl_escan_up(struct net_device *net, dhd_pub_t *dhdp);\r
+void wl_escan_down(dhd_pub_t *dhdp);\r
 \r
 #endif /* _wl_escan_ */\r
 \r
index 1556d9c8118eb58f654bf3425deee61980011f55..7859fba395c8894186123ef9d2b437076a02c054 100644 (file)
@@ -472,18 +472,35 @@ wl_iw_set_pm(
 #endif /* WIRELESS_EXT > 12 */
 
 static void
-wl_iw_check_handshake(struct net_device *dev, bool set)
+wl_iw_update_connect_status(struct net_device *dev, enum wl_ext_status status)
 {
 #ifndef WL_CFG80211
        struct dhd_pub *dhd = dhd_get_pub(dev);
        int cur_eapol_status = 0;
        int wpa_auth = 0;
        int error = -EINVAL;
+       wl_conn_info_t *conn_info = NULL;
+#ifdef WL_ESCAN
+       wl_escan_info_t *escan;
+       if (dhd && dhd->escan) {
+               escan = (wl_escan_info_t *)dhd->escan;
+               conn_info = &escan->conn_info;
+       }
+#else
+       iscan_info_t *iscan;
+       if (dhd && dhd->iscan) {
+               iscan = (iscan_info_t *)dhd->iscan;
+               conn_info = &iscan->conn_info;
+       }
+#endif
+
+       if (!dhd || !dhd->conf || !conn_info)
+               return;
 
-       if (dhd && dhd->conf)
-               cur_eapol_status = dhd->conf->eapol_status;
+       cur_eapol_status = dhd->conf->eapol_status;
 
-       if (set) {
+       if (status == WL_EXT_STATUS_CONNECTING) {
+               wl_ext_add_remove_pm_enable_work(conn_info, TRUE);
                if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &wpa_auth))) {
                        WL_ERROR(("%s: wpa_auth get error %d\n", __FUNCTION__, error));
                        return;
@@ -492,7 +509,20 @@ wl_iw_check_handshake(struct net_device *dev, bool set)
                        dhd->conf->eapol_status = EAPOL_STATUS_WPA_START;
                else
                        dhd->conf->eapol_status = EAPOL_STATUS_NONE;
-       } else {
+       } else if (status == WL_EXT_STATUS_ADD_KEY) {
+               dhd->conf->eapol_status = EAPOL_STATUS_WPA_END;
+       } else if (status == WL_EXT_STATUS_DISCONNECTING) {
+               wl_ext_add_remove_pm_enable_work(conn_info, FALSE);
+               if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
+                               cur_eapol_status < EAPOL_STATUS_WPA_END) {
+                       WL_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
+                       dhd->conf->eapol_status = EAPOL_STATUS_NONE;
+               } else if (cur_eapol_status >= EAPOL_STATUS_WPS_WSC_START &&
+                               cur_eapol_status < EAPOL_STATUS_WPS_DONE) {
+                       WL_ERROR(("%s: WPS failed at %d\n", __FUNCTION__, cur_eapol_status));
+                       dhd->conf->eapol_status = EAPOL_STATUS_NONE;
+               }
+       } else if (status == WL_EXT_STATUS_DISCONNECTED) {
                if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
                                cur_eapol_status < EAPOL_STATUS_WPA_END) {
                        WL_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
@@ -722,8 +752,11 @@ wl_iw_set_mode(
 #endif
 
        WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));
-       if (conn_info)
-               memset(conn_info, 0, sizeof(wl_conn_info_t));
+       if (conn_info) {
+               memset(&conn_info->ssid, 0, sizeof(wlc_ssid_t));
+               memset(&conn_info->bssid, 0, sizeof(struct ether_addr));
+               conn_info->channel = 0;
+       }
 
        switch (*uwrq) {
        case IW_MODE_MASTER:
@@ -1098,7 +1131,7 @@ wl_iw_set_wap(
                if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
                        WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
                }
-               wl_iw_check_handshake(dev, FALSE);
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
                return 0;
        }
        /* WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data),
@@ -1117,7 +1150,7 @@ wl_iw_set_wap(
                }
                WL_ERROR(("%s: join BSSID="MACSTR"\n", __FUNCTION__, MAC2STR((u8 *)awrq->sa_data)));
        }
-       wl_iw_check_handshake(dev, TRUE);
+       wl_iw_update_connect_status(dev, WL_EXT_STATUS_CONNECTING);
 
        return 0;
 }
@@ -1178,7 +1211,7 @@ wl_iw_mlme(
                WL_ERROR(("%s: Invalid ioctl data.\n", __FUNCTION__));
                return error;
        }
-       wl_iw_check_handshake(dev, FALSE);
+       wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
 
        return error;
 }
@@ -1869,7 +1902,7 @@ wl_iw_set_essid(
                        }
                        WL_ERROR(("%s: join SSID=%s\n", __FUNCTION__, ssid.SSID));
                }
-               wl_iw_check_handshake(dev, TRUE);
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_CONNECTING);
        }
        /* If essid null then it is "iwconfig <interface> essid off" command */
        else {
@@ -1880,7 +1913,7 @@ wl_iw_set_essid(
                        WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
                        return error;
                }
-               wl_iw_check_handshake(dev, FALSE);
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
        }
        return 0;
 }
@@ -2540,7 +2573,6 @@ wl_iw_set_encodeext(
        wl_wsec_key_t key;
        int error;
        struct iw_encode_ext *iwe;
-       struct dhd_pub *dhd = dhd_get_pub(dev);
 
        WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name));
 
@@ -2666,8 +2698,7 @@ wl_iw_set_encodeext(
                error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
                if (error)
                        return error;
-               if (dhd && dhd->conf)
-                       dhd->conf->eapol_status = EAPOL_STATUS_WPA_END;
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_ADD_KEY);
        }
        return 0;
 }
@@ -3458,11 +3489,20 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        uint32 datalen = ntoh32(e->datalen);
        uint32 status =  ntoh32(e->status);
        uint32 reason =  ntoh32(e->reason);
-#ifndef WL_ESCAN
        struct dhd_pub *dhd = dhd_get_pub(dev);
+       wl_conn_info_t *conn_info = NULL;
+#ifdef WL_ESCAN
+       wl_escan_info_t *escan;
+       if (dhd && dhd->escan) {
+               escan = (wl_escan_info_t *)dhd->escan;
+               conn_info = &escan->conn_info;
+       }
+#else
        iscan_info_t *iscan;
-       if (dhd && dhd->iscan)
+       if (dhd && dhd->iscan) {
                iscan = (iscan_info_t *)dhd->iscan;
+               conn_info = &iscan->conn_info;
+       }
 #endif
 
        memset(&wrqu, 0, sizeof(wrqu));
@@ -3481,13 +3521,21 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        case WLC_E_REASSOC_IND:
                cmd = IWEVREGISTERED;
                break;
+       case WLC_E_DEAUTH:
+       case WLC_E_DISASSOC:
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
+               printf("%s: disconnected with "MACSTR", event %d, reason %d\n",
+                       __FUNCTION__, MAC2STR((u8 *)wrqu.addr.sa_data), event_type, reason);
+               break;
        case WLC_E_DEAUTH_IND:
        case WLC_E_DISASSOC_IND:
                cmd = SIOCGIWAP;
                wrqu.data.length = strlen(extra);
                bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
                bzero(&extra, ETHER_ADDR_LEN);
-               wl_iw_check_handshake(dev, FALSE);
+               wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
+               printf("%s: disconnected with "MACSTR", event %d, reason %d\n",
+                       __FUNCTION__, MAC2STR((u8 *)wrqu.addr.sa_data), event_type, reason);
                break;
 
        case WLC_E_LINK:
@@ -3497,7 +3545,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                                MAC2STR((u8 *)wrqu.addr.sa_data), reason);
                        bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
                        bzero(&extra, ETHER_ADDR_LEN);
-                       wl_iw_check_handshake(dev, FALSE);
+                       wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
                } else {
                        printf("%s: Link UP with "MACSTR"\n", __FUNCTION__,
                                MAC2STR((u8 *)wrqu.addr.sa_data));
@@ -4035,6 +4083,14 @@ _iscan_sysioc_thread(void *data)
        complete_and_exit(&iscan->sysioc_exited, 0);
 }
 
+void wl_iw_down(dhd_pub_t *dhdp)
+{
+       iscan_info_t *iscan = dhdp->iscan;
+
+       if (iscan)
+               wl_ext_add_remove_pm_enable_work(&iscan->conn_info, FALSE);
+}
+
 int
 wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
 {
@@ -4056,6 +4112,8 @@ wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
        iscan->sysioc_pid = -1;
        /* we only care about main interface so save a global here */
        iscan->dev = dev;
+       iscan->conn_info.dev = dev;
+       iscan->conn_info.dhd = dhdp;
        iscan->iscan_state = ISCAN_STATE_IDLE;
 
        /* Set up the timer */
@@ -4078,6 +4136,8 @@ wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
 #endif
        if (iscan->sysioc_pid < 0)
                return -ENOMEM;
+       mutex_init(&iscan->conn_info.pm_sync);
+       INIT_DELAYED_WORK(&iscan->conn_info.pm_enable_work, wl_ext_pm_work_handler);
        return 0;
 }
 
@@ -4091,6 +4151,7 @@ void wl_iw_detach(dhd_pub_t *dhdp)
                KILL_PROC(iscan->sysioc_pid, SIGTERM);
                wait_for_completion(&iscan->sysioc_exited);
        }
+       wl_ext_add_remove_pm_enable_work(&iscan->conn_info, FALSE);
 
        while (iscan->list_hdr) {
                buf = iscan->list_hdr->next;
index 0adba1b52b03d17000e588ea5ad83a73d8d6fcad..b00a48958dcec776e0f07db8eb794969215debe7 100644 (file)
@@ -132,6 +132,7 @@ int wl_iw_handle_scanresults_ies(char **event_p, char *end,
 #else
 int wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp);
 void wl_iw_detach(dhd_pub_t *dhdp);
+void wl_iw_down(dhd_pub_t *dhdp);
 #endif
 
 #define CSCAN_COMMAND                          "CSCAN "
index ac72f966a362bc778751afc14a65c62605a575e8..398c54a4e80c700f96ea8a8872c25efc066abf09 100644 (file)
@@ -471,7 +471,6 @@ int wldev_set_country(
        int error = -1;
        wl_country_t cspec = {{0}, 0, {0}};
        scb_val_t scbval;
-       char smbuf[WLC_IOCTL_SMLEN];
 #ifdef WL_CFG80211
        struct wireless_dev *wdev = ndev_to_wdev(dev);
        struct wiphy *wiphy = wdev->wiphy;
@@ -518,8 +517,7 @@ int wldev_set_country(
                error = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec);
                if (error)
                        dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
-               error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
-                       smbuf, sizeof(smbuf), NULL);
+               error = dhd_conf_set_country(dhd_get_pub(dev), &cspec);
                if (error < 0) {
                        WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
                                __FUNCTION__, country_code, cspec.ccode, cspec.rev));