Skip to content

Commit

Permalink
wl12xx: implement scheduled scan driver operations and reporting
Browse files Browse the repository at this point in the history
This patch adds the mac80211 operations for scheduled scan and the
scheduled scan results reporting.

Signed-off-by: Luciano Coelho <coelho@ti.com>
  • Loading branch information
Luciano Coelho committed May 12, 2011
1 parent 95feadc commit 33c2c06
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
6 changes: 6 additions & 0 deletions drivers/net/wireless/wl12xx/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,17 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
"(status 0x%0x)", mbox->scheduled_scan_status);

wl1271_scan_sched_scan_results(wl);
}

if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
"(status 0x%0x)", mbox->scheduled_scan_status);
if (wl->sched_scanning) {
wl1271_scan_sched_scan_stop(wl);
ieee80211_sched_scan_stopped(wl->hw);
}
}

/* disable dynamic PS when requested by the firmware */
Expand Down
70 changes: 70 additions & 0 deletions drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,11 @@ static void wl1271_recovery_work(struct work_struct *work)
/* Prevent spurious TX during FW restart */
ieee80211_stop_queues(wl->hw);

if (wl->sched_scanning) {
ieee80211_sched_scan_stopped(wl->hw);
wl->sched_scanning = false;
}

/* reboot the chipset */
__wl1271_op_remove_interface(wl, false);
ieee80211_restart_hw(wl->hw);
Expand Down Expand Up @@ -1576,6 +1581,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
wl->ap_fw_ps_map = 0;
wl->ap_ps_map = 0;
wl->sched_scanning = false;

/*
* this is performed after the cancel_work calls and the associated
Expand Down Expand Up @@ -1778,6 +1784,13 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
wl->session_counter++;
if (wl->session_counter >= SESSION_COUNTER_MAX)
wl->session_counter = 0;

/* The current firmware only supports sched_scan in idle */
if (wl->sched_scanning) {
wl1271_scan_sched_scan_stop(wl);
ieee80211_sched_scan_stopped(wl->hw);
}

ret = wl1271_dummy_join(wl);
if (ret < 0)
goto out;
Expand Down Expand Up @@ -2330,6 +2343,60 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
return ret;
}

static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
struct ieee80211_sched_scan_ies *ies)
{
struct wl1271 *wl = hw->priv;
int ret;

wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");

mutex_lock(&wl->mutex);

ret = wl1271_ps_elp_wakeup(wl);
if (ret < 0)
goto out;

ret = wl1271_scan_sched_scan_config(wl, req, ies);
if (ret < 0)
goto out_sleep;

ret = wl1271_scan_sched_scan_start(wl);
if (ret < 0)
goto out_sleep;

wl->sched_scanning = true;

out_sleep:
wl1271_ps_elp_sleep(wl);
out:
mutex_unlock(&wl->mutex);
return ret;
}

static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct wl1271 *wl = hw->priv;
int ret;

wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");

mutex_lock(&wl->mutex);

ret = wl1271_ps_elp_wakeup(wl);
if (ret < 0)
goto out;

wl1271_scan_sched_scan_stop(wl);

wl1271_ps_elp_sleep(wl);
out:
mutex_unlock(&wl->mutex);
}

static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
{
struct wl1271 *wl = hw->priv;
Expand Down Expand Up @@ -3445,6 +3512,8 @@ static const struct ieee80211_ops wl1271_ops = {
.tx = wl1271_op_tx,
.set_key = wl1271_op_set_key,
.hw_scan = wl1271_op_hw_scan,
.sched_scan_start = wl1271_op_sched_scan_start,
.sched_scan_stop = wl1271_op_sched_scan_stop,
.bss_info_changed = wl1271_op_bss_info_changed,
.set_frag_threshold = wl1271_op_set_frag_threshold,
.set_rts_threshold = wl1271_op_set_rts_threshold,
Expand Down Expand Up @@ -3765,6 +3834,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl->ap_fw_ps_map = 0;
wl->quirks = 0;
wl->platform_quirks = 0;
wl->sched_scanning = false;

memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/wireless/wl12xx/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,12 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl)

ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
sizeof(*stop), 0);
if (ret < 0)
if (ret < 0) {
wl1271_error("failed to send sched scan stop command");
goto out_free;
}
wl->sched_scanning = false;

out_free:
kfree(stop);
}
2 changes: 2 additions & 0 deletions drivers/net/wireless/wl12xx/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ struct wl1271 {
struct wl1271_scan scan;
struct delayed_work scan_complete_work;

bool sched_scanning;

/* probe-req template for the current AP */
struct sk_buff *probereq;

Expand Down

0 comments on commit 33c2c06

Please sign in to comment.