diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/scan.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index edfe01c321ca..7229eaa89018 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -33,6 +33,8 @@ void wl1271_scan_complete_work(struct work_struct *work) { struct delayed_work *dwork; struct wl1271 *wl; + int ret; + bool is_sta, is_ibss; dwork = container_of(work, struct delayed_work, work); wl = container_of(dwork, struct wl1271, scan_complete_work); @@ -50,21 +52,34 @@ void wl1271_scan_complete_work(struct work_struct *work) wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan.req = NULL; - ieee80211_scan_completed(wl->hw, false); - /* restore hardware connection monitoring template */ + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { - if (wl1271_ps_elp_wakeup(wl) == 0) { - wl1271_cmd_build_ap_probe_req(wl, wl->probereq); - wl1271_ps_elp_sleep(wl); - } + /* restore hardware connection monitoring template */ + wl1271_cmd_build_ap_probe_req(wl, wl->probereq); + } + + /* return to ROC if needed */ + is_sta = (wl->bss_type == BSS_TYPE_STA_BSS); + is_ibss = (wl->bss_type == BSS_TYPE_IBSS); + if ((is_sta && !test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) || + (is_ibss && !test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags))) { + /* restore remain on channel */ + wl12xx_cmd_role_start_dev(wl); + wl12xx_roc(wl, wl->dev_role_id); } + wl1271_ps_elp_sleep(wl); if (wl->scan.failed) { wl1271_info("Scan completed due to error."); wl12xx_queue_recovery_work(wl); } + ieee80211_scan_completed(wl->hw, false); + out: mutex_unlock(&wl->mutex); @@ -156,6 +171,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, if (passive || wl->scan.req->n_ssids == 0) scan_options |= WL1271_SCAN_OPT_PASSIVE; + if (WARN_ON(wl->role_id == WL12XX_INVALID_ROLE_ID)) { + ret = -EINVAL; + goto out; + } + cmd->params.role_id = wl->role_id; cmd->params.scan_options = cpu_to_le16(scan_options); cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, @@ -167,10 +187,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, } cmd->params.tx_rate = cpu_to_le32(basic_rate); - cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); - cmd->params.rx_filter_options = - cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; cmd->params.tx_rate = cpu_to_le32(basic_rate); cmd->params.tid_trigger = 0; @@ -186,6 +202,8 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); } + memcpy(cmd->addr, wl->mac_addr, ETH_ALEN); + ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len, wl->scan.req->ie, wl->scan.req->ie_len, band); |