net: wireless: bcmdhd: Update to Version 5.90.125.84
Dmitry Shmidt [Tue, 13 Sep 2011 22:51:00 +0000 (15:51 -0700)]
- Fix no scan problem for cfg80211 when Scan Event missed
- Improve logic to generate Event via cfg80211 when FW hangs
- Fix a crash on Android driver removal
- DHD read has chance to crash under long stress : fix (dhd_sdio.c)
- Fix power consumption issue as sending disassoc explicitly
- Change the logic for listen timer to solve memory leak and guarantee
  listen timing
- Adding wl_cfg80211_get_station for HostAPD

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>

16 files changed:
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
drivers/net/wireless/bcmdhd/dhd_cdc.c
drivers/net/wireless/bcmdhd/dhd_common.c
drivers/net/wireless/bcmdhd/dhd_linux.c
drivers/net/wireless/bcmdhd/dhd_sdio.c
drivers/net/wireless/bcmdhd/include/epivers.h
drivers/net/wireless/bcmdhd/include/linuxver.h
drivers/net/wireless/bcmdhd/include/wlioctl.h
drivers/net/wireless/bcmdhd/linux_osl.c
drivers/net/wireless/bcmdhd/wl_android.c
drivers/net/wireless/bcmdhd/wl_cfg80211.c
drivers/net/wireless/bcmdhd/wl_cfg80211.h
drivers/net/wireless/bcmdhd/wl_cfgp2p.c
drivers/net/wireless/bcmdhd/wl_cfgp2p.h
drivers/net/wireless/bcmdhd/wldev_common.c

index 8c328b8..a48e85c 100644 (file)
@@ -198,9 +198,14 @@ sdioh_detach(osl_t *osh, sdioh_info_t *sd)
                sdio_release_host(gInstance->func[2]);
 
                /* Disable Function 1 */
-               sdio_claim_host(gInstance->func[1]);
-               sdio_disable_func(gInstance->func[1]);
-               sdio_release_host(gInstance->func[1]);
+               if (gInstance->func[1]) {
+                       sdio_claim_host(gInstance->func[1]);
+                       sdio_disable_func(gInstance->func[1]);
+                       sdio_release_host(gInstance->func[1]);
+               }
+
+               gInstance->func[1] = NULL;
+               gInstance->func[2] = NULL;
 
                /* deregister irq */
                sdioh_sdmmc_osfree(sd);
index c73e04c..8baa60b 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <typedefs.h>
 #include <bcmutils.h>
-#include <sdio.h>      /* SDIO Specs */
+#include <sdio.h>      /* SDIO Device and Protocol Specs */
 #include <bcmsdbus.h>  /* bcmsdh to/from specific controller APIs */
 #include <sdiovar.h>   /* to get msglevel bit values */
 
@@ -133,6 +133,11 @@ static void bcmsdh_sdmmc_remove(struct sdio_func *func)
        if (func->num == 2) {
                sd_trace(("F2 found, calling bcmsdh_remove...\n"));
                bcmsdh_remove(&func->dev);
+       } else if (func->num == 1) {
+               sdio_claim_host(func);
+               sdio_disable_func(func);
+               sdio_release_host(func);
+               gInstance->func[1] = NULL;
        }
 }
 
@@ -259,7 +264,6 @@ int sdio_function_init(void)
 
        error = sdio_register_driver(&bcmsdh_sdmmc_driver);
 
-
        return error;
 }
 
index 67d9481..3a4de96 100644 (file)
@@ -53,7 +53,7 @@
                                 * defined in dhd_sdio.c (amount of header tha might be added)
                                 * plus any space that might be needed for alignment padding.
                                 */
-#define ROUND_UP_MARGIN        2048    /* Biggest SDIO block size possible for
+#define ROUND_UP_MARGIN        2048    /* Biggest SDIO block size possible for
                                 * round off at the end of buffer
                                 */
 
@@ -68,6 +68,7 @@ typedef struct dhd_wlfc_commit_info {
        void*                                   p;
 } dhd_wlfc_commit_info_t;
 #endif /* PROP_TXSTATUS */
+
 typedef struct dhd_prot {
        uint16 reqid;
        uint8 pending;
@@ -218,6 +219,7 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
        DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
+
        if (dhd->busstate == DHD_BUS_DOWN) {
                DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
                return -EIO;
@@ -287,7 +289,6 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
                goto done;
        }
 
-
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
        ASSERT(len <= WLC_IOCTL_MAXLEN);
@@ -1333,6 +1334,7 @@ _dhd_wlfc_borrow_credit(athost_wl_status_info_t* ctx, uint8 available_credit_map
 
        return rc;
 }
+
 int
 dhd_wlfc_interface_entry_update(void* state,
        ewlfc_mac_entry_action_t action, uint8 ifid, uint8 iftype, uint8* ea)
@@ -1444,6 +1446,7 @@ _dhd_wlfc_handle_packet_commit(athost_wl_status_info_t* ctx, int ac,
 
        return rc;
 }
+
 int
 dhd_wlfc_commit_packets(void* state, f_commitpkt_t fcommit, void* commit_ctx)
 {
@@ -1808,6 +1811,7 @@ dhd_wlfc_txstatus_update(dhd_pub_t *dhd, uint8* pkt_info)
        /* pick up the implicit credit from this packet */
        if (DHD_PKTTAG_CREDITCHECK(PKTTAG(pktbuf))) {
                if (wlfc->proptxstatus_mode == WLFC_FCMODE_IMPLIED_CREDIT) {
+
                        int lender, credit_returned = 0; /* Note that borrower is fifo_id */
 
                        /* Return credits to highest priority lender first */
@@ -2227,7 +2231,7 @@ dhd_wlfc_enable(dhd_pub_t *dhd)
                wlfc->hostif_flow_state[i] = OFF;
        }
 
-       /* 
+       /*
        create the SENDQ containing
        sub-queues for all AC precedences + 1 for bc/mc traffic
        */
@@ -2497,7 +2501,6 @@ dhd_prot_init(dhd_pub_t *dhd)
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
 
-
        /* Get the device rev info */
        memset(&revinfo, 0, sizeof(revinfo));
        ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
@@ -2509,7 +2512,7 @@ dhd_prot_init(dhd_pub_t *dhd)
        ret = dhd_wlfc_init(dhd);
 #endif
 
-#ifndef WL_CFG80211
+#if !defined(WL_CFG80211)
        ret = dhd_preinit_ioctls(dhd);
 #endif /* WL_CFG80211 */
 
index 94d3262..9996267 100644 (file)
@@ -1432,7 +1432,8 @@ dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable)
                __FUNCTION__, arp_enable));
 }
 
-void dhd_aoe_arp_clr(dhd_pub_t *dhd)
+void
+dhd_aoe_arp_clr(dhd_pub_t *dhd)
 {
        int ret = 0;
        int iov_len = 0;
@@ -1445,7 +1446,8 @@ void dhd_aoe_arp_clr(dhd_pub_t *dhd)
                DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
 }
 
-void dhd_aoe_hostip_clr(dhd_pub_t *dhd)
+void
+dhd_aoe_hostip_clr(dhd_pub_t *dhd)
 {
        int ret = 0;
        int iov_len = 0;
@@ -1458,7 +1460,8 @@ void dhd_aoe_hostip_clr(dhd_pub_t *dhd)
                DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
 }
 
-void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr)
+void
+dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr)
 {
        int iov_len = 0;
        char iovbuf[32];
@@ -1475,7 +1478,8 @@ void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr)
                __FUNCTION__));
 }
 
-int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen)
+int
+dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen)
 {
        int retcode, i;
        int iov_len = 0;
index 6f19cb7..42f3528 100644 (file)
@@ -89,6 +89,7 @@ typedef struct histo_ {
 #if !ISPOWEROF2(DHD_SDALIGN)
 #error DHD_SDALIGN is not a power of 2!
 #endif
+
 static histo_t vi_d1, vi_d2, vi_d3, vi_d4;
 #endif /* WLMEDIA_HTSF */
 
@@ -1412,7 +1413,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
                        continue;
                }
 
-
                pnext = PKTNEXT(dhdp->osh, pktbuf);
                PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
 
@@ -2192,6 +2192,7 @@ done:
        return OSL_ERROR(bcmerror);
 }
 
+#ifdef WL_CFG80211
 static int
 dhd_cleanup_virt_ifaces(dhd_info_t *dhd)
 {
@@ -2226,6 +2227,7 @@ dhd_cleanup_virt_ifaces(dhd_info_t *dhd)
 
        return 0;
 }
+#endif /* WL_CFG80211 */
 
 static int
 dhd_stop(struct net_device *net)
@@ -2666,7 +2668,9 @@ dhd_bus_start(dhd_pub_t *dhdp)
 
        DHD_TRACE(("Enter %s:\n", __FUNCTION__));
 
+#ifdef DHDTHREAD
        dhd_os_sdlock(dhdp);
+#endif /* DHDTHREAD */
 
        /* try to download image and nvram to the dongle */
        if  ((dhd->pub.busstate == DHD_BUS_DOWN) &&
@@ -2677,12 +2681,16 @@ dhd_bus_start(dhd_pub_t *dhdp)
                                                fw_path, nv_path))) {
                        DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n",
                                   __FUNCTION__, fw_path, nv_path));
