diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_event.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.c | 69 |
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 @@ | |||
32 | static int wl1271_event_scan_complete(struct wl1271 *wl, | 31 | static 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 | ||
128 | static 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 | |||
146 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) | 146 | static 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 | ||