OSDN Git Service

net: wireless: bcmdhd: Combined P2P fix
authorDmitry Shmidt <dimitrysh@google.com>
Tue, 27 Sep 2011 18:21:13 +0000 (11:21 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Tue, 27 Sep 2011 19:26:09 +0000 (12:26 -0700)
- Fix random kernel panic during p2p certification and change private
  command for set_ap_wps_ie of wpa_supplicant
- Fix problem for 5.1.18 discoverability exchange of P2P sigma
- Fix problem for 7.1.3 to change PM_FAST to PM_MAX (802.11 legacy power save)
- Change type of signal variable in wl_inform_single_bss from uint to int
- Fix crash on P2P interface removal
- Add new DHD_BLOC logic for our internal purposes to keep track of FW crashes
  and build info

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
drivers/net/wireless/bcmdhd/dhd_dbg.h
drivers/net/wireless/bcmdhd/dhd_linux.c
drivers/net/wireless/bcmdhd/dhd_sdio.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_iw.c

index a48e85c..70bacbd 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: bcmsdh_sdmmc.c,v 1.14.64.3 2010-12-23 01:13:15 Exp $
+ * $Id: bcmsdh_sdmmc.c 282820 2011-09-09 15:40:35Z $
  */
 #include <typedefs.h>
 
@@ -30,7 +30,7 @@
 #include <bcmutils.h>
 #include <osl.h>
 #include <sdio.h>      /* SDIO Device and Protocol Specs */
-#include <sdioh.h>     /* SDIO Host Controller Specification */
+#include <sdioh.h>     /* Standard SDIO Host Controller Specification */
 #include <bcmsdbus.h>  /* bcmsdh to/from specific controller APIs */
 #include <sdiovar.h>   /* ioctl/iovars */
 
index 10851c4..a195cbe 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_dbg.h,v 1.9.6.1 2010-12-22 23:47:24 Exp $
+ * $Id: dhd_dbg.h 285933 2011-09-23 21:45:31Z $
  */
 
 #ifndef _dhd_dbg_
@@ -95,6 +95,7 @@
 
 #define DHD_LOG(args)
 
+#define DHD_BLOG(cp, size)
 #define DHD_NONE(args)
 extern int dhd_msg_level;
 
index eee6c3f..2363da9 100644 (file)
@@ -22,7 +22,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_linux.c 285209 2011-09-21 01:21:24Z $
+ * $Id: dhd_linux.c 285933 2011-09-23 21:45:31Z $
  */
 
 #include <typedefs.h>
@@ -473,7 +473,7 @@ static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol);
 static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
                              wl_event_msg_t *event_ptr, void **data_ptr);
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
 static int dhd_sleep_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored)
 {
        int ret = NOTIFY_DONE;
@@ -2225,9 +2225,11 @@ dhd_cleanup_virt_ifaces(dhd_info_t *dhd)
        for (i = 1; i < DHD_MAX_IFS; i++) {
                if (dhd->iflist[i]) {
                        DHD_TRACE(("Deleting IF: %d \n", i));
-                       dhd->iflist[i]->state = WLC_E_IF_DEL;
-                       dhd->iflist[i]->idx = i;
-                       dhd_op_if(dhd->iflist[i]);
+                       if (dhd->iflist[i]->state != WLC_E_IF_DEL) {
+                               dhd->iflist[i]->state = WLC_E_IF_DEL;
+                               dhd->iflist[i]->idx = i;
+                               dhd_op_if(dhd->iflist[i]);
+                       }
                }
        }
 
@@ -2389,7 +2391,7 @@ dhd_osl_detach(osl_t *osh)
                DHD_ERROR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh)));
        }
        osl_detach(osh);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        up(&dhd_registration_sem);
 #endif
 }
@@ -2636,7 +2638,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
         */
        memcpy(netdev_priv(net), &dhd, sizeof(dhd));
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
        register_pm_notifier(&dhd_sleep_pm_notifier);
 #endif /*  (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
 