+#ifdef DHDTHREAD
                        dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                        return -1;
                }
        }
        if (dhd->pub.busstate != DHD_BUS_LOAD) {
+#ifdef DHDTHREAD
                dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                return -ENETDOWN;
        }
 
@@ -2692,21 +2700,27 @@ dhd_bus_start(dhd_pub_t *dhdp)
 
        /* Bring up the bus */
        if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) {
+
                DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret));
+#ifdef DHDTHREAD
                dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                return ret;
        }
 #if defined(OOB_INTR_ONLY)
        /* Host registration for OOB interrupt */
        if (bcmsdh_register_oob_intr(dhdp)) {
                /* deactivate timer and wait for the handler to finish */
+
                flags = dhd_os_spin_lock(&dhd->pub);
                dhd->wd_timer_valid = FALSE;
                dhd_os_spin_unlock(&dhd->pub, flags);
                del_timer_sync(&dhd->timer);
 
                DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
+#ifdef DHDTHREAD
                dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                return -ENODEV;
        }
 
@@ -2721,11 +2735,15 @@ dhd_bus_start(dhd_pub_t *dhdp)
                dhd_os_spin_unlock(&dhd->pub, flags);
                del_timer_sync(&dhd->timer);
                DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
+#ifdef DHDTHREAD
                dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                return -ENODEV;
        }
 
+#ifdef DHDTHREAD
        dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
 
 #ifdef READ_MACADDR
        dhd_read_macaddr(dhd);
@@ -2960,6 +2978,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        setbit(eventmask, WLC_E_AUTH);
        setbit(eventmask, WLC_E_REASSOC);
        setbit(eventmask, WLC_E_REASSOC_IND);
+       setbit(eventmask, WLC_E_DEAUTH);
        setbit(eventmask, WLC_E_DEAUTH_IND);
        setbit(eventmask, WLC_E_DISASSOC_IND);
        setbit(eventmask, WLC_E_DISASSOC);
@@ -3195,6 +3214,12 @@ static int dhd_device_event(struct notifier_block *this,
                        DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n",
                                __FUNCTION__, ifa->ifa_label, ifa->ifa_address));
 
+                       /* firmware not downloaded, do nothing */
+                       if (dhd->pub.busstate == DHD_BUS_DOWN) {
+                               DHD_ERROR(("%s: bus is down, exit\n", __FUNCTION__));
+                               break;
+                       }
+
 #ifdef AOE_IP_ALIAS_SUPPORT
                        if (ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a) {
                                DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n",
@@ -3415,10 +3440,16 @@ void dhd_detach(dhd_pub_t *dhdp)
 
        /* delete all interfaces, start with virtual  */
        if (dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) {
+               int i = 1;
                dhd_if_t *ifp;
 
-               /* Cleanup all virtual Interfaces */
-               dhd_cleanup_virt_ifaces(dhd);
+               /* Cleanup virtual interfaces */
+               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]);
+                       }
 
                /*  delete primary interface 0 */
                ifp = dhd->iflist[0];
@@ -4348,7 +4379,7 @@ int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
 #ifdef CONFIG_HAS_WAKELOCK
                if (dhd->wakelock_timeout_enable)
                        wake_lock_timeout(&dhd->wl_rxwake,
-                                         dhd->wakelock_timeout_enable * HZ);
+                               dhd->wakelock_timeout_enable * HZ);
 #endif
                dhd->wakelock_timeout_enable = 0;
                spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
index cdb2448..37ab680 100644 (file)
@@ -380,7 +380,6 @@ static const uint max_roundup = 512;
 /* Try doing readahead */
 static bool dhd_readahead;
 
-
 /* To check if there's window offered */
 #define DATAOK(bus) \
        (((uint8)(bus->tx_max - bus->tx_seq) > 2) && \
@@ -2021,7 +2020,8 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
                        bcm_bprintf(&strbuf,
                        "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
                        "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
-                       "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n\n",
+                       "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, "
+                       "r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n\n",
                        ltoh32(tr.type), ltoh32(tr.epc), ltoh32(tr.cpsr), ltoh32(tr.spsr),
                        ltoh32(tr.r13), ltoh32(tr.r14), ltoh32(tr.pc),
                        ltoh32(sdpcm_shared.trap_addr),
@@ -2029,30 +2029,35 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
                        ltoh32(tr.r4), ltoh32(tr.r5), ltoh32(tr.r6), ltoh32(tr.r7));
 
                        addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log);
-                       if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&console_ptr, sizeof(console_ptr))) < 0)
+                       if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+                               (uint8 *)&console_ptr, sizeof(console_ptr))) < 0)
                                goto printbuf;
 
                        addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.buf_size);
-                       if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&console_size, sizeof(console_size))) < 0)
+                       if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+                               (uint8 *)&console_size, sizeof(console_size))) < 0)
                                goto printbuf;
 
                        addr = sdpcm_shared.console_addr + OFFSETOF(hndrte_cons_t, log.idx);
-                       if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)&console_index, sizeof(console_index))) < 0)
+                       if ((rv = dhdsdio_membytes(bus, FALSE, addr,
+                               (uint8 *)&console_index, sizeof(console_index))) < 0)
                                goto printbuf;
 
                        console_ptr = ltoh32(console_ptr);
                        console_size = ltoh32(console_size);
                        console_index = ltoh32(console_index);
 
-                       if (console_size > CONSOLE_BUFFER_MAX || !(console_buffer = MALLOC(bus->dhd->osh, console_size)))
+                       if (console_size > CONSOLE_BUFFER_MAX ||
+                               !(console_buffer = MALLOC(bus->dhd->osh, console_size)))
                                goto printbuf;
 
-                       if ((rv = dhdsdio_membytes(bus, FALSE, console_ptr, (uint8 *)console_buffer, console_size)) < 0)
+                       if ((rv = dhdsdio_membytes(bus, FALSE, console_ptr,
+                               (uint8 *)console_buffer, console_size)) < 0)
                                goto printbuf;
 
-                       for ( i = 0, n = 0; i < console_size; i += n + 1 ) {
+                       for (i = 0, n = 0; i < console_size; i += n + 1) {
                                for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
-                                       ch = console_buffer[ (console_index + i + n) % console_size];
+                                       ch = console_buffer[(console_index + i + n) % console_size];
                                        if (ch == '\n')
                                                break;
                                        line[n] = ch;
@@ -2063,8 +2068,10 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
                                        if (line[n - 1] == '\r')
                                                n--;
                                        line[n] = 0;
-                                       /* Don't use DHD_ERROR macro since we print a lot of information quickly */
-                                       /* The macro will truncate a lot of the printfs */
+                                       /* Don't use DHD_ERROR macro since we print
+                                        * a lot of information quickly. The macro
+                                        * will truncate a lot of the printfs
+                                        */
 
                                        if (dhd_msg_level & DHD_ERROR_VAL)
                                                printf("CONSOLE: %s\n", line);
@@ -3541,7 +3548,7 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
                if ((uint8)(txmax - bus->tx_seq) > 0x40) {
                        DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
                                   __FUNCTION__, txmax, bus->tx_seq));
-                       txmax = bus->tx_seq + 2;
+                       txmax = bus->tx_seq;
                }
                bus->tx_max = txmax;
 
@@ -3962,7 +3969,7 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
                        if ((uint8)(txmax - bus->tx_seq) > 0x40) {
                                        DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
                                                __FUNCTION__, txmax, bus->tx_seq));
-                                       txmax = bus->tx_seq + 2;
+                                       txmax = bus->tx_seq;
                        }
                        bus->tx_max = txmax;
 
@@ -4119,7 +4126,7 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
                if ((uint8)(txmax - bus->tx_seq) > 0x40) {
                        DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n",
                                   __FUNCTION__, txmax, bus->tx_seq));
-                       txmax = bus->tx_seq + 2;
+                       txmax = bus->tx_seq;
                }
                bus->tx_max = txmax;
 
@@ -6182,8 +6189,9 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
 
                if (bus->dhd->dongle_reset) {
                        /* Turn on WLAN */
+#ifdef DHDTHREAD
                        dhd_os_sdlock(dhdp);
-
+#endif /* DHDTHREAD */
                        /* Reset SD client */
                        bcmsdh_reset(bus->sdh);
 
@@ -6223,7 +6231,9 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
                        } else
                                bcmerror = BCME_SDIO_ERROR;
 
+#ifdef DHDTHREAD
                        dhd_os_sdunlock(dhdp);
