wifi:bcm4329: update to 4.218.248.20
authorlbt <lbt@rock-chip.com>
Mon, 14 Feb 2011 03:29:57 +0000 (11:29 +0800)
committerlbt <lbt@rock-chip.com>
Mon, 14 Feb 2011 03:29:57 +0000 (11:29 +0800)
16 files changed:
drivers/net/wireless/bcm4329/Kconfig
drivers/net/wireless/bcm4329/Makefile
drivers/net/wireless/bcm4329/bcmsdh_linux.c
drivers/net/wireless/bcm4329/bcmsdh_sdmmc.c
drivers/net/wireless/bcm4329/bcmsdh_sdmmc_linux.c
drivers/net/wireless/bcm4329/dhd.h
drivers/net/wireless/bcm4329/dhd_bus.h
drivers/net/wireless/bcm4329/dhd_common.c
drivers/net/wireless/bcm4329/dhd_dbg.h
drivers/net/wireless/bcm4329/dhd_linux.c
drivers/net/wireless/bcm4329/dhd_sdio.c
drivers/net/wireless/bcm4329/include/epivers.h
drivers/net/wireless/bcm4329/include/proto/bcmevent.h
drivers/net/wireless/bcm4329/include/wlioctl.h
drivers/net/wireless/bcm4329/wl_iw.c
drivers/net/wireless/bcm4329/wl_iw.h

index aa4355a6225e1b951c6bbbddb21ca6c8003bd6fa..ca5760d32385d886cae591f477b2bde753eb9f37 100644 (file)
@@ -22,6 +22,6 @@ config BCM4329_FW_PATH
 config BCM4329_NVRAM_PATH
        depends on BCM4329
        string "NVRAM path"
-       default "/system/etc/firmware/nvram_B23.txt"
+       default "/proc/calibration"
        ---help---
          Path to the calibration file.
index 3f3b0b0f21b9eb5173cc51bd37685e783a70c01c..6391138c765a298cb038940bd497be32f5553907 100755 (executable)
@@ -6,10 +6,11 @@ DHDCFLAGS = -DLINUX -DBCMDRIVER -DBCMDONGLEHOST -DDHDTHREAD -DBCMWPA2         \
        -Wall -Wstrict-prototypes -Werror -DCUSTOMER_HW2      \
        -DDHD_DEBUG_TRAP -DSOFTAP       \
        -DEMBEDDED_PLATFORM -DARP_OFFLOAD_SUPPORT -DPKT_FILTER_SUPPORT        \
-       -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP    \
+       -DGET_CUSTOM_MAC_ENABLE -DSET_RANDOM_MAC_SOFTAP     \
+       -DKEEP_ALIVE                                                          \
        -Idrivers/net/wireless/bcm4329 -Idrivers/net/wireless/bcm4329/include
 
-#options defines dependent on platform board and applicantion requirements: 
+#options defines dependent on platform board and applicantion requirements:
 #-DOOB_INTR_ONLY -DDHD_USE_STATIC_BUF -DMMC_SDIO_ABORT -DHW_OOB -DCSCAN
 
 DHDOFILES = dhd_linux.o linux_osl.o bcmutils.o dhd_common.o dhd_custom_gpio.o \
index 559f4819b1b650d175c84754152ed594c917fb50..1e33555b0531ee01d5a84d656bf54492812768db 100644 (file)
@@ -301,7 +301,7 @@ int bcmsdh_remove(struct device *dev)
        MFREE(osh, sdhc, sizeof(bcmsdh_hc_t));
        osl_detach(osh);
 
-#if !defined(BCMLXSDMMC)
+#if !defined(BCMLXSDMMC) || defined(OOB_INTR_ONLY)
        dev_set_drvdata(dev, NULL);
 #endif /* !defined(BCMLXSDMMC) */
 
@@ -581,8 +581,6 @@ bcmsdh_unregister(void)
 #endif /* BCMPLATFORM_BUS */
 }
 
-
-
 #if defined(OOB_INTR_ONLY)
 void bcmsdh_oob_intr_set(bool enable)
 {
@@ -624,6 +622,9 @@ int bcmsdh_register_oob_intr(void * dhdp)
 
        SDLX_MSG(("%s Enter\n", __FUNCTION__));
 
+/* Example of  HW_OOB for HW2: please refer to your host  specifiction */
+/* sdhcinfo->oob_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE; */
+
        dev_set_drvdata(sdhcinfo->dev, dhdp);
 
        if (!sdhcinfo->oob_irq_registered) {
@@ -646,10 +647,12 @@ void bcmsdh_unregister_oob_intr(void)
 {
        SDLX_MSG(("%s: Enter\n", __FUNCTION__));
 
-       set_irq_wake(sdhcinfo->oob_irq, 0);
-       disable_irq(sdhcinfo->oob_irq); /* just in case.. */
-       free_irq(sdhcinfo->oob_irq, NULL);
-       sdhcinfo->oob_irq_registered = FALSE;
+       if (sdhcinfo->oob_irq_registered) {
+               set_irq_wake(sdhcinfo->oob_irq, 0);
+               disable_irq(sdhcinfo->oob_irq); /* just in case.. */
+               free_irq(sdhcinfo->oob_irq, NULL);
+               sdhcinfo->oob_irq_registered = FALSE;
+       }
 }
 #endif /* defined(OOB_INTR_ONLY) */
 /* Module parameters specific to each host-controller driver */
index bda91939058765bf788faccaaa65278fc1596314..031367b8f18f996f6ccf50d64909ca3fa111b460 100644 (file)
@@ -675,7 +675,6 @@ sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
                data = 3;       /* enable hw oob interrupt */
        else
                data = 4;       /* disable hw oob interrupt */
-
        data |= 4;              /* Active HIGH */
 
        status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
index 8992a4267f9f78ab6047a3f929dc4fef3a9f55d5..5a1a46c93571c0516f6f2c4ed827e38260fd4261 100644 (file)
@@ -82,7 +82,6 @@ PBCMSDH_SDMMC_INSTANCE gInstance;
 
 extern int bcmsdh_probe(struct device *dev);
 extern int bcmsdh_remove(struct device *dev);
-struct device sdmmc_dev;
 
 static int bcmsdh_sdmmc_probe(struct sdio_func *func,
                               const struct sdio_device_id *id)
@@ -102,7 +101,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
                if(func->device == 0x4) { /* 4318 */
                        gInstance->func[2] = NULL;
                        sd_trace(("NIC found, calling bcmsdh_probe...\n"));
-                       ret = bcmsdh_probe(&sdmmc_dev);
+                       ret = bcmsdh_probe(&func->dev);
                }
        }
 
@@ -110,7 +109,7 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
 
        if (func->num == 2) {
                sd_trace(("F2 found, calling bcmsdh_probe...\n"));
-               ret = bcmsdh_probe(&sdmmc_dev);
+               ret = bcmsdh_probe(&func->dev);
        }
 
        return ret;
@@ -126,7 +125,7 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func)
 
        if (func->num == 2) {
                sd_trace(("F2 found, calling bcmsdh_remove...\n"));
-               bcmsdh_remove(&sdmmc_dev);
+               bcmsdh_remove(&func->dev);
        }
 }
 
@@ -250,10 +249,8 @@ int sdio_function_init(void)
        if (!gInstance)
                return -ENOMEM;
 
-       bzero(&sdmmc_dev, sizeof(sdmmc_dev));
        error = sdio_register_driver(&bcmsdh_sdmmc_driver);
 
-
        return error;
 }
 
@@ -265,7 +262,6 @@ void sdio_function_cleanup(void)
 {
        sd_trace(("%s Enter\n", __FUNCTION__));
 
-
        sdio_unregister_driver(&bcmsdh_sdmmc_driver);
 
        if (gInstance)
index 5d8dc32fd304ca4b5146da95c9824678f1ecebce..1ddf1ff61e7052cd36613dfd0e5c18296fd5d871 100644 (file)
@@ -24,7 +24,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd.h,v 1.32.4.7.2.4.14.49 2010/08/20 17:32:48 Exp $
+ * $Id: dhd.h,v 1.32.4.7.2.4.14.49.4.7 2010/11/12 22:48:36 Exp $
  */
 
 /****************
@@ -86,9 +86,11 @@ enum dhd_bus_wake_state {
        WAKE_LOCK_TMOUT,
        WAKE_LOCK_WATCHDOG,
        WAKE_LOCK_LINK_DOWN_TMOUT,
+       WAKE_LOCK_PNO_FIND_TMOUT,
        WAKE_LOCK_SOFTAP_SET,
        WAKE_LOCK_SOFTAP_STOP,
        WAKE_LOCK_SOFTAP_START,
+       WAKE_LOCK_SOFTAP_THREAD,
        WAKE_LOCK_MAX
 };
 enum dhd_prealloc_index {
@@ -220,6 +222,8 @@ extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub);
 
 extern void dhd_os_start_lock(dhd_pub_t *pub);
 extern void dhd_os_start_unlock(dhd_pub_t *pub);
+extern unsigned long dhd_os_spin_lock(dhd_pub_t *pub);
+extern void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags);
 
 typedef struct dhd_if_event {
        uint8 ifidx;
@@ -348,8 +352,11 @@ typedef enum cust_gpio_modes {
        WLAN_POWER_ON,
        WLAN_POWER_OFF
 } cust_gpio_modes_t;
+
 extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
 extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+extern int net_os_send_hang_message(struct net_device *dev);
+
 /*
  * Insmod parameters for debug/test
  */
@@ -399,6 +406,10 @@ extern uint dhd_sdiod_drive_strength;
 /* Override to force tx queueing all the time */
 extern uint dhd_force_tx_queueing;
 
+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
+#define KEEP_ALIVE_PERIOD 55000
+#define NULL_PKT_STR   "null_pkt"
+
 #ifdef SDTEST
 /* Echo packet generator (SDIO), pkts/s */
 extern uint dhd_pktgen;
index 9e29fb955444611dad6cd1bc0840963ee68d0359..97af41b313d0f3a0e32aadf257fe1ec24dd0400e 100644 (file)
@@ -24,7 +24,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_bus.h,v 1.4.6.3.2.3.6.6 2010/05/17 18:18:13 Exp $
+ * $Id: dhd_bus.h,v 1.4.6.3.2.3.6.7 2010/08/13 01:35:24 Exp $
  */
 
 #ifndef _dhd_bus_h_
@@ -63,7 +63,7 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
 #ifdef DHD_DEBUG
 /* Device console input function */
 extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
-#endif
+#endif /* DHD_DEBUG */
 
 /* Deferred processing for the bus, return TRUE requests reschedule */
 extern bool dhd_bus_dpc(struct dhd_bus *bus);
index dab1ca42b338bfd8841d652966f1977601d77774..df7adbef694158c5c69365ae3ebd473ed142cc1e 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.3 2010/09/10 21:30:16 Exp $
+ * $Id: dhd_common.c,v 1.5.6.8.2.6.6.69.4.20 2010/12/20 23:37:28 Exp $
  */
 #include <typedefs.h>
 #include <osl.h>
@@ -74,6 +74,13 @@ extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen);
 void dhd_iscan_lock(void);
 void dhd_iscan_unlock(void);
 
+#if defined(SOFTAP)
+extern bool ap_fw_loaded;
+#endif
+#if defined(KEEP_ALIVE)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on);
+#endif /* KEEP_ALIVE */
+
 /* Packet alignment for most efficient SDIO (can change based on platform) */
 #ifndef DHD_SDALIGN
 #define DHD_SDALIGN    32
@@ -140,7 +147,7 @@ dhd_common_init(void)
         * behaviour since the value of the globals may be different on the
         * first time that the driver is initialized vs subsequent initializations.
         */
-       dhd_msg_level = DHD_ERROR_VAL |DHD_TRACE_VAL|DHD_INFO_VAL;
+       dhd_msg_level = DHD_ERROR_VAL;
 #ifdef CONFIG_BCM4329_FW_PATH
        strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN-1);
 #else
@@ -1225,11 +1232,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        uint power_mode = PM_FAST;
        uint32 dongle_align = DHD_SDALIGN;
        uint32 glom = 0;
-       uint bcn_timeout = 3;
+       uint bcn_timeout = 4;
        int scan_assoc_time = 40;
        int scan_unassoc_time = 40;
+       uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
+#if defined(SOFTAP)
+       uint dtim = 1;
+#endif
+       int ret = 0;
 #ifdef GET_CUSTOM_MAC_ENABLE
-       int ret;
        struct ether_addr ea_addr;
 #endif /* GET_CUSTOM_MAC_ENABLE */
 
@@ -1256,7 +1267,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef SET_RANDOM_MAC_SOFTAP
        if (strstr(fw_path, "apsta") != NULL) {
                uint rand_mac;
-               int ret;
 
                srandom32((uint)jiffies);
                rand_mac = random32();
@@ -1287,6 +1297,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                }
        }
 
+       /* Set Listen Interval */
+       bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf));
+       if ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf))) < 0)
+               DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
+
        /* query for 'ver' to get version info from firmware */
        memset(buf, 0, sizeof(buf));
        ptr = buf;
@@ -1315,6 +1330,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
        dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 
+#if defined(SOFTAP)
+       if (ap_fw_loaded == TRUE) {
+               dhdcdc_set_ioctl(dhd, 0, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim));
+       }
+#endif
+
        if (dhd_roam == 0)
        {
                /* set internal roaming roaming parameters */
@@ -1395,6 +1416,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* PKT_FILTER_SUPPORT */
 
+#if defined(KEEP_ALIVE)
+       {
+       /* Set Keep Alive : be sure to use FW with -keepalive */
+       int res;
+
+       if (ap_fw_loaded == FALSE) {
+               if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0)
+                       DHD_ERROR(("%s set keeplive failed %d\n", \
+               __FUNCTION__, res));
+               }
+       }
+#endif
+
        dhd_os_proto_unblock(dhd);
 
        return 0;
@@ -1449,7 +1483,7 @@ dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
        dhd_pub_t *dhd = dhd_bus_pub(dhdp);
 
        dhd_iscan_lock();
-       /* If iscan_delete is null then delete the entire 
+       /* If iscan_delete is null then delete the entire
         * chain or else delete specific one provided
         */
        if (!iscan_delete) {
@@ -1780,7 +1814,58 @@ fail:
        return status;
 }
 
-#endif 
+#endif
+
+/* Function to estimate possible DTIM_SKIP value */
+int dhd_get_dtim_skip(dhd_pub_t *dhd)
+{
+       int bcn_li_dtim;
+       char buf[128];
+       int ret;
+       int dtim_assoc = 0;
+
+       if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
+               bcn_li_dtim = 3;
+       else
+               bcn_li_dtim = dhd->dtim_skip;
+
+       /* Read DTIM value if associated */
+       memset(buf, 0, sizeof(buf));
+       bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf));
+       if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf))) < 0) {
+               DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
+               bcn_li_dtim = 1;
+               goto exit;
+       }
+       else
+               dtim_assoc = dtoh32(*(int *)buf);
+
+       DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n", \
+                        __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
+
+       /* if not assocated just eixt */
+       if (dtim_assoc == 0) {
+               goto exit;
+       }
+
+       /* check if sta listen interval fits into AP dtim */
+       if (dtim_assoc > LISTEN_INTERVAL) {
+               /* AP DTIM to big for our Listen Interval : no dtim skiping */
+               bcn_li_dtim = 1;
+               DHD_ERROR(("%s DTIM=%d > Listen=%d : too big ...\n", \
+                                __FUNCTION__, dtim_assoc, LISTEN_INTERVAL));
+               goto exit;
+       }
+
+       if ((bcn_li_dtim * dtim_assoc) > LISTEN_INTERVAL) {
+               /* Round up dtim_skip to fit into STAs Listen Interval */
+               bcn_li_dtim = (int)(LISTEN_INTERVAL / dtim_assoc);
+               DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim));
+       }
+
+exit:
+       return bcn_li_dtim;
+}
 
 #ifdef PNO_SUPPORT
 int dhd_pno_clean(dhd_pub_t *dhd)
@@ -1888,6 +1973,11 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
        if (scan_fr  != 0)
                pfn_param.scan_freq = htod32(scan_fr);
 
+       if (pfn_param.scan_freq > PNO_SCAN_MAX_FW) {
+               DHD_ERROR(("%s pno freq above %d sec\n", __FUNCTION__, PNO_SCAN_MAX_FW));
+               return err;
+       }
+
        bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf));
        dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 
@@ -1912,6 +2002,9 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr)
                                        __FUNCTION__, i, err));
                                return err;
                        }
+                       else
+                               DHD_ERROR(("%s set OK with PNO time=%d\n", __FUNCTION__, \
+                                                               pfn_param.scan_freq));
                }
                else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err));
        }
@@ -1933,6 +2026,53 @@ int dhd_pno_get_status(dhd_pub_t *dhd)
 
 #endif /* PNO_SUPPORT */
 
+#if defined(KEEP_ALIVE)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on)
+{
+       char buf[256];
+       char *buf_ptr = buf;
+       wl_keep_alive_pkt_t keep_alive_pkt;
+       char * str;
+       int str_len, buf_len;
+       int res = 0;
+       int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */
+
+       DHD_TRACE(("%s: ka:%d\n", __FUNCTION__, ka_on));
+
+       if (ka_on) { /* on suspend */
+               keep_alive_pkt.period_msec = keep_alive_period;
+
+       } else {
+               /* on resume, turn off keep_alive packets  */
+               keep_alive_pkt.period_msec = 0;
+       }
+
+       /* IOC var name  */
+       str = "keep_alive";
+       str_len = strlen(str);
+       strncpy(buf, str, str_len);
+       buf[str_len] = '\0';
+       buf_len = str_len + 1;
+
+       /* set ptr to IOCTL payload after the var name */
+       buf_ptr += buf_len; /* include term Z */
+
+       /* copy Keep-alive attributes from local var keep_alive_pkt */
+       str = NULL_PKT_STR;
+       keep_alive_pkt.len_bytes = strlen(str);
+
+       memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN);
+       buf_ptr += WL_KEEP_ALIVE_FIXED_LEN;
+
+       /* copy packet data */
+       memcpy(buf_ptr, str, keep_alive_pkt.len_bytes);
+       buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes);
+
+       res = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+       return res;
+}
+#endif /* defined(KEEP_ALIVE) */
+
 #if defined(CSCAN)
 
 /* Androd ComboSCAN support */
