net: wireless: bcmdhd: Update to 5.90.125.69
Greg Goldman [Tue, 23 Aug 2011 17:28:41 +0000 (10:28 -0700)]
Change-Id: I25a516ca4d8f5edc72a2a54e420f5e1b4fe3aa16
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>

17 files changed:
drivers/net/wireless/bcmdhd/Makefile
drivers/net/wireless/bcmdhd/bcmsdh_linux.c
drivers/net/wireless/bcmdhd/dhd.h
drivers/net/wireless/bcmdhd/dhd_bus.h
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_linux_mon.c
drivers/net/wireless/bcmdhd/dhd_sdio.c
drivers/net/wireless/bcmdhd/include/epivers.h
drivers/net/wireless/bcmdhd/include/sdio.h
drivers/net/wireless/bcmdhd/include/wlioctl.h
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/wl_iw.c

index 56500b7..e82c985 100644 (file)
@@ -1,5 +1,5 @@
 # bcmdhd
-DHDCFLAGS = -Wall -Wstrict-prototypes -Werror -Dlinux -DBCMDRIVER             \
+DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER                     \
        -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE  \
        -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DSDTEST -DBDC -DTOE    \
        -DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG               \
index 6fa4737..a4dc6ff 100644 (file)
@@ -48,15 +48,6 @@ extern void dhdsdio_isr(void * args);
 #include <dngl_stats.h>
 #include <dhd.h>
 #endif /* defined(OOB_INTR_ONLY) */
-#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
-#if !defined(BCMPLATFORM_BUS)
-#define BCMPLATFORM_BUS
-#endif /* !defined(BCMPLATFORM_BUS) */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
-#include <linux/platform_device.h>
-#endif /* KERNEL_VERSION(2, 6, 19) */
-#endif /* CONFIG_MACH_SANDGATE2G || CONFIG_MACH_LOGICPD_PXA270 */
 
 /**
  * SDIO Host Controller info
index b0df6c7..281e047 100644 (file)
@@ -430,6 +430,7 @@ extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
 extern int dhd_timeout_expired(dhd_timeout_t *tmo);
 
 extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net);
 extern struct net_device * dhd_idx2net(struct dhd_pub *dhd_pub, int ifidx);
 extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata,
                          wl_event_msg_t *, void **data_ptr);
index 2943220..bccb8b6 100644 (file)
@@ -48,6 +48,11 @@ extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
 /* Initialize bus module: prepare for communication w/dongle */
 extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
 
+/* Get the Bus Idle Time */
+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime);
+
+/* Set the Bus Idle Time*/
+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
 /* Send a data frame to the dongle.  Callee disposes of txp. */
 extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp);
 
index fde8a35..0f9893a 100644 (file)
@@ -916,7 +916,10 @@ _dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descript
 #ifdef PROP_TXSTATUS_DEBUG
                ctx->stats.signal_only_pkts_sent++;
 #endif
-               dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p);
+               rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p);
+               if (rc != BCME_OK) {
+                       PKTFREE(ctx->osh, p, TRUE);
+               }
        }
        else {
                DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n",
@@ -2236,49 +2239,6 @@ dhd_prot_dstats(dhd_pub_t *dhd)
        return;
 }
 
-int dhd_set_suspend(int value, dhd_pub_t *dhd)
-{
-       int power_mode = PM_MAX;
-       wl_pkt_filter_enable_t  enable_parm;
-       char iovbuf[32];
-       int bcn_li_dtim = 3;
-
-#define htod32(i) i
-
-       if (dhd && dhd->up) {
-               if (value) {
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_PM,
-                               (char *)&power_mode, sizeof(power_mode), TRUE, 0);
-                       /* Enable packet filter, only allow unicast packet to send up */
-                       enable_parm.id = htod32(100);
-                       enable_parm.enable = htod32(1);
-                       bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
-                               sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-                       /* set bcn_li_dtim */
-                       bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
-                               4, iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-               } else {
-                       power_mode = PM_FAST;
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
-                               sizeof(power_mode), TRUE, 0);
-                       /* disable pkt filter */
-                       enable_parm.id = htod32(100);
-                       enable_parm.enable = htod32(0);
-                       bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
-                               sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-                       /* set bcn_li_dtim */
-                       bcn_li_dtim = 0;
-                       bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
-                               4, iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-               }
-       }
-
-       return 0;
-}
 
 int
 dhd_prot_init(dhd_pub_t *dhd)