+#endif /* DHDTHREAD */
                } else {
                        bcmerror = BCME_SDIO_ERROR;
                        DHD_INFO(("%s called when dongle is not in reset\n",
index ab96c07..60f842c 100644 (file)
 
 #define        EPI_RC_NUMBER           125
 
-#define        EPI_INCREMENTAL_NUMBER  78
+#define        EPI_INCREMENTAL_NUMBER  84
 
 #define        EPI_BUILD_NUMBER        0
 
-#define        EPI_VERSION             5, 90, 125, 78
+#define        EPI_VERSION             5, 90, 125, 84
 
-#define        EPI_VERSION_NUM         0x055a7d4e
+#define        EPI_VERSION_NUM         0x055a7d54
 
 #define EPI_VERSION_DEV                5.90.125
 
 
-#define        EPI_VERSION_STR         "5.90.125.78"
+#define        EPI_VERSION_STR         "5.90.125.84"
 
 #endif 
index e1c62b7..96844db 100644 (file)
@@ -70,7 +70,9 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 #include <linux/semaphore.h>
+#endif 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
 #undef IP_TOS
 #endif 
index 1059de1..9357552 100644 (file)
@@ -657,6 +657,49 @@ typedef struct wl_assoc_info {
 #define WLC_ASSOC_REQ_IS_REASSOC 0x01
 
 
+typedef struct {
+       uint16          ver;        
+       uint16          len;        
+       uint16          cap;        
+       uint32          flags;      
+       uint32          idle;       
+       struct ether_addr   ea;     
+       wl_rateset_t        rateset;    
+       uint32          in;     
+       uint32          listen_interval_inms; 
+       uint32          tx_pkts;    
+       uint32          tx_failures;    
+       uint32          rx_ucast_pkts;  
+       uint32          rx_mcast_pkts;  
+       uint32          tx_rate;    
+       uint32          rx_rate;    
+       uint32          rx_decrypt_succeeds;    
+       uint32          rx_decrypt_failures;    
+} sta_info_t;
+
+#define WL_OLD_STAINFO_SIZE OFFSETOF(sta_info_t, tx_pkts)
+
+#define WL_STA_VER      3
+
+
+#define WL_STA_BRCM     0x1     
+#define WL_STA_WME      0x2     
+#define WL_STA_ABCAP        0x4
+#define WL_STA_AUTHE        0x8     
+#define WL_STA_ASSOC        0x10        
+#define WL_STA_AUTHO        0x20        
+#define WL_STA_WDS      0x40        
+#define WL_STA_WDS_LINKUP   0x80        
+#define WL_STA_PS       0x100       
+#define WL_STA_APSD_BE      0x200       
+#define WL_STA_APSD_BK      0x400       
+#define WL_STA_APSD_VI      0x800       
+#define WL_STA_APSD_VO      0x1000      
+#define WL_STA_N_CAP        0x2000      
+#define WL_STA_SCBSTATS     0x4000      
+
+#define WL_WDS_LINKUP       WL_STA_WDS_LINKUP   
+
 
 #define WLC_TXFILTER_OVERRIDE_DISABLED  0
 #define WLC_TXFILTER_OVERRIDE_ENABLED   1
index 17b68e5..1a54437 100644 (file)
@@ -68,6 +68,7 @@ typedef struct bcm_static_pkt {
        struct semaphore osl_pkt_sem;
        unsigned char pkt_use[STATIC_PKT_MAX_NUM * 2];
 } bcm_static_pkt_t;
+
 static bcm_static_pkt_t *bcm_static_skb = 0;
 #endif 
 
@@ -169,10 +170,14 @@ osl_t *
 osl_attach(void *pdev, uint bustype, bool pkttag)
 {
        osl_t *osh;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        gfp_t flags;
 
        flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
        osh = kmalloc(sizeof(osl_t), flags);
+#else
+       osh = kmalloc(sizeof(osl_t), GFP_ATOMIC);
+#endif 
        ASSERT(osh);
 
        bzero(osh, sizeof(osl_t));
@@ -218,13 +223,10 @@ osl_attach(void *pdev, uint bustype, bool pkttag)
 
                sema_init(&bcm_static_buf->static_sem, 1);
 
-
                bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
-
        }
 
-       if (!bcm_static_skb)
-       {
+       if (!bcm_static_skb) {
                int i;
                void *skb_buff_ptr = 0;
                bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
@@ -251,7 +253,7 @@ osl_detach(osl_t *osh)
        kfree(osh);
 }
 
-struct sk_buff *osl_alloc_skb(unsigned int len)
+static struct sk_buff *osl_alloc_skb(unsigned int len)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
        gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
@@ -325,10 +327,14 @@ osl_ctfpool_replenish(osl_t *osh, uint thresh)
 int32
 osl_ctfpool_init(osl_t *osh, uint numobj, uint size)
 {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        gfp_t flags;
 
        flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
        osh->ctfpool = kmalloc(sizeof(ctfpool_t), flags);
+#else
+       osh->ctfpool = kmalloc(sizeof(ctfpool_t), GFP_ATOMIC);
+#endif 
        ASSERT(osh->ctfpool);
        bzero(osh->ctfpool, sizeof(ctfpool_t));
 
@@ -543,20 +549,17 @@ osl_pktfree(osl_t *osh, void *p, bool send)
 }
 
 #ifdef DHD_USE_STATIC_BUF
-void*
+void *
 osl_pktget_static(osl_t *osh, uint len)
 {
-       int i = 0;
+       int i;
        struct sk_buff *skb;
 
-
        if (len > (PAGE_SIZE * 2)) {
                printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len);
-               printk("Do we really need this big skb??\n");
                return osl_pktget(osh, len);
        }
 
-
        down(&bcm_static_skb->osl_pkt_sem);
 
        if (len <= PAGE_SIZE) {
@@ -614,7 +617,6 @@ osl_pktfree_static(osl_t *osh, void *p, bool send)
                        down(&bcm_static_skb->osl_pkt_sem);
                        bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0;
                        up(&bcm_static_skb->osl_pkt_sem);
-
                        return;
                }
        }
@@ -622,6 +624,7 @@ osl_pktfree_static(osl_t *osh, void *p, bool send)
        return osl_pktfree(osh, p, send);
 }
 #endif 
+
 uint32
 osl_pci_read_config(osl_t *osh, uint offset, uint size)
 {
@@ -702,13 +705,18 @@ void *
 osl_malloc(osl_t *osh, uint size)
 {
        void *addr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        gfp_t flags;
+
        
        if (osh)
                ASSERT(osh->magic == OS_HANDLE_MAGIC);
 
        flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
        if ((addr = kmalloc(size, flags)) == NULL) {
+#else
+       if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) {
+#endif 
                if (osh)
                        osh->failed++;
                return (NULL);
@@ -836,10 +844,14 @@ void *
 osl_pktdup(osl_t *osh, void *skb)
 {
        void * p;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        gfp_t flags;
 
        flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
        if ((p = skb_clone((struct sk_buff *)skb, flags)) == NULL)
+#else
+       if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL)
+#endif 
                return NULL;
 
 #ifdef CTFPOOL
index 36110f9..8bc6b36 100644 (file)
@@ -110,7 +110,8 @@ void dhd_dev_init_ioctl(struct net_device *dev);
 int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
 int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command);
 #else
-int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) { return 0; }
+int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
+{ return 0; }
 #endif
 
 extern bool ap_fw_loaded;
@@ -158,6 +159,7 @@ static int wl_android_get_rssi(struct net_device *net, char *command, int total_
        error = wldev_get_rssi(net, &rssi);
        if (error)
                return -1;
+
        error = wldev_get_ssid(net, &ssid);
        if (error)
                return -1;
@@ -187,7 +189,7 @@ static int wl_android_set_suspendopt(struct net_device *dev, char *command, int
        if (ret_now != suspend_flag) {
                if (!(ret = net_os_set_suspend(dev, ret_now)))
                        DHD_INFO(("%s: Suspend Flag %d -> %d\n",
-                                       __FUNCTION__, ret_now, suspend_flag));
+                               __FUNCTION__, ret_now, suspend_flag));
                else
                        DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
        }
@@ -220,6 +222,27 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
        int pno_repeat = 0;
        int pno_freq_expo_max = 0;
 
+#ifdef PNO_SET_DEBUG
+       int i;
+       char pno_in_example[] = {
+               'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
+               'S', '1', '2', '0',
+               'S',
+               0x05,
+               'd', 'l', 'i', 'n', 'k',
+               'S',
+               0x04,
+               'G', 'O', 'O', 'G',
+               'T',
+               '0', 'B',
+               'R',
+               '2',
+               'M',
+               '2',
+               0x00
+               };
+#endif /* PNO_SET_DEBUG */
+
        DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
 
        if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
@@ -227,6 +250,14 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
                goto exit_proc;
        }
 
+#ifdef PNO_SET_DEBUG
+       memcpy(command, pno_in_example, sizeof(pno_in_example));
+       for (i = 0; i < sizeof(pno_in_example); i++)
+               printf("%02X ", command[i]);
+       printf("\n");
+       total_len = sizeof(pno_in_example);
+#endif
+
        str_ptr = command + strlen(CMD_PNOSETUP_SET);
        tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
 
@@ -448,7 +479,6 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                /* TBD: BTCOEXSCAN-STOP */
        }
        else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
-               /* TBD: BTCOEXMODE */
                uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
 
                if (mode == 1)
@@ -527,8 +557,10 @@ int wl_android_init(void)
        dhd_download_fw_on_driverload = FALSE;
 #endif /* ENABLE_INSMOD_NO_FW_LOAD */
 #ifdef CUSTOMER_HW2
-       if (!iface_name[0])
+       if (!iface_name[0]) {
+               memset(iface_name, 0, IFNAMSIZ);
                bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ);
+       }
 #endif /* CUSTOMER_HW2 */
        return ret;
 }