@@ -2183,4 +2323,4 @@ wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
        return num;
 }
 
-#endif 
+#endif
index 9bbd289ce496eb9db156de38f1f7369c7bcb7c44..b48c1d70f1441c8dde928f24ac7d9b3823d50d93 100644 (file)
@@ -29,8 +29,8 @@
 
 #ifdef DHD_DEBUG
 
-#define DHD_ERROR(args)                do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
-                                               printf args;} while (0)
+#define DHD_ERROR(args)               do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
+                                                               printf args;} while (0)
 #define DHD_TRACE(args)                do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
 #define DHD_INFO(args)         do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
 #define DHD_DATA(args)         do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
index f35ed9cd834c193092a11b953933d619fa0eb848..f6b47a26e29eed79dec15ceb6d848d993c0a086a 100644 (file)
@@ -22,7 +22,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104 2010/08/20 19:15:40 Exp $
+ * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.104.4.35 2010/11/17 03:13:21 Exp $
  */
 
 #ifdef CONFIG_WIFI_CONTROL_FUNC
@@ -107,7 +107,7 @@ int wifi_set_power(int on, unsigned long msec)
 
 int wifi_set_reset(int on, unsigned long msec)
 {
-       printk("%s = %d\n", __FUNCTION__, on);
+       DHD_TRACE(("%s = %d\n", __FUNCTION__, on));
        if (wifi_control_data && wifi_control_data->set_reset) {
                wifi_control_data->set_reset(on);
        }
@@ -118,7 +118,7 @@ int wifi_set_reset(int on, unsigned long msec)
 
 int wifi_get_mac_addr(unsigned char *buf)
 {
-       printk("%s\n", __FUNCTION__);
+       DHD_TRACE(("%s\n", __FUNCTION__));
        if (!buf)
                return -EINVAL;
        if (wifi_control_data && wifi_control_data->get_mac_addr) {
@@ -220,9 +220,10 @@ print_tainted()
 #include <wl_iw.h>
 #endif /* defined(CONFIG_WIRELESS_EXT) */
 
+extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
+
 #if defined(CONFIG_HAS_EARLYSUSPEND)
 #include <linux/earlysuspend.h>
-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len);
 #endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
 
 #ifdef PKT_FILTER_SUPPORT
@@ -263,6 +264,8 @@ typedef struct dhd_info {
        struct tasklet_struct tasklet;
        spinlock_t      sdlock;
        spinlock_t      txqlock;
+       spinlock_t      dhd_lock;
+
        /* Thread based operation */
        bool threads_only;
        struct semaphore sdsem;
@@ -282,10 +285,10 @@ typedef struct dhd_info {
        int wl_count;
        int wl_packet;
 
-       int hang_was_sent;
-
-       struct mutex wl_start_lock;
-
+       int hang_was_sent; /* flag that message was send at least once */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+       struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */
+#endif
        /* Thread to issue ioctl for multicast */
        long sysioc_pid;
        struct semaphore sysioc_sem;
@@ -309,7 +312,7 @@ char nvram_path[MOD_PARAM_PATHLEN];
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 struct semaphore dhd_registration_sem;
-#define DHD_REGISTRATION_TIMEOUT  8000  /* msec : allowed time to finished dhd registration */
+#define DHD_REGISTRATION_TIMEOUT  12000  /* msec : allowed time to finished dhd registration */
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
 /* load firmware and/or nvram values from the filesystem */
 module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0);
@@ -523,6 +526,8 @@ static void dhd_set_packet_filter(int value, dhd_pub_t *dhd)
 #endif
 }
 
+
+
 #if defined(CONFIG_HAS_EARLYSUSPEND)
 static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 {
@@ -541,7 +546,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                if (value && dhd->in_suspend) {
 
                        /* Kernel suspended */
-                               DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__));
+                       DHD_TRACE(("%s: force extra Suspend setting \n", __FUNCTION__));
 
                        dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
                                (char *)&power_mode, sizeof(power_mode));
@@ -549,26 +554,24 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        /* Enable packet filter, only allow unicast packet to send up */
                        dhd_set_packet_filter(1, dhd);
 
-                               /* if dtim skip setup as default force it to wake each thrid dtim
-                                *  for better power saving.
-                                *  Note that side effect is chance to miss BC/MC packet
-                               */
-                               if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
-                                       bcn_li_dtim = 3;
-                               else
-                                       bcn_li_dtim = dhd->dtim_skip;
+                       /* if dtim skip setup as default force it to wake each thrid dtim
+                        *  for better power saving.
+                        *  Note that side effect is chance to miss BC/MC packet
+                       */
+                       bcn_li_dtim = dhd_get_dtim_skip(dhd);
                        bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
                                4, iovbuf, sizeof(iovbuf));
                        dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 #ifdef CUSTOMER_HW2
-                       /* Disable build-in roaming to allowed ext supplicant to take of roaming */
+                       /* Disable build-in roaming during suspend */
                        bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
                        dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 #endif /* CUSTOMER_HW2 */
+
                } else {
 
                        /* Kernel resumed  */
-                               DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__));
+                       DHD_TRACE(("%s: Remove extra suspend setting \n", __FUNCTION__));
 
                        power_mode = PM_FAST;
                        dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode,
@@ -577,11 +580,11 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        /* disable pkt filter */
                        dhd_set_packet_filter(0, dhd);
 
-                               /* restore pre-suspend setting for dtim_skip */
-                               bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
-                                       4, iovbuf, sizeof(iovbuf));
+                       /* restore pre-suspend setting for dtim_skip */
+                       bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
+                               4, iovbuf, sizeof(iovbuf));
 
-                               dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+                       dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
 #ifdef CUSTOMER_HW2
                        roamvar = dhd_roam;
                        bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
@@ -903,13 +906,18 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr)
 
 #ifdef SOFTAP
 extern struct net_device *ap_net_dev;
+/* semaphore that the soft AP CODE waits on */
+extern struct semaphore ap_eth_sema;
 #endif
 
 static void
 dhd_op_if(dhd_if_t *ifp)
 {
-       dhd_info_t      *dhd;
-       int                     ret = 0, err = 0;
+       dhd_info_t *dhd;
+       int ret = 0, err = 0;
+#ifdef SOFTAP
+       unsigned long flags;
+#endif
 
        ASSERT(ifp && ifp->info && ifp->idx);   /* Virtual interfaces only */
 
@@ -944,13 +952,12 @@ dhd_op_if(dhd_if_t *ifp)
                                ret = -EOPNOTSUPP;
                        } else {
 #ifdef SOFTAP
-                                /* semaphore that the soft AP CODE waits on */
-                               extern struct semaphore  ap_eth_sema;
-
+                               flags = dhd_os_spin_lock(&dhd->pub);
                                /* save ptr to wl0.1 netdev for use in wl_iw.c  */
                                ap_net_dev = ifp->net;
                                 /* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */
                                up(&ap_eth_sema);
+                               dhd_os_spin_unlock(&dhd->pub, flags);
 #endif
                                DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n",
                                        current->pid, ifp->net->name));
@@ -979,8 +986,10 @@ dhd_op_if(dhd_if_t *ifp)
                dhd->iflist[ifp->idx] = NULL;
                MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
 #ifdef SOFTAP
+               flags = dhd_os_spin_lock(&dhd->pub);
                if (ifp->net == ap_net_dev)
                        ap_net_dev = NULL;     /* NULL SOFTAP global as well */
+               dhd_os_spin_unlock(&dhd->pub, flags);
 #endif /*  SOFTAP */
        }
 }
@@ -992,6 +1001,7 @@ _dhd_sysioc_thread(void *data)
        int i;
 #ifdef SOFTAP
        bool in_ap = FALSE;
+       unsigned long flags;
 #endif
 
        DAEMONIZE("dhd_sysioc");
@@ -1003,7 +1013,9 @@ _dhd_sysioc_thread(void *data)
                        if (dhd->iflist[i]) {
                                DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i));
 #ifdef SOFTAP
+                               flags = dhd_os_spin_lock(&dhd->pub);
                                in_ap = (ap_net_dev != NULL);
+                               dhd_os_spin_unlock(&dhd->pub, flags);
 #endif /* SOFTAP */
                                if (dhd->iflist[i]->state)
                                        dhd_op_if(dhd->iflist[i]);
@@ -1038,6 +1050,7 @@ _dhd_sysioc_thread(void *data)
                dhd_os_wake_unlock(&dhd->pub);
                dhd_os_start_unlock(&dhd->pub);
        }
+       DHD_TRACE(("%s: stopped\n",__FUNCTION__));
        complete_and_exit(&dhd->sysioc_exited, 0);
 }
 
@@ -1389,22 +1402,24 @@ dhd_watchdog_thread(void *data)
        /* Run until signal received */
        while (1) {
                if (down_interruptible (&dhd->watchdog_sem) == 0) {
-
+                       dhd_os_sdlock(&dhd->pub);
                        if (dhd->pub.dongle_reset == FALSE) {
+                               DHD_TIMER(("%s:\n", __FUNCTION__));
                                /* Call the bus module watchdog */
                                dhd_bus_watchdog(&dhd->pub);
-                       }
-                       /* Count the tick for reference */
-                       dhd->pub.tickcnt++;
 
-                       /* Reschedule the watchdog */
-                       if (dhd->wd_timer_valid)
-                               mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+                               /* Count the tick for reference */
+                               dhd->pub.tickcnt++;
 
+                               /* Reschedule the watchdog */
+                               if (dhd->wd_timer_valid)
+                                       mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+                       }
+                       dhd_os_sdunlock(&dhd->pub);
                        dhd_os_wake_unlock(&dhd->pub);
-               }
-               else
+               } else {
                        break;
+               }
        }
 
        complete_and_exit(&dhd->watchdog_exited, 0);
@@ -1416,11 +1431,17 @@ dhd_watchdog(ulong data)
        dhd_info_t *dhd = (dhd_info_t *)data;
 
        dhd_os_wake_lock(&dhd->pub);
+       if (dhd->pub.dongle_reset) {
+               dhd_os_wake_unlock(&dhd->pub);
+               return;
+       }
+
        if (dhd->watchdog_pid >= 0) {
                up(&dhd->watchdog_sem);
                return;
        }
 
+       dhd_os_sdlock(&dhd->pub);
        /* Call the bus module watchdog */
        dhd_bus_watchdog(&dhd->pub);
 
@@ -1430,6 +1451,7 @@ dhd_watchdog(ulong data)
        /* Reschedule the watchdog */
        if (dhd->wd_timer_valid)
                mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+       dhd_os_sdunlock(&dhd->pub);
        dhd_os_wake_unlock(&dhd->pub);
 }
 
@@ -1854,7 +1876,7 @@ dhd_stop(struct net_device *net)
 #if !defined(IGNORE_ETH0_DOWN)
        dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
 
-       DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+       DHD_TRACE(("%s: Enter %s\n", __FUNCTION__, net->name));
        if (dhd->pub.up == 0) {
                return 0;
        }
@@ -1879,7 +1901,8 @@ dhd_open(struct net_device *net)
 #endif
        int ifidx;
 
-       wl_control_wl_start(net);  /* start if needed */
+       /*  Force start if ifconfig_up gets called before START command */
+       wl_control_wl_start(net);
 
        ifidx = dhd_net2idx(dhd, net);
        DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
@@ -1889,7 +1912,6 @@ dhd_open(struct net_device *net)
                return -1;
        }
 
-
        if (ifidx == 0) { /* do it only for primary eth0 */
 
                atomic_set(&dhd->pend_8021x_cnt, 0);
@@ -2047,6 +2069,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        /* Initialize the spinlocks */
        spin_lock_init(&dhd->sdlock);
        spin_lock_init(&dhd->txqlock);
+       spin_lock_init(&dhd->dhd_lock);
 
        /* Initialize Wakelock stuff */
        spin_lock_init(&dhd->wl_lock);
@@ -2056,8 +2079,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
        wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
 #endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        mutex_init(&dhd->wl_start_lock);
-
+#endif
        /* Link to info module */
        dhd->pub.info = dhd;
 
@@ -2164,12 +2188,15 @@ dhd_bus_start(dhd_pub_t *dhdp)
 
        DHD_TRACE(("%s: \n", __FUNCTION__));
 
+       dhd_os_sdlock(dhdp);
+
        /* try to download image and nvram to the dongle */
        if  (dhd->pub.busstate == DHD_BUS_DOWN) {
                if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh,
                                                fw_path, nv_path))) {
                        DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n",
                                   __FUNCTION__, fw_path, nv_path));
+                       dhd_os_sdunlock(dhdp);
                        return -1;
                }
        }
@@ -2179,16 +2206,18 @@ dhd_bus_start(dhd_pub_t *dhdp)
        dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
 
        /* Bring up the bus */
-       if ((ret = dhd_bus_init(&dhd->pub, TRUE)) != 0) {
+       if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) {
                DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret));
+               dhd_os_sdunlock(dhdp);
                return ret;
        }
 #if defined(OOB_INTR_ONLY)
        /* Host registration for OOB interrupt */
        if (bcmsdh_register_oob_intr(dhdp)) {
-               del_timer_sync(&dhd->timer);
                dhd->wd_timer_valid = FALSE;
+               del_timer_sync(&dhd->timer);
                DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__));
+               dhd_os_sdunlock(dhdp);
                return -ENODEV;
        }
 
@@ -2198,12 +2227,15 @@ dhd_bus_start(dhd_pub_t *dhdp)
 
        /* If bus is not ready, can't come up */
        if (dhd->pub.busstate != DHD_BUS_DATA) {
-               del_timer_sync(&dhd->timer);
                dhd->wd_timer_valid = FALSE;
+               del_timer_sync(&dhd->timer);
                DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
+               dhd_os_sdunlock(dhdp);
                return -ENODEV;
        }
 
+       dhd_os_sdunlock(dhdp);
+
 #ifdef EMBEDDED_PLATFORM
        bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
        dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
@@ -2227,6 +2259,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
        setbit(dhdp->eventmask, WLC_E_TXFAIL);
        setbit(dhdp->eventmask, WLC_E_JOIN_START);
        setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
+       setbit(dhdp->eventmask, WLC_E_RELOAD);
 #ifdef PNO_SUPPORT
        setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
 #endif /* PNO_SUPPORT */
@@ -2364,6 +2397,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
               dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]);
 
 #if defined(CONFIG_WIRELESS_EXT)
+#if defined(CONFIG_FIRST_SCAN)
 #ifdef SOFTAP
        if (ifidx == 0)
                /* Don't call for SOFTAP Interface in SOFTAP MODE */
@@ -2371,6 +2405,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
 #else
                wl_iw_iscan_set_scan_broadcast_prep(net, 1);
 #endif /* SOFTAP */
+#endif /* CONFIG_FIRST_SCAN */
 #endif /* CONFIG_WIRELESS_EXT */
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -2407,8 +2442,8 @@ dhd_bus_detach(dhd_pub_t *dhdp)
 #endif /* defined(OOB_INTR_ONLY) */
 
                        /* Clear the watchdog timer */
-                       del_timer_sync(&dhd->timer);
                        dhd->wd_timer_valid = FALSE;
+                       del_timer_sync(&dhd->timer);
                }
        }
 }
@@ -2434,16 +2469,18 @@ dhd_detach(dhd_pub_t *dhdp)
                        /* Attach and link in the iw */
                        wl_iw_detach();
 #endif
-
-                       for (i = 1; i < DHD_MAX_IFS; i++)
-                               if (dhd->iflist[i])
-                                       dhd_del_if(dhd, i);
-
                        if (dhd->sysioc_pid >= 0) {
                                KILL_PROC(dhd->sysioc_pid, SIGTERM);
                                wait_for_completion(&dhd->sysioc_exited);
                        }
 
+                       for (i = 1; i < DHD_MAX_IFS; i++)
+                               if (dhd->iflist[i]) {
+                                       dhd->iflist[i]->state = WLC_E_IF_DEL;
+                                       dhd->iflist[i]->idx = i;
+                                       dhd_op_if(dhd->iflist[i]);
+                               }
+
                        ifp = dhd->iflist[0];
                        ASSERT(ifp);
 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
@@ -2488,8 +2525,7 @@ dhd_detach(dhd_pub_t *dhdp)
        }
 }
 
-void
-rockchip_wifi_exit_module(void)
+void rockchip_wifi_exit_module(void)
 {
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -2501,8 +2537,7 @@ rockchip_wifi_exit_module(void)
        dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
 }
 