@@ -2930,6 +2932,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                bcmstrtok(&ptr, "\n", 0);
                /* Print fw version info */
                DHD_ERROR(("Firmware version = %s\n", buf));
+               DHD_BLOG(buf, strlen(buf) + 1);
+               DHD_BLOG(dhd_version, strlen(dhd_version) + 1);
        }
        /* Set PowerSave mode */
        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
index b79ef44..361b2a2 100644 (file)
@@ -21,7 +21,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_sdio.c 285209 2011-09-21 01:21:24Z $
+ * $Id: dhd_sdio.c 285933 2011-09-23 21:45:31Z $
  */
 
 #include <typedefs.h>
@@ -1579,6 +1579,7 @@ const bcm_iovar_t dhdsdio_iovars[] = {
        {"cpu",         IOV_CPU,        0,      IOVT_BOOL,      0 },
 #ifdef DHD_DEBUG
        {"checkdied",   IOV_CHECKDIED,  0,      IOVT_BUFFER,    0 },
+       {"serial",      IOV_SERIALCONS, 0,      IOVT_UINT32,    0 },
 #endif /* DHD_DEBUG  */
 #endif /* DHD_DEBUG */
 #ifdef SDTEST
@@ -2087,8 +2088,10 @@ dhdsdio_checkdied(dhd_bus_t *bus, uint8 *data, uint size)
                                         * will truncate a lot of the printfs
                                         */
 
-                                       if (dhd_msg_level & DHD_ERROR_VAL)
+                                       if (dhd_msg_level & DHD_ERROR_VAL) {
                                                printf("CONSOLE: %s\n", line);
+                                               DHD_BLOG(line, strlen(line) + 1);
+                                       }
                                }
                        }
                }
index 8c0e3ae..ccb9aa8 100644 (file)
@@ -75,9 +75,8 @@
 #define CMD_P2P_SET_NOA                        "P2P_SET_NOA"
 #define CMD_P2P_GET_NOA                        "P2P_GET_NOA"
 #define CMD_P2P_SET_PS                 "P2P_SET_PS"
-#define CMD_SET_ASSOC_RESP_IE  "SET_ASSOC_RESP_IE"
-#define CMD_SET_PROBE_RESP_IE  "SET_PROBE_RESP_IE"
-#define CMD_SET_BEACON_IE              "SET_BEACON_IE"
+#define CMD_SET_AP_WPS_P2P_IE  "SET_AP_WPS_P2P_IE"
+
 
 #ifdef PNO_SUPPORT
 #define CMD_PNOSSIDCLR_SET     "PNOSSIDCLR"
@@ -546,20 +545,11 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                        priv_cmd.total_len - skip);
        }
 #ifdef WL_CFG80211
-       else if (strnicmp(command, CMD_SET_ASSOC_RESP_IE, strlen(CMD_SET_ASSOC_RESP_IE)) == 0) {
-               int skip = strlen(CMD_SET_ASSOC_RESP_IE) + 1;
-               bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
-                       priv_cmd.total_len - skip, WL_ASSOC_RESP);
-       }
-       else if (strnicmp(command, CMD_SET_PROBE_RESP_IE, strlen(CMD_SET_PROBE_RESP_IE)) == 0) {
-               int skip = strlen(CMD_SET_PROBE_RESP_IE) + 1;
-               bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
-                       priv_cmd.total_len - skip, WL_PROBE_RESP);
-       }
-       else if (strnicmp(command, CMD_SET_BEACON_IE, strlen(CMD_SET_BEACON_IE)) == 0) {
-               int skip = strlen(CMD_SET_BEACON_IE) + 1;
+       else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE,
+               strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) {
+               int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3;
                bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
-                       priv_cmd.total_len - skip, WL_BEACON);
+                       priv_cmd.total_len - skip, *(command + skip - 2) - '0');
        }
 #endif /* WL_CFG80211 */
        else {
index 65c4806..16cb75f 100644 (file)
@@ -3326,6 +3326,8 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
                        wldev_iovar_setint(dev, "mpc", 0);
                } else if (act_frm->subtype == P2P_PAF_GON_CONF) {
                        wldev_iovar_setint(dev, "mpc", 1);
+               } else if (act_frm->subtype == P2P_PAF_DEVDIS_REQ) {
+                       af_params->dwell_time = WL_LONG_DWELL_TIME;
                }
        }
 