@@ -542,12 +574,24 @@ int wl_android_exit(void)
 
 int wl_android_post_init(void)
 {
+       struct net_device *ndev;
        int ret = 0;
+       char buf[IFNAMSIZ];
        if (!dhd_download_fw_on_driverload) {
                /* Call customer gpio to turn off power with WL_REG_ON signal */
                dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
                g_wifi_on = 0;
-
+       } else {
+               memset(buf, 0, IFNAMSIZ);
+#ifdef CUSTOMER_HW2
+               snprintf(buf, IFNAMSIZ, "%s%d", iface_name, 0);
+#else
+               snprintf(buf, IFNAMSIZ, "%s%d", "eth", 0);
+#endif
+               if ((ndev = dev_get_by_name (&init_net, buf)) != NULL) {
+                       dhd_dev_init_ioctl(ndev);
+                       dev_put(ndev);
+               }
        }
        return ret;
 }
index 8a77231..13530d2 100644 (file)
@@ -52,7 +52,6 @@
 #include <proto/ethernet.h>
 #include <dngl_stats.h>
 #include <dhd.h>
-
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/netdevice.h>
@@ -80,7 +79,6 @@ u32 wl_dbg_level = WL_DBG_ERR;
 
 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
-#define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 #define MAX_WAIT_TIME 1500
@@ -1318,7 +1316,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
                iscan->ioctl_buf, WLC_IOCTL_MEDLEN);
        if (unlikely(err)) {
                if (err == -EBUSY) {
-                       WL_INFO(("system busy : iscan canceled\n"));
+                       WL_ERR(("system busy : iscan canceled\n"));
                } else {
                        WL_ERR(("error (%d)\n", err));
                }
@@ -1498,6 +1496,8 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
        s32 i;
        u32 wpsie_len = 0;
        u8 wpsie[IE_MAX_LEN];
+
+       WL_DBG(("Enter wiphy (%p)\n", wiphy));
        if (unlikely(wl_get_drv_status(wl, SCANNING))) {
                WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
                return -EAGAIN;
@@ -1512,8 +1512,8 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
                return -EOPNOTSUPP;
        }
 
-       WL_DBG(("wiphy (%p)\n", wiphy));
-
+       /* Arm scan timeout timer */
+       mod_timer(&wl->scan_timeout, jiffies + WL_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
        iscan_req = false;
        spec_scan = false;
        if (request) {          /* scan bss */
@@ -1640,7 +1640,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
                        sizeof(sr->ssid), false);
                if (err) {
                        if (err == -EBUSY) {
-                               WL_INFO(("system busy : scan for \"%s\" "
+                               WL_ERR(("system busy : scan for \"%s\" "
                                        "canceled\n", sr->ssid.SSID));
                        } else {
                                WL_ERR(("WLC_SCAN error (%d)\n", err));
@@ -2240,24 +2240,34 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                wl->channel = 0;
        WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
        err = wl_set_wpa_version(dev, sme);
-       if (unlikely(err))
+       if (unlikely(err)) {
+               WL_ERR(("Invalid wpa_version\n"));
                return err;
+       }
 
        err = wl_set_auth_type(dev, sme);
-       if (unlikely(err))
+       if (unlikely(err)) {
+               WL_ERR(("Invalid auth type\n"));
                return err;
+       }
 
        err = wl_set_set_cipher(dev, sme);
-       if (unlikely(err))
+       if (unlikely(err)) {
+               WL_ERR(("Invalid ciper\n"));
                return err;
+       }
 
        err = wl_set_key_mgmt(dev, sme);
-       if (unlikely(err))
+       if (unlikely(err)) {
+               WL_ERR(("Invalid key mgmt\n"));
                return err;
+       }
 
        err = wl_set_set_sharedkey(dev, sme);
-       if (unlikely(err))
+       if (unlikely(err)) {
+               WL_ERR(("Invalid shared key\n"));
                return err;
+       }
 
        wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
        /*
@@ -2284,7 +2294,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                        join_params.ssid.SSID_len));
        }
        wl_set_drv_status(wl, CONNECTING);
-       err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, false);
+       err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
        if (unlikely(err)) {
                WL_ERR(("error (%d)\n", err));
                wl_clr_drv_status(wl, CONNECTING);
@@ -2317,7 +2327,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
                memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
                scbval.val = htod32(scbval.val);
                err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
-                       sizeof(scb_val_t), false);
+                       sizeof(scb_val_t), true);
                if (unlikely(err)) {
                        wl_clr_drv_status(wl, DISCONNECTING);
                        WL_ERR(("error (%d)\n", err));
@@ -2359,7 +2369,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
        /* Make sure radio is off or on as far as software is concerned */
        disable = WL_RADIO_SW_DISABLE << 16;
        disable = htod32(disable);
-       err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), false);
+       err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true);
        if (unlikely(err)) {
                WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
                return err;
@@ -2422,7 +2432,7 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
                index = (u32) key_idx;
                index = htod32(index);
                err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
-                       sizeof(index), false);
+                       sizeof(index), true);
                if (unlikely(err)) {
                        WL_ERR(("error (%d)\n", err));
                }
@@ -2616,16 +2626,6 @@ exit:
                return err;
        }
 
-#ifdef NOT_YET
-       /* TODO: Removed in P2P, check later --lm */
-       val = 1;                /* assume shared key. otherwise 0 */
-       val = htod32(val);
-       err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
-       if (unlikely(err)) {
-               WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
-               return err;
-       }
-#endif
        return err;
 }
 
@@ -2734,51 +2734,72 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 {
        struct wl_priv *wl = wiphy_priv(wiphy);
        scb_val_t scb_val;
-       int rssi;
+       s32 rssi;
        s32 rate;
        s32 err = 0;
+       sta_info_t *sta;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+       s8 eabuf[ETHER_ADDR_STR_LEN];
+#endif
 
        CHECK_SYS_UP(wl);
-       if (unlikely
-               (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
-               WL_ERR(("Wrong Mac address\n"));
-               return -ENOENT;
-       }
-
-       /* Report the current tx rate */
-       err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
-       if (err) {
-               WL_ERR(("Could not get rate (%d)\n", err));
-       } else {
-               rate = dtoh32(rate);
-               sinfo->filled |= STATION_INFO_TX_BITRATE;
-               sinfo->txrate.legacy = rate * 5;
-               WL_DBG(("Rate %d Mbps\n", (rate / 2)));
-       }
-
-       if (wl_get_drv_status(wl, CONNECTED)) {
-               memset(&scb_val, 0, sizeof(scb_val));
-               scb_val.val = 0;
-               err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
-                       sizeof(scb_val_t), false);
-               if (unlikely(err)) {
-                       WL_ERR(("Could not get rssi (%d)\n", err));
+       if (get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
+               err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
+                       ETHER_ADDR_LEN, ioctlbuf, sizeof(ioctlbuf));
+               if (err < 0) {
+                       WL_ERR(("GET STA INFO failed, %d\n", err));
                        return err;
                }
-               rssi = dtoh32(scb_val.val);
-               sinfo->filled |= STATION_INFO_SIGNAL;
-               sinfo->signal = rssi;
-               WL_DBG(("RSSI %d dBm\n", rssi));
-       }
-
-#if defined(ANDROID_WIRELESS_PATCH)
-       err = wldev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed), false);
-       sinfo->link_speed = sinfo->link_speed / 2; /* Convert internal 500Kbps to Mpbs */
-       if (!err)
-               sinfo->filled |= STATION_LINK_SPEED;
-       else
-               WL_ERR(("WLC_GET_RATE failed\n"));
+               sinfo->filled = STATION_INFO_INACTIVE_TIME;
+               sta = (sta_info_t *)ioctlbuf;
+               sta->len = dtoh16(sta->len);
+               sta->cap = dtoh16(sta->cap);
+               sta->flags = dtoh32(sta->flags);
+               sta->idle = dtoh32(sta->idle);
+               sta->in = dtoh32(sta->in);
+               sinfo->inactive_time = sta->idle * 1000;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+               if (sta->flags & WL_STA_ASSOC) {
+                       sinfo->filled |= STATION_INFO_CONNECTED_TIME;
+                       sinfo->connected_time = sta->in;
+               }
+               WL_INFO(("STA %s : idle time : %d sec, connected time :%d ms\n",
+                       bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time,
+                       sta->idle * 1000));
 #endif
+       } else if (get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
+                       if (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID),
+                               ETHER_ADDR_LEN)) {
+                               WL_ERR(("Wrong Mac address\n"));
+                               return -ENOENT;
+                       }
+
+                       /* Report the current tx rate */
+                       err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
+                       if (err) {
+                               WL_ERR(("Could not get rate (%d)\n", err));
+                       } else {
+                               rate = dtoh32(rate);
+                               sinfo->filled |= STATION_INFO_TX_BITRATE;
+                               sinfo->txrate.legacy = rate * 5;
+                               WL_DBG(("Rate %d Mbps\n", (rate / 2)));
+                       }
+
+                       if (wl_get_drv_status(wl, CONNECTED)) {
+                               memset(&scb_val, 0, sizeof(scb_val));
+                               scb_val.val = 0;
+                               err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+                                       sizeof(scb_val_t), false);
+                               if (err) {
+                                       WL_ERR(("Could not get rssi (%d)\n", err));
+                                       return err;
+                               }
+                               rssi = dtoh32(scb_val.val);
+                               sinfo->filled |= STATION_INFO_SIGNAL;
+                               sinfo->signal = rssi;
+                               WL_DBG(("RSSI %d dBm\n", rssi));
+                       }
+       }
 
        return err;
 }