-int
-rockchip_wifi_init_module(void)
+int rockchip_wifi_init_module(void)
 {
        int error;
 
@@ -2686,29 +2721,28 @@ void
 dhd_os_wd_timer(void *bus, uint wdtick)
 {
        dhd_pub_t *pub = bus;
-       static uint save_dhd_watchdog_ms = 0;
        dhd_info_t *dhd = (dhd_info_t *)pub->info;
+       unsigned long flags;
+       int del_timer_flag = FALSE;
 
-       /* don't start the wd until fw is loaded */
-       if (pub->busstate == DHD_BUS_DOWN)
-               return;
+       flags = dhd_os_spin_lock(pub);
 
-       /* Totally stop the timer */
-       if (!wdtick && dhd->wd_timer_valid == TRUE) {
-               del_timer_sync(&dhd->timer);
-               dhd->wd_timer_valid = FALSE;
-               save_dhd_watchdog_ms = wdtick;
-               return;
+       /* don't start the wd until fw is loaded */
+       if (pub->busstate != DHD_BUS_DOWN) {
+               if (wdtick) {
+                       dhd_watchdog_ms = (uint)wdtick;
+                       dhd->wd_timer_valid = TRUE;
+                       /* Re arm the timer, at last watchdog period */
+                       mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+               } else if (dhd->wd_timer_valid == TRUE) {
+                       /* Totally stop the timer */
+                       dhd->wd_timer_valid = FALSE;
+                       del_timer_flag = TRUE;
+               }
        }
-
-       if (wdtick) {
-               dhd_watchdog_ms = (uint)wdtick;
-
-               /* Re arm the timer, at last watchdog period */
-               mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
-
-               dhd->wd_timer_valid = TRUE;
-               save_dhd_watchdog_ms = wdtick;
+       dhd_os_spin_unlock(pub, flags);
+       if (del_timer_flag) {
+               del_timer_sync(&dhd->timer);
        }
 }
 
@@ -2922,20 +2956,18 @@ void dhd_wait_event_wakeup(dhd_pub_t *dhd)
 int
 dhd_dev_reset(struct net_device *dev, uint8 flag)
 {
-       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
-
-       /* Turning off watchdog */
-       if (flag)
-               dhd_os_wd_timer(&dhd->pub, 0);
+       int ret;
 
-       dhd_bus_devreset(&dhd->pub, flag);
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
 
-       /* Turning on watchdog back */
-       if (!flag)
-               dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
-       DHD_ERROR(("%s:  WLAN OFF DONE\n", __FUNCTION__));
+       ret = dhd_bus_devreset(&dhd->pub, flag);
+       if (ret) {
+               DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
+               return ret;
+       }
+       DHD_ERROR(("%s: WLAN %s DONE\n", __FUNCTION__, flag ? "OFF" : "ON"));
 
-       return 1;
+       return ret;
 }
 
 int net_os_set_suspend_disable(struct net_device *dev, int val)
@@ -3046,6 +3078,57 @@ dhd_dev_get_pno_status(struct net_device *dev)
 
 #endif /* PNO_SUPPORT */
 
+int net_os_send_hang_message(struct net_device *dev)
+{
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+       int ret = 0;
+
+       if (dhd) {
+               if (!dhd->hang_was_sent) {
+                       dhd->hang_was_sent = 1;
+                       ret = wl_iw_send_priv_event(dev, "HANG");
+               }
+       }
+       return ret;
+}
+
+void dhd_bus_country_set(struct net_device *dev, char *country_code)
+{
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+       if (dhd && dhd->pub.up)
+               strncpy(dhd->pub.country_code, country_code, WLC_CNTRY_BUF_SZ);
+}
+
+char *dhd_bus_country_get(struct net_device *dev)
+{
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+       if (dhd && (dhd->pub.country_code[0] != 0))
+               return dhd->pub.country_code;
+       return NULL;
+}
+
+void dhd_os_start_lock(dhd_pub_t *pub)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+       dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+       if (dhd)
+               mutex_lock(&dhd->wl_start_lock);
+#endif
+}
+
+void dhd_os_start_unlock(dhd_pub_t *pub)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+       dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+       if (dhd)
+               mutex_unlock(&dhd->wl_start_lock);
+#endif
+}
+
 static int
 dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
 {
@@ -3228,32 +3311,21 @@ int net_os_wake_unlock(struct net_device *dev)
        return ret;
 }
 
-int net_os_send_hang_message(struct net_device *dev)
-{
-       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
-       int ret = 0;
-
-       if (dhd) {
-               if (!dhd->hang_was_sent) {
-                       dhd->hang_was_sent = 1;
-                       ret = wl_iw_send_priv_event(dev, "HANG");
-               }
-       }
-       return ret;
-}
-
-void dhd_os_start_lock(dhd_pub_t *pub)
+unsigned long dhd_os_spin_lock(dhd_pub_t *pub)
 {
        dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+       unsigned long flags = 0;
 
        if (dhd)
-               mutex_lock(&dhd->wl_start_lock);
+               spin_lock_irqsave(&dhd->dhd_lock, flags);
+
+       return flags;
 }
 
-void dhd_os_start_unlock(dhd_pub_t *pub)
+void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags)
 {
        dhd_info_t *dhd = (dhd_info_t *)(pub->info);
 
        if (dhd)
-               mutex_unlock(&dhd->wl_start_lock);
+               spin_unlock_irqrestore(&dhd->dhd_lock, flags);
 }
index ff1bdedbc9f3c2d95f76d7a65ec0a5b93991e344..f9b9eceb91c7ac817547f098360c9ac38a61ee75 100644 (file)
@@ -426,7 +426,6 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
 
 #ifdef DHD_DEBUG_TRAP
 static int dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size);
-static int dhdsdio_mem_dump(dhd_bus_t *bus);
 #endif /* DHD_DEBUG_TRAP */
 static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
 
@@ -438,7 +437,7 @@ static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh,
                                  void * regsva, uint16  devid);
 static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh);
 static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh);
-static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh);
+static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag);
 
 static uint process_nvram_vars(char *varbuf, uint len);
 
@@ -705,6 +704,7 @@ dhdsdio_sdclk(dhd_bus_t *bus, bool on)
 static int
 dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
 {
+       int ret = BCME_OK;
 #ifdef DHD_DEBUG
        uint oldstate = bus->clkstate;
 #endif /* DHD_DEBUG */
@@ -717,7 +717,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
                        dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
                        bus->activity = TRUE;
                }
-               return BCME_OK;
+               return ret;
        }
 
        switch (target) {
@@ -726,29 +726,32 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
                if (bus->clkstate == CLK_NONE)
                        dhdsdio_sdclk(bus, TRUE);
                /* Now request HT Avail on the backplane */
-               dhdsdio_htclk(bus, TRUE, pendok);
-               dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
-               bus->activity = TRUE;
+               ret = dhdsdio_htclk(bus, TRUE, pendok);
+               if (ret == BCME_OK) {
+                       dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+                       bus->activity = TRUE;
+               }
                break;
 
        case CLK_SDONLY:
                /* Remove HT request, or bring up SD clock */
                if (bus->clkstate == CLK_NONE)
-                       dhdsdio_sdclk(bus, TRUE);
+                       ret = dhdsdio_sdclk(bus, TRUE);
                else if (bus->clkstate == CLK_AVAIL)
-                       dhdsdio_htclk(bus, FALSE, FALSE);
+                       ret = dhdsdio_htclk(bus, FALSE, FALSE);
                else
                        DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
                                   bus->clkstate, target));
-               dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+               if (ret == BCME_OK)
+                       dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
                break;
 
        case CLK_NONE:
                /* Make sure to remove HT request */
                if (bus->clkstate == CLK_AVAIL)
-                       dhdsdio_htclk(bus, FALSE, FALSE);
+                       ret = dhdsdio_htclk(bus, FALSE, FALSE);
                /* Now remove the SD clock */
-               dhdsdio_sdclk(bus, FALSE);
+               ret = dhdsdio_sdclk(bus, FALSE);
                dhd_os_wd_timer(bus->dhd, 0);
                break;
        }
@@ -756,7 +759,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
        DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
 #endif /* DHD_DEBUG */
 
-       return BCME_OK;
+       return ret;
 }
 
 int
@@ -1839,11 +1842,6 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
                DHD_ERROR(("%s: %s\n", __FUNCTION__, strbuf.origbuf));
        }
 
-       if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
-                       /* Mem dump to a file on device */
-                       dhdsdio_mem_dump(bus);
-       }
-
 done:
        if (mbuffer)
                MFREE(bus->dhd->osh, mbuffer, msize);
@@ -1852,60 +1850,6 @@ done:
 
        return bcmerror;
 }
-
-static int
-dhdsdio_mem_dump(dhd_bus_t *bus)
-{
-       int ret = 0;
-       int size; /* Full mem size */
-       int start = 0; /* Start address */
-       int read_size = 0; /* Read size of each iteration */
-       uint8 *buf = NULL, *databuf = NULL;
-
-       /* Get full mem size */
-       size = bus->ramsize;
-       buf = MALLOC(bus->dhd->osh, size);
-       if (!buf) {
-               printf("%s: Out of memory (%d bytes)\n", __FUNCTION__, size);
-               return -1;
-       }
-
-       /* Read mem content */
-       printf("Dump dongle memory");
-       databuf = buf;
-       while (size)
-       {
-               read_size = MIN(MEMBLOCK, size);
-               if ((ret = dhdsdio_membytes(bus, FALSE, start, databuf, read_size)))
-               {
-                       printf("%s: Error membytes %d\n", __FUNCTION__, ret);
-                       if (buf) {
-                               MFREE(bus->dhd->osh, buf, size);
-                       }
-                       return -1;
-               }
-               printf(".");
-
-               /* Decrement size and increment start address */
-               size -= read_size;
-               start += read_size;
-               databuf += read_size;
-       }
-       printf("Done\n");
-
-#ifdef DHD_DEBUG
-       /* free buf before return !!! */
-       if (write_to_file(bus->dhd, buf, bus->ramsize))
-       {
-               printf("%s: Error writing to files\n", __FUNCTION__);
-               return -1;
-       }
-       /* buf free handled in write_to_file, not here */
-#else
-       MFREE(bus->dhd->osh, buf, size);
-#endif
-       return 0;
-}
 #endif /* DHD_DEBUG_TRAP */
 
 #ifdef DHD_DEBUG
@@ -2719,6 +2663,9 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
 
        BUS_WAKE(bus);
 
+       /* Change our idea of bus state */
+       bus->dhd->busstate = DHD_BUS_DOWN;
+
        /* Enable clock for device interrupts */
        dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
 
@@ -2727,9 +2674,6 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
        local_hostintmask = bus->hostintmask;
        bus->hostintmask = 0;
 
-       /* Change our idea of bus state */
-       bus->dhd->busstate = DHD_BUS_DOWN;
-
        /* Force clocks on backplane to be sure F2 interrupt propagates */
        saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
        if (!err) {
@@ -2782,23 +2726,24 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
        dhd_timeout_t tmo;
        uint retries = 0;
        uint8 ready, enable;
-       int err, ret = 0;
+       int err, ret = BCME_ERROR;
        uint8 saveclk;
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
        ASSERT(bus->dhd);
        if (!bus->dhd)
-               return 0;
+               return BCME_OK;
 
        if (enforce_mutex)
                dhd_os_sdlock(bus->dhd);
 
        /* Make sure backplane clock is on, needed to generate F2 interrupt */
-       dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
-       if (bus->clkstate != CLK_AVAIL)
+       err = dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
+       if ((err != BCME_OK) || (bus->clkstate != CLK_AVAIL)) {
+               DHD_ERROR(("%s: Failed to set backplane clock: err %d\n", __FUNCTION__, err));
                goto exit;
-
+       }
 
        /* Force clocks on backplane to be sure F2 interrupt propagates */
        saveclk = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
@@ -2873,6 +2818,7 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
        if (dhdp->busstate != DHD_BUS_DATA)
                dhdsdio_clkctl(bus, CLK_NONE, FALSE);
 
+       ret = BCME_OK;
 exit:
        if (enforce_mutex)
                dhd_os_sdunlock(bus->dhd);
@@ -4631,8 +4577,6 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
        if (bus->sleeping)
                return FALSE;
 
-       dhd_os_sdlock(bus->dhd);
-
        /* Poll period: check device if appropriate. */
        if (bus->poll && (++bus->polltick >= bus->pollrate)) {
                uint32 intstatus = 0;
@@ -4702,8 +4646,6 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
                }
        }
 
-       dhd_os_sdunlock(bus->dhd);
-
        return bus->ipend;
 }
 
@@ -5299,7 +5241,7 @@ dhdsdio_release(dhd_bus_t *bus, osl_t *osh)
 
                if (bus->dhd) {
 
-                       dhdsdio_release_dongle(bus, osh);
+                       dhdsdio_release_dongle(bus, osh, TRUE);
 
                        dhd_detach(bus->dhd);
                        bus->dhd = NULL;
@@ -5343,11 +5285,11 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
 
 
 static void
-dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh)
+dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh, int reset_flag)
 {
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
-       if (bus->dhd && bus->dhd->dongle_reset)
+       if ((bus->dhd && bus->dhd->dongle_reset) && reset_flag)
                return;
 
        if (bus->sih) {
@@ -5797,27 +5739,22 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
 
        if (flag == TRUE) {
                if (!bus->dhd->dongle_reset) {
+                       dhd_os_sdlock(dhdp);
+                       /* Turning off watchdog */
+                       dhd_os_wd_timer(dhdp, 0);
 #if !defined(IGNORE_ETH0_DOWN)
                        /* Force flow control as protection when stop come before ifconfig_down */
                        dhd_txflowcontrol(bus->dhd, 0, ON);
 #endif /* !defined(IGNORE_ETH0_DOWN) */
-                       /* save country settinng if was pre-setup with priv ioctl */
-                       dhd_os_proto_block(dhdp);
-                       dhdcdc_query_ioctl(bus->dhd, 0, WLC_GET_COUNTRY,
-                               bus->dhd->country_code, sizeof(bus->dhd->country_code));
-                       dhd_os_proto_unblock(dhdp);
                        /* Expect app to have torn down any connection before calling */
                        /* Stop the bus, disable F2 */
-                       dhd_os_sdlock(dhdp);
-
                        dhd_bus_stop(bus, FALSE);
 
                        /* Clean tx/rx buffer pointers, detach from the dongle */
-                       dhdsdio_release_dongle(bus, bus->dhd->osh);
+                       dhdsdio_release_dongle(bus, bus->dhd->osh, TRUE);
 
                        bus->dhd->dongle_reset = TRUE;
                        bus->dhd->up = FALSE;
-
                        dhd_os_sdunlock(dhdp);
 
                        DHD_TRACE(("%s:  WLAN OFF DONE\n", __FUNCTION__));
@@ -5845,25 +5782,30 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
                                        dhdsdio_download_firmware(bus, bus->dhd->osh, bus->sdh)) {
 
                                        /* Re-init bus, enable F2 transfer */
-                                       dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
-
+                                       bcmerror = dhd_bus_init((dhd_pub_t *) bus->dhd, FALSE);
+                                       if (bcmerror == BCME_OK) {
 #if defined(OOB_INTR_ONLY)
-                                       dhd_enable_oob_intr(bus, TRUE);
+                                               dhd_enable_oob_intr(bus, TRUE);
 #endif /* defined(OOB_INTR_ONLY) */
-
-                                       bus->dhd->dongle_reset = FALSE;
-                                       bus->dhd->up = TRUE;
-
+                                               bus->dhd->dongle_reset = FALSE;
+                                               bus->dhd->up = TRUE;
 #if !defined(IGNORE_ETH0_DOWN)
-                                       /* Restore flow control  */
-                                       dhd_txflowcontrol(bus->dhd, 0, OFF);
-#endif 
+                                               /* Restore flow control  */
+                                               dhd_txflowcontrol(bus->dhd, 0, OFF);
+#endif
+                                               /* Turning on watchdog back */
+                                               dhd_os_wd_timer(dhdp, dhd_watchdog_ms);
 
-                                       DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
+                                               DHD_TRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
+                                       } else {
+                                               dhd_bus_stop(bus, FALSE);
+                                               dhdsdio_release_dongle(bus, bus->dhd->osh, FALSE);
+                                       }
                                } else
                                        bcmerror = BCME_SDIO_ERROR;
                        } else
                                bcmerror = BCME_SDIO_ERROR;
+
                        dhd_os_sdunlock(dhdp);
                } else {
                        bcmerror = BCME_NOTDOWN;
index 92dc32635a25f394e83557e6938d1a5c2551fc23..00e3cac14dc5d329b7c4f9dac8480ef8e4d6c205 100644 (file)
 
 #define        EPI_RC_NUMBER           248
 
-#define        EPI_INCREMENTAL_NUMBER  6
+#define        EPI_INCREMENTAL_NUMBER  20
 
 #define        EPI_BUILD_NUMBER        0
 
-#define        EPI_VERSION             4, 218, 248, 6
+#define        EPI_VERSION             4, 218, 248, 20
 
-#define        EPI_VERSION_NUM         0x04daf806
+#define        EPI_VERSION_NUM         0x04daf814
 
 
-#define        EPI_VERSION_STR         "4.218.248.6"
-#define        EPI_ROUTER_VERSION_STR  "4.219.248.6"
+#define        EPI_VERSION_STR         "4.218.248.20"
+#define        EPI_ROUTER_VERSION_STR  "4.219.248.20"
 
 #endif 
index 46c04d379227f3b5044236d8db868ac617ac1043..1f8ecb14d97a05f62ea263595e1530e756c46b09 100644 (file)
@@ -24,7 +24,7 @@
  *
  * Dependencies: proto/bcmeth.h
  *
- * $Id: bcmevent.h,v 9.34.4.1.20.16 2009/09/25 23:52:38 Exp $
+ * $Id: bcmevent.h,v 9.34.4.1.20.16.64.1 2010/11/08 21:57:03 Exp $
  *
  */
 
@@ -131,10 +131,10 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
 #define WLC_E_ACTION_FRAME      58      
 #define WLC_E_ACTION_FRAME_COMPLETE 59  
 
-#define WLC_E_ESCAN_RESULT 69               
-#define WLC_E_WAKE_EVENT       70      
-#define WLC_E_LAST             71      
-       
+#define WLC_E_ESCAN_RESULT     69
+#define WLC_E_WAKE_EVENT       70
+#define WLC_E_RELOAD           71
+#define WLC_E_LAST             72
 
 
 
@@ -205,6 +205,7 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
 #define WLC_E_IF_ADD           1       
 #define WLC_E_IF_DEL           2       
 
+#define WLC_E_RELOAD_STATUS1   1
 
 #include <packed_section_end.h>
 
index 345ba34b94c096b1f95a357cbce2fc79fa591ebf..cd7725a70db41d3fdd4f509fe9ba706b0747f38d 100644 (file)
@@ -24,7 +24,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62 2010/08/19 01:20:12 Exp $
+ * $Id: wlioctl.h,v 1.601.4.15.2.14.2.62.4.1 2010/11/17 03:09:28 Exp $
  */
 
 
@@ -857,6 +857,7 @@ typedef struct wl_ioctl {
 #define PM_MAX 1
 #define PM_FAST 2
 
+#define LISTEN_INTERVAL                        20
 
 #define        INTERFERE_NONE  0       
 #define        NON_WLAN        1       
index eb8649f4d832d6e33733b73c83dc64fa492a8812..351c740368db52f5e8e1810d319eda36e1ca2f82 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.13 2010/09/15 03:34:56 Exp $
+ * $Id: wl_iw.c,v 1.51.4.9.2.6.4.142.4.69 2010/12/21 03:00:08 Exp $
  */
 
 
@@ -54,6 +54,7 @@ typedef const struct si_pub  si_t;
 #define WL_INFORM(x)
 #define WL_WSEC(x)
 #define WL_SCAN(x)
+#define WL_TRACE_COEX(x)
 
 #include <wl_iw.h>
 
@@ -96,11 +97,13 @@ typedef const struct si_pub  si_t;
 #define WL_SOFTAP(x) printk x
 static struct net_device *priv_dev;
 static bool ap_cfg_running = FALSE;
-static bool ap_fw_loaded = FALSE;
+bool ap_fw_loaded = FALSE;
+static long ap_cfg_pid = -1;
 struct net_device *ap_net_dev = NULL;
 struct semaphore  ap_eth_sema;
+static struct completion ap_cfg_exited;
 static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap);
-static int wl_iw_softap_deassoc_stations(struct net_device *dev);
+static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac);
 #endif
 
 #define WL_IW_IOCTL_CALL(func_call) \
@@ -112,6 +115,10 @@ static int         g_onoff = G_WLAN_SET_ON;
 wl_iw_extra_params_t   g_wl_iw_params;
 static struct mutex    wl_cache_lock;
 
+#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY
+static bool use_non_dfs_channels = true;
+#endif
+
 extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
        uint32 reason, char* stringBuf, uint buflen);
 #include <bcmsdbus.h>