@@ -2300,7 +2260,9 @@ dhd_prot_init(dhd_pub_t *dhd)
        ret = dhd_wlfc_init(dhd);
 #endif
 
+#ifndef WL_CFG80211
        ret = dhd_preinit_ioctls(dhd);
+#endif /* WL_CFG80211 */
 
        /* Always assumes wl for now */
        dhd->iswl = TRUE;
index 66d6042..f6bb8e5 100644 (file)
@@ -70,6 +70,7 @@ char nv_path[MOD_PARAM_PATHLEN];
 
 #ifdef SOFTAP
 char fw_path2[MOD_PARAM_PATHLEN];
+extern bool softap_enabled;
 #endif
 
 /* Last connection success/failure status */
@@ -1534,7 +1535,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        uint32 glom = 0;
        uint bcn_timeout = 4;
        uint retry_max = 3;
+#if defined(ARP_OFFLOAD_SUPPORT)
        int arpoe = 1;
+#endif
        int scan_assoc_time = 40;
        int scan_unassoc_time = 40;
        const char                              *str;
@@ -1589,7 +1592,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* GET_CUSTOM_MAC_ENABLE */
 
 #ifdef SET_RANDOM_MAC_SOFTAP
-       if (strstr(fw_path, "apsta") != NULL) {
+       if (strstr(fw_path, "_apsta") != NULL) {
                uint rand_mac;
 
                srandom32((uint)jiffies);
@@ -1610,6 +1613,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* SET_RANDOM_MAC_SOFTAP */
 
+       DHD_TRACE(("Firmware = %s\n", fw_path));
 #if !defined(AP) && defined(WLP2P)
        /* Check if firmware with WFD support used */
        if (strstr(fw_path, "_p2p") != NULL) {
@@ -1619,7 +1623,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                        DHD_ERROR(("%s APSTA for WFD failed ret= %d\n", __FUNCTION__, ret));
                } else {
                        dhd->op_mode |= WFD_MASK;
+#if defined(ARP_OFFLOAD_SUPPORT)
                        arpoe = 0;
+#endif /* (ARP_OFFLOAD_SUPPORT) */
+                       dhd_pkt_filter_enable = FALSE;
                }
        }
 #endif /* !defined(AP) && defined(WLP2P) */
@@ -1634,10 +1641,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                                DHD_ERROR(("%s mpc for HostAPD failed  %d\n", __FUNCTION__, ret));
                        } else {
                                dhd->op_mode |= HOSTAPD_MASK;
+#if defined(ARP_OFFLOAD_SUPPORT)
                                arpoe = 0;
+#endif /* (ARP_OFFLOAD_SUPPORT) */
+                               dhd_pkt_filter_enable = FALSE;
                        }
        }
 #endif /* !defined(AP) && defined(WL_CFG80211) */
+
+       if ((dhd->op_mode != WFD_MASK) && (dhd->op_mode != HOSTAPD_MASK)) {
+               /* STA only operation mode */
+               dhd->op_mode |= STA_MASK;
+               dhd_pkt_filter_enable = TRUE;
+       }
        DHD_ERROR(("Firmware up: op_mode=%d, "
                        "Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
                        dhd->op_mode,
@@ -2089,6 +2105,17 @@ exit:
        return bcn_li_dtim;
 }
 
+/* Check if HostAPD or WFD mode setup */
+bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd)
+{
+#ifdef  WL_CFG80211
+       if (((dhd->op_mode & HOSTAPD_MASK) == HOSTAPD_MASK) ||
+               ((dhd->op_mode & WFD_MASK) == WFD_MASK))
+               return TRUE;
+       else
+#endif /* WL_CFG80211 */
+               return FALSE;
+}
 
 #ifdef PNO_SUPPORT
 int
@@ -2133,6 +2160,8 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
                return ret;
        }
 
