diff options
author | David Gnedt <david.gnedt@davizone.at> | 2014-01-07 07:05:45 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-01-09 10:53:38 -0500 |
commit | f7ad1eed4d4b9d5f0b7ada151d5670e7cb33a6e7 (patch) | |
tree | c15725d6f87621d80a9bb90fa62cef24ed75c429 | |
parent | 64322e28d3f91a196c0e86de2790cdd338a74c28 (diff) |
wl1251: retry power save entry
Port of the power save entry retry code from wl1251 driver version included
in the Maemo Fremantle kernel.
This tries to enable power save mode up to 3 times before failing.
Signed-off-by: David Gnedt <david.gnedt@davizone.at>
Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ti/wl1251/boot.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl1251/event.c | 44 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl1251/event.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl1251/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl1251/wl1251.h | 3 |
5 files changed, 58 insertions, 1 deletions
diff --git a/drivers/net/wireless/ti/wl1251/boot.c b/drivers/net/wireless/ti/wl1251/boot.c index a2e5241382da..2000cd536077 100644 --- a/drivers/net/wireless/ti/wl1251/boot.c +++ b/drivers/net/wireless/ti/wl1251/boot.c | |||
@@ -299,7 +299,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) | |||
299 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | | 299 | ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | |
300 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | | 300 | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | |
301 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | | 301 | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | |
302 | BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; | 302 | BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID | |
303 | PS_REPORT_EVENT_ID; | ||
303 | 304 | ||
304 | ret = wl1251_event_unmask(wl); | 305 | ret = wl1251_event_unmask(wl); |
305 | if (ret < 0) { | 306 | if (ret < 0) { |
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index 74ae8e1c2e33..192cebd120d8 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c | |||
@@ -46,6 +46,43 @@ static int wl1251_event_scan_complete(struct wl1251 *wl, | |||
46 | return ret; | 46 | return ret; |
47 | } | 47 | } |
48 | 48 | ||
49 | #define WL1251_PSM_ENTRY_RETRIES 3 | ||
50 | static int wl1251_event_ps_report(struct wl1251 *wl, | ||
51 | struct event_mailbox *mbox) | ||
52 | { | ||
53 | int ret = 0; | ||
54 | |||
55 | wl1251_debug(DEBUG_EVENT, "ps status: %x", mbox->ps_status); | ||
56 | |||
57 | switch (mbox->ps_status) { | ||
58 | case EVENT_ENTER_POWER_SAVE_FAIL: | ||
59 | wl1251_debug(DEBUG_PSM, "PSM entry failed"); | ||
60 | |||
61 | if (wl->station_mode != STATION_POWER_SAVE_MODE) { | ||
62 | /* remain in active mode */ | ||
63 | wl->psm_entry_retry = 0; | ||
64 | break; | ||
65 | } | ||
66 | |||
67 | if (wl->psm_entry_retry < WL1251_PSM_ENTRY_RETRIES) { | ||
68 | wl->psm_entry_retry++; | ||
69 | ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); | ||
70 | } else { | ||
71 | wl1251_error("Power save entry failed, giving up"); | ||
72 | wl->psm_entry_retry = 0; | ||
73 | } | ||
74 | break; | ||
75 | case EVENT_ENTER_POWER_SAVE_SUCCESS: | ||
76 | case EVENT_EXIT_POWER_SAVE_FAIL: | ||
77 | case EVENT_EXIT_POWER_SAVE_SUCCESS: | ||
78 | default: | ||
79 | wl->psm_entry_retry = 0; | ||
80 | break; | ||
81 | } | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
49 | static void wl1251_event_mbox_dump(struct event_mailbox *mbox) | 86 | static void wl1251_event_mbox_dump(struct event_mailbox *mbox) |
50 | { | 87 | { |
51 | wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); | 88 | wl1251_debug(DEBUG_EVENT, "MBOX DUMP:"); |
@@ -80,6 +117,13 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) | |||
80 | } | 117 | } |
81 | } | 118 | } |
82 | 119 | ||
120 | if (vector & PS_REPORT_EVENT_ID) { | ||
121 | wl1251_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); | ||
122 | ret = wl1251_event_ps_report(wl, mbox); | ||
123 | if (ret < 0) | ||
124 | return ret; | ||
125 | } | ||
126 | |||
83 | if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { | 127 | if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { |
84 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); | 128 | wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); |
85 | 129 | ||
diff --git a/drivers/net/wireless/ti/wl1251/event.h b/drivers/net/wireless/ti/wl1251/event.h index 30eb5d150bf7..88570a5cd042 100644 --- a/drivers/net/wireless/ti/wl1251/event.h +++ b/drivers/net/wireless/ti/wl1251/event.h | |||
@@ -112,6 +112,13 @@ struct event_mailbox { | |||
112 | u8 padding[19]; | 112 | u8 padding[19]; |
113 | } __packed; | 113 | } __packed; |
114 | 114 | ||
115 | enum { | ||
116 | EVENT_ENTER_POWER_SAVE_FAIL = 0, | ||
117 | EVENT_ENTER_POWER_SAVE_SUCCESS, | ||
118 | EVENT_EXIT_POWER_SAVE_FAIL, | ||
119 | EVENT_EXIT_POWER_SAVE_SUCCESS, | ||
120 | }; | ||
121 | |||
115 | int wl1251_event_unmask(struct wl1251 *wl); | 122 | int wl1251_event_unmask(struct wl1251 *wl); |
116 | void wl1251_event_mbox_config(struct wl1251 *wl); | 123 | void wl1251_event_mbox_config(struct wl1251 *wl); |
117 | int wl1251_event_handle(struct wl1251 *wl, u8 mbox); | 124 | int wl1251_event_handle(struct wl1251 *wl, u8 mbox); |
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 4d89ac800e78..358073d6029e 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c | |||
@@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) | |||
479 | wl->next_tx_complete = 0; | 479 | wl->next_tx_complete = 0; |
480 | wl->elp = false; | 480 | wl->elp = false; |
481 | wl->station_mode = STATION_ACTIVE_MODE; | 481 | wl->station_mode = STATION_ACTIVE_MODE; |
482 | wl->psm_entry_retry = 0; | ||
482 | wl->tx_queue_stopped = false; | 483 | wl->tx_queue_stopped = false; |
483 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 484 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
484 | wl->rssi_thold = 0; | 485 | wl->rssi_thold = 0; |
@@ -1414,6 +1415,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) | |||
1414 | wl->elp = false; | 1415 | wl->elp = false; |
1415 | wl->station_mode = STATION_ACTIVE_MODE; | 1416 | wl->station_mode = STATION_ACTIVE_MODE; |
1416 | wl->psm_requested = false; | 1417 | wl->psm_requested = false; |
1418 | wl->psm_entry_retry = 0; | ||
1417 | wl->tx_queue_stopped = false; | 1419 | wl->tx_queue_stopped = false; |
1418 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; | 1420 | wl->power_level = WL1251_DEFAULT_POWER_LEVEL; |
1419 | wl->rssi_thold = 0; | 1421 | wl->rssi_thold = 0; |
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h index 2c3bd1bff3f6..24869458cf74 100644 --- a/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/drivers/net/wireless/ti/wl1251/wl1251.h | |||
@@ -368,6 +368,9 @@ struct wl1251 { | |||
368 | /* PSM mode requested */ | 368 | /* PSM mode requested */ |
369 | bool psm_requested; | 369 | bool psm_requested; |
370 | 370 | ||
371 | /* retry counter for PSM entries */ | ||
372 | u8 psm_entry_retry; | ||
373 | |||
371 | u16 beacon_int; | 374 | u16 beacon_int; |
372 | u8 dtim_period; | 375 | u8 dtim_period; |
373 | 376 | ||