@@ -160,9 +167,11 @@ static wlc_ssid_t g_specific_ssid;
 static wlc_ssid_t g_ssid;
 
 static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl;  
+#if defined(CONFIG_FIRST_SCAN)
 static volatile uint g_first_broadcast_scan;
 static volatile uint g_first_counter_scans;
 #define MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN 3
+#endif
 
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
@@ -183,7 +192,9 @@ static volatile uint g_first_counter_scans;
 static void wl_iw_free_ss_cache(void);
 static int   wl_iw_run_ss_cache_timer(int kick_off);
 #endif
+#if defined(CONFIG_FIRST_SCAN)
 int  wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
+#endif
 static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len);
 #define ISCAN_STATE_IDLE   0
 #define ISCAN_STATE_SCANING 1
@@ -217,7 +228,12 @@ typedef struct iscan_info {
        wl_iscan_params_t *iscan_ex_params_p;
        int iscan_ex_param_size;
 } iscan_info_t;
-#define COEX_DHCP 1 
+#define COEX_DHCP 1
+
+#define BT_DHCP_eSCO_FIX
+#define BT_DHCP_USE_FLAGS
+#define BT_DHCP_OPPORTUNITY_WINDOW_TIME         2500
+#define BT_DHCP_FLAG_FORCE_TIME 5500
 static void wl_iw_bt_flag_set(struct net_device *dev, bool set);
 static void wl_iw_bt_release(void);
 
@@ -227,18 +243,16 @@ typedef enum bt_coex_status {
        BT_DHCP_OPPORTUNITY_WINDOW,
        BT_DHCP_FLAG_FORCE_TIMEOUT
 } coex_status_t;
-#define BT_DHCP_OPPORTUNITY_WINDOW_TIEM        2500    
-#define BT_DHCP_FLAG_FORCE_TIME                                5500    
 
 typedef struct bt_info {
        struct net_device *dev;
        struct timer_list timer;
        uint32 timer_ms;
        uint32 timer_on;
-       int     bt_state;
+       bool   dhcp_done;
+       int    bt_state;
 
-       
-       long bt_pid;
+       long   bt_pid;
        struct semaphore bt_sem;
        struct completion bt_exited;
 } bt_info_t;
@@ -605,6 +619,31 @@ wl_iw_get_macaddr(
        return error;
 }
 
+static int
+wl_iw_set_country_code(struct net_device *dev, char *ccode)
+{
+       char country_code[WLC_CNTRY_BUF_SZ];
+       int ret = -1;
+
+       WL_TRACE(("%s\n", __FUNCTION__));
+       if (!ccode)
+               ccode = dhd_bus_country_get(dev);
+       strncpy(country_code, ccode, sizeof(country_code));
+       if (ccode && (country_code[0] != 0)) {
+#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY
+               if (use_non_dfs_channels && !strncmp(country_code, "US", 2))
+                       strncpy(country_code, "Q2", WLC_CNTRY_BUF_SZ);
+               if (!use_non_dfs_channels && !strncmp(country_code, "Q2", 2))
+                       strncpy(country_code, "US", WLC_CNTRY_BUF_SZ);
+#endif
+               ret = dev_wlc_ioctl(dev, WLC_SET_COUNTRY, &country_code, sizeof(country_code));
+               if (ret >= 0) {
+                       WL_TRACE(("%s: set country %s OK\n", __FUNCTION__, country_code));
+                       dhd_bus_country_set(dev, &country_code[0]);
+               }
+       }
+       return ret;
+}
 
 static int
 wl_iw_set_country(
@@ -626,14 +665,11 @@ wl_iw_set_country(
        country_offset = strcspn(extra, " ");
        country_code_size = strlen(extra) - country_offset;
 
-       
        if (country_offset != 0) {
                strncpy(country_code, extra + country_offset + 1,
                        MIN(country_code_size, sizeof(country_code)));
-
-               
-               if ((error = dev_wlc_ioctl(dev, WLC_SET_COUNTRY,
-                       &country_code, sizeof(country_code))) >= 0) {
+               error = wl_iw_set_country_code(dev, country_code);
+               if (error >= 0) {
                        p += snprintf(p, MAX_WX_STRING, "OK");
                        WL_TRACE(("%s: set country %s OK\n", __FUNCTION__, country_code));
                        goto exit;
@@ -663,29 +699,34 @@ wl_iw_set_power_mode(
        int pm_local = PM_OFF;
        char powermode_val = 0;
 
+       WL_TRACE_COEX(("%s: DHCP session cmd:%s\n", __FUNCTION__, extra));
+
        strncpy((char *)&powermode_val, extra + strlen("POWERMODE") + 1, 1);
 
        if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
 
-               WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
-
                dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
                dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
 
                /* Disable packet filtering if necessary */
                net_os_set_packet_filter(dev, 0);
 
-       } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
+               g_bt->dhcp_done = false;
+               WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n",
+                       __FUNCTION__, pm, pm_local));
 
-               WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
+       } else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
 
                dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
 
                /* Enable packet filtering if was turned off */
                net_os_set_packet_filter(dev, 1);
 
+               g_bt->dhcp_done = true;
+
        } else {
-               WL_ERROR(("Unkwown yet power setting, ignored\n"));
+               WL_ERROR(("%s Unkwown yet power setting, ignored\n",
+                       __FUNCTION__));
        }
 
        p += snprintf(p, MAX_WX_STRING, "OK");
@@ -696,6 +737,122 @@ wl_iw_set_power_mode(
 }
 #endif
 
+
+static bool btcoex_is_sco_active(struct net_device *dev)
+{
+       int ioc_res = 0;
+       bool res = false;
+       int temp = 0;
+
+       ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 4, &temp);
+
+       if (ioc_res == 0) {
+               WL_TRACE_COEX(("%s: read btc_params[4] = %x\n", __FUNCTION__, temp));
+
+               if ((temp > 0xea0) && (temp < 0xed8)) {
+                       WL_TRACE_COEX(("%s: BT SCO/eSCO is ACTIVE\n", __FUNCTION__));
+                       res = true;
+               } else {
+                       WL_TRACE_COEX(("%s: BT SCO/eSCO is NOT detected\n", __FUNCTION__));
+               }
+       } else {
+               WL_ERROR(("%s ioc read btc params error\n", __FUNCTION__));
+       }
+       return res;
+}
+
+#if defined(BT_DHCP_eSCO_FIX)
+
+static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
+{
+       static bool saved_status = false;
+
+       char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 };
+       char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+       char buf_reg64va_dhcp_on[8] = { 64, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+       char buf_reg65va_dhcp_on[8] = { 65, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+       char buf_reg71va_dhcp_on[8] = { 71, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
+
+       uint32 regaddr;
+       static uint32 saved_reg50;
+       static uint32 saved_reg51;
+       static uint32 saved_reg64;
+       static uint32 saved_reg65;
+       static uint32 saved_reg71;
+
+       if (trump_sco) {
+
+               WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n"));
+
+               if  ((!dev_wlc_intvar_get_reg(dev, "btc_params", 50,  &saved_reg50)) &&
+                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 51,  &saved_reg51)) &&
+                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 64,  &saved_reg64)) &&
+                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 65,  &saved_reg65)) &&
+                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 71,  &saved_reg71))) {
+
+                       saved_status = TRUE;
+                       WL_TRACE_COEX(("%s saved bt_params[50,51,64,65,71]:"
+                               " 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                               __FUNCTION__, saved_reg50, saved_reg51,
+                               saved_reg64, saved_reg65, saved_reg71));
+
+               } else {
+                       WL_ERROR((":%s: save btc_params failed\n",
+                               __FUNCTION__));
+                       saved_status = false;
+                       return -1;
+               }
+
+               WL_TRACE_COEX(("override with [50,51,64,65,71]:"
+                       " 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                       *(u32 *)(buf_reg50va_dhcp_on+4),
+                       *(u32 *)(buf_reg51va_dhcp_on+4),
+                       *(u32 *)(buf_reg64va_dhcp_on+4),
+                       *(u32 *)(buf_reg65va_dhcp_on+4),
+                       *(u32 *)(buf_reg71va_dhcp_on+4)));
+
+               dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg50va_dhcp_on[0], 8);
+               dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg51va_dhcp_on[0], 8);
+               dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg64va_dhcp_on[0], 8);
+               dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8);
+               dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8);
+
+               saved_status = true;
+
+       } else if (saved_status) {
+
+               WL_TRACE_COEX(("Do new SCO/eSCO coex algo {save & override} \n"));
+
+               regaddr = 50;
+               dev_wlc_intvar_set_reg(dev, "btc_params",
+                       (char *)&regaddr, (char *)&saved_reg50);
+               regaddr = 51;
+               dev_wlc_intvar_set_reg(dev, "btc_params",
+                       (char *)&regaddr, (char *)&saved_reg51);
+               regaddr = 64;
+               dev_wlc_intvar_set_reg(dev, "btc_params",
+                       (char *)&regaddr, (char *)&saved_reg64);
+               regaddr = 65;
+               dev_wlc_intvar_set_reg(dev, "btc_params",
+                       (char *)&regaddr, (char *)&saved_reg65);
+               regaddr = 71;
+               dev_wlc_intvar_set_reg(dev, "btc_params",
+                       (char *)&regaddr, (char *)&saved_reg71);
+
+               WL_TRACE_COEX(("restore bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+                       saved_reg50, saved_reg51, saved_reg64,
+                       saved_reg65, saved_reg71));
+
+               saved_status = false;
+       } else {
+               WL_ERROR((":%s att to restore not saved BTCOEX params\n",
+                       __FUNCTION__));
+               return -1;
+       }
+       return 0;
+}
+#endif
+
 static int
 wl_iw_get_power_mode(
        struct net_device *dev,
@@ -751,9 +908,6 @@ wl_iw_set_btcoex_dhcp(
        static bool saved_status = FALSE;
 
        char buf_flag7_default[8] =   { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
-#ifndef CUSTOMER_HW2
-       uint32 temp1, temp2;
-#endif
 
 #ifdef CUSTOMER_HW2
        strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") + 1, 1);
@@ -763,44 +917,43 @@ wl_iw_set_btcoex_dhcp(
 
        if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
 
-               WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
+               WL_TRACE_COEX(("%s: DHCP session start, cmd:%s\n", __FUNCTION__, extra));
 
                if ((saved_status == FALSE) &&
 #ifndef CUSTOMER_HW2
-                       (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) &&
+                  (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) &&
 #endif
-                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 66,  &saved_reg66)) &&
-                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 41,  &saved_reg41)) &&
-                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 68,  &saved_reg68)))   {
-                               saved_status = TRUE;
-                               WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", \
-                                       saved_reg66, saved_reg41, saved_reg68));
+                  (!dev_wlc_intvar_get_reg(dev, "btc_params", 66,  &saved_reg66)) &&
+                  (!dev_wlc_intvar_get_reg(dev, "btc_params", 41,  &saved_reg41)) &&
+                  (!dev_wlc_intvar_get_reg(dev, "btc_params", 68,  &saved_reg68))) {
+                       WL_TRACE_COEX(("save regs {66,41,68} ->: 0x%x 0x%x 0x%x\n", \
+                               saved_reg66, saved_reg41, saved_reg68));
 
 #ifndef CUSTOMER_HW2
-                               dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
+                       dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
 #endif
 
-               dev_wlc_bufvar_set(dev, "btc_params", \
-                                  (char *)&buf_reg66va_dhcp_on[0], sizeof(buf_reg66va_dhcp_on));
-               dev_wlc_bufvar_set(dev, "btc_params", \
-                                  (char *)&buf_reg41va_dhcp_on[0], sizeof(buf_reg41va_dhcp_on));
-               dev_wlc_bufvar_set(dev, "btc_params", \
-                                  (char *)&buf_reg68va_dhcp_on[0], sizeof(buf_reg68va_dhcp_on));
-#ifndef CUSTOMER_HW2
-                               if ((!dev_wlc_intvar_get_reg(dev, "btc_params", 12, &temp1)) &&
-                                       (!dev_wlc_intvar_get_reg(dev, "btc_params", 13, &temp2)))
-                               {
-                                       if ((temp1 != 0) && (temp2 != 0)) {
-#endif
-                                               g_bt->bt_state = BT_DHCP_START;
-                                               g_bt->timer_on = 1;
-                                               mod_timer(&g_bt->timer, g_bt->timer.expires);
-                                               WL_TRACE(("%s enable BT DHCP Timer\n", \
-                                                       __FUNCTION__));
-#ifndef CUSTOMER_HW2
-                                       }
-                               }
-#endif
+                               if (btcoex_is_sco_active(dev)) {
+
+                                       dev_wlc_bufvar_set(dev, "btc_params", \
+                                               (char *)&buf_reg66va_dhcp_on[0], \
+                                                sizeof(buf_reg66va_dhcp_on));
+
+                                       dev_wlc_bufvar_set(dev, "btc_params", \
+                                               (char *)&buf_reg41va_dhcp_on[0], \
+                                                sizeof(buf_reg41va_dhcp_on));
+
+                                       dev_wlc_bufvar_set(dev, "btc_params", \
+                                               (char *)&buf_reg68va_dhcp_on[0], \
+                                                sizeof(buf_reg68va_dhcp_on));
+                                       saved_status = TRUE;
+
+                                       g_bt->bt_state = BT_DHCP_START;
+                                       g_bt->timer_on = 1;
+                                       mod_timer(&g_bt->timer, g_bt->timer.expires);
+                                       WL_TRACE_COEX(("%s enable BT DHCP Timer\n", \
+                                       __FUNCTION__));
+                       }
                }
                else if (saved_status == TRUE) {
                        WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__));