+       if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+               return (ret);
        memset(iovbuf, 0, sizeof(iovbuf));
        /* Check if disassoc to enable pno */
        if ((pfn_enabled) &&
@@ -2180,6 +2209,8 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr,
                DHD_ERROR(("%s error exit\n", __FUNCTION__));
                err = -1;
        }
+       if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+               return (err);
 
        /* Check for broadcast ssid */
        for (k = 0; k < nssid; k++) {
@@ -2296,7 +2327,10 @@ int dhd_keep_alive_onoff(dhd_pub_t *dhd)
        int                     str_len;
        int res                 = -1;
 
-       DHD_ERROR(("%s Enter\n", __FUNCTION__));
+       if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+               return (res);
+
+       DHD_TRACE(("%s execution\n", __FUNCTION__));
 
        str = "mkeep_alive";
        str_len = strlen(str);
index d07b3ca..03ba34a 100644 (file)
@@ -671,7 +671,7 @@ dhd_timeout_expired(dhd_timeout_t *tmo)
        return 0;
 }
 
-static int
+int
 dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
 {
        int i = 0;
@@ -1022,10 +1022,10 @@ dhd_op_if(dhd_if_t *ifp)
                        free_netdev(ifp->net);
                }
                dhd->iflist[ifp->idx] = NULL;
-               MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
 #ifdef WL_CFG80211
-               if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+               if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
                        wl_cfg80211_notify_ifdel(ifp->net);
+               }
 #endif
 #ifdef SOFTAP
                flags = dhd_os_spin_lock(&dhd->pub);
@@ -1033,6 +1033,7 @@ dhd_op_if(dhd_if_t *ifp)
                        ap_net_dev = NULL;   /*  NULL  SOFTAP global wl0.1 as well */
                dhd_os_spin_unlock(&dhd->pub, flags);
 #endif /*  SOFTAP */
+       MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
        }
 }
 
index 6c1ff4d..dd9c71f 100644 (file)
@@ -106,8 +106,10 @@ static struct net_device* lookup_real_netdev(char *name)
        for (i = 0; i < DHD_MAX_IFS; i++) {
                ndev = dhd_idx2net(g_monitor.dhd_pub, i);
                if (ndev && strstr(name, ndev->name)) {
-                       if (strlen(ndev->name) > last_name_len)
+                       if (strlen(ndev->name) > last_name_len) {
                                ndev_found = ndev;
+                               last_name_len = strlen(ndev->name);
+                       }
                }
        }
 
index 50bc7e4..6d89f6b 100644 (file)
 
 #define TXRETRIES      2       /* # of retries for tx frames */
 
-#if defined(CONFIG_MACH_SANDGATE2G)
-#define DHD_RXBOUND    250     /* Default for max rx frames in one scheduling */
-#else
 #define DHD_RXBOUND    50      /* Default for max rx frames in one scheduling */
-#endif /* defined(CONFIG_MACH_SANDGATE2G) */
 
 #define DHD_TXBOUND    20      /* Default for max tx frames in one scheduling */
 
@@ -1846,6 +1842,8 @@ dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
        sh->console_addr = ltoh32(sh->console_addr);
        sh->msgtrace_addr = ltoh32(sh->msgtrace_addr);
 