@@ -4127,7 +4129,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
        struct wl_scan_req *sr = wl_to_sr(wl);
        struct beacon_proberesp *beacon_proberesp;
        s32 mgmt_type;
-       u32 signal;
+       s32 signal;
        u32 freq;
        s32 err = 0;
 
@@ -4149,7 +4151,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
                band = wiphy->bands[IEEE80211_BAND_2GHZ];
        else
                band = wiphy->bands[IEEE80211_BAND_5GHZ];
-       notif_bss_info->rssi = bi->RSSI;
+       notif_bss_info->rssi = dtoh16(bi->RSSI);
        memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
        mgmt_type = wl->active_scan ?
                IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
@@ -4178,9 +4180,9 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
 
        WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM"
                        "mgmt_type %d frame_len %d\n", bi->SSID,
-                               notif_bss_info->rssi, notif_bss_info->channel,
-                               mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type,
-                               notif_bss_info->frame_len));
+                       notif_bss_info->rssi, notif_bss_info->channel,
+                       mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type,
+                       notif_bss_info->frame_len));
 
        signal = notif_bss_info->rssi * 100;
 
@@ -4334,11 +4336,11 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                isfree = true;
 
                if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
-                       cfg80211_send_rx_assoc(ndev, mgmt_frame, len);
+                       cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
                } else if (event == WLC_E_DISASSOC_IND) {
-                       cfg80211_send_disassoc(ndev, mgmt_frame, len);
+                       cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
                } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
-                       cfg80211_send_disassoc(ndev, mgmt_frame, len);
+                       cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
                }
 
        } else {
@@ -6686,7 +6688,8 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
                                pktflag = VNDR_IE_ASSOCRSP_FLAG;
                                break;
                }
-               ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len);
+               if (pktflag)
+                       ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len);
        }
 
        return ret;
index 066103e..8403cce 100644 (file)
@@ -127,8 +127,9 @@ do {                                                                        \
 #define WL_AP_MAX      256     /* virtually unlimitted as long
                                 * as kernel memory allows
                                 */
-#define WL_FILE_NAME_MAX               256
-#define WL_DWELL_TIME  200
+#define WL_FILE_NAME_MAX       256
+#define WL_DWELL_TIME          200
+#define WL_LONG_DWELL_TIME     1000
 #define VWDEV_CNT 3
 
 #define WL_SCAN_TIMER_INTERVAL_MS      8000 /* Scan timeout */
index 653fbcd..2a5fdd1 100644 (file)
@@ -1021,15 +1021,12 @@ 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);
-               }
+       if (timer_pending(&wl->p2p->listen_timer)) {
+               CFGP2P_DBG(("previous LISTEN is not completed yet\n"));
+               goto exit;
+
        } else