@@ -811,22 +964,28 @@ wl_iw_set_btcoex_dhcp(
 #else
        else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
 #endif
-               WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
 
 #ifndef CUSTOMER_HW2
                dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
 #endif
 
-               WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
+               WL_TRACE_COEX(("%s disable BT DHCP Timer\n", __FUNCTION__));
                if (g_bt->timer_on) {
                        g_bt->timer_on = 0;
                        del_timer_sync(&g_bt->timer);
+
+                       if (g_bt->bt_state != BT_DHCP_IDLE) {
+                               WL_TRACE_COEX(("%s bt->bt_state:%d\n",
+                                       __FUNCTION__, g_bt->bt_state));
+
+                               up(&g_bt->bt_sem);
+                       }
                }
 
-               dev_wlc_bufvar_set(dev, "btc_flags", \
+               if (saved_status == TRUE) {
+                       dev_wlc_bufvar_set(dev, "btc_flags", \
                                (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
 
-               if (saved_status) {
                        regaddr = 66;
                        dev_wlc_intvar_set_reg(dev, "btc_params", \
                                (char *)&regaddr, (char *)&saved_reg66);
@@ -836,11 +995,15 @@ wl_iw_set_btcoex_dhcp(
                        regaddr = 68;
                        dev_wlc_intvar_set_reg(dev, "btc_params", \
                                (char *)&regaddr, (char *)&saved_reg68);
+
+                       WL_TRACE_COEX(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n", \
+                                       saved_reg66, saved_reg41, saved_reg68));
                }
                saved_status = FALSE;
        }
        else {
-               WL_ERROR(("Unkwown yet power setting, ignored\n"));
+               WL_ERROR(("%s Unkwown yet power setting, ignored\n",
+                       __FUNCTION__));
        }
 
        p += snprintf(p, MAX_WX_STRING, "OK");
@@ -880,6 +1043,22 @@ wl_iw_set_suspend(
        return ret;
 }
 
+#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY
+static int
+wl_iw_set_dfs_channels(
+       struct net_device *dev,
+       struct iw_request_info *info,
+       union iwreq_data *wrqu,
+       char *extra
+)
+{
+       use_non_dfs_channels = *(extra + strlen(SETDFSCHANNELS_CMD) + 1) - '0';
+       use_non_dfs_channels = (use_non_dfs_channels != 0) ? false : true;
+       wl_iw_set_country_code(dev, NULL);
+       return 0;
+}
+#endif
+
 int
 wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len)
 {
@@ -1062,7 +1241,6 @@ wl_iw_set_band(
 
                if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
 
-                       
                        if ((error = dev_wlc_ioctl(dev, WLC_SET_BAND,
                                &band, sizeof(band))) >= 0) {
                                p += snprintf(p, MAX_WX_STRING, "OK");
@@ -1164,15 +1342,15 @@ wl_iw_set_pno_set(
        wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
        int nssid = 0;
        cmd_tlv_t *cmd_tlv_temp;
-       char type;
        char *str_ptr;
+       char *str_ptr_end;
        int tlv_size_left;
        int pno_time;
 
 #ifdef PNO_SET_DEBUG
        int i;
        char pno_in_example[] = {'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', \
-                                                       'S', 0x01, 0x01, 0x00,
+                                                       'S', '1', '2', '0',
                                                        'S',
                                                        0x04,
                                                        'B', 'R', 'C', 'M',
@@ -1180,8 +1358,8 @@ wl_iw_set_pno_set(
                                                        0x04,
                                                        'G', 'O', 'O', 'G',
                                                        'T',
-                                                       0x00,
-                                                       0x0A
+                                                       '1','E',
+                                                       0x00
                                                        };
 #endif
 
@@ -1238,29 +1416,15 @@ wl_iw_set_pno_set(
                        goto exit_proc;
                }
                else {
-                       while (tlv_size_left > 0)
-                       {
-                               type = str_ptr[0];
-                               switch (type) {
-                                       case PNO_TLV_TYPE_TIME:
-
-                                       if ((res = wl_iw_parse_data_tlv(&str_ptr, \
-                                               &pno_time, \
-                                               sizeof(pno_time), \
-                                               type, sizeof(short), &tlv_size_left)) == -1) {
-                                                       WL_ERROR(("%s return %d\n", \
-                                                       __FUNCTION__, res));
-                                                       goto exit_proc;
-                                       }
-                                       break;
-
-                                       default:
-                                               WL_ERROR(("%s get unkwown type %X\n", \
-                                                       __FUNCTION__, type));
-                                               goto exit_proc;
-                                       break;
-                               }
+                       if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
+                               WL_ERROR(("%s scan duration corrupted field size %d\n", \
+                                               __FUNCTION__, tlv_size_left));
+                               goto exit_proc;
                        }
+                       str_ptr++;
+                       pno_time = simple_strtoul(str_ptr, &str_ptr_end, 16);
+                       WL_ERROR((" got %d bytes left pno_time %d or %#x\n", \
+                                       tlv_size_left, pno_time, pno_time));
                }
        }
        else {
@@ -1279,7 +1443,7 @@ exit_proc:
 static int
 wl_iw_get_wext_rssi(
         struct net_device *dev,
-        struct iw_request_info *info,
+       struct iw_request_info *info,
         union iwreq_data *wrqu,
         char *extra
 )
@@ -1341,19 +1505,24 @@ wl_iw_get_rssi(
                error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
                if (error) {
                        WL_ERROR(("%s: Fails %d\n", __FUNCTION__, error));
-                       net_os_wake_unlock(dev);
-                       return error;
-               }
-               rssi = dtoh32(scb_val.val);
+               } else {
+                       rssi = dtoh32(scb_val.val);
 
-               error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
-               if (!error) {
-                       ssid.SSID_len = dtoh32(ssid.SSID_len);
-                       wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len));
+                       error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
+                       if (!error) {
+                               ssid.SSID_len = dtoh32(ssid.SSID_len);
+                               wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len));
+                       }
                }
        }
 
-       p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi);
+       WL_ASSOC(("%s ssid_len:%d, rssi:%d\n", __FUNCTION__, ssid.SSID_len, rssi));
+
+       if (error || (ssid.SSID_len == 0)) {
+               p += snprintf(p, MAX_WX_STRING, "FAIL");
+       } else {
+               p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi);
+       }
        wrqu->data.length = p - extra + 1;
 
        net_os_wake_unlock(dev);
@@ -1388,8 +1557,8 @@ wl_iw_send_priv_event(
 int
 wl_control_wl_start(struct net_device *dev)
 {
-       wl_iw_t *iw;
        int ret = 0;
+       wl_iw_t *iw;
 
        WL_TRACE(("Enter %s \n", __FUNCTION__));
 
@@ -1399,6 +1568,11 @@ wl_control_wl_start(struct net_device *dev)
        }
 
        iw = *(wl_iw_t **)netdev_priv(dev);
+
+       if (!iw) {
+               WL_ERROR(("%s: wl is null\n", __FUNCTION__));
+               return -1;
+       }
        dhd_os_start_lock(iw->pub);
 
        if (g_onoff == G_WLAN_SET_OFF) {
@@ -1408,15 +1582,15 @@ wl_control_wl_start(struct net_device *dev)
                sdioh_start(NULL, 0);
 #endif
 
-               dhd_dev_reset(dev, 0);
+               ret = dhd_dev_reset(dev, 0);
 
+               if (ret == BCME_OK) {
 #if defined(BCMLXSDMMC)
-               sdioh_start(NULL, 1);
+                       sdioh_start(NULL, 1);
 #endif
-
-               dhd_dev_init_ioctl(dev);
-
-               g_onoff = G_WLAN_SET_ON;
+                       dhd_dev_init_ioctl(dev);
+                       g_onoff = G_WLAN_SET_ON;
+               }
        }
        WL_TRACE(("Exited %s \n", __FUNCTION__));
 
@@ -1431,8 +1605,8 @@ wl_iw_control_wl_off(
        struct iw_request_info *info
 )
 {
-       wl_iw_t *iw;
        int ret = 0;
+       wl_iw_t *iw;
 
        WL_TRACE(("Enter %s\n", __FUNCTION__));
 
@@ -1442,6 +1616,10 @@ wl_iw_control_wl_off(
        }
 
        iw = *(wl_iw_t **)netdev_priv(dev);
+       if (!iw) {
+               WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+               return -1;
+       }
        dhd_os_start_lock(iw->pub);
 
 #ifdef SOFTAP
@@ -1465,10 +1643,11 @@ wl_iw_control_wl_off(
 #endif
                memset(g_scan, 0, G_SCAN_RESULTS);
                g_scan_specified_ssid = 0;
-
+#if defined(CONFIG_FIRST_SCAN)
                g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
                g_first_counter_scans = 0;
 #endif
+#endif
 
 #if defined(BCMLXSDMMC)
                sdioh_stop(NULL);
@@ -1498,7 +1677,15 @@ wl_iw_control_wl_on(
 
        WL_TRACE(("Enter %s \n", __FUNCTION__));
 
-       ret = wl_control_wl_start(dev);
+       if ((ret = wl_control_wl_start(dev)) != BCME_OK) {
+               WL_ERROR(("%s failed first attemp\n", __FUNCTION__));
+               dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
+               if ((ret = wl_control_wl_start(dev)) != BCME_OK) {
+                       WL_ERROR(("%s failed second attemp\n", __FUNCTION__));
+                       net_os_send_hang_message(dev);
+                       return ret;
+               }
+       }
 
        wl_iw_send_priv_event(dev, "START");
 
@@ -1519,7 +1706,7 @@ wl_iw_control_wl_on(
 static struct ap_profile my_ap;
 static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap);
 static int get_assoc_sta_list(struct net_device *dev, char *buf, int len);
-static int set_ap_mac_list(struct net_device *dev, char *buf);
+static int set_ap_mac_list(struct net_device *dev, void *buf);
 
 #define PTYPE_STRING   0
 #define PTYPE_INTDEC   1
@@ -1601,9 +1788,13 @@ int init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg)
 
        ret |= get_parmeter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5);
 
-       ret |= get_parmeter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5);
+       get_parmeter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5);
+
+       get_parmeter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC,  &ap_cfg->max_scb, 5);
 
-       ret |= get_parmeter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC,  &ap_cfg->max_scb, 5);
+       get_parmeter_from_string(&str_ptr, "HIDDEN=", PTYPE_INTDEC, &ap_cfg->closednet, 5);
+
+       get_parmeter_from_string(&str_ptr, "COUNTRY=", PTYPE_STRING, &ap_cfg->country_code, 3);
 
        return ret;
 }
@@ -1620,7 +1811,8 @@ static int iwpriv_set_ap_config(struct net_device *dev,
        char  *extra = NULL;
        struct ap_profile *ap_cfg = &my_ap;
 
-       WL_TRACE(("> Got IWPRIV SET_AP IOCTL: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n",
+       WL_TRACE(("%s: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n",
+               __FUNCTION__,
                info->cmd, info->flags,
                wrqu->data.pointer, wrqu->data.length));
 
@@ -1674,52 +1866,86 @@ static int iwpriv_get_assoc_list(struct net_device *dev,
        char mac_buf[256];
        struct maclist *sta_maclist = (struct maclist *)mac_buf;
 
-       char mac_lst[256];
+       char mac_lst[384];
        char *p_mac_str;
+       char *p_mac_str_end;
+
+       if ((!dev) || (!extra)) {
+               return -EINVAL;
+       }
+
+       net_os_wake_lock(dev);
 
        WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d, \
                iwp.len:%p, iwp.flags:%x  \n", __FUNCTION__, info->cmd, info->flags, \
                extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags));
 
-       WL_SOFTAP(("extra:%s\n", extra));
-       print_buf((u8 *)p_iwrq, 16, 0);
-
        memset(sta_maclist, 0, sizeof(mac_buf));
 
        sta_maclist->count = 8;
 
-       WL_TRACE((" net device:%s, buf_sz:%d\n", dev->name, sizeof(mac_buf)));
-       get_assoc_sta_list(dev, mac_buf, 256);
-       WL_TRACE((" got %d stations\n", sta_maclist->count));
+       WL_SOFTAP(("%s: net device:%s, buf_sz:%d\n",
+               __FUNCTION__, dev->name, sizeof(mac_buf)));
+
+       if ((ret = get_assoc_sta_list(dev, mac_buf, sizeof(mac_buf))) < 0) {
+               WL_ERROR(("%s: sta list ioctl error:%d\n",
+                       __FUNCTION__, ret));
+               goto func_exit;
+       }
+
+       WL_SOFTAP(("%s: got %d stations\n", __FUNCTION__,
+               sta_maclist->count));
 
        memset(mac_lst, 0, sizeof(mac_lst));
        p_mac_str = mac_lst;
+       p_mac_str_end = &mac_lst[sizeof(mac_lst)-1];
 
        for (i = 0; i < 8; i++) {
                struct ether_addr *id = &sta_maclist->ea[i];
+               if (!ETHER_ISNULLADDR(id->octet)) {
+                       scb_val_t scb_val;
+                       int rssi = 0;
 
-               WL_SOFTAP(("dhd_drv>> sta_mac[%d] :", i));
-               print_buf((unsigned char *)&sta_maclist->ea[i], 6, 0);
+                       bzero(&scb_val, sizeof(scb_val_t));
+
+                       if ((p_mac_str_end - p_mac_str) <= 36) {
+                               WL_ERROR(("%s: mac list buf is < 36 for item[%i] item\n",
+                                       __FUNCTION__, i));
+                               break;
+                       }
 
-               p_mac_str += snprintf(p_mac_str, MAX_WX_STRING,
-                       "Mac[%d]=%02X:%02X:%02X:%02X:%02X:%02X\n", i,
+                       p_mac_str += snprintf(p_mac_str, MAX_WX_STRING,
+                       "\nMac[%d]=%02X:%02X:%02X:%02X:%02X:%02X,", i,
                        id->octet[0], id->octet[1], id->octet[2],
                        id->octet[3], id->octet[4], id->octet[5]);
 
+                       bcopy(id->octet, &scb_val.ea, 6);
+                       ret = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
+                       if (ret  < 0) {
+                               snprintf(p_mac_str, MAX_WX_STRING, "RSSI:ERR");
+                               WL_ERROR(("%s: RSSI ioctl error:%d\n",
+                                       __FUNCTION__, ret));
+                               break;
+                       }
+
+                       rssi = dtoh32(scb_val.val);
+                       p_mac_str += snprintf(p_mac_str, MAX_WX_STRING,
+                       "RSSI:%d", rssi);
+               }
        }
 
-       p_iwrq->data.length = strlen(mac_lst);
+       p_iwrq->data.length = strlen(mac_lst) + 1;
 
-       WL_TRACE(("u.pointer:%p\n", p_iwrq->data.pointer));
-       WL_TRACE(("resulting str:\n%s \n len:%d\n\n", mac_lst, p_iwrq->data.length));
+       WL_SOFTAP(("%s: data to user:\n%s\n usr_ptr:%p\n", __FUNCTION__,
+               mac_lst, p_iwrq->data.pointer));
 
        if (p_iwrq->data.length) {
-               if (copy_to_user(p_iwrq->data.pointer, mac_lst, p_iwrq->data.length)) {
-                       WL_ERROR(("%s: Can't copy to user\n", __FUNCTION__));
-                       return -EFAULT;
-               }
+               bcopy(mac_lst, extra, p_iwrq->data.length);
        }
 
+func_exit:
+       net_os_wake_unlock(dev);
+
        WL_TRACE(("Exited %s \n", __FUNCTION__));
        return ret;
 }
@@ -1727,19 +1953,20 @@ static int iwpriv_get_assoc_list(struct net_device *dev,
 
 
 #ifdef SOFTAP
+#define MAC_FILT_MAX 8
 static int iwpriv_set_mac_filters(struct net_device *dev,
                struct iw_request_info *info,
                union iwreq_data *wrqu,
                char *ext)
 {
-
        int i, ret = -1;
-       char *extra = NULL;
-       u8  macfilt[8][6];
+       char  * extra = NULL;
        int mac_cnt = 0;
-       char sub_cmd[16];
+       int mac_mode = 0;
+       struct ether_addr *p_ea;
+       struct mac_list_set mflist_set;
 
-       WL_TRACE((">>> Got IWPRIV SET_MAC_FILTER IOCTL:  info->cmd:%x, \
+       WL_SOFTAP((">>> Got IWPRIV SET_MAC_FILTER IOCTL:  info->cmd:%x, \
                        info->flags:%x, u.data:%p, u.len:%d\n",
                        info->cmd, info->flags,
                        wrqu->data.pointer, wrqu->data.length));
@@ -1759,25 +1986,21 @@ static int iwpriv_set_mac_filters(struct net_device *dev,
                extra[wrqu->data.length] = 0;
                WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra));
 
-               memset(macfilt, 0, sizeof(macfilt));
-               memset(sub_cmd, 0, sizeof(sub_cmd));
+               memset(&mflist_set, 0, sizeof(mflist_set));
 
                str_ptr = extra;
 
-               if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=", PTYPE_STRING, sub_cmd, 15) != 0) {
+               if (get_parmeter_from_string(&str_ptr, "MAC_MODE=",
+                       PTYPE_INTDEC, &mac_mode, 4) != 0) {
+                       WL_ERROR(("ERROR: 'MAC_MODE=' token is missing\n"));
                        goto exit_proc;
                }
 
-#define MAC_FILT_MAX 8
-
-               if (strncmp(sub_cmd, "MAC_FLT_W", strlen("MAC_FLT_W"))) {
-                       WL_ERROR(("ERROR: sub_cmd:%s != 'MAC_FLT_W'!\n", sub_cmd));
-                       goto exit_proc;
-               }
+               p_ea = &mflist_set.mac_list.ea[0];
 
                if (get_parmeter_from_string(&str_ptr, "MAC_CNT=",
                        PTYPE_INTDEC, &mac_cnt, 4) != 0) {
-                       WL_ERROR(("ERROR: MAC_CNT param is missing \n"));
+                       WL_ERROR(("ERROR: 'MAC_CNT=' token param is missing \n"));
                        goto exit_proc;
                }
 
@@ -1786,19 +2009,23 @@ static int iwpriv_set_mac_filters(struct net_device *dev,
                        goto exit_proc;
                }
 
-               for (i = 0; i < mac_cnt; i++) {
+               for (i=0; i < mac_cnt; i++)
                        if (get_parmeter_from_string(&str_ptr, "MAC=",
-                               PTYPE_STR_HEX, macfilt[i], 12) != 0) {
+                               PTYPE_STR_HEX, &p_ea[i], 12) != 0) {
                                WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i));
                                goto exit_proc;
                        }
-               }
 
+               WL_SOFTAP(("MAC_MODE=:%d, MAC_CNT=%d, MACs:..\n", mac_mode, mac_cnt));
                for (i = 0; i < mac_cnt; i++) {
-                       WL_SOFTAP(("mac_filt[%d]:", i));
-                       print_buf(macfilt[i], 6, 0);
+                  WL_SOFTAP(("mac_filt[%d]:", i));
+                  print_buf(&p_ea[i], 6, 0);
                }
 
+               mflist_set.mode = mac_mode;
+               mflist_set.mac_list.count = mac_cnt;
+               set_ap_mac_list(dev, &mflist_set);
+
                wrqu->data.pointer = NULL;
                wrqu->data.length = 0;
                ret = 0;
@@ -1814,8 +2041,44 @@ static int iwpriv_set_mac_filters(struct net_device *dev,
 }
 #endif
 
+
+#ifdef SOFTAP
+static int iwpriv_set_ap_sta_disassoc(struct net_device *dev,
+        struct iw_request_info *info,
+        union iwreq_data *wrqu,
+        char *ext)
+{
+       int res = 0;
+       char sta_mac[6] = {0, 0, 0, 0, 0, 0};
+       char cmd_buf[256];
+       char *str_ptr = cmd_buf;
+
+       WL_SOFTAP((">>%s called\n args: info->cmd:%x,"
+               " info->flags:%x, u.data.p:%p, u.data.len:%d\n",
+               __FUNCTION__, info->cmd, info->flags,
+               wrqu->data.pointer, wrqu->data.length));
+
+       if (wrqu->data.length != 0) {
+
+               if (copy_from_user(cmd_buf, wrqu->data.pointer, wrqu->data.length)) {
+                       return -EFAULT;
+               }
+
+               if (get_parmeter_from_string(&str_ptr,
+                       "MAC=", PTYPE_STR_HEX, sta_mac, 12) == 0) {
+                       res = wl_iw_softap_deassoc_stations(dev, sta_mac);
+               } else  {
+                       WL_ERROR(("ERROR: STA_MAC= token not found\n"));
+               }
+       }
+
+       return res;
+}
+#endif
+
 #endif
 
+
 #if WIRELESS_EXT < 13
 struct iw_request_info
 {
@@ -2342,7 +2605,7 @@ wl_iw_set_wap(
        join_params.ssid.SSID_len = htod32(g_ssid.SSID_len);
        memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN);
 
-       WL_TRACE(("%s  target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel));
+       WL_ASSOC(("%s  target_channel=%d\n", __FUNCTION__, g_wl_iw_params.target_channel));
        wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size);
 
        if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size))) {
@@ -2351,7 +2614,7 @@ wl_iw_set_wap(
        }
 
        if (g_ssid.SSID_len) {
-               WL_TRACE(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__,  \
+               WL_ASSOC(("%s: join SSID=%s BSSID="MACSTR" ch=%d\n", __FUNCTION__,  \
                        g_ssid.SSID, MAC2STR((u8 *)awrq->sa_data), \
                        g_wl_iw_params.target_channel));
        }
@@ -2591,7 +2854,10 @@ wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid)
        params->passive_time = -1;
        params->home_time = -1;
        params->channel_num = 0;
-
+#if defined(CONFIG_FIRST_SCAN)
+       if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED)
+               params->passive_time = 30;
+#endif
        params->nprobes = htod32(params->nprobes);
        params->active_time = htod32(params->active_time);
        params->passive_time = htod32(params->passive_time);
@@ -2618,7 +2884,6 @@ wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action)
        WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type));
        WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type));
 