+       if ((sh->flags & SDPCM_SHARED_VERSION_MASK) == 3 && SDPCM_SHARED_VERSION == 1)
+               return BCME_OK;
        if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
                DHD_ERROR(("%s: sdpcm_shared version %d in dhd "
                           "is different than sdpcm_shared version %d in dongle\n",
index 30ef842..f474dfa 100644 (file)
 
 #define        EPI_RC_NUMBER           125
 
-#define        EPI_INCREMENTAL_NUMBER  65
+#define        EPI_INCREMENTAL_NUMBER  69
 
 #define        EPI_BUILD_NUMBER        0
 
-#define        EPI_VERSION             5, 90, 125, 65
+#define        EPI_VERSION             5, 90, 125, 69
 
-#define        EPI_VERSION_NUM         0x055a7d41
+#define        EPI_VERSION_NUM         0x055a7d45
 
 #define EPI_VERSION_DEV                5.90.125
 
 
-#define        EPI_VERSION_STR         "5.90.125.65"
+#define        EPI_VERSION_STR         "5.90.125.69"
 
 #endif 
index 7e94e7d..ca93226 100644 (file)
@@ -376,6 +376,7 @@ typedef volatile struct {
 #define SDIOH_CMD_5            5
 #define SDIOH_CMD_7            7
 #define SDIOH_CMD_11           11
+#define SDIOH_CMD_14           14
 #define SDIOH_CMD_15           15
 #define SDIOH_CMD_19           19
 #define SDIOH_CMD_52           52
@@ -411,6 +412,10 @@ typedef volatile struct {
 
 #define CMD7_RCA_M             BITFIELD_MASK(16)
 #define CMD7_RCA_S             16
+#define CMD14_RCA_M            BITFIELD_MASK(16)
+#define CMD14_RCA_S            16
+#define CMD14_SLEEP_M          BITFIELD_MASK(1)
+#define CMD14_SLEEP_S          15
 
 #define CMD_15_RCA_M           BITFIELD_MASK(16)
 #define CMD_15_RCA_S           16
index a09dd26..1059de1 100644 (file)
@@ -555,6 +555,7 @@ typedef enum sup_auth_status {
 #define CRYPTO_ALGO_AES_OCB_MSDU    5
 #define CRYPTO_ALGO_AES_OCB_MPDU    6
 #define CRYPTO_ALGO_NALG        7
+#define CRYPTO_ALGO_PMK                        12
 
 #define WSEC_GEN_MIC_ERROR  0x0001
 #define WSEC_GEN_REPLAY     0x0002
@@ -616,6 +617,9 @@ typedef struct {
 #define WPA2_AUTH_PSK       0x0080  
 #define BRCM_AUTH_PSK           0x0100  
 #define BRCM_AUTH_DPT       0x0200  
+#define WPA2_AUTH_MFP           0x1000
+#define WPA2_AUTH_TPK          0x2000
+#define WPA2_AUTH_FT           0x4000
 
 
 #define MAXPMKID        16
@@ -1499,6 +1503,7 @@ typedef struct wl_sampledata {
 #define WL_JOIN_PREF_WPA    2   
 #define WL_JOIN_PREF_BAND   3   
 #define WL_JOIN_PREF_RSSI_DELTA 4   
+#define WL_JOIN_PREF_TRANS_PREF        5
 
 
 #define WLJP_BAND_ASSOC_PREF    255 
index b2861f4..0952913 100644 (file)
@@ -874,7 +874,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
                                return ERR_PTR(-ENOMEM);
                        }
                        vwdev->wiphy = wl->wdev->wiphy;
-                       WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
+                       WL_INFO((" virtual interface(%s) is created memalloc done \n",
+                       wl->p2p->vir_ifname));
                        index = alloc_idx_vwdev(wl);
                        wl->vwdev[index] = vwdev;
                        vwdev->iftype =
@@ -891,7 +892,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
                        rtnl_unlock();
                        if (net_attach && !net_attach(dhd, _ndev->ifindex))
                                WL_DBG((" virtual interface(%s) is "
-                                       "created\n", wl->p2p->vir_ifname));
+                                       "created net attach done\n", wl->p2p->vir_ifname));
                        else {
                                rtnl_lock();
                                goto fail;
@@ -918,6 +919,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
        struct wl_priv *wl = wiphy_priv(wiphy);
        s32 timeout = -1;
        s32 ret = 0;
+       WL_DBG(("Enter\n"));
        if (wl->p2p_supported) {
                memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
                if (wl->p2p->vif_created) {
@@ -925,8 +927,17 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
                                wl_cfg80211_scan_abort(wl, dev);
                        }
 
-                       wl_cfgp2p_ifdel(wl, &p2p_mac);
+                       ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
                        wl_set_p2p_status(wl, IF_DELETING);
+                       if (ret) {
+                               /* Firmware could not delete the interface so we will not get WLC_E_IF event for cleaning the dhd virtual nw interace
+                                * So lets do it here. Failures from fw will ensure the application to do ifconfig <inter> down and up sequnce, which will reload the fw
+                               * however we should cleanup the linux network virtual interfaces
+                               */
+                               dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+                               WL_ERR(("Firmware returned an error from p2p_ifdel, try to remove linux virtual network interface dev->name %s\n", dev->name));
+                               dhd_del_if(dhd->info, dhd_net2idx(dhd->info, dev));
+                       }
 
                        /* Wait for any pending scan req to get aborted from the sysioc context */
                        timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
@@ -1082,8 +1093,8 @@ wl_cfg80211_notify_ifdel(struct net_device *net)
        if (wl->p2p->vif_created) {
                s32 index = 0;
 
-               WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
-                       net->name, wl->p2p->vir_ifname));
+               WL_DBG(("IF_DEL event called from dongle, net %x, vif name: %s\n",
+                       (unsigned int)net, wl->p2p->vir_ifname));
 
                memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
                index = wl_cfgp2p_find_idx(wl, net);
@@ -2220,12 +2231,20 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
        CHECK_SYS_UP(wl);
        act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
        if (likely(act)) {
+               /*
+               * Cancel ongoing scan to sync up with sme state machine of cfg80211.
+               */
+               if (wl->scan_request) {
+                       wl_cfg80211_scan_abort(wl, dev);
+               }
+               wl_set_drv_status(wl, DISCONNECTING);
                scbval.val = reason_code;
                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);
                if (unlikely(err)) {
+                       wl_clr_drv_status(wl, DISCONNECTING);
                        WL_ERR(("error (%d)\n", err));
                        return err;
                }
@@ -2710,6 +2729,11 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
 
        CHECK_SYS_UP(wl);
        pm = enabled ? PM_FAST : PM_OFF;
+       /* Do not enable the power save after assoc if it is p2p interface */
+       if (wl->p2p && wl->p2p->vif_created) {
+               WL_DBG(("Do not enable the power save for p2p interfaces even after assoc\n"));
+               pm = PM_OFF;
+       }
        pm = htod32(pm);
        WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
        err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
@@ -3616,7 +3640,10 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                        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);
-                       wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false);
+                       if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false)) < 0) {
+                               WL_ERR(("setting AP mode failed %d \n", err));
+                               return err;
+                       }
                        /* find the RSN_IE */
                        if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
                                DOT11_MNG_RSN_ID)) != NULL) {
@@ -4188,21 +4215,30 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                        ntoh32(e->event_type), ntoh32(e->status)));
                if (wl_is_linkup(wl, e, ndev)) {
                        wl_link_up(wl);
+                       act = true;
+                       wl_update_prof(wl, e, &act, WL_PROF_ACT);
                        if (wl_is_ibssmode(wl, ndev)) {
                                printk("cfg80211_ibss_joined");
                                cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
                                        GFP_KERNEL);
                                WL_DBG(("joined in IBSS network\n"));
                        } else {
-                               printk("wl_bss_connect_done succeeded");
-                               wl_bss_connect_done(wl, ndev, e, data, true);
-                               WL_DBG(("joined in BSS network \"%s\"\n",
+                               if (!wl_get_drv_status(wl, DISCONNECTING)) {
+                                       printk("wl_bss_connect_done succeeded");
+                                       wl_bss_connect_done(wl, ndev, e, data, true);
+                                       WL_DBG(("joined in BSS network \"%s\"\n",
                                        ((struct wlc_ssid *)
                                         wl_read_prof(wl, WL_PROF_SSID))->SSID));
+                               }
                        }
-                       act = true;
-                       wl_update_prof(wl, e, &act, WL_PROF_ACT);
+
                } else if (wl_is_linkdown(wl, e)) {
+                       if (wl->scan_request) {
+                               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 ");
                                wl_clr_drv_status(wl, CONNECTED);
@@ -4213,9 +4249,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                                printk("link down, during connecting");
                                wl_bss_connect_done(wl, ndev, e, data, false);
                        }
-                       if (wl->scan_request) {
-                               wl_cfg80211_scan_abort(wl, ndev);
-                       }
+                       wl_clr_drv_status(wl, DISCONNECTING);
+
                } else if (wl_is_nonetwork(wl, e)) {
                        printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
                        if (wl_get_drv_status(wl, CONNECTING))
@@ -4498,7 +4533,9 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
        s32 err = 0;
 
        WL_DBG((" enter\n"));
-
+       if (wl->scan_request) {
+                       wl_cfg80211_scan_abort(wl, ndev);
+       }
        if (wl_get_drv_status(wl, CONNECTING)) {
                wl_clr_drv_status(wl, CONNECTING);
                if (completed) {
@@ -4506,6 +4543,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
                        memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
                        wl_update_bss_info(wl, ndev);
                        wl_update_pmklist(ndev, wl->pmk_list, err);
+                       wl_set_drv_status(wl, CONNECTED);
                }
                cfg80211_connect_result(ndev,
                        (u8 *)&wl->bssid,
@@ -4518,14 +4556,6 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
                WL_DBG(("Report connect result - connection %s\n",
                        completed ? "succeeded" : "failed"));
        }
-       if (completed)
-               wl_set_drv_status(wl, CONNECTED);
-       else {
-               if (wl->scan_request) {
-                       wl_cfg80211_scan_abort(wl, ndev);
-               }
-       }
-
        return err;
 }
 
@@ -5085,6 +5115,7 @@ static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
        if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
                wl_clr_drv_status(wl, SCANNING);
                WL_ERR(("Scan complete while device not scanning\n"));
+               wl->scan_request = NULL;
                return;
        }
        wl_clr_drv_status(wl, SCANNING);
@@ -5191,7 +5222,9 @@ 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();
-                       WL_INFO(("ESCAN COMPLETED\n"));
+                       WL_INFO(("ESCAN ABORTED\n"));
+                       wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+                       wl_inform_bss(wl);
                        wl_notify_escan_complete(wl, true);
                        rtnl_unlock();
                }
