net: wireless: bcmdhd: Fix BSSID report for disassoc
authorDmitry Shmidt <dimitrysh@google.com>
Wed, 24 Oct 2012 20:14:48 +0000 (13:14 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Wed, 24 Oct 2012 20:14:48 +0000 (13:14 -0700)
Change-Id: I5e3b01a1a471e5983ab934fc9d65802a389ab1af
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/include/bcmutils.h
drivers/net/wireless/bcmdhd/wl_cfg80211.c
drivers/net/wireless/bcmdhd/wl_cfg80211.h

index 6849c26da837260ce50d625e2c84acb9ace07624..a570fa2789fb1798eb06167931ee9e069231e213 100644 (file)
@@ -603,6 +603,8 @@ extern void *_bcmutils_dummy_fn;
 #define CRC32_INIT_VALUE 0xffffffff    
 #define CRC32_GOOD_VALUE 0xdebb20e3    
 
+#define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5]
 
 typedef struct bcm_bit_desc {
        uint32  bit;
index 5abe2b3b3dd39f4acc9dc7cd782aa4af2d190521..b4f47d1393cdd495f17469e81b08a586ad114a08 100644 (file)
@@ -1867,6 +1867,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        /* Clean BSSID */
        bzero(&bssid, sizeof(bssid));
        wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
+       wl_update_prof(wl, dev, NULL, params->bssid, WL_PROF_PENDING_BSSID);
 
        if (params->ssid)
                WL_INFO(("SSID: %s\n", params->ssid));
@@ -2338,6 +2339,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        /* Clean BSSID */
        bzero(&bssid, sizeof(bssid));
        wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
+       wl_update_prof(wl, dev, NULL, sme->bssid, WL_PROF_PENDING_BSSID);
 
        if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
                /* we only allow to connect using virtual interface in case of P2P */
@@ -5142,7 +5144,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                                WL_DBG(("wl_ibss_join_done succeeded\n"));
                        } else {
                                if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
-                                       printk("wl_bss_connect_done succeeded\n");
+                                       printk("wl_bss_connect_done succeeded with " MACDBG "\n",
+                                               MAC2STRDBG((u8*)(&e->addr)));
                                        wl_bss_connect_done(wl, ndev, e, data, true);
                                        WL_DBG(("joined in BSS network \"%s\"\n",
                                        ((struct wlc_ssid *)
@@ -5191,8 +5194,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
                        wl_clr_drv_status(wl, DISCONNECTING, ndev);
 
                } else if (wl_is_nonetwork(wl, e)) {
-                       printk("connect failed event=%d e->status 0x%x\n",
-                               event, (int)ntoh32(e->status));
+                       printk("connect failed event=%d e->status %d e->reason %d\n",
+                               event, (int)ntoh32(e->status), (int)ntoh32(e->reason));
                        /* Clean up any pending scan request */
                        if (wl->scan_request) {
                                if (wl->escan_on) {
@@ -5452,9 +5455,17 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
        u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
 
        WL_DBG((" enter\n"));
+
        if (wl->scan_request) {
                wl_notify_escan_complete(wl, ndev, true, true);
        }
+       if (is_zero_ether_addr(curbssid)) {
+               curbssid = wl_read_prof(wl, ndev, WL_PROF_PENDING_BSSID);
+               if (is_zero_ether_addr(curbssid)) {
+                       WL_ERR(("Invalid BSSID\n"));
+                       curbssid = NULL;
+               }
+       }
        if (wl_get_drv_status(wl, CONNECTING, ndev)) {
                wl_clr_drv_status(wl, CONNECTING, ndev);
                if (completed) {
@@ -5471,7 +5482,9 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
                        conn_info->req_ie_len,
                        conn_info->resp_ie,
                        conn_info->resp_ie_len,
-                       completed ? WLAN_STATUS_SUCCESS : e->reason,
+                       completed ? WLAN_STATUS_SUCCESS :
+                       (e->reason) ? ntoh32(e->reason) :
+                       WLAN_STATUS_UNSPECIFIED_FAILURE,
                        GFP_KERNEL);
                if (completed)
                        WL_INFO(("Report connect result - connection succeeded\n"));
@@ -7469,6 +7482,9 @@ static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
        case WL_PROF_BSSID:
                rptr = profile->bssid;
                break;
+       case WL_PROF_PENDING_BSSID:
+               rptr = profile->pending_bssid;
+               break;
        case WL_PROF_SSID:
                rptr = &profile->ssid;
                break;
@@ -7505,6 +7521,12 @@ wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
                else
                        memset(profile->bssid, 0, ETHER_ADDR_LEN);
                break;
+       case WL_PROF_PENDING_BSSID:
+               if (data)
+                       memcpy(profile->pending_bssid, data, ETHER_ADDR_LEN);
+               else
+                       memset(profile->pending_bssid, 0, ETHER_ADDR_LEN);
+               break;
        case WL_PROF_SEC:
                memcpy(&profile->sec, data, sizeof(profile->sec));
                break;
index 39832a568cc45b4b6f5432fc1f3722d38b1e05e3..dfb0d0de2f7ea1bbb9df9cac51350cafc1a3d625 100644 (file)
@@ -183,6 +183,7 @@ enum wl_prof_list {
        WL_PROF_IBSS,
        WL_PROF_BAND,
        WL_PROF_BSSID,
+       WL_PROF_PENDING_BSSID,
        WL_PROF_ACT,
        WL_PROF_BEACONINT,
        WL_PROF_DTIMPERIOD
@@ -285,6 +286,7 @@ struct wl_profile {
        struct wl_security sec;
        struct wl_ibss ibss;
        u8 bssid[ETHER_ADDR_LEN];
+       u8 pending_bssid[ETHER_ADDR_LEN];
        u16 beacon_interval;
        u8 dtim_period;
        bool active;