-       
        if ((err = dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, \
                iscan->iscan_ex_param_size, iscan->ioctlbuf, sizeof(iscan->ioctlbuf)))) {
                        WL_ERROR(("Set ISCAN for %s failed with %d\n", __FUNCTION__, err));
@@ -2721,7 +2986,7 @@ wl_iw_iscan_get(iscan_info_t *iscan)
 
 static void wl_iw_force_specific_scan(iscan_info_t *iscan)
 {
-       WL_TRACE(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID));
+       WL_SCAN(("%s force Specific SCAN for %s\n", __FUNCTION__, g_specific_ssid.SSID));
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        rtnl_lock();
 #endif
@@ -2739,9 +3004,11 @@ static void wl_iw_send_scan_complete(iscan_info_t *iscan)
        memset(&wrqu, 0, sizeof(wrqu));
 
        wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL);
+#if defined(CONFIG_FIRST_SCAN)
        if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED)
                g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_READY;
-       WL_TRACE(("Send Event ISCAN complete\n"));
+#endif
+       WL_SCAN(("Send Event ISCAN complete\n"));
 #endif 
 }
 
@@ -3046,7 +3313,7 @@ __u16 *merged_len)
        mutex_lock(&wl_cache_lock);
        node = g_ss_cache_ctrl.m_cache_head;
        for (;node;) {
-               list_merge = (wl_scan_results_t *)node;
+               list_merge = (wl_scan_results_t *)&node->buflen;
                WL_TRACE(("%s: Cached Specific APs list=%d\n", __FUNCTION__, list_merge->count));
                if (buflen_from_user - *merged_len > 0) {
                        *merged_len += (__u16) wl_iw_get_scan_prep(list_merge, info,
@@ -3136,14 +3403,16 @@ wl_iw_set_scan(
        if (wrqu->data.length == sizeof(struct iw_scan_req)) {
                if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
                        struct iw_scan_req *req = (struct iw_scan_req *)extra;
+#if defined(CONFIG_FIRST_SCAN)
                        if (g_first_broadcast_scan != BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
-                               WL_TRACE(("%s Ignoring SC %s first BC is not done = %d\n", \
+                               WL_ERROR(("%s Ignoring SC %s first BC is not done = %d\n", \
                                                __FUNCTION__, req->essid, \
                                                g_first_broadcast_scan));
                                return -EBUSY;
                        }
+#endif
                        if (g_scan_specified_ssid) {
-                               WL_TRACE(("%s Specific SCAN is not done ignore scan for = %s \n", \
+                               WL_SCAN(("%s Specific SCAN is not done ignore scan for = %s \n", \
                                        __FUNCTION__, req->essid));
                                return -EBUSY;
                        }
@@ -3161,7 +3430,7 @@ wl_iw_set_scan(
 #endif 
        
        if ((error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)))) {
-               WL_TRACE(("#### Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error));
+               WL_SCAN(("Set SCAN for %s failed with %d\n", g_specific_ssid.SSID, error));
                g_scan_specified_ssid = 0;
                return -EBUSY;
        }
@@ -3176,14 +3445,16 @@ wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
        wlc_ssid_t ssid;
        iscan_info_t *iscan = g_iscan;
 
+#if defined(CONFIG_FIRST_SCAN)
        if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_IDLE) {
                g_first_broadcast_scan = BROADCAST_SCAN_FIRST_STARTED;
-               WL_TRACE(("%s: First Brodcast scan was forced\n", __FUNCTION__));
+               WL_SCAN(("%s: First Brodcast scan was forced\n", __FUNCTION__));
        }
        else if (g_first_broadcast_scan == BROADCAST_SCAN_FIRST_STARTED) {
-               WL_TRACE(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__));
+               WL_SCAN(("%s: ignore ISCAN request first BS is not done yet\n", __FUNCTION__));
                return 0;
        }
+#endif
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        if (flag)
@@ -3193,7 +3464,7 @@ wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
        dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &iscan->scan_flag, sizeof(iscan->scan_flag));
        wl_iw_set_event_mask(dev);
 
-       WL_TRACE(("+++: Set Broadcast ISCAN\n"));
+       WL_SCAN(("+++: Set Broadcast ISCAN\n"));
        
        memset(&ssid, 0, sizeof(ssid));
 
@@ -3228,7 +3499,7 @@ wl_iw_iscan_set_scan(
        iscan_info_t *iscan = g_iscan;
        int ret = 0;
 
-       WL_TRACE(("%s: SIOCSIWSCAN : ISCAN\n", dev->name));
+       WL_SCAN(("%s: SIOCSIWSCAN : ISCAN\n", dev->name));
 
 #if defined(CSCAN)
        WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __FUNCTION__));
@@ -3239,19 +3510,19 @@ wl_iw_iscan_set_scan(
 
 #if defined(SOFTAP)
        if (ap_cfg_running) {
-               WL_TRACE(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__));
+               WL_SCAN(("\n>%s: Not executed, reason -'SOFTAP is active'\n", __FUNCTION__));
                goto set_scan_end;
        }
 #endif
 
        if (g_onoff == G_WLAN_SET_OFF) {
-               WL_TRACE(("%s: driver is not up yet after START\n", __FUNCTION__));
+               WL_SCAN(("%s: driver is not up yet after START\n", __FUNCTION__));
                goto set_scan_end;
        }
 
 #ifdef PNO_SUPPORT
        if  (dhd_dev_get_pno_status(dev)) {
-               WL_ERROR(("%s: Scan called when PNO is active\n", __FUNCTION__));
+               WL_SCAN(("%s: Scan called when PNO is active\n", __FUNCTION__));
        }
 #endif
 
@@ -3261,7 +3532,7 @@ wl_iw_iscan_set_scan(
        }
 
        if (g_scan_specified_ssid) {
-               WL_TRACE(("%s Specific SCAN already running ignoring BC scan\n", \
+               WL_SCAN(("%s Specific SCAN already running ignoring BC scan\n", \
                                __FUNCTION__));
                ret = EBUSY;
                goto set_scan_end;
@@ -3287,14 +3558,14 @@ wl_iw_iscan_set_scan(
                        g_scan_specified_ssid = 0;
 
                        if (iscan->iscan_state == ISCAN_STATE_SCANING) {
-                               WL_TRACE(("%s ISCAN already in progress \n", __FUNCTION__));
+                               WL_SCAN(("%s ISCAN already in progress \n", __FUNCTION__));
                                goto set_scan_end;
                        }
                }
        }
 #endif 
 
-#if !defined(CSCAN)
+#if defined(CONFIG_FIRST_SCAN) && !defined(CSCAN)
        if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
                if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) {
 
@@ -3457,6 +3728,7 @@ wl_iw_handle_scanresults_ies(char **event_p, char *end,
                        wpa_snprintf_hex(buf + 10, 2+1, &(ie->len), 1);
                        wpa_snprintf_hex(buf + 12, 2*ie->len+1, ie->data, ie->len);
                        event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, buf);
+                       kfree(buf);
 #endif 
                        break;
                }
@@ -3480,6 +3752,7 @@ wl_iw_get_scan_prep(
        wl_bss_info_t *bi = NULL;
        char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value;
        int     ret = 0;
+       int channel;
 
        if (!list) {
                WL_ERROR(("%s: Null list pointer",__FUNCTION__));
@@ -3518,8 +3791,9 @@ wl_iw_get_scan_prep(
                }
 
                iwe.cmd = SIOCGIWFREQ;
-               iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
-                       CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL ?
+               channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
+               iwe.u.freq.m = wf_channel2mhz(channel,
+                       channel <= CH_MAX_2G_CHANNEL ?
                        WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
                iwe.u.freq.e = 6;
                event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
@@ -3596,7 +3870,6 @@ wl_iw_get_scan(
                return -EINVAL;
        }
 
-       
        if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
                return error;
        ci.scan_channel = dtoh32(ci.scan_channel);
@@ -3766,7 +4039,7 @@ wl_iw_iscan_get_scan(
        uint buflen_from_user = dwrq->length;
 #endif
 
-       WL_TRACE(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length));
+       WL_SCAN(("%s %s buflen_from_user %d:\n", dev->name, __FUNCTION__, dwrq->length));
 
 #if defined(SOFTAP)
        if (ap_cfg_running) {
@@ -3780,11 +4053,13 @@ wl_iw_iscan_get_scan(
                return -EINVAL;
        }
 
+#if defined(CONFIG_FIRST_SCAN)
        if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_READY) {
                WL_TRACE(("%s %s: first ISCAN results are NOT ready yet \n", \
                         dev->name, __FUNCTION__));
                return -EAGAIN;
        }
+#endif
 
        if ((!iscan) || (iscan->sysioc_pid < 0)) {
                WL_ERROR(("%ssysioc_pid\n", __FUNCTION__));
@@ -3913,7 +4188,9 @@ wl_iw_iscan_get_scan(
        wl_iw_run_ss_cache_timer(0);
        wl_iw_run_ss_cache_timer(1);
 #endif /* CSCAN */
+#if defined(CONFIG_FIRST_SCAN)
        g_first_broadcast_scan = BROADCAST_SCAN_FIRST_RESULT_CONSUMED;
+#endif
 
        WL_TRACE(("%s return to WE %d bytes APs=%d\n", __FUNCTION__, dwrq->length, counter));
 
@@ -4636,7 +4913,7 @@ wl_iw_set_encodeext(
        int error;
        struct iw_encode_ext *iwe;
 
-       WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name));
+       WL_WSEC(("%s: SIOCSIWENCODEEXT\n", dev->name));
 
        CHECK_EXTRA_FOR_NULL(extra);
 
@@ -4866,7 +5143,7 @@ wl_iw_get_encodeext(
        char *extra
 )
 {
-       WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name));
+       WL_WSEC(("%s: SIOCGIWENCODEEXT\n", dev->name));
        return 0;
 }
 
@@ -4884,7 +5161,7 @@ wl_iw_set_wpaauth(
        int val = 0;
        wl_iw_t *iw = *(wl_iw_t **)netdev_priv(dev);
 
-       WL_TRACE(("%s: SIOCSIWAUTH\n", dev->name));
+       WL_WSEC(("%s: SIOCSIWAUTH\n", dev->name));
 
 #if defined(SOFTAP)
        if (ap_cfg_running) {
@@ -4896,7 +5173,7 @@ wl_iw_set_wpaauth(
        paramid = vwrq->flags & IW_AUTH_INDEX;
        paramval = vwrq->value;
 
-       WL_TRACE(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
+       WL_WSEC(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
                dev->name, paramid, paramval));
 
        switch (paramid) {
@@ -4912,7 +5189,7 @@ wl_iw_set_wpaauth(
 #endif 
                else if (paramval & IW_AUTH_WAPI_VERSION_1)
                        val = WPA_AUTH_WAPI;
-               WL_INFORM(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val));
+               WL_WSEC(("%s: %d: setting wpa_auth to 0x%0x\n", __FUNCTION__, __LINE__, val));
                if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
                        return error;
                break;
@@ -4942,24 +5219,28 @@ wl_iw_set_wpaauth(
                        WL_WSEC(("%s: %s: 'Privacy invoked' TRUE but clearing wsec, assuming "
                                "we're a WPS enrollee\n", dev->name, __FUNCTION__));
                        if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", TRUE))) {
-                               WL_WSEC(("Failed to set iovar is_WPS_enrollee\n"));
+                               WL_ERROR(("Failed to set iovar is_WPS_enrollee\n"));
                                return error;
                        }
                } else if (val) {
                        if ((error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", FALSE))) {
-                               WL_WSEC(("Failed to clear iovar is_WPS_enrollee\n"));
+                               WL_ERROR(("Failed to clear iovar is_WPS_enrollee\n"));
                                return error;
                        }
                }
 
-               if ((error = dev_wlc_intvar_set(dev, "wsec", val)))
+               if ((error = dev_wlc_intvar_set(dev, "wsec", val))) {
+                       WL_ERROR(("Failed to set 'wsec'iovar\n"));
                        return error;
+               }
 
                break;
 
        case IW_AUTH_KEY_MGMT:
-               if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val)))
+               if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &val))) {
+                       WL_ERROR(("Failed to get 'wpa_auth'iovar\n"));
                        return error;
+               }
 
                if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
                        if (paramval & IW_AUTH_KEY_MGMT_PSK)
@@ -4977,18 +5258,22 @@ wl_iw_set_wpaauth(
 #endif 
                if (paramval & (IW_AUTH_KEY_MGMT_WAPI_PSK | IW_AUTH_KEY_MGMT_WAPI_CERT))
                        val = WPA_AUTH_WAPI;
-               WL_INFORM(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val));
-               if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val)))
+               WL_WSEC(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val));
+               if ((error = dev_wlc_intvar_set(dev, "wpa_auth", val))) {
+                       WL_ERROR(("Failed to set 'wpa_auth'iovar\n"));
                        return error;
+               }
 
                break;
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               dev_wlc_bufvar_set(dev, "tkip_countermeasures", (char *)&paramval, 1);
+               if ((error = dev_wlc_bufvar_set(dev, "tkip_countermeasures", \
+                                               (char *)&paramval, sizeof(paramval))))
+                       WL_WSEC(("%s: tkip_countermeasures failed %d\n", __FUNCTION__, error));
                break;
 
        case IW_AUTH_80211_AUTH_ALG:
                
-               WL_INFORM(("Setting the D11auth %d\n", paramval));
+               WL_WSEC(("Setting the D11auth %d\n", paramval));
                if (paramval == IW_AUTH_ALG_OPEN_SYSTEM)
                        val = 0;
                else if (paramval == IW_AUTH_ALG_SHARED_KEY)
@@ -5005,15 +5290,21 @@ wl_iw_set_wpaauth(
                if (paramval == 0) {
                        iw->pwsec = 0;
                        iw->gwsec = 0;
-                       if ((error = dev_wlc_intvar_get(dev, "wsec", &val)))
+                       if ((error = dev_wlc_intvar_get(dev, "wsec", &val))) {
+                               WL_ERROR(("Failed to get 'wsec'iovar\n"));
                                return error;
+                       }
                        if (val & (TKIP_ENABLED | AES_ENABLED)) {
                                val &= ~(TKIP_ENABLED | AES_ENABLED);
                                dev_wlc_intvar_set(dev, "wsec", val);
                        }
                        val = 0;
-               WL_INFORM(("%s: %d: setting wpa_auth to %d\n", __FUNCTION__, __LINE__, val));
-                       dev_wlc_intvar_set(dev, "wpa_auth", 0);
+
+                       WL_INFORM(("%s: %d: setting wpa_auth to %d\n",
+                               __FUNCTION__, __LINE__, val));
+                       error = dev_wlc_intvar_set(dev, "wpa_auth", 0);
+                       if (error)
+                               WL_ERROR(("Failed to set 'wpa_auth'iovar\n"));
                        return error;
                }
 
@@ -5021,11 +5312,17 @@ wl_iw_set_wpaauth(
                break;
 
        case IW_AUTH_DROP_UNENCRYPTED:
-               dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)&paramval, 1);
+               error = dev_wlc_bufvar_set(dev, "wsec_restrict", \
+                                  (char *)&paramval, sizeof(paramval));
+               if (error)
+                       WL_ERROR(("%s: wsec_restrict %d\n", __FUNCTION__, error));
                break;
 
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+               error = dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", \
+                                  (char *)&paramval, sizeof(paramval));
+               if (error)
+                       WL_WSEC(("%s: rx_unencrypted_eapol %d\n", __FUNCTION__, error));
                break;
 
 #if WIRELESS_EXT > 17
@@ -5154,15 +5451,24 @@ wl_iw_get_wpaauth(
 
                break;
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               dev_wlc_bufvar_get(dev, "tkip_countermeasures", (char *)&paramval, 1);
+               error = dev_wlc_bufvar_get(dev, "tkip_countermeasures", \
+                                                       (char *)&paramval, sizeof(paramval));
+               if (error)
+                       WL_ERROR(("%s get tkip_countermeasures %d\n", __FUNCTION__, error));
                break;
 
        case IW_AUTH_DROP_UNENCRYPTED:
-               dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)&paramval, 1);
+               error = dev_wlc_bufvar_get(dev, "wsec_restrict", \
+                                          (char *)&paramval, sizeof(paramval));
+               if (error)
+                       WL_ERROR(("%s get wsec_restrict %d\n", __FUNCTION__, error));
                break;
 
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", (char *)&paramval, 1);
+               error = dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", \
+                                                  (char *)&paramval, sizeof(paramval));
+               if (error)
+                       WL_ERROR(("%s get rx_unencrypted_eapol %d\n", __FUNCTION__, error));
                break;
 
        case IW_AUTH_80211_AUTH_ALG:
@@ -5391,7 +5697,7 @@ wl_iw_combined_scan_set(struct net_device *dev, wlc_ssid_t* ssids_local, int nss
        int i;
        iscan_info_t *iscan = g_iscan;
 
-       WL_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan));
+       WL_SCAN(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, nchan));
 
        if ((!dev) && (!g_iscan) && (!iscan->iscan_ex_params_p)) {
                WL_ERROR(("%s error exit\n", __FUNCTION__));
@@ -5537,8 +5843,12 @@ static int iwpriv_set_cscan(struct net_device *dev, struct iw_request_info *info
                        return -1;
                }
 
+               if (iscan->iscan_ex_param_size > WLC_IOCTL_MAXLEN) {
+                       WL_ERROR(("%s wrong ex_param_size %d", \
+                               __FUNCTION__, iscan->iscan_ex_param_size));
+                       return -1;
+               }
                memset(iscan->iscan_ex_params_p, 0, iscan->iscan_ex_param_size);
-               ASSERT(iscan->iscan_ex_param_size < WLC_IOCTL_MAXLEN);
 
                
                wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, NULL);