@@ -6040,7 +6073,6 @@ static s32 wl_update_wiphybands(struct wl_priv *wl)
        }
        phy = phylist_buf;
        for (; *phy; phy++) {
-       WL_ERR(("%c phy\n", *phy));
                if (*phy == 'a' || *phy == 'n') {
                        wiphy = wl_to_wiphy(wl);
                        wiphy->bands[IEEE80211_BAND_5GHZ] =
@@ -6087,6 +6119,7 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
        wl_clr_drv_status(wl, SCAN_ABORTING);
        wl_clr_drv_status(wl, CONNECTING);
        wl_clr_drv_status(wl, CONNECTED);
+       wl_clr_drv_status(wl, DISCONNECTING);
        if (wl_get_drv_status(wl, AP_CREATED)) {
                wl_clr_drv_status(wl, AP_CREATED);
                wl_clr_drv_status(wl, AP_CREATING);
index 8116d63..a563724 100644 (file)
@@ -129,6 +129,7 @@ enum wl_status {
        WL_STATUS_SCAN_ABORTING,
        WL_STATUS_CONNECTING,
        WL_STATUS_CONNECTED,
+       WL_STATUS_DISCONNECTING,
        WL_STATUS_AP_CREATING,
        WL_STATUS_AP_CREATED
 };
index 3d7b548..98271c2 100644 (file)
@@ -176,8 +176,8 @@ wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac)
        s32 ret;
        struct net_device *netdev = wl_to_prmry_ndev(wl);
 
-       CFGP2P_INFO(("---wl p2p_ifdel %02x:%02x:%02x:%02x:%02x:%02x\n",
-           mac->octet[0], mac->octet[1], mac->octet[2],
+       CFGP2P_INFO(("------primary idx %d : wl p2p_ifdel %02x:%02x:%02x:%02x:%02x:%02x\n",
+           netdev->ifindex, mac->octet[0], mac->octet[1], mac->octet[2],
            mac->octet[3], mac->octet[4], mac->octet[5]));
 
        ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
@@ -1047,10 +1047,13 @@ wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
        if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {
 
                CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
-               if (status == WLC_E_STATUS_SUCCESS)
+               if (status == WLC_E_STATUS_SUCCESS) {
                        wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
-               else
+               }
+               else {
+                       wl_set_p2p_status(wl, ACTION_TX_NOACK);
                        CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
+               }
                wake_up_interruptible(&wl->dongle_event_wait);
        } else {
                CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
@@ -1081,6 +1084,7 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
            af_params->channel, af_params->dwell_time));
 
        wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
+       wl_clr_p2p_status(wl, ACTION_TX_NOACK);
 #define MAX_WAIT_TIME 2000
        if (bssidx == P2PAPI_BSSCFG_PRIMARY)
                bssidx =  wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
@@ -1094,7 +1098,7 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
                goto exit;
        }
        timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
-                       (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) == TRUE),
+       (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) ||wl_get_p2p_status(wl, ACTION_TX_NOACK)),
                            msecs_to_jiffies(MAX_WAIT_TIME));
 
        if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
