From eef7ae49c591eef0cdd1bccd9da6fb27b762dd23 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 19 Oct 2011 13:09:49 -0700 Subject: [PATCH] net: wireless: bcmdhd: Fix bssid profile update Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcmdhd/dhd.h | 2 ++ drivers/net/wireless/bcmdhd/wl_cfg80211.c | 52 +++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index ac374af3ca50..fae07abaad9d 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -477,6 +477,8 @@ extern int dhd_bus_start(dhd_pub_t *dhdp); extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size); extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line); +bool is_associated(dhd_pub_t *dhd, void *bss_buf); + #if defined(KEEP_ALIVE) extern int dhd_keep_alive_onoff(dhd_pub_t *dhd); #endif /* KEEP_ALIVE */ diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c index 2703784bbfd8..d269172a7711 100644 --- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c @@ -2187,6 +2187,8 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, u32 wpsie_len = 0; u32 chan_cnt = 0; u8 wpsie[IE_MAX_LEN]; + struct ether_addr bssid; + WL_DBG(("In\n")); CHECK_SYS_UP(wl); @@ -2197,6 +2199,10 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, wl_cfg80211_scan_abort(wl, dev); } + /* Clean BSSID */ + bzero(&bssid, sizeof(bssid)); + wl_update_prof(wl, NULL, (void *)&bssid, WL_PROF_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 */ if (p2p_on(wl) && is_wps_conn(sme)) { @@ -2302,7 +2308,6 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return err; } - wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID); /* * Join with specific BSSID and cached SSID * If SSID is zero join based on BSSID only @@ -2835,8 +2840,10 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) s8 eabuf[ETHER_ADDR_STR_LEN]; #endif + dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); CHECK_SYS_UP(wl); + WL_DBG((" Enter\n")); 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)); @@ -2863,12 +2870,19 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, #endif } else if (get_mode_by_netdev(wl, dev) == WL_MODE_BSS) { u8 *curmacp = wl_read_prof(wl, WL_PROF_BSSID); + + if (!wl_get_drv_status(wl, CONNECTED) || + (is_associated(dhd, NULL) == FALSE)) { + WL_ERR(("NOT assoc\n")); + err = -ENODEV; + goto get_station_err; + } + if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) { WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n", MAC2STR(mac), MAC2STR(curmacp))); - err = -ENOENT; - goto get_station_err; } + /* Report the current tx rate */ err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false); if (err) { @@ -2880,23 +2894,27 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, 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, + 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)); - goto get_station_err; - } - rssi = dtoh32(scb_val.val); - sinfo->filled |= STATION_INFO_SIGNAL; - sinfo->signal = rssi; - WL_DBG(("RSSI %d dBm\n", rssi)); + if (err) { + WL_ERR(("Could not get rssi (%d)\n", err)); + goto get_station_err; } + + rssi = dtoh32(scb_val.val); + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = rssi; + WL_DBG(("RSSI %d dBm\n", rssi)); + get_station_err: - if (err) + if (err) { + WL_ERR(("force cfg80211_disconnected\n")); + wl_clr_drv_status(wl, CONNECTED); cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL); + wl_link_down(wl); + } } return err; @@ -4427,6 +4445,7 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, wl_link_up(wl); act = true; wl_update_prof(wl, e, &act, WL_PROF_ACT); + wl_update_prof(wl, NULL, (void *)&e->addr, WL_PROF_BSSID); if (wl_is_ibssmode(wl, ndev)) { printk("cfg80211_ibss_joined\n"); cfg80211_ibss_joined(ndev, (s8 *)&e->addr, @@ -4511,6 +4530,7 @@ wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, wl_bss_connect_done(wl, ndev, e, data, true); act = true; wl_update_prof(wl, e, &act, WL_PROF_ACT); + wl_update_prof(wl, NULL, (void *)&e->addr, WL_PROF_BSSID); } return err; } -- 2.11.0