@@ -2800,7 +2821,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        }
        pm = htod32(pm);
        WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
-       err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
+       err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
        if (unlikely(err)) {
                if (err == -ENODEV)
                        WL_DBG(("net_device is not ready yet\n"));
@@ -2862,6 +2883,8 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 {
        struct wl_priv *wl = wiphy_priv(wiphy);
        struct net_device *ndev = wl_to_prmry_ndev(wl);
+       unsigned long flags;
+
        if (unlikely(!wl_get_drv_status(wl, READY))) {
                WL_INFO(("device is not ready : status (%d)\n",
                        (int)wl->status));
@@ -2875,16 +2898,14 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
                wl_delay(500);
                return -EAGAIN;
        }
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
        if (wl->scan_request) {
                cfg80211_scan_done(wl->scan_request, true);
                wl->scan_request = NULL;
-               /* Make sure WPA_supplicant receives scan abort event */
-               wl_delay(500);
-               return -EAGAIN;
        }
        wl_clr_drv_status(wl, SCANNING);
        wl_clr_drv_status(wl, SCAN_ABORTING);
-
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
        return 0;
 }
 
@@ -3054,12 +3075,14 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
        *out_params_size = params_size; /* rtn size to the caller */
        return params;
 }
+
 s32
 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
 {
        wl_scan_params_t *params;
        s32 params_size;
        s32 err = BCME_OK;
+       unsigned long flags;
 
        WL_DBG(("Enter\n"));
 
@@ -3070,13 +3093,22 @@ wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
                err = -ENOMEM;
        }
        /* Do a scan abort to stop the driver's scan engine */
-       err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, false);
+       err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, true);
        if (err < 0) {
                WL_ERR(("scan abort  failed \n"));
        }
+       del_timer_sync(&wl->scan_timeout);
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
+       if (wl->scan_request) {
+               cfg80211_scan_done(wl->scan_request, true);
+               wl->scan_request = NULL;
+       }
+       wl_clr_drv_status(wl, SCANNING);
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
 
        return err;
 }
+
 static s32
 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_channel * channel,
@@ -3322,7 +3354,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
        channel = ieee80211_frequency_to_channel(chan->center_freq);
        WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
                dev->ifindex, channel_type, channel));
-       wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), false);
+       wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), true);
 
        return err;
 }
@@ -3578,7 +3610,7 @@ exit:
 }
 
 static s32
-wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
+wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
        struct beacon_parameters *info)
 {
        s32 err = BCME_OK;
@@ -3654,8 +3686,6 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                }
                wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
                        beacon_ie, wpsie_len + p2pie_len);
-               wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
-                       beacon_ie, wpsie_len + p2pie_len);
 
                /* find the RSN_IE */
                if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
@@ -3670,7 +3700,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                                WL_ERR(("WPA2 IE parsing error"));
                                goto exit;
                        }
-                       err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
+                       err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
                        if (err < 0) {
                                WL_ERR(("SET INFRA error %d\n", err));
                                goto exit;
@@ -3698,9 +3728,9 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                        WL_DBG(("SSID is (%s) in Head \n", ssid.SSID));
                        ssid.SSID_len = ssid_ie->len;
                        wldev_iovar_setint(dev, "mpc", 0);
-                       wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), false);
-                       wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
-                       if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false)) < 0) {
+                       wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true);
+                       wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+                       if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
                                WL_ERR(("setting AP mode failed %d \n", err));
                                return err;
                        }
@@ -3756,7 +3786,21 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                        } else {
                                WL_DBG(("No WPSIE in beacon \n"));
                        }
-                       err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), false);
+                       if (info->interval) {
+                               if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
+                                       &info->interval, sizeof(s32), true)) < 0) {
+                                       WL_ERR(("Beacon Interval Set Error, %d\n", err));
+                                       return err;
+                               }
+                       }
+                       if (info->dtim_period) {
+                               if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
+                                       &info->dtim_period, sizeof(s32), true)) < 0) {
+                                       WL_ERR(("DTIM Interval Set Error, %d\n", err));
+                                       return err;
+                               }
+                       }
+                       err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
                        if (unlikely(err)) {
                                WL_ERR(("WLC_UP error (%d)\n", err));
                                return err;
@@ -3768,7 +3812,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                        join_params.ssid.SSID_len = htod32(ssid.SSID_len);
                        /* create softap */
                        if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
-                               join_params_size, false)) == 0) {
+                               join_params_size, true)) == 0) {
                                wl_clr_drv_status(wl, AP_CREATING);
                                wl_set_drv_status(wl, AP_CREATED);
                        }
@@ -3880,26 +3924,6 @@ exit:
        return err;
 }
 
-#if defined(ANDROID_WIRELESS_PATCH)
-static s32
-wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
-{
-       s32 err = 0;
-
-       printk("Android driver start command\n");
-       return err;
-}
-
-static s32
-wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
-{
-       s32 err = 0;
-
-       printk("Android driver stop command\n");
-       return err;
-}
-#endif /* defined(ANDROID_WIRELESS_PATCH) */
-
 static struct cfg80211_ops wl_cfg80211_ops = {
        .add_virtual_intf = wl_cfg80211_add_virtual_iface,
        .del_virtual_intf = wl_cfg80211_del_virtual_iface,
@@ -3930,11 +3954,8 @@ static struct cfg80211_ops wl_cfg80211_ops = {
        .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
        .change_bss = wl_cfg80211_change_bss,
        .set_channel = wl_cfg80211_set_channel,
-       .set_beacon = wl_cfg80211_set_beacon,
-#if defined(ANDROID_WIRELESS_PATCH)
-       .drv_start = wl_cfg80211_drv_start,
-       .drv_stop = wl_cfg80211_drv_stop
-#endif
+       .set_beacon = wl_cfg80211_add_set_beacon,
+       .add_beacon = wl_cfg80211_add_set_beacon,
 };
 
 static s32 wl_mode_to_nl80211_iftype(s32 mode)
@@ -4132,9 +4153,21 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
                mgmt->u.beacon.capab_info, &bi->BSSID));
 
        signal = notif_bss_info->rssi * 100;
+
+       if (wl->p2p_supported && p2p_on(wl)) {
+       /* &&TODO !memcmp(mgmt->bssid, wl_to_p2p_bss(wl, P2PAPI_BSSCFG_DEVICE), bi->SSID_len) */
+       /* && TODO !memcmp(bi->SSID, wl_to_p2p_bss(wl, P2PAPI_BSSCFG_CONNECTION), bi->SSID_len) */
+               /* find the P2PIE, if we do not find it, we will discard this frame */
+               wifi_p2p_ie_t * p2p_ie;
+               if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)beacon_proberesp->variable,
+                       wl_get_ielen(wl))) == NULL) {
+                       WL_ERR(("Couldn't find P2PIE in probe response/beacon\n"));
+                       kfree(notif_bss_info);
+                       return err;
+               }
+       }
        if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