index d62f542..b08504d 100644 (file)
@@ -88,6 +88,7 @@ enum wl_cfgp2p_status {
        WLP2P_STATUS_IF_CHANGED,
        WLP2P_STATUS_LISTEN_EXPIRED,
        WLP2P_STATUS_ACTION_TX_COMPLETED,
+       WLP2P_STATUS_ACTION_TX_NOACK,
        WLP2P_STATUS_SCANNING
 };
 
index ae28c6d..6d546fc 100644 (file)
@@ -792,7 +792,7 @@ wl_iw_set_power_mode(
 
 #ifdef COEX_DHCP
                g_bt->ts_dhcp_start = JF2MS;
-               g_bt->dhcp_done = false;
+               g_bt->dhcp_done = FALSE;
                WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n",
                        __FUNCTION__, pm, pm_local));
 
@@ -806,7 +806,7 @@ wl_iw_set_power_mode(
                net_os_set_packet_filter(dev, 1);
 
 #ifdef COEX_DHCP
-               g_bt->dhcp_done = true;
+               g_bt->dhcp_done = TRUE;
                g_bt->ts_dhcp_ok = JF2MS;
                WL_TRACE_COEX(("%s: DHCP done for:%d ms, restored pm:%d\n",
                        __FUNCTION__, (g_bt->ts_dhcp_ok - g_bt->ts_dhcp_start), pm));
@@ -828,7 +828,7 @@ wl_iw_set_power_mode(
 bool btcoex_is_sco_active(struct net_device *dev)
 {
        int ioc_res = 0;
-       bool res = false;
+       bool res = FALSE;
        int sco_id_cnt = 0;
        int param27;
        int i;
@@ -852,7 +852,7 @@ bool btcoex_is_sco_active(struct net_device *dev)
                if (sco_id_cnt > 2) {
                        WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d  samples:%d\n",
                                __FUNCTION__, sco_id_cnt, i));
-                       res = true;
+                       res = TRUE;
                        break;
                }
 
@@ -866,7 +866,7 @@ bool btcoex_is_sco_active(struct net_device *dev)
 
 static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
 {
-       static bool saved_status = false;
+       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 };
@@ -902,7 +902,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                } else {
                        WL_ERROR((":%s: save btc_params failed\n",
                                __FUNCTION__));
-                       saved_status = false;
+                       saved_status = FALSE;
                        return -1;
                }
 
