aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_event.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c69
1 files changed, 35 insertions, 34 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 7468ef10194b..cf37aa6eb137 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -23,7 +23,6 @@
23 23
24#include "wl1271.h" 24#include "wl1271.h"
25#include "wl1271_reg.h" 25#include "wl1271_reg.h"
26#include "wl1271_spi.h"
27#include "wl1271_io.h" 26#include "wl1271_io.h"
28#include "wl1271_event.h" 27#include "wl1271_event.h"
29#include "wl1271_ps.h" 28#include "wl1271_ps.h"
@@ -32,34 +31,24 @@
32static int wl1271_event_scan_complete(struct wl1271 *wl, 31static int wl1271_event_scan_complete(struct wl1271 *wl,
33 struct event_mailbox *mbox) 32 struct event_mailbox *mbox)
34{ 33{
35 int size = sizeof(struct wl12xx_probe_req_template);
36 wl1271_debug(DEBUG_EVENT, "status: 0x%x", 34 wl1271_debug(DEBUG_EVENT, "status: 0x%x",
37 mbox->scheduled_scan_status); 35 mbox->scheduled_scan_status);
38 36
39 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { 37 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
40 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { 38 if (wl->scan.state == WL1271_SCAN_BAND_DUAL) {
41 wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
42 NULL, size);
43 /* 2.4 GHz band scanned, scan 5 GHz band, pretend 39 /* 2.4 GHz band scanned, scan 5 GHz band, pretend
44 * to the wl1271_cmd_scan function that we are not 40 * to the wl1271_cmd_scan function that we are not
45 * scanning as it checks that. 41 * scanning as it checks that.
46 */ 42 */
47 clear_bit(WL1271_FLAG_SCANNING, &wl->flags); 43 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
44 /* FIXME: ie missing! */
48 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 45 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
46 NULL, 0,
49 wl->scan.active, 47 wl->scan.active,
50 wl->scan.high_prio, 48 wl->scan.high_prio,
51 WL1271_SCAN_BAND_5_GHZ, 49 WL1271_SCAN_BAND_5_GHZ,
52 wl->scan.probe_requests); 50 wl->scan.probe_requests);
53 } else { 51 } else {
54 if (wl->scan.state == WL1271_SCAN_BAND_2_4_GHZ)
55 wl1271_cmd_template_set(wl,
56 CMD_TEMPL_CFG_PROBE_REQ_2_4,
57 NULL, size);
58 else
59 wl1271_cmd_template_set(wl,
60 CMD_TEMPL_CFG_PROBE_REQ_5,
61 NULL, size);
62
63 mutex_unlock(&wl->mutex); 52 mutex_unlock(&wl->mutex);
64 ieee80211_scan_completed(wl->hw, false); 53 ieee80211_scan_completed(wl->hw, false);
65 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
@@ -92,16 +81,9 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
92 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, 81 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
93 true); 82 true);
94 } else { 83 } else {
95 wl1271_error("PSM entry failed, giving up.\n"); 84 wl1271_info("No ack to nullfunc from AP.");
96 /* FIXME: this may need to be reconsidered. for now it
97 is not possible to indicate to the mac80211
98 afterwards that PSM entry failed. To maximize
99 functionality (receiving data and remaining
100 associated) make sure that we are in sync with the
101 AP in regard of PSM mode. */
102 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
103 false);
104 wl->psm_entry_retry = 0; 85 wl->psm_entry_retry = 0;
86 *beacon_loss = true;
105 } 87 }
106 break; 88 break;
107 case EVENT_ENTER_POWER_SAVE_SUCCESS: 89 case EVENT_ENTER_POWER_SAVE_SUCCESS:
@@ -143,6 +125,24 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
143 return ret; 125 return ret;
144} 126}
145 127
128static void wl1271_event_rssi_trigger(struct wl1271 *wl,
129 struct event_mailbox *mbox)
130{
131 enum nl80211_cqm_rssi_threshold_event event;
132 s8 metric = mbox->rssi_snr_trigger_metric[0];
133
134 wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);
135
136 if (metric <= wl->rssi_thold)
137 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
138 else
139 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
140
141 if (event != wl->last_rssi_event)
142 ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL);
143 wl->last_rssi_event = event;
144}
145
146static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 146static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
147{ 147{
148 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 148 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -172,10 +172,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon 172 * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon
173 * filtering) is enabled. Without PSM, the stack will receive all 173 * filtering) is enabled. Without PSM, the stack will receive all
174 * beacons and can detect beacon loss by itself. 174 * beacons and can detect beacon loss by itself.
175 *
176 * As there's possibility that the driver disables PSM before receiving
177 * BSS_LOSE_EVENT, beacon loss has to be reported to the stack.
178 *
175 */ 179 */
176 if (vector & BSS_LOSE_EVENT_ID && 180 if (vector & BSS_LOSE_EVENT_ID) {
177 test_bit(WL1271_FLAG_PSM, &wl->flags)) { 181 wl1271_info("Beacon loss detected.");
178 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
179 182
180 /* indicate to the stack, that beacons have been lost */ 183 /* indicate to the stack, that beacons have been lost */
181 beacon_loss = true; 184 beacon_loss = true;
@@ -188,17 +191,15 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
188 return ret; 191 return ret;
189 } 192 }
190 193
191 if (wl->vif && beacon_loss) { 194 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
192 /* Obviously, it's dangerous to release the mutex while 195 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
193 we are holding many of the variables in the wl struct. 196 if (wl->vif)
194 That's why it's done last in the function, and care must 197 wl1271_event_rssi_trigger(wl, mbox);
195 be taken that nothing more is done after this function
196 returns. */
197 mutex_unlock(&wl->mutex);
198 ieee80211_beacon_loss(wl->vif);
199 mutex_lock(&wl->mutex);
200 } 198 }
201 199
200 if (wl->vif && beacon_loss)
201 ieee80211_connection_loss(wl->vif);
202
202 return 0; 203 return 0;
203} 204}
204 205