summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-10-19 13:09:49 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:39:12 -0800
commit6f992a7610aab53f2e9ba75b5e94aca36bc585d3 (patch)
tree613bffae8a0d623493534b811211c4a2a523f0c0 /drivers/net/wireless
parent3698608c0da689990cbdd2ccca0f572923538c2f (diff)
net: wireless: bcmdhd: Fix bssid profile update
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h2
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c52
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;
}