@@ -5758,6 +6068,7 @@ wl_iw_set_cscan(
                        goto exit_proc;
                }
 
+#if defined(CONFIG_FIRST_SCAN)
                if (g_first_broadcast_scan < BROADCAST_SCAN_FIRST_RESULT_CONSUMED) {
                        if (++g_first_counter_scans == MAX_ALLOWED_BLOCK_SCAN_FROM_FIRST_SCAN) {
 
@@ -5772,6 +6083,7 @@ wl_iw_set_cscan(
                                goto exit_proc;
                        }
                }
+#endif
 
                res = wl_iw_combined_scan_set(dev, ssids_local, nssid, nchan);
 
@@ -5787,21 +6099,36 @@ exit_proc:
 
 static int thr_wait_for_2nd_eth_dev(void *data)
 {
+       struct net_device *dev = (struct net_device *)data;
+       wl_iw_t *iw;
        int ret = 0;
+       unsigned long flags;
+
+       net_os_wake_lock(dev);
 
        DAEMONIZE("wl0_eth_wthread");
 
-       WL_TRACE(("\n>%s threda started:, PID:%x\n", __FUNCTION__, current->pid));
+       WL_TRACE(("\n>%s thread started:, PID:%x\n", __FUNCTION__, current->pid));
+       iw = *(wl_iw_t **)netdev_priv(dev);
+       if (!iw) {
+               WL_ERROR(("%s: dev is null\n", __FUNCTION__));
+               ret = -1;
+               goto fail;
+       }
 
+#ifndef BCMSDIOH_STD
        if (down_timeout(&ap_eth_sema,  msecs_to_jiffies(5000)) != 0) {
                WL_ERROR(("\n%s: sap_eth_sema timeout \n", __FUNCTION__));
                ret = -1;
                goto fail;
        }
+#endif
 
+       flags = dhd_os_spin_lock(iw->pub);
        if (!ap_net_dev) {
                WL_ERROR((" ap_net_dev is null !!!"));
                ret = -1;
+               dhd_os_spin_unlock(iw->pub, flags);
                goto fail;
        }
 
@@ -5810,6 +6137,8 @@ static int thr_wait_for_2nd_eth_dev(void *data)
 
        ap_cfg_running = TRUE;
 
+       dhd_os_spin_unlock(iw->pub, flags);
+
        bcm_mdelay(500);
 
        wl_iw_send_priv_event(priv_dev, "AP_SET_CFG_OK");
@@ -5817,6 +6146,9 @@ static int thr_wait_for_2nd_eth_dev(void *data)
 fail:
        WL_TRACE(("\n>%s, thread completed\n", __FUNCTION__));
 
+       net_os_wake_unlock(dev);
+
+       complete_and_exit(&ap_cfg_exited, 0);
        return ret;
 }
 #endif 
@@ -5931,15 +6263,14 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
 
 #ifdef AP_ONLY
        if (ap_cfg_running) {
-               wl_iw_softap_deassoc_stations(dev);
+               wl_iw_softap_deassoc_stations(dev, NULL);
                ap_cfg_running = FALSE;
        }
-#endif 
+#endif
 
        if (ap_cfg_running == FALSE) {
 
 #ifndef AP_ONLY
-
                sema_init(&ap_eth_sema, 0);
 
                mpc = 0;
@@ -5972,7 +6303,10 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                iolen = wl_bssiovar_mkbuf("apsta",
                        bsscfg_index,  &apsta_var, sizeof(apsta_var)+4,
                        buf, sizeof(buf), &mkvar_err);
-               ASSERT(iolen);
+
+               if (iolen <= 0)
+                       goto fail;
+
                if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) {
                        WL_ERROR(("%s fail to set apsta \n", __FUNCTION__));
                        goto fail;
@@ -5993,7 +6327,7 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                        goto fail;
                }
 
-               res = wl_iw_softap_deassoc_stations(ap_net_dev);
+               res = wl_iw_softap_deassoc_stations(ap_net_dev, NULL);
 
                
                if ((res = dev_iw_write_cfg1_bss_var(dev, 0)) < 0) {
@@ -6002,6 +6336,32 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                }
        }
 
+       if (strlen(ap->country_code)) {
+               int error = 0;
+               if ((error = dev_wlc_ioctl(dev, WLC_SET_COUNTRY,
+                       ap->country_code, sizeof(ap->country_code))) >= 0) {
+                       WL_SOFTAP(("%s: set country %s OK\n",
+                               __FUNCTION__, ap->country_code));
+                       dhd_bus_country_set(dev, &ap->country_code[0]);
+               } else {
+                       WL_ERROR(("%s: ERROR:%d setting country %s\n",
+                               __FUNCTION__, error, ap->country_code));
+               }
+       } else {
+               WL_SOFTAP(("%s: Country code is not specified,"
+                       " will use Radio's default\n",
+                       __FUNCTION__));
+       }
+
+       iolen = wl_bssiovar_mkbuf("closednet",
+               bsscfg_index,  &ap->closednet, sizeof(ap->closednet)+4,
+               buf, sizeof(buf), &mkvar_err);
+       ASSERT(iolen);
+       if ((res = dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen)) < 0) {
+               WL_ERROR(("%s failed to set 'closednet'for apsta \n", __FUNCTION__));
+               goto fail;
+       }
+
        
        if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) {
                ap->channel = 1;
@@ -6050,8 +6410,10 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                goto fail;
        }
        if (ap_cfg_running == FALSE) {
-               kernel_thread(thr_wait_for_2nd_eth_dev, 0, 0);
+               init_completion(&ap_cfg_exited);
+               ap_cfg_pid = kernel_thread(thr_wait_for_2nd_eth_dev, dev, 0);
        } else {
+               ap_cfg_pid = -1;
                if (ap_net_dev == NULL) {
                        WL_ERROR(("%s ERROR: ap_net_dev is NULL !!!\n", __FUNCTION__));
                        goto fail;
@@ -6097,8 +6459,9 @@ static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
        WL_SOFTAP(("wl_iw: set ap profile:\n"));
        WL_SOFTAP(("    ssid = '%s'\n", ap->ssid));
        WL_SOFTAP(("    security = '%s'\n", ap->sec));
-       if (ap->key[0] != '\0')
+       if (ap->key[0] != '\0') {
                WL_SOFTAP(("    key = '%s'\n", ap->key));
+       }
        WL_SOFTAP(("    channel = %d\n", ap->channel));
        WL_SOFTAP(("    max scb = %d\n", ap->max_scb));
 
@@ -6199,6 +6562,7 @@ static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap)
                if (key_len < WSEC_MAX_PSK_LEN) {
                        unsigned char output[2*SHA1HashSize];
                        char key_str_buf[WSEC_MAX_PSK_LEN+1];
+                       bzero(output, 2*SHA1HashSize);
 
                        WL_SOFTAP(("%s: do passhash...\n", __FUNCTION__));
 
@@ -6254,7 +6618,6 @@ int get_parmeter_from_string(
        int parm_str_len;
        char  *param_str_begin;
        char  *param_str_end;
-       char  *orig_str = *str_ptr;
 
        if ((*str_ptr) && !strncmp(*str_ptr, token, strlen(token))) {
 
@@ -6311,27 +6674,36 @@ int get_parmeter_from_string(
 
                return 0;
        } else {
-               WL_ERROR(("\n %s: ERROR: can't find token:%s in str:%s \n",
-                       __FUNCTION__, token, orig_str));
+               WL_ERROR(("\n %s: No token:%s in str:%s\n",
+                       __FUNCTION__, token, *str_ptr));
 
                return -1;
        }
 }
 
-
-static int wl_iw_softap_deassoc_stations(struct net_device *dev)
+static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac)
 {
        int i;
        int res = 0;
        char mac_buf[128] = {0};
-       struct maclist *assoc_maclist = (struct maclist *)mac_buf;
+       char z_mac[6] = {0, 0, 0, 0, 0, 0};
+       char *sta_mac;
+       struct maclist *assoc_maclist = (struct maclist *) mac_buf;
+       bool deauth_all = false;
+
+       if (mac == NULL) {
+               deauth_all = true;
+               sta_mac = z_mac;
+       } else {
+               sta_mac = mac;
+       }
 
        memset(assoc_maclist, 0, sizeof(mac_buf));
        assoc_maclist->count = 8;
 
        res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 128);
        if (res != 0) {
-               WL_SOFTAP((" Error:%d in :%s, Couldn't get ASSOC List\n", res, __FUNCTION__));
+               WL_SOFTAP(("%s: Error:%d Couldn't get ASSOC List\n", __FUNCTION__, res));
                return res;
        }
 
@@ -6342,18 +6714,19 @@ static int wl_iw_softap_deassoc_stations(struct net_device *dev)
                        scbval.val = htod32(1);
                        bcopy(&assoc_maclist->ea[i], &scbval.ea, ETHER_ADDR_LEN);
 
-                       WL_SOFTAP(("deauth STA:%d \n", i));
-                       res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON,
+                       if (deauth_all || (memcmp(&scbval.ea, sta_mac, ETHER_ADDR_LEN) == 0)) {
+                               WL_SOFTAP(("%s, deauth STA:%d \n", __FUNCTION__, i));
+                               res |= dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON,
                                        &scbval, sizeof(scb_val_t));
+                       }
                }
        } else {
                WL_SOFTAP((" STA ASSOC list is empty\n"));
        }
 
-       if (res != 0)
-               WL_SOFTAP((" Error:%d in :%s\n", res, __FUNCTION__));
-       else if (assoc_maclist->count) {
-               
+       if (res != 0) {
+               WL_ERROR(("%s: Error:%d\n", __FUNCTION__, res));
+       } else if (assoc_maclist->count) {
                bcm_mdelay(200);
        }
        return res;
@@ -6378,9 +6751,9 @@ static int iwpriv_softap_stop(struct net_device *dev,
 
        if ((ap_cfg_running == TRUE)) {
 #ifdef AP_ONLY
-                wl_iw_softap_deassoc_stations(dev);
+               wl_iw_softap_deassoc_stations(dev, NULL);
 #else
-                wl_iw_softap_deassoc_stations(ap_net_dev);
+               wl_iw_softap_deassoc_stations(ap_net_dev, NULL);
 
                if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0)
                        WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res));
@@ -6510,9 +6883,14 @@ iwpriv_en_ap_bss(
 
        net_os_wake_lock(dev);
 
-       WL_TRACE(("%s: rcvd IWPRIV IOCTL:  for dev:%s\n", __FUNCTION__, dev->name));
+       WL_SOFTAP(("%s: rcvd IWPRIV IOCTL:  for dev:%s\n", __FUNCTION__, dev->name));
 
 #ifndef AP_ONLY
+       if (ap_cfg_pid >= 0) {
+               wait_for_completion(&ap_cfg_exited);
+               ap_cfg_pid = -1;
+       }
+
        if ((res = wl_iw_set_ap_security(dev, &my_ap)) != 0) {
                WL_ERROR((" %s ERROR setting SOFTAP security in :%d\n", __FUNCTION__, res));
        }
@@ -6534,84 +6912,108 @@ iwpriv_en_ap_bss(
 static int
 get_assoc_sta_list(struct net_device *dev, char *buf, int len)
 {
-       WL_TRACE(("calling dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n",
-               dev, WLC_GET_ASSOCLIST, buf, len));
+       WL_TRACE(("%s: dev_wlc_ioctl(dev:%p, cmd:%d, buf:%p, len:%d)\n",
+               __FUNCTION__, dev, WLC_GET_ASSOCLIST, buf, len));
 
-       dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len);
+       return dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, buf, len);
 
-       return 0;
 }
 
 
+void check_error(int res, const char *msg, const char *func, int line)
+{
+       if (res != 0)
+               WL_ERROR(("%s, %d function:%s, line:%d\n", msg, res, func, line));
+}
+
 static int
-set_ap_mac_list(struct net_device *dev, char *buf)
+set_ap_mac_list(struct net_device *dev, void *buf)
 {
        struct mac_list_set *mac_list_set = (struct mac_list_set *)buf;
-       struct maclist *white_maclist = (struct maclist *)&mac_list_set->white_list;
-       struct maclist *black_maclist = (struct maclist *)&mac_list_set->black_list;
-       int mac_mode = mac_list_set->mode;
+       struct maclist *maclist = (struct maclist *)&mac_list_set->mac_list;
        int length;
        int i;
+       int mac_mode = mac_list_set->mode;
+       int ioc_res = 0;
+       ap_macmode = mac_list_set->mode;
 
-       ap_macmode = mac_mode;
-       if (mac_mode == MACLIST_MODE_DISABLED) {
+       bzero(&ap_black_list, sizeof(struct mflist));
 
-               bzero(&ap_black_list, sizeof(struct mflist));
+       if (mac_mode == MACLIST_MODE_DISABLED) {
 
-               dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode));
+               ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode));
+               check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__);
+               WL_SOFTAP(("%s: MAC filtering disabled\n", __FUNCTION__));
        } else {
+
                scb_val_t scbval;
                char mac_buf[256] = {0};
                struct maclist *assoc_maclist = (struct maclist *) mac_buf;
 
-               mac_mode = MACLIST_MODE_ALLOW;
+               bcopy(maclist, &ap_black_list, sizeof(ap_black_list));
+
+               ioc_res = dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode));
+               check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__);
 
-               dev_wlc_ioctl(dev, WLC_SET_MACMODE, &mac_mode, sizeof(mac_mode));
+               length = sizeof(maclist->count) + maclist->count*ETHER_ADDR_LEN;
+               dev_wlc_ioctl(dev, WLC_SET_MACLIST, maclist, length);
 
-               length = sizeof(white_maclist->count)+white_maclist->count*ETHER_ADDR_LEN;
-               dev_wlc_ioctl(dev, WLC_SET_MACLIST, white_maclist, length);
-               WL_SOFTAP(("White List, length %d:\n", length));
-               for (i = 0; i < white_maclist->count; i++)
+               WL_SOFTAP(("%s: applied MAC List, mode:%d, length %d:\n",
+                       __FUNCTION__, mac_mode, length));
+               for (i = 0; i < maclist->count; i++)
                        WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n",
-                               i, white_maclist->ea[i].octet[0], white_maclist->ea[i].octet[1],
-                               white_maclist->ea[i].octet[2],
-                               white_maclist->ea[i].octet[3], white_maclist->ea[i].octet[4],
-                               white_maclist->ea[i].octet[5]));
+                               i, maclist->ea[i].octet[0], maclist->ea[i].octet[1], \
+                               maclist->ea[i].octet[2], \
+                               maclist->ea[i].octet[3], maclist->ea[i].octet[4], \
+                               maclist->ea[i].octet[5]));
 
