aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c35
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c21
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h3
6 files changed, 47 insertions, 26 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index a74259bb596b..dd2b5f0540a5 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -555,7 +555,7 @@ out:
555 return ret; 555 return ret;
556} 556}
557 557
558int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode) 558int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
559{ 559{
560 struct wl1271_cmd_ps_params *ps_params = NULL; 560 struct wl1271_cmd_ps_params *ps_params = NULL;
561 int ret = 0; 561 int ret = 0;
@@ -576,7 +576,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
576 } 576 }
577 577
578 ps_params->ps_mode = ps_mode; 578 ps_params->ps_mode = ps_mode;
579 ps_params->send_null_data = 1; 579 ps_params->send_null_data = send;
580 ps_params->retries = 5; 580 ps_params->retries = 5;
581 ps_params->hang_over_period = 128; 581 ps_params->hang_over_period = 128;
582 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */ 582 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 09fe91297acf..ba433f423c8b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -38,7 +38,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); 38int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); 39int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
40int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); 40int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode); 41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 0a145afc9905..cecbae2ded35 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -78,24 +78,55 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
78 78
79 switch (mbox->ps_status) { 79 switch (mbox->ps_status) {
80 case EVENT_ENTER_POWER_SAVE_FAIL: 80 case EVENT_ENTER_POWER_SAVE_FAIL:
81 wl1271_debug(DEBUG_PSM, "PSM entry failed");
82
81 if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) { 83 if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
84 /* remain in active mode */
82 wl->psm_entry_retry = 0; 85 wl->psm_entry_retry = 0;
83 break; 86 break;
84 } 87 }
85 88
86 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { 89 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
87 wl->psm_entry_retry++; 90 wl->psm_entry_retry++;
88 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 91 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
92 true);
89 } else { 93 } else {
90 wl1271_error("PSM entry failed, giving up.\n"); 94 wl1271_error("PSM entry failed, giving up.\n");
95 /* make sure the firmware goes into active mode */
96 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
97 false);
91 wl->psm_entry_retry = 0; 98 wl->psm_entry_retry = 0;
92 } 99 }
93 break; 100 break;
94 case EVENT_ENTER_POWER_SAVE_SUCCESS: 101 case EVENT_ENTER_POWER_SAVE_SUCCESS:
95 wl->psm_entry_retry = 0; 102 wl->psm_entry_retry = 0;
103
104 /* enable beacon filtering */
105 ret = wl1271_acx_beacon_filter_opt(wl, true);
106 if (ret < 0)
107 break;
108
109 /* enable beacon early termination */
110 ret = wl1271_acx_bet_enable(wl, true);
111 if (ret < 0)
112 break;
113
114 /* go to extremely low power mode */
115 wl1271_ps_elp_sleep(wl);
116 if (ret < 0)
117 break;
96 break; 118 break;
97 case EVENT_EXIT_POWER_SAVE_FAIL: 119 case EVENT_EXIT_POWER_SAVE_FAIL:
98 wl1271_info("PSM exit failed"); 120 wl1271_debug(DEBUG_PSM, "PSM exit failed");
121
122 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
123 wl->psm_entry_retry = 0;
124 break;
125 }
126
127 /* make sure the firmware goes to active mode */
128 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
129 false);
99 break; 130 break;
100 case EVENT_EXIT_POWER_SAVE_SUCCESS: 131 case EVENT_EXIT_POWER_SAVE_SUCCESS:
101 default: 132 default:
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index e4867b895c43..6f026fe63d7f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1248,7 +1248,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1248 */ 1248 */
1249 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { 1249 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1250 wl1271_info("psm enabled"); 1250 wl1271_info("psm enabled");
1251 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 1251 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1252 true);
1252 } 1253 }
1253 } else if (!(conf->flags & IEEE80211_CONF_PS) && 1254 } else if (!(conf->flags & IEEE80211_CONF_PS) &&
1254 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { 1255 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
@@ -1257,7 +1258,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1257 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); 1258 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
1258 1259
1259 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) 1260 if (test_bit(WL1271_FLAG_PSM, &wl->flags))
1260 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE); 1261 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
1262 true);
1261 } 1263 }
1262 1264
1263 if (conf->power_level != wl->power_level) { 1265 if (conf->power_level != wl->power_level) {
@@ -1637,7 +1639,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1637 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && 1639 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
1638 !test_bit(WL1271_FLAG_PSM, &wl->flags)) { 1640 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
1639 mode = STATION_POWER_SAVE_MODE; 1641 mode = STATION_POWER_SAVE_MODE;
1640 ret = wl1271_ps_set_mode(wl, mode); 1642 ret = wl1271_ps_set_mode(wl, mode, true);
1641 if (ret < 0) 1643 if (ret < 0)
1642 goto out_sleep; 1644 goto out_sleep;
1643 } 1645 }
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index e407790f6771..29f670099d94 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -118,7 +118,8 @@ out:
118 return 0; 118 return 0;
119} 119}
120 120
121int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode) 121int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
122 bool send)
122{ 123{
123 int ret; 124 int ret;
124 125
@@ -126,21 +127,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
126 case STATION_POWER_SAVE_MODE: 127 case STATION_POWER_SAVE_MODE:
127 wl1271_debug(DEBUG_PSM, "entering psm"); 128 wl1271_debug(DEBUG_PSM, "entering psm");
128 129
129 /* enable beacon filtering */ 130 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);
130 ret = wl1271_acx_beacon_filter_opt(wl, true);
131 if (ret < 0)
132 return ret;
133
134 /* enable beacon early termination */
135 ret = wl1271_acx_bet_enable(wl, true);
136 if (ret < 0)
137 return ret;
138
139 ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
140 if (ret < 0)
141 return ret;
142
143 wl1271_ps_elp_sleep(wl);
144 if (ret < 0) 131 if (ret < 0)
145 return ret; 132 return ret;
146 133
@@ -163,7 +150,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
163 if (ret < 0) 150 if (ret < 0)
164 return ret; 151 return ret;
165 152
166 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE); 153 ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);
167 if (ret < 0) 154 if (ret < 0)
168 return ret; 155 return ret;
169 156
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index 779653d0ae85..940276f517a4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -27,7 +27,8 @@
27#include "wl1271.h" 27#include "wl1271.h"
28#include "wl1271_acx.h" 28#include "wl1271_acx.h"
29 29
30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode); 30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
31 bool send);
31void wl1271_ps_elp_sleep(struct wl1271 *wl); 32void wl1271_ps_elp_sleep(struct wl1271 *wl);
32int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); 33int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
33void wl1271_elp_work(struct work_struct *work); 34void wl1271_elp_work(struct work_struct *work);