-               le16_to_cpu
-               (notif_bss_info->frame_len),
+               le16_to_cpu(notif_bss_info->frame_len),
                signal, GFP_KERNEL))) {
                WL_ERR(("cfg80211_inform_bss_frame error\n"));
                kfree(notif_bss_info);
@@ -4226,7 +4259,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
        if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
                memcpy(body, data, len);
                wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
-               &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+               NULL, 0, ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+               memcpy(da.octet, ioctlbuf, ETHER_ADDR_LEN);
                err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
                switch (event) {
                        case WLC_E_ASSOC_IND:
@@ -4239,10 +4273,10 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                                fc = FC_DISASSOC;
                                break;
                        case WLC_E_DEAUTH_IND:
-                               fc = FC_DEAUTH;
+                               fc = FC_DISASSOC;
                                break;
                        case WLC_E_DEAUTH:
-                               fc = FC_DEAUTH;
+                               fc = FC_DISASSOC;
                                break;
                        default:
                                fc = 0;
@@ -4274,7 +4308,7 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                } else if (event == WLC_E_DISASSOC_IND) {
                        cfg80211_send_disassoc(ndev, mgmt_frame, len);
                } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
-                       cfg80211_send_deauth(ndev, mgmt_frame, len);
+                       cfg80211_send_disassoc(ndev, mgmt_frame, len);
                }
 
        } else {
@@ -4285,13 +4319,14 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                        act = true;
                        wl_update_prof(wl, e, &act, WL_PROF_ACT);
                        if (wl_is_ibssmode(wl, ndev)) {
-                               printk("cfg80211_ibss_joined");
+                               printk("cfg80211_ibss_joined\n");
                                cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
                                        GFP_KERNEL);
                                WL_DBG(("joined in IBSS network\n"));
                        } else {
                                if (!wl_get_drv_status(wl, DISCONNECTING)) {
-                                       printk("wl_bss_connect_done succeeded");
+                                       printk("wl_bss_connect_done succeeded status=(0x%x)\n",
+                                               (int)wl->status);
                                        wl_bss_connect_done(wl, ndev, e, data, true);
                                        WL_DBG(("joined in BSS network \"%s\"\n",
                                        ((struct wlc_ssid *)
@@ -4301,31 +4336,49 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
 
                } else if (wl_is_linkdown(wl, e)) {
                        if (wl->scan_request) {
+                               del_timer_sync(&wl->scan_timeout);
                                if (wl->escan_on) {
                                        wl_notify_escan_complete(wl, true);
                                } else
                                        wl_iscan_aborted(wl);
                        }
                        if (wl_get_drv_status(wl, CONNECTED)) {
-                               printk("link down, call cfg80211_disconnected ");
+                               scb_val_t scbval;
+                               printk("link down, call cfg80211_disconnected\n");
                                wl_clr_drv_status(wl, CONNECTED);
+                               /* To make sure disconnect, explictly send dissassoc
+                               *  for BSSID 00:00:00:00:00:00 issue
+                               */
+                               scbval.val = WLAN_REASON_DEAUTH_LEAVING;
+                               memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
+                               scbval.val = htod32(scbval.val);
+                               wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
+                                       sizeof(scb_val_t), true);
                                cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
                                wl_link_down(wl);
                                wl_init_prof(wl->profile);
                        } else if (wl_get_drv_status(wl, CONNECTING)) {
-                               printk("link down, during connecting");
+                               printk("link down, during connecting\n");
                                wl_bss_connect_done(wl, ndev, e, data, false);
                        }
                        wl_clr_drv_status(wl, DISCONNECTING);
 
                } else if (wl_is_nonetwork(wl, e)) {
-                       printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
+                       printk("connect failed event=%d e->status 0x%x\n",
+                               event, (int)ntoh32(e->status));
+                       /* Clean up any pending scan request */
+                       if (wl->scan_request) {
+                               del_timer_sync(&wl->scan_timeout);
+                               if (wl->escan_on) {
+                                       wl_notify_escan_complete(wl, true);
+                               } else
+                                       wl_iscan_aborted(wl);
+                       }
                        if (wl_get_drv_status(wl, CONNECTING))
                                wl_bss_connect_done(wl, ndev, e, data, false);
                } else {
                        printk("%s nothing\n", __FUNCTION__);
                }
-               printk("\n");
        }
 exit:
        if (isfree)
@@ -4362,7 +4415,7 @@ wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
        buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
        BUG_ON(unlikely(!buflen));
 
-       return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, false);
+       return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, true);
 }
 
 static s32
@@ -4620,8 +4673,10 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
                        conn_info->resp_ie_len,
                        completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
                        GFP_KERNEL);
-               WL_DBG(("Report connect result - connection %s\n",
-                       completed ? "succeeded" : "failed"));
+               if (completed)
+                       WL_INFO(("Report connect result - connection succeeded\n"));
+               else
+                       WL_ERR(("Report connect result - connection failed\n"));
        }
        return err;
 }
@@ -4654,6 +4709,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
        struct wl_scan_results *bss_list;
        u32 len = WL_SCAN_BUF_MAX;
        s32 err = 0;
+       unsigned long flags;
 
        WL_DBG(("Enter \n"));
        if (wl->iscan_on && wl->iscan_kickstart)
@@ -4697,11 +4753,14 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
                goto scan_done_out;
 
 scan_done_out:
+       del_timer_sync(&wl->scan_timeout);
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
        if (wl->scan_request) {
                WL_DBG(("cfg80211_scan_done\n"));
                cfg80211_scan_done(wl->scan_request, false);
                wl->scan_request = NULL;
        }
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
        rtnl_unlock();
        return err;
 }
@@ -4779,8 +4838,9 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
 #endif
        if (event == WLC_E_ACTION_FRAME_RX) {
                wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
-               &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
+               NULL, 0, ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
                wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+               memcpy(da.octet, ioctlbuf, ETHER_ADDR_LEN);
                err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
                        &mgmt_frame, &mgmt_frame_len,
                        (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
@@ -4999,6 +5059,7 @@ static void wl_term_iscan(struct wl_priv *wl)
 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
 {
        struct wl_priv *wl = iscan_to_wl(iscan);
+       unsigned long flags;
 
        WL_DBG(("Enter \n"));
        if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
@@ -5006,11 +5067,13 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
                WL_ERR(("Scan complete while device not scanning\n"));
                return;
        }
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
        wl_clr_drv_status(wl, SCANNING);
        if (likely(wl->scan_request)) {
                cfg80211_scan_done(wl->scan_request, aborted);
                wl->scan_request = NULL;
        }
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
        wl->iscan_kickstart = false;
 }
 
@@ -5153,6 +5216,16 @@ static s32 wl_iscan_thread(void *data)
        return 0;
 }
 
+static void wl_scan_timeout(unsigned long data)
+{
+       struct wl_priv *wl = (struct wl_priv *)data;
+
+       if (wl->scan_request) {
+               WL_ERR(("timer expired\n"));
+               wl_notify_escan_complete(wl, true);
+       }
+}
+
 static void wl_iscan_timer(unsigned long data)
 {
        struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
@@ -5195,6 +5268,8 @@ static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
 
 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
 {
+       unsigned long flags;
+
        WL_DBG(("Enter \n"));
        if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
                wl_clr_drv_status(wl, SCANNING);
@@ -5206,10 +5281,12 @@ static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
        if (wl->p2p_supported && p2p_on(wl))
                wl_clr_p2p_status(wl, SCANNING);
 
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
        if (likely(wl->scan_request)) {
                cfg80211_scan_done(wl->scan_request, aborted);
                wl->scan_request = NULL;
        }
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
 }
 
 static s32 wl_escan_handler(struct wl_priv *wl,
@@ -5295,6 +5372,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
                wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
                if (likely(wl->scan_request)) {
                        rtnl_lock();
+                       del_timer_sync(&wl->scan_timeout);
                        WL_INFO(("ESCAN COMPLETED\n"));
                        wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
                        wl_inform_bss(wl);
@@ -5306,6 +5384,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
                wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
                if (likely(wl->scan_request)) {
                        rtnl_lock();
+                       del_timer_sync(&wl->scan_timeout);
                        WL_INFO(("ESCAN ABORTED\n"));
                        wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
                        wl_inform_bss(wl);
@@ -5313,6 +5392,18 @@ static s32 wl_escan_handler(struct wl_priv *wl,
                        rtnl_unlock();
                }
        }
+       else {
+               WL_ERR(("unexpected Escan Event %d : abort\n", status));
+               wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+               if (likely(wl->scan_request)) {
+                       rtnl_lock();
+                       del_timer_sync(&wl->scan_timeout);
+                       wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+                       wl_inform_bss(wl);
+                       wl_notify_escan_complete(wl, true);
+                       rtnl_unlock();
+               }
+       }
 exit:
        return err;
 }
@@ -5342,6 +5433,10 @@ static s32 wl_init_scan(struct wl_priv *wl)
                wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
                wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
        }
+       /* Init scan_timeout timer */
+       init_timer(&wl->scan_timeout);
+       wl->scan_timeout.data = (unsigned long) wl;
+       wl->scan_timeout.function = wl_scan_timeout;
 
        return err;
 }
@@ -5396,6 +5491,7 @@ static void wl_deinit_priv(struct wl_priv *wl)
        wl->dongle_up = false;  /* dongle down */
        wl_flush_eq(wl);
        wl_link_down(wl);
+       del_timer_sync(&wl->scan_timeout);
        wl_term_iscan(wl);
        wl_deinit_priv_mem(wl);
 }
@@ -5589,6 +5685,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
 
        if (event_type == WLC_E_PFN_NET_FOUND)
                WL_ERR((" PNO Event\n"));
+
        if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
                wl_wakeup_event(wl);
 }
@@ -5714,7 +5811,7 @@ static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftyp
                return err;
        }
        infra = htod32(infra);
-       err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), false);
+       err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true);
        if (unlikely(err)) {
                WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
                return err;
@@ -5747,7 +5844,7 @@ static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, boo
        }
        bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
                sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (unlikely(err)) {
                WL_ERR(("Set event_msgs error (%d)\n", err));
                goto dongle_eventmsg_out;
@@ -5772,7 +5869,7 @@ static s32 wl_dongle_up(struct net_device *ndev, u32 up)
 {
        s32 err = 0;
 
-       err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), false);
+       err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), true);
        if (unlikely(err)) {
                WL_ERR(("WLC_UP error (%d)\n", err));
        }
@@ -5784,7 +5881,7 @@ static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
        s32 err = 0;
 
        WL_TRACE(("In\n"));
-       err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), false);
+       err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), true);
        if (unlikely(err)) {
                WL_ERR(("WLC_SET_PM error (%d)\n", err));
        }
@@ -5801,14 +5898,14 @@ wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
        /* Match Host and Dongle rx alignment */
        bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
                sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (unlikely(err)) {
                WL_ERR(("txglomalign error (%d)\n", err));
                goto dongle_glom_out;
        }
        /* disable glom option per default */
        bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (unlikely(err)) {
                WL_ERR(("txglom error (%d)\n", err));
                goto dongle_glom_out;
@@ -5828,7 +5925,7 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
        if (roamvar) {
                bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
                        sizeof(iovbuf));
-               err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+               err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
                if (unlikely(err)) {
                        WL_ERR(("bcn_timeout error (%d)\n", err));
                        goto dongle_rom_out;
@@ -5836,7 +5933,7 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
        }
        /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
        bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (unlikely(err)) {
                WL_ERR(("roam_off error (%d)\n", err));
                goto dongle_rom_out;
@@ -5852,7 +5949,7 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
        s32 err = 0;
 
        err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
-               sizeof(scan_assoc_time), false);
+               sizeof(scan_assoc_time), true);
        if (err) {
                if (err == -EOPNOTSUPP) {
                        WL_INFO(("Scan assoc time is not supported\n"));
@@ -5862,7 +5959,7 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
                goto dongle_scantime_out;
        }
        err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
-               sizeof(scan_unassoc_time), false);
+               sizeof(scan_unassoc_time), true);
        if (err) {
                if (err == -EOPNOTSUPP) {
                        WL_INFO(("Scan unassoc time is not supported\n"));
@@ -5886,7 +5983,7 @@ wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
 
        /* Set ARP offload */
        bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (err) {
                if (err == -EOPNOTSUPP)
                        WL_INFO(("arpoe is not supported\n"));
@@ -5896,7 +5993,7 @@ wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
                goto dongle_offload_out;
        }
        bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (err) {
                if (err == -EOPNOTSUPP)
                        WL_INFO(("arp_ol is not supported\n"));
@@ -5995,7 +6092,7 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
        memcpy((char *)pkt_filterp, &pkt_filter,
                WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
 
-       err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, true);
        if (err) {
                if (err == -EOPNOTSUPP) {
                        WL_INFO(("filter not supported\n"));
@@ -6008,7 +6105,7 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
        /* set mode to allow pattern */
        bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
                sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
        if (err) {
                if (err == -EOPNOTSUPP) {
                        WL_INFO(("filter_mode not supported\n"));
@@ -6139,6 +6236,7 @@ static s32 __wl_cfg80211_up(struct wl_priv *wl)
 static s32 __wl_cfg80211_down(struct wl_priv *wl)
 {
        s32 err = 0;
+       unsigned long flags;
 
        WL_TRACE(("In\n"));
        /* Check if cfg80211 interface is already down */
@@ -6148,6 +6246,7 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
        wl_set_drv_status(wl, SCAN_ABORTING);
 
        wl_term_iscan(wl);
+       flags = dhd_os_spin_lock((dhd_pub_t *)(wl->pub));
        if (wl->scan_request) {
                cfg80211_scan_done(wl->scan_request, true);
                wl->scan_request = NULL;
@@ -6158,6 +6257,7 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
        wl_clr_drv_status(wl, CONNECTING);
        wl_clr_drv_status(wl, CONNECTED);
        wl_clr_drv_status(wl, DISCONNECTING);
+       dhd_os_spin_unlock((dhd_pub_t *)(wl->pub), flags);
        if (wl_get_drv_status(wl, AP_CREATED)) {
                wl_clr_drv_status(wl, AP_CREATED);
                wl_clr_drv_status(wl, AP_CREATING);
@@ -6220,6 +6320,7 @@ s32 wl_cfg80211_down(void)
 
        return err;
 }
+
 static s32 wl_dongle_probecap(struct wl_priv *wl)
 {
        s32 err = 0;
@@ -6669,7 +6770,7 @@ dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
 
        bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));
 
-       return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf, sizeof(ioctlbuf), false));
+       return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf, sizeof(ioctlbuf), true));
 }
 /*
 get named driver variable to uint register value and return error indication
@@ -6699,7 +6800,7 @@ static bool btcoex_is_sco_active(struct net_device *dev)
 
                ioc_res = dev_wlc_intvar_get_reg(dev, "btc_params", 27, &param27);
 
-               WL_INFO(("%s, sample[%d], btc params: 27:%x\n",
+               WL_TRACE(("%s, sample[%d], btc params: 27:%x\n",
                        __FUNCTION__, i, param27));
 
                if (ioc_res < 0) {
@@ -6712,7 +6813,7 @@ static bool btcoex_is_sco_active(struct net_device *dev)
                }
 
                if (sco_id_cnt > 2) {
-                       WL_INFO(("%s, sco/esco detected, pkt id_cnt:%d  samples:%d\n",
+                       WL_TRACE(("%s, sco/esco detected, pkt id_cnt:%d  samples:%d\n",
                                __FUNCTION__, sco_id_cnt, i));
                        res = TRUE;
                        break;
@@ -6753,7 +6854,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                 */
 
                /* 1st save current */
-               WL_INFO(("Do new SCO/eSCO coex algo {save &"
+               WL_TRACE(("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)) &&
@@ -6761,7 +6862,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                        (!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_INFO(("%s saved bt_params[50,51,64,65,71]:"
+                       WL_TRACE(("%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));
@@ -6772,7 +6873,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                        return -1;
                }
 
-               WL_INFO(("override with [50,51,64,65,71]:"
+               WL_TRACE(("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),
@@ -6794,7 +6895,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                saved_status = TRUE;
        } else if (saved_status) {
                /* restore previously saved bt params */
-               WL_INFO(("Do new SCO/eSCO coex algo {save &"
+               WL_TRACE(("Do new SCO/eSCO coex algo {save &"
                          "override}\n"));
 
                regaddr = 50;
@@ -6813,7 +6914,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                dev_wlc_intvar_set_reg(dev, "btc_params",
                        (char *)&regaddr, (char *)&saved_reg71);
 
-               WL_INFO(("restore bt_params[50,51,64,65,71]:"
+               WL_TRACE(("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));
@@ -6989,7 +7090,7 @@ wl_cfg80211_btcoex_deinit(struct wl_priv *wl)
        kfree(wl->btcoex_info);
        wl->btcoex_info = NULL;
 }
-#endif         /* OEM_ANDROID */
+#endif         /* COEX_DHCP */
 
 int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
 {
@@ -7022,7 +7123,7 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
                        (!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_INFO(("Saved 0x%x 0x%x 0x%x\n",
+                               WL_TRACE(("Saved 0x%x 0x%x 0x%x\n",
                                        saved_reg66, saved_reg41, saved_reg68));
 
                                /* Disable PM mode during dhpc session */
@@ -7048,7 +7149,7 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
                                        btco_inf->bt_state = BT_DHCP_START;
                                        btco_inf->timer_on = 1;
                                        mod_timer(&btco_inf->timer, btco_inf->timer.expires);
-                                       WL_INFO(("%s enable BT DHCP Timer\n",
+                                       WL_TRACE(("%s enable BT DHCP Timer\n",
                                        __FUNCTION__));
                                }
 #endif /* COEX_DHCP */
@@ -7064,14 +7165,14 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
 
 #ifdef COEX_DHCP
                /* Stop any bt timer because DHCP session is done */
-               WL_INFO(("%s disable BT DHCP Timer\n", __FUNCTION__));
+               WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
                if (btco_inf->timer_on) {
                        btco_inf->timer_on = 0;
                        del_timer_sync(&btco_inf->timer);
 
                        if (btco_inf->bt_state != BT_DHCP_IDLE) {
                        /* need to restore original btc flags & extra btc params */
-                               WL_INFO(("%s bt->bt_state:%d\n",
+                               WL_TRACE(("%s bt->bt_state:%d\n",
                                        __FUNCTION__, btco_inf->bt_state));
                                /* wake up btcoex thread to restore btlags+params  */
                                schedule_work(&btco_inf->work);
@@ -7096,7 +7197,7 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command)
                        dev_wlc_intvar_set_reg(dev, "btc_params",
                                (char *)&regaddr, (char *)&saved_reg68);
 
-                       WL_INFO(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n",
+                       WL_TRACE(("restore regs {66,41,68} <- 0x%x 0x%x 0x%x\n",
                                saved_reg66, saved_reg41, saved_reg68));
                }
                saved_status = FALSE;
index 4159bd7..9fae79e 100644 (file)
@@ -52,11 +52,11 @@ struct wl_ibss;
 #define dtohchanspec(i) i
 
 #define WL_DBG_NONE    0
+#define WL_DBG_TRACE   (1 << 4)
 #define WL_DBG_SCAN    (1 << 3)
 #define WL_DBG_DBG     (1 << 2)
 #define WL_DBG_INFO    (1 << 1)
 #define WL_DBG_ERR     (1 << 0)
-#define WL_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1)
 
 /* 0 invalidates all debug messages.  default is 1 */
 #define WL_DBG_LEVEL 0xFF
@@ -82,6 +82,13 @@ do {                                                                 \
                printk args;                                                    \
        }                                                                       \
 } while (0)
+#define        WL_TRACE(args)                                                          \
+do {                                                                   \
+       if (wl_dbg_level & WL_DBG_TRACE) {                      \
+               printk(KERN_ERR "CFG80211-TRACE) %s :", __func__);      \
+               printk args;                                                    \
+       }                                                                       \
+} while (0)
 #if (WL_DBG_LEVEL > 0)
 #define        WL_DBG(args)                                                            \
 do {                                                                   \
@@ -94,6 +101,7 @@ do {                                                                 \
 #define        WL_DBG(args)
 #endif                         /* (WL_DBG_LEVEL > 0) */
 
+
 #define WL_SCAN_RETRY_MAX      3       /* used for ibss scan */
 #define WL_NUM_PMKIDS_MAX      MAXPMKID        /* will be used
                                                 * for 2.6.33 kernel
@@ -122,6 +130,9 @@ do {                                                                        \
 #define WL_FILE_NAME_MAX               256
 #define WL_DWELL_TIME  200
 #define VWDEV_CNT 3
+
+#define WL_SCAN_TIMER_INTERVAL_MS      8000 /* Scan timeout */
+
 /* dongle status */
 enum wl_status {
        WL_STATUS_READY = 0,
@@ -196,7 +207,6 @@ struct wl_conf {
 typedef s32(*EVENT_HANDLER) (struct wl_priv *wl,
                             struct net_device *ndev, const wl_event_msg_t *e, void *data);
 
-
 /* bss inform structure for cfg80211 interface */
 struct wl_cfg80211_bss_info {
        u16 band;
@@ -408,6 +418,7 @@ struct wl_priv {
        struct p2p_info *p2p;
        bool p2p_supported;
        struct btcoex_info *btcoex_info;
+       struct timer_list scan_timeout;   /* Timer for catch scan event timeout */
 };
 
 #define wl_to_wiphy(w) (w->wdev->wiphy)
index 2487a67..dd5f5fa 100644 (file)
@@ -59,7 +59,7 @@ wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u
 static s32
 wl_cfgp2p_vndr_ie(struct net_device *ndev, s32 bssidx, s32 pktflag,
             s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete);
-/* 
+/*
  *  Initialize variables related to P2P
  *
  */
@@ -99,7 +99,7 @@ wl_cfgp2p_init_priv(struct wl_priv *wl)
        wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0;
        wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = NULL;
        wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = 0;
-
+       spin_lock_init(&wl->p2p->timer_lock);
        return BCME_OK;
 
 }
@@ -129,9 +129,9 @@ wl_cfgp2p_set_firm_p2p(struct wl_priv *wl)
        wldev_iovar_getint(ndev, "apsta", &val);
        if (val == 0) {
                val = 1;
-               wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), false);
+               wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true);
                wldev_iovar_setint(ndev, "apsta", val);
-               wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), false);
+               wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), true);
        }
        val = 1;
        /* Disable firmware roaming for P2P  */
@@ -958,13 +958,15 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
        CFGP2P_DBG((" Enter\n"));
        if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
                wl_set_p2p_status(wl, LISTEN_EXPIRED);
-
-               if (wl->p2p->listen_timer)
-                       del_timer_sync(wl->p2p->listen_timer);
-
+               if (timer_pending(&wl->p2p->listen_timer)) {
+                       spin_lock_bh(&wl->p2p->timer_lock);
+                       del_timer_sync(&wl->p2p->listen_timer);
+                       spin_unlock_bh(&wl->p2p->timer_lock);
+               }
                cfg80211_remain_on_channel_expired(ndev, wl->cache_cookie, &wl->remain_on_chan,
                    wl->remain_on_chan_type, GFP_KERNEL);
-       }
+       } else
+               wl_clr_p2p_status(wl, LISTEN_EXPIRED);
 
        return ret;
 
@@ -972,7 +974,7 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev,
 
 /*
  *  Timer expire callback function for LISTEN
- *  We can't report cfg80211_remain_on_channel_expired from Timer ISR context, 
+ *  We can't report cfg80211_remain_on_channel_expired from Timer ISR context,
  *  so lets do it from thread context.
  */
 static void
@@ -986,7 +988,7 @@ wl_cfgp2p_listen_expired(unsigned long data)
        wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
 }
 
-/* 
+/*
  * Do a P2P Listen on the given channel for the given duration.
  * A listen consists of sitting idle and responding to P2P probe requests
  * with a P2P probe response.
@@ -1010,6 +1012,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
        } while (0);
 
        s32 ret = BCME_OK;
+       struct timer_list *_timer;
        CFGP2P_DBG((" Enter Channel : %d, Duration : %d\n", channel, duration_ms));
        if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
 
@@ -1018,26 +1021,24 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
                ret = BCME_NOTREADY;
                goto exit;
        }
-
+       if (!wl_get_p2p_status(wl, LISTEN_EXPIRED)) {
+               wl_set_p2p_status(wl, LISTEN_EXPIRED);
+               if (timer_pending(&wl->p2p->listen_timer)) {
+                       spin_lock_bh(&wl->p2p->timer_lock);
+                       del_timer_sync(&wl->p2p->listen_timer);
+                       spin_unlock_bh(&wl->p2p->timer_lock);
+               }
+       } else
        wl_clr_p2p_status(wl, LISTEN_EXPIRED);
 
        wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
                    wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
+       _timer = &wl->p2p->listen_timer;
 
-       if (wl->p2p->listen_timer)
-               del_timer_sync(wl->p2p->listen_timer);
-
-       wl->p2p->listen_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
-
-       if (wl->p2p->listen_timer == NULL) {
-               CFGP2P_ERR(("listen_timer allocation failed\n"));
-               return -ENOMEM;
-       }
-
-       /*  We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle , 
+       /*  We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
         *  otherwise we will wait up to duration_ms + 200ms
         */
-       INIT_TIMER(wl->p2p->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 200);
+       INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration_ms, 200);
 
 #undef INIT_TIMER
 exit:
@@ -1308,7 +1309,7 @@ wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
 s32
 wl_cfgp2p_down(struct wl_priv *wl)
 {
-       if (wl->p2p->listen_timer)
-               del_timer_sync(wl->p2p->listen_timer);
+       if (timer_pending(&wl->p2p->listen_timer))
+               del_timer_sync(&wl->p2p->listen_timer);
        return 0;
 }
index b08504d..5aff468 100644 (file)
@@ -45,11 +45,11 @@ typedef enum {
 #define IE_MAX_LEN 300
 /* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
 struct p2p_saved_ie {
-       u8   p2p_probe_req_ie[IE_MAX_LEN];
-       u8   p2p_probe_res_ie[IE_MAX_LEN];
-       u8   p2p_assoc_req_ie[IE_MAX_LEN];
-       u8   p2p_assoc_res_ie[IE_MAX_LEN];
-       u8   p2p_beacon_ie[IE_MAX_LEN];
+       u8  p2p_probe_req_ie[IE_MAX_LEN];
+       u8  p2p_probe_res_ie[IE_MAX_LEN];
+       u8  p2p_assoc_req_ie[IE_MAX_LEN];
+       u8  p2p_assoc_res_ie[IE_MAX_LEN];
+       u8  p2p_beacon_ie[IE_MAX_LEN];
        u32 p2p_probe_req_ie_len;
        u32 p2p_probe_res_ie_len;
        u32 p2p_assoc_req_ie_len;
@@ -73,8 +73,9 @@ struct p2p_info {
        struct ether_addr dev_addr;
        struct ether_addr int_addr;
        struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
-       struct timer_list *listen_timer;
+       struct timer_list listen_timer;
        wlc_ssid_t ssid;
+       spinlock_t timer_lock;
 };
 
 /* dongle status */
@@ -96,7 +97,7 @@ enum wl_cfgp2p_status {
 #define wl_to_p2p_bss_ndev(w, type)    ((wl)->p2p->bss_idx[type].dev)
 #define wl_to_p2p_bss_bssidx(w, type)  ((wl)->p2p->bss_idx[type].bssidx)
 #define wl_to_p2p_bss_saved_ie(w, type)        ((wl)->p2p->bss_idx[type].saved_ie)
-#define wl_to_p2p_bss_private(w, type)  ((wl)->p2p->bss_idx[type].private_data)
+#define wl_to_p2p_bss_private(w, type)         ((wl)->p2p->bss_idx[type].private_data)
 #define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type])
 #define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \
                                                                        &(wl)->p2p->status))
index e69561e..92c4198 100644 (file)
@@ -37,7 +37,6 @@
 #define dtoh16(i) i
 #define htodchanspec(i) i
 #define dtohchanspec(i) i
-
 extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
 
 s32 wldev_ioctl(
@@ -78,7 +77,7 @@ s32 wldev_iovar_getbuf(
        s32 iovar_len = 0;
 
        iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
-       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, iovar_len, FALSE);
+       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
        return ret;
 }
 
@@ -184,7 +183,7 @@ s32 wldev_iovar_getbuf_bsscfg(
        s32 iovar_len = 0;
 
        iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
-       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, iovar_len, FALSE);
+       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
        return ret;
 
 }
@@ -310,7 +309,7 @@ int wldev_set_country(
                return error;
 
        error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
-                                       smbuf, sizeof(smbuf));
+               smbuf, sizeof(smbuf));
        if (error < 0)
                DHD_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
 
@@ -328,7 +327,7 @@ int wldev_set_country(
        memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
        get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
        error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
-                                       smbuf, sizeof(smbuf));
+               smbuf, sizeof(smbuf));
        if (error < 0) {
                DHD_ERROR(("%s: set country for %s as %s rev %d failed\n",
                        __FUNCTION__, country_code, cspec.ccode, cspec.rev));