-               bcopy(black_maclist, &ap_black_list, sizeof(ap_black_list));
+               assoc_maclist->count = 8;
+               ioc_res = dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256);
+               check_error(ioc_res, "ioctl ERROR:", __FUNCTION__, __LINE__);
+               WL_SOFTAP((" Cur assoc clients:%d\n", assoc_maclist->count));
 
-               WL_SOFTAP(("Black List, size %d:\n", sizeof(ap_black_list)));
-               for (i = 0; i < ap_black_list.count; i++)
-                       WL_SOFTAP(("mac %d: %02X:%02X:%02X:%02X:%02X:%02X\n",
-                               i, ap_black_list.ea[i].octet[0], ap_black_list.ea[i].octet[1],
-                               ap_black_list.ea[i].octet[2],
-                               ap_black_list.ea[i].octet[3],
-                               ap_black_list.ea[i].octet[4], ap_black_list.ea[i].octet[5]));
-
-               dev_wlc_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, 256);
-               if (assoc_maclist->count) {
-                       int j;
+               if (assoc_maclist->count)
                        for (i = 0; i < assoc_maclist->count; i++) {
-                               for (j = 0; j < white_maclist->count; j++) {
-                                       if (!bcmp(&assoc_maclist->ea[i], &white_maclist->ea[j],
+                               int j;
+                               bool assoc_mac_matched = false;
+
+                               WL_SOFTAP(("\n Cheking assoc STA: "));
+                               print_buf(&assoc_maclist->ea[i], 6, 7);
+                               WL_SOFTAP(("with the b/w list:"));
+
+                               for (j = 0; j < maclist->count; j++)
+                                       if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j],
                                                ETHER_ADDR_LEN)) {
-                                               WL_SOFTAP(("match allow, let it be\n"));
+
+                                               assoc_mac_matched = true;
                                                break;
                                        }
-                               }
-                               if (j == white_maclist->count) {
-                                               WL_SOFTAP(("match black, deauth it\n"));
-                                               scbval.val = htod32(1);
-                                               bcopy(&assoc_maclist->ea[i], &scbval.ea,
+
+                               if (((mac_mode == MACLIST_MODE_ALLOW) && !assoc_mac_matched) ||
+                                       ((mac_mode == MACLIST_MODE_DENY) && assoc_mac_matched)) {
+
+                                       WL_SOFTAP(("b-match or w-mismatch,"
+                                                               " do deauth/disassoc \n"));
+                                                       scbval.val = htod32(1);
+                                                       bcopy(&assoc_maclist->ea[i], &scbval.ea, \
                                                        ETHER_ADDR_LEN);
-                                               dev_wlc_ioctl(dev,
-                                                       WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
-                                                       sizeof(scb_val_t));
+                                                       ioc_res = dev_wlc_ioctl(dev,
+                                                               WLC_SCB_DEAUTHENTICATE_FOR_REASON,
+                                                               &scbval, sizeof(scb_val_t));
+                                                       check_error(ioc_res,
+                                                               "ioctl ERROR:",
+                                                               __FUNCTION__, __LINE__);
+
+                               } else {
+                                       WL_SOFTAP((" no b/w list hits, let it be\n"));
                                }
-                       }
+               } else {
+                       WL_SOFTAP(("No ASSOC CLIENTS\n"));
                }
-       }
-       return 0;
+       } 
+
+       WL_SOFTAP(("%s iocres:%d\n", __FUNCTION__, ioc_res));
+       return ioc_res;
 }
 #endif
 
@@ -6744,22 +7146,26 @@ static int wl_iw_set_priv(
                        ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra);
                else if (strnicmp(extra, "STOP", strlen("STOP")) == 0)
                        ret = wl_iw_control_wl_off(dev, info);
-           else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0)
+               else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0)
                        ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0)
+               else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0)
                        ret = wl_iw_set_band(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0)
+               else if (strnicmp(extra, DTIM_SKIP_GET_CMD, strlen(DTIM_SKIP_GET_CMD)) == 0)
                        ret = wl_iw_get_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0)
+               else if (strnicmp(extra, DTIM_SKIP_SET_CMD, strlen(DTIM_SKIP_SET_CMD)) == 0)
                        ret = wl_iw_set_dtim_skip(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0)
+               else if (strnicmp(extra, SETSUSPEND_CMD, strlen(SETSUSPEND_CMD)) == 0)
                        ret = wl_iw_set_suspend(dev, info, (union iwreq_data *)dwrq, extra);
+#ifdef CONFIG_US_NON_DFS_CHANNELS_ONLY
+               else if (strnicmp(extra, SETDFSCHANNELS_CMD, strlen(SETDFSCHANNELS_CMD)) == 0)
+                       ret = wl_iw_set_dfs_channels(dev, info, (union iwreq_data *)dwrq, extra);
+#endif
 #if defined(PNO_SUPPORT)
-           else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0)
+               else if (strnicmp(extra, PNOSSIDCLR_SET_CMD, strlen(PNOSSIDCLR_SET_CMD)) == 0)
                        ret = wl_iw_set_pno_reset(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0)
+               else if (strnicmp(extra, PNOSETUP_SET_CMD, strlen(PNOSETUP_SET_CMD)) == 0)
                        ret = wl_iw_set_pno_set(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0)
+               else if (strnicmp(extra, PNOENABLE_SET_CMD, strlen(PNOENABLE_SET_CMD)) == 0)
                        ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra);
 #endif
 #if defined(CSCAN)
@@ -6816,7 +7222,7 @@ static const iw_handler wl_iw_handler[] =
        (iw_handler) wl_iw_get_freq,            
        (iw_handler) wl_iw_set_mode,            
        (iw_handler) wl_iw_get_mode,            
-       (iw_handler) NULL, 
+       (iw_handler) NULL,
        (iw_handler) wl_iw_get_wext_rssi,
        (iw_handler) NULL,
        (iw_handler) wl_iw_get_range,
@@ -6926,6 +7332,9 @@ static const iw_handler wl_iw_priv_handler[] = {
 
        NULL,
        (iw_handler)iwpriv_fw_reload,
+
+       NULL,
+       (iw_handler)iwpriv_set_ap_sta_disassoc,
 #endif
 #if defined(CSCAN)
 
@@ -6988,8 +7397,8 @@ static const struct iw_priv_args wl_iw_priv_args[] = {
 
        {
                WL_AP_STA_LIST,
-               0,
                IW_PRIV_TYPE_CHAR | 0,
+               IW_PRIV_TYPE_CHAR | 1024,
                "AP_GET_STA_LIST"
        },
 
@@ -7027,6 +7436,13 @@ static const struct iw_priv_args wl_iw_priv_args[] = {
                IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 0,
                "WL_FW_RELOAD"
        },
+
+       {
+               WL_AP_STA_DISASSOC,
+               IW_PRIV_TYPE_CHAR | 256,
+               IW_PRIV_TYPE_CHAR | 0,
+               "AP_STA_DISASSOC"
+       },
 #endif
 #if defined(CSCAN)
        {
@@ -7304,6 +7720,12 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type));
 
        switch (event_type) {
+
+       case WLC_E_RELOAD:
+               WL_ERROR(("%s: Firmware ERROR %d\n", __FUNCTION__, status));
+               net_os_send_hang_message(dev);
+               goto wl_iw_event_end;
+
 #if defined(SOFTAP)
        case WLC_E_PRUNE:
                if (ap_cfg_running) {
@@ -7354,10 +7776,14 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                cmd = IWEVREGISTERED;
                break;
        case WLC_E_ROAM:
-               if (status != WLC_E_STATUS_SUCCESS) {
+               if (status == WLC_E_STATUS_SUCCESS) {
+                       memcpy(wrqu.addr.sa_data, &e->addr.octet, ETHER_ADDR_LEN);
+                       wrqu.addr.sa_family = ARPHRD_ETHER;
+                       cmd = SIOCGIWAP;
+               }
+               else if (status == WLC_E_STATUS_NO_NETWORKS) {
                        roam_no_success++;
-                       if ((roam_no_success == 3) && (roam_no_success_send == FALSE)) {
-
+                       if ((roam_no_success == 5) && (roam_no_success_send == FALSE)) {
                                roam_no_success_send = TRUE;
                                bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
                                bzero(&extra, ETHER_ADDR_LEN);
@@ -7368,10 +7794,6 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                                WL_TRACE(("##### ROAMING did not succeeded %d\n", roam_no_success));
                                goto wl_iw_event_end;
                        }
-               } else {
-                       memcpy(wrqu.addr.sa_data, &e->addr.octet, ETHER_ADDR_LEN);
-                       wrqu.addr.sa_family = ARPHRD_ETHER;
-                       cmd = SIOCGIWAP;
                }
                break;
        case WLC_E_DEAUTH_IND:
@@ -7660,13 +8082,21 @@ wl_iw_bt_flag_set(
        struct net_device *dev,
        bool set)
 {
+#if defined(BT_DHCP_USE_FLAGS)
        char buf_flag7_dhcp_on[8] = { 7, 00, 00, 00, 0x1, 0x0, 0x00, 0x00 };
        char buf_flag7_default[8]   = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
+#endif
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        rtnl_lock();
 #endif
 
+#if defined(BT_DHCP_eSCO_FIX)
+       set_btc_esco_params(dev, set);
+#endif
+
+#if defined(BT_DHCP_USE_FLAGS)
+       WL_TRACE_COEX(("WI-FI priority boost via bt flags, set:%d\n", set));
        if (set == TRUE) {
                dev_wlc_bufvar_set(dev, "btc_flags",
                                        (char *)&buf_flag7_dhcp_on[0], sizeof(buf_flag7_dhcp_on));
@@ -7675,6 +8105,7 @@ wl_iw_bt_flag_set(
                dev_wlc_bufvar_set(dev, "btc_flags",
                                        (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
        }
+#endif
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        rtnl_unlock();
@@ -7707,14 +8138,23 @@ _bt_dhcp_sysioc_thread(void *data)
 
                switch (g_bt->bt_state) {
                        case BT_DHCP_START:
+                               WL_TRACE_COEX(("%s bt_dhcp stm: started \n", __FUNCTION__));
                                g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW;
-                               mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000);
+                               mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIME*HZ/1000);
                                g_bt->timer_on = 1;
                                break;
 
                        case BT_DHCP_OPPORTUNITY_WINDOW:
-                               WL_TRACE(("%s waiting for %d msec expired, force bt flag\n", \
-                                               __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIEM));
+                               if (g_bt->dhcp_done) {
+                                       WL_TRACE_COEX(("%s DHCP Done before T1 expiration\n", \
+                                               __FUNCTION__));
+                                       g_bt->bt_state = BT_DHCP_IDLE;
+                                       g_bt->timer_on = 0;
+                                       break;
+                               }
+
+                               WL_TRACE_COEX(("%s DHCP T1:%d expired\n", \
+                                               __FUNCTION__, BT_DHCP_OPPORTUNITY_WINDOW_TIME));
                                if (g_bt->dev) wl_iw_bt_flag_set(g_bt->dev, TRUE);
                                g_bt->bt_state = BT_DHCP_FLAG_FORCE_TIMEOUT;
                                mod_timer(&g_bt->timer, jiffies + BT_DHCP_FLAG_FORCE_TIME*HZ/1000);
@@ -7722,9 +8162,14 @@ _bt_dhcp_sysioc_thread(void *data)
                                break;
 
                        case BT_DHCP_FLAG_FORCE_TIMEOUT:
-                               WL_TRACE(("%s waiting for %d msec expired remove bt flag\n", \
+                               if (g_bt->dhcp_done) {
+                                       WL_TRACE_COEX(("%s DHCP Done before T2 expiration\n", \
+                                               __FUNCTION__));
+                               } else {
+                                       WL_TRACE_COEX(("%s DHCP wait interval T2:%d msec expired\n",
                                                __FUNCTION__, BT_DHCP_FLAG_FORCE_TIME));
-                               
+                               }
+
                                if (g_bt->dev)  wl_iw_bt_flag_set(g_bt->dev, FALSE);
                                g_bt->bt_state = BT_DHCP_IDLE;
                                g_bt->timer_on = 0;
@@ -7835,9 +8280,11 @@ int wl_iw_attach(struct net_device *dev, void *dhdp)
        g_iscan = iscan;
        iscan->dev = dev;
        iscan->iscan_state = ISCAN_STATE_IDLE;
+#if defined(CONFIG_FIRST_SCAN)
        g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
        g_first_counter_scans = 0;
        g_iscan->scan_flag = 0;
+#endif
 
        iscan->timer_ms    = 8000;
        init_timer(&iscan->timer);
@@ -7912,5 +8359,4 @@ void wl_iw_detach(void)
                wl_iw_send_priv_event(priv_dev, "AP_DOWN");
        }
 #endif
-
 }
index 43088cf886bdf3647f40831a93bd95c9510023fe..928291fe589a58e801ce7e66e9653e68bf4d925c 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: wl_iw.h,v 1.5.34.1.6.36.4.1 2010/09/10 19:24:30 Exp $
+ * $Id: wl_iw.h,v 1.5.34.1.6.36.4.15 2010/11/17 03:13:51 Exp $
  */
 
 
@@ -52,6 +52,7 @@
 #define PNOSETUP_SET_CMD                       "PNOSETUP "
 #define PNOENABLE_SET_CMD                      "PNOFORCE"
 #define PNODEBUG_SET_CMD                       "PNODEBUG"
+#define SETDFSCHANNELS_CMD                     "SETDFSCHANNELS"
 
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
@@ -87,8 +88,9 @@ typedef struct wl_iw_extra_params {
 #define AP_LPB_CMD              (SIOCIWFIRSTPRIV+23)
 #define WL_AP_STOP              (SIOCIWFIRSTPRIV+25)
 #define WL_FW_RELOAD            (SIOCIWFIRSTPRIV+27)
-#define WL_COMBO_SCAN           (SIOCIWFIRSTPRIV+29)
-#define WL_AP_SPARE3            (SIOCIWFIRSTPRIV+31)
+#define WL_AP_STA_DISASSOC             (SIOCIWFIRSTPRIV+29)
+#define WL_COMBO_SCAN           (SIOCIWFIRSTPRIV+31)
+
 #define G_SCAN_RESULTS         (8*1024)
 #define WE_ADD_EVENT_FIX       0x80
 #define G_WLAN_SET_ON          0
@@ -116,19 +118,18 @@ typedef struct wl_iw {
        dhd_pub_t * pub;
 } wl_iw_t;
 
-#define WLC_IW_SS_CACHE_MAXLEN                         512
+#define WLC_IW_SS_CACHE_MAXLEN                         2048
 #define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN      32
 #define WLC_IW_BSS_INFO_MAXLEN                                 \
        (WLC_IW_SS_CACHE_MAXLEN - WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN)
 
 typedef struct wl_iw_ss_cache {
+       struct wl_iw_ss_cache *next;
+       int dirty;
        uint32 buflen;
        uint32 version;
        uint32 count;
        wl_bss_info_t bss_info[1];
-       char dummy[WLC_IW_BSS_INFO_MAXLEN - sizeof(wl_bss_info_t)];
-       int dirty;
-       struct wl_iw_ss_cache *next;
 } wl_iw_ss_cache_t;
 
 typedef struct wl_iw_ss_cache_ctrl {
@@ -140,6 +141,7 @@ typedef struct wl_iw_ss_cache_ctrl {
        uint m_cons_br_scan_cnt;        
        struct timer_list *m_timer;     
 } wl_iw_ss_cache_ctrl_t;
+
 typedef enum broadcast_first_scan {
        BROADCAST_SCAN_FIRST_IDLE = 0,
        BROADCAST_SCAN_FIRST_STARTED,
@@ -158,12 +160,14 @@ struct ap_profile {
        uint32  channel;
        uint32  preamble;
        uint32  max_scb;
+       uint32  closednet;
+       char country_code[WLC_CNTRY_BUF_SZ];
 };
 
 
 #define MACLIST_MODE_DISABLED  0
-#define MACLIST_MODE_ENABLED   1
-#define MACLIST_MODE_ALLOW     2
+#define MACLIST_MODE_DENY              1
+#define MACLIST_MODE_ALLOW             2
 struct mflist {
        uint count;
        struct ether_addr ea[16];
@@ -171,8 +175,7 @@ struct mflist {
 
 struct mac_list_set {
        uint32  mode;
-       struct mflist white_list;
-       struct mflist black_list;
+       struct mflist mac_list;
 };
 #endif
 
@@ -196,7 +199,9 @@ extern int net_os_set_suspend_disable(struct net_device *dev, int val);
 extern int net_os_set_suspend(struct net_device *dev, int val);
 extern int net_os_set_dtim_skip(struct net_device *dev, int val);
 extern int net_os_set_packet_filter(struct net_device *dev, int val);
-extern int net_os_send_hang_message(struct net_device *dev);
+extern void dhd_bus_country_set(struct net_device *dev, char *country_code);
+extern char *dhd_bus_country_get(struct net_device *dev);
+extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
 #define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
@@ -225,12 +230,13 @@ extern int dhd_dev_pno_enable(struct net_device *dev,  int pfn_enabled);
 extern int dhd_dev_get_pno_status(struct net_device *dev);
 
 #define PNO_TLV_PREFIX                 'S'
-#define PNO_TLV_VERSION                        1
-#define PNO_TLV_SUBVERSION             1
-#define PNO_TLV_RESERVED               0
+#define PNO_TLV_VERSION                        '1'
+#define PNO_TLV_SUBVERSION             '2'
+#define PNO_TLV_RESERVED               '0'
 #define PNO_TLV_TYPE_SSID_IE           'S'
 #define PNO_TLV_TYPE_TIME              'T'
 #define  PNO_EVENT_UP                  "PNO_EVENT"
+#define PNO_SCAN_MAX_FW                        508
 
 typedef struct cmd_tlv {
        char prefix;