@@ -920,7 +920,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                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;
+               saved_status = TRUE;
 
        } else if (saved_status) {
                
@@ -946,7 +946,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
                        saved_reg50, saved_reg51, saved_reg64,
                        saved_reg65, saved_reg71));
 
-               saved_status = false;
+               saved_status = FALSE;
        } else {
                WL_ERROR((":%s att to restore not saved BTCOEX params\n",
                        __FUNCTION__));
@@ -6320,12 +6320,12 @@ fail:
 #ifndef AP_ONLY
 static int last_auto_channel = 6;
 #endif
+
 static int
 get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
 {
        int chosen = 0;
        wl_uint32_list_t request;
-       int rescan = 0;
        int retry = 0;
        int updown = 0;
        int ret = 0;
@@ -6354,42 +6354,57 @@ get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
                null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err);
        ASSERT(iolen);
        res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen);
+
 #endif
-       auto_channel_retry:
-                       request.count = htod32(0);
-                       ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
-                       if (ret < 0) {
-                               WL_ERROR(("can't start auto channel scan\n"));
-                               goto fail;
-                       }
+
+       request.count = htod32(0);
+       ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
+       if (ret < 0) {
+               WL_ERROR(("can't start auto channel scan\n"));
+               goto fail;
+       }
 
        get_channel_retry:
-                       bcm_mdelay(500);
+               bcm_mdelay(350);
 
-                       ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
-                       if (ret < 0 || dtoh32(chosen) == 0) {
-                               if (retry++ < 3)
-                                       goto get_channel_retry;
-                               else {
+       ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
+               if (ret < 0 || dtoh32(chosen) == 0) {
+                       if (retry++ < 15) {
+                               goto get_channel_retry;
+                       } else {
+                               if (ret < 0) {
                                        WL_ERROR(("can't get auto channel sel, err = %d, "
-                                                 "chosen = %d\n", ret, chosen));
+                                                 "chosen = 0x%04X\n", ret, (uint16)chosen));
                                        goto fail;
+                               } else {
+                                       ap->channel = (uint16)last_auto_channel;
+                                       WL_ERROR(("auto channel sel timed out. we get channel %d\n",
+                                               ap->channel));
                                }
                        }
-                       if ((chosen == 1) && (!rescan++))
-                               goto auto_channel_retry;
-                       WL_SOFTAP(("Set auto channel = %d\n", chosen));
-                       ap->channel = chosen;
-                       if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) {
-                               WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
-                               goto fail;
-                       }
+               }
+
+               if (chosen) {
+                       ap->channel = (uint16)chosen & 0x00FF;
+                       WL_SOFTAP(("%s: Got auto channel = %d, attempt:%d\n",
+                               __FUNCTION__, ap->channel, retry));
+               }
+
+               if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) {
+                       WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
+                       goto fail;
+               }
+
 #ifndef AP_ONLY
-       if (!res)
+       if (!res || !ret)
                last_auto_channel = ap->channel;
 #endif
 
 fail :
+       if (ret < 0) {
+               WL_TRACE(("%s: return value %d\n", __FUNCTION__, ret));
+               return ret;
+       }
        return res;
 } 
 
@@ -6482,6 +6497,15 @@ set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                        goto fail;
                }
                WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res));
+
+
+               mpc = 0;
+               if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) {
+                       WL_ERROR(("%s fail to set mpc\n", __FUNCTION__));
+                       goto fail;
+               }
+
+
 #endif 
 
                updown = 1;
@@ -6528,16 +6552,16 @@ set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
        
        if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) {
                ap->channel = 1;
-               WL_ERROR(("%s auto channel failed, pick up channel=%d\n",
+               WL_ERROR(("%s auto channel failed, use channel=%d\n",
                          __FUNCTION__, ap->channel));
        }
 
        channel = ap->channel;
        if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) {
                WL_ERROR(("%s fail to set channel\n", __FUNCTION__));
-               goto fail;
        }
 
+
        if (ap_cfg_running == FALSE) {
                updown = 0;
                if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) {
@@ -6877,11 +6901,11 @@ static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac)
        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;
+       bool deauth_all = FALSE;
 
        
        if (mac == NULL) {
-               deauth_all = true;
+               deauth_all = TRUE;
                sta_mac = z_mac;  
        } else {
                sta_mac = mac;  
@@ -7179,7 +7203,7 @@ set_ap_mac_list(struct net_device *dev, void *buf)
                if (assoc_maclist->count)
                        for (i = 0; i < assoc_maclist->count; i++) {
                                int j;
-                               bool assoc_mac_matched = false;
+                               bool assoc_mac_matched = FALSE;
                                
                                WL_SOFTAP(("\n Cheking assoc STA: "));
                                dhd_print_buf(&assoc_maclist->ea[i], 6, 7);
@@ -7189,7 +7213,7 @@ set_ap_mac_list(struct net_device *dev, void *buf)
                                        if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j],
                                                ETHER_ADDR_LEN)) {
                                                
-                                               assoc_mac_matched = true;
+                                               assoc_mac_matched = TRUE;
                                                break;
                                        }