-       wl_clr_p2p_status(wl, LISTEN_EXPIRED);
+               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));
@@ -1322,6 +1319,7 @@ s32 wl_cfgp2p_set_p2p_noa(struct wl_priv *wl, struct net_device *ndev, char* buf
        wl_p2p_sched_t dongle_noa;
 
        CFGP2P_DBG((" Enter\n"));
+
        memset(&dongle_noa, 0, sizeof(dongle_noa));
 
        if (wl->p2p && wl->p2p->vif_created) {
@@ -1436,7 +1434,7 @@ s32 wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, struct net_device *ndev, char* buf,
                }
 
                if (legacy_ps != -1) {
-                       s32 pm = legacy_ps ? PM_FAST : PM_OFF;
+                       s32 pm = legacy_ps ? PM_MAX : PM_OFF;
                        ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION),
                                WLC_SET_PM, &pm, sizeof(pm), true);
                        if (unlikely(ret)) {
index f71f29a..3acdea1 100644 (file)
@@ -5287,6 +5287,7 @@ wl_iw_set_pmksa(
        uint i;
        int ret = 0;
        char eabuf[ETHER_ADDR_STR_LEN];
+       pmkid_t * pmkid_array = pmkid_list.pmkids.pmkid;
 
        WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name));
 
@@ -5319,18 +5320,18 @@ wl_iw_set_pmksa(
                }
 
                for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
-                       if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID,
+                       if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID,
                                ETHER_ADDR_LEN))
                                break;
 
                if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) {
-                       bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t));
+                       bzero(&pmkid_array[i], sizeof(pmkid_t));
                        for (; i < (pmkid_list.pmkids.npmkid - 1); i++) {
-                               bcopy(&pmkid_list.pmkids.pmkid[i+1].BSSID,
-                                       &pmkid_list.pmkids.pmkid[i].BSSID,
+                               bcopy(&pmkid_array[i+1].BSSID,
+                                       &pmkid_array[i].BSSID,
                                        ETHER_ADDR_LEN);
-                               bcopy(&pmkid_list.pmkids.pmkid[i+1].PMKID,
-                                       &pmkid_list.pmkids.pmkid[i].PMKID,
+                               bcopy(&pmkid_array[i+1].PMKID,
+                                       &pmkid_array[i].PMKID,
                                        WPA2_PMKID_LEN);
                        }
                        pmkid_list.pmkids.npmkid--;
@@ -5341,14 +5342,14 @@ wl_iw_set_pmksa(
 
        else if (iwpmksa->cmd == IW_PMKSA_ADD) {
                for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
-                       if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID,
+                       if (!bcmp(&iwpmksa->bssid.sa_data[0], &pmkid_array[i].BSSID,
                                ETHER_ADDR_LEN))
                                break;
                if (i < MAXPMKID) {
                        bcopy(&iwpmksa->bssid.sa_data[0],
-                               &pmkid_list.pmkids.pmkid[i].BSSID,
+                               &pmkid_array[i].BSSID,
                                ETHER_ADDR_LEN);
-                       bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID,
+                       bcopy(&iwpmksa->pmkid[0], &pmkid_array[i].PMKID,
                                WPA2_PMKID_LEN);
                        if (i == pmkid_list.pmkids.npmkid)
                                pmkid_list.pmkids.npmkid++;
@@ -5361,10 +5362,10 @@ wl_iw_set_pmksa(
                        uint k;
                        k = pmkid_list.pmkids.npmkid;
                        WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %s = ",
-                               bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[k].BSSID,
+                               bcm_ether_ntoa(&pmkid_array[k].BSSID,
                                eabuf)));
                        for (j = 0; j < WPA2_PMKID_LEN; j++)
-                               WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j]));
+                               WL_WSEC(("%02x ", pmkid_array[k].PMKID[j]));
                        WL_WSEC(("\n"));
                }
        }
@@ -5372,10 +5373,10 @@ wl_iw_set_pmksa(
        for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
                uint j;
                WL_WSEC(("\nPMKID[%d]: %s = ", i,
-                       bcm_ether_ntoa(&pmkid_list.pmkids.pmkid[i].BSSID,
+                       bcm_ether_ntoa(&pmkid_array[i].BSSID,
                        eabuf)));
                for (j = 0; j < WPA2_PMKID_LEN; j++)
-                       WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]));
+                       WL_WSEC(("%02x ", pmkid_array[i].PMKID[j]));
        }
        WL_WSEC(("\n"));