diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_conf.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 5 |
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 | ||
71 | static 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 | |||
71 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) | 105 | static 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 | ||
66 | enum { | ||
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 | |||
66 | struct event_debug_report { | 73 | struct 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; |