aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c53
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c5
6 files changed, 77 insertions, 2 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 566f1521ec22..94359b1a861f 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -417,6 +417,9 @@ struct wl1271 {
417 /* PSM mode requested */ 417 /* PSM mode requested */
418 bool psm_requested; 418 bool psm_requested;
419 419
420 /* retry counter for PSM entries */
421 u8 psm_entry_retry;
422
420 /* in dBm */ 423 /* in dBm */
421 int power_level; 424 int power_level;
422 425
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 8678bea05ed5..b7c96454cca3 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -407,7 +407,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
407 407
408 /* unmask required mbox events */ 408 /* unmask required mbox events */
409 wl->event_mask = BSS_LOSE_EVENT_ID | 409 wl->event_mask = BSS_LOSE_EVENT_ID |
410 SCAN_COMPLETE_EVENT_ID; 410 SCAN_COMPLETE_EVENT_ID |
411 PS_REPORT_EVENT_ID;
411 412
412 ret = wl1271_event_unmask(wl); 413 ret = wl1271_event_unmask(wl);
413 if (ret < 0) { 414 if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 061d47520a32..565373ede265 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -712,6 +712,14 @@ struct conf_conn_settings {
712 * Range 0 - 255 712 * Range 0 - 255
713 */ 713 */
714 u8 bet_max_consecutive; 714 u8 bet_max_consecutive;
715
716 /*
717 * Specifies the maximum number of times to try PSM entry if it fails
718 * (if sending the appropriate null-func message fails.)
719 *
720 * Range 0 - 255
721 */
722 u8 psm_entry_retries;
715}; 723};
716 724
717#define CONF_SR_ERR_TBL_MAX_VALUES 14 725#define CONF_SR_ERR_TBL_MAX_VALUES 14
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 31d396ba9188..e135d894b42a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -68,6 +68,40 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
68 return 0; 68 return 0;
69} 69}
70 70
71static int wl1271_event_ps_report(struct wl1271 *wl,
72 struct event_mailbox *mbox,
73 bool *beacon_loss)
74{
75 int ret = 0;
76
77 wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
78
79 switch (mbox->ps_status) {
80 case EVENT_ENTER_POWER_SAVE_FAIL:
81 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
82 wl->psm_entry_retry++;
83 wl1271_error("PSM entry failed, retrying %d\n",
84 wl->psm_entry_retry);
85 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
86 } else {
87 wl->psm_entry_retry = 0;
88 *beacon_loss = true;
89 }
90 break;
91 case EVENT_ENTER_POWER_SAVE_SUCCESS:
92 wl->psm_entry_retry = 0;
93 break;
94 case EVENT_EXIT_POWER_SAVE_FAIL:
95 wl1271_info("PSM exit failed");
96 break;
97 case EVENT_EXIT_POWER_SAVE_SUCCESS:
98 default:
99 break;
100 }
101
102 return ret;
103}
104
71static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 105static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
72{ 106{
73 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 107 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -79,6 +113,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
79{ 113{
80 int ret; 114 int ret;
81 u32 vector; 115 u32 vector;
116 bool beacon_loss = false;
82 117
83 wl1271_event_mbox_dump(mbox); 118 wl1271_event_mbox_dump(mbox);
84 119
@@ -101,7 +136,25 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
101 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); 136 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
102 137
103 /* indicate to the stack, that beacons have been lost */ 138 /* indicate to the stack, that beacons have been lost */
139 beacon_loss = true;
140 }
141
142 if (vector & PS_REPORT_EVENT_ID) {
143 wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
144 ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
145 if (ret < 0)
146 return ret;
147 }
148
149 if (beacon_loss) {
150 /* Obviously, it's dangerous to release the mutex while
151 we are holding many of the variables in the wl struct.
152 That's why it's done last in the function, and care must
153 be taken that nothing more is done after this function
154 returns. */
155 mutex_unlock(&wl->mutex);
104 ieee80211_beacon_loss(wl->vif); 156 ieee80211_beacon_loss(wl->vif);
157 mutex_lock(&wl->mutex);
105 } 158 }
106 159
107 return 0; 160 return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 3ab53d331f15..4e3f55ebb1a8 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -63,6 +63,13 @@ enum {
63 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, 63 EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
64}; 64};
65 65
66enum {
67 EVENT_ENTER_POWER_SAVE_FAIL = 0,
68 EVENT_ENTER_POWER_SAVE_SUCCESS,
69 EVENT_EXIT_POWER_SAVE_FAIL,
70 EVENT_EXIT_POWER_SAVE_SUCCESS,
71};
72
66struct event_debug_report { 73struct event_debug_report {
67 u8 debug_event_id; 74 u8 debug_event_id;
68 u8 num_params; 75 u8 num_params;
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 0ae506a2e90b..d2149fcd3cf1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -222,7 +222,8 @@ static struct conf_drv_settings default_conf = {
222 .snr_pkt_avg_weight = 10 222 .snr_pkt_avg_weight = 10
223 }, 223 },
224 .bet_enable = CONF_BET_MODE_ENABLE, 224 .bet_enable = CONF_BET_MODE_ENABLE,
225 .bet_max_consecutive = 100 225 .bet_max_consecutive = 100,
226 .psm_entry_retries = 3
226 }, 227 },
227 .init = { 228 .init = {
228 .sr_err_tbl = { 229 .sr_err_tbl = {
@@ -973,6 +974,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
973 wl->rx_counter = 0; 974 wl->rx_counter = 0;
974 wl->elp = false; 975 wl->elp = false;
975 wl->psm = 0; 976 wl->psm = 0;
977 wl->psm_entry_retry = 0;
976 wl->tx_queue_stopped = false; 978 wl->tx_queue_stopped = false;
977 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 979 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
978 wl->tx_blocks_available = 0; 980 wl->tx_blocks_available = 0;
@@ -1822,6 +1824,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
1822 wl->elp = false; 1824 wl->elp = false;
1823 wl->psm = 0; 1825 wl->psm = 0;
1824 wl->psm_requested = false; 1826 wl->psm_requested = false;
1827 wl->psm_entry_retry = 0;
1825 wl->tx_queue_stopped = false; 1828 wl->tx_queue_stopped = false;
1826 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 1829 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1827 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET; 1830 wl->basic_rate_set = WL1271_DEFAULT_BASIC_RATE_SET;