aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl1251
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-12 16:18:44 -0400
commit252f4bf400df1712408fe83ba199a66a1b57ab1d (patch)
treee07fa00abdd55b31e22567786c78635f32c6a66c /drivers/net/wireless/wl1251
parent6ba1037c3d871ab70e342631516dbf841c35b086 (diff)
parentb37e3b6d64358604960b35e8ecbb7aed22e0926e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/ath/ar9170/main.c drivers/net/wireless/ath/ar9170/phy.c drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
Diffstat (limited to 'drivers/net/wireless/wl1251')
-rw-r--r--drivers/net/wireless/wl1251/cmd.h4
-rw-r--r--drivers/net/wireless/wl1251/event.c6
-rw-r--r--drivers/net/wireless/wl1251/main.c22
-rw-r--r--drivers/net/wireless/wl1251/ps.c23
-rw-r--r--drivers/net/wireless/wl1251/ps.h2
-rw-r--r--drivers/net/wireless/wl1251/wl1251.h9
6 files changed, 49 insertions, 17 deletions
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/wl1251/cmd.h
index e5c74c63137..79ca5273c9e 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/wl1251/cmd.h
@@ -313,8 +313,8 @@ struct wl1251_cmd_vbm_update {
313} __packed; 313} __packed;
314 314
315enum wl1251_cmd_ps_mode { 315enum wl1251_cmd_ps_mode {
316 STATION_ACTIVE_MODE, 316 CHIP_ACTIVE_MODE,
317 STATION_POWER_SAVE_MODE 317 CHIP_POWER_SAVE_MODE
318}; 318};
319 319
320struct wl1251_cmd_ps_params { 320struct wl1251_cmd_ps_params {
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c
index dfc4579acb0..9f15ccaf8f0 100644
--- a/drivers/net/wireless/wl1251/event.c
+++ b/drivers/net/wireless/wl1251/event.c
@@ -68,14 +68,16 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
68 if (vector & BSS_LOSE_EVENT_ID) { 68 if (vector & BSS_LOSE_EVENT_ID) {
69 wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); 69 wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
70 70
71 if (wl->psm_requested && wl->psm) { 71 if (wl->psm_requested &&
72 wl->station_mode != STATION_ACTIVE_MODE) {
72 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 73 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
73 if (ret < 0) 74 if (ret < 0)
74 return ret; 75 return ret;
75 } 76 }
76 } 77 }
77 78
78 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) { 79 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
80 wl->station_mode != STATION_ACTIVE_MODE) {
79 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); 81 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
80 82
81 /* indicate to the stack, that beacons have been lost */ 83 /* indicate to the stack, that beacons have been lost */
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 12c9e635a6d..a14a48c99cd 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -497,7 +497,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
497 wl->rx_last_id = 0; 497 wl->rx_last_id = 0;
498 wl->next_tx_complete = 0; 498 wl->next_tx_complete = 0;
499 wl->elp = false; 499 wl->elp = false;
500 wl->psm = 0; 500 wl->station_mode = STATION_ACTIVE_MODE;
501 wl->tx_queue_stopped = false; 501 wl->tx_queue_stopped = false;
502 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 502 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
503 wl->rssi_thold = 0; 503 wl->rssi_thold = 0;
@@ -632,13 +632,29 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
632 632
633 wl->psm_requested = false; 633 wl->psm_requested = false;
634 634
635 if (wl->psm) { 635 if (wl->station_mode != STATION_ACTIVE_MODE) {
636 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE); 636 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
637 if (ret < 0) 637 if (ret < 0)
638 goto out_sleep; 638 goto out_sleep;
639 } 639 }
640 } 640 }
641 641
642 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
643 if (conf->flags & IEEE80211_CONF_IDLE) {
644 ret = wl1251_ps_set_mode(wl, STATION_IDLE);
645 if (ret < 0)
646 goto out_sleep;
647 } else {
648 ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
649 if (ret < 0)
650 goto out_sleep;
651 ret = wl1251_join(wl, wl->bss_type, wl->channel,
652 wl->beacon_int, wl->dtim_period);
653 if (ret < 0)
654 goto out_sleep;
655 }
656 }
657
642 if (conf->power_level != wl->power_level) { 658 if (conf->power_level != wl->power_level) {
643 ret = wl1251_acx_tx_power(wl, conf->power_level); 659 ret = wl1251_acx_tx_power(wl, conf->power_level);
644 if (ret < 0) 660 if (ret < 0)
@@ -1384,7 +1400,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
1384 wl->rx_config = WL1251_DEFAULT_RX_CONFIG; 1400 wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
1385 wl->rx_filter = WL1251_DEFAULT_RX_FILTER; 1401 wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
1386 wl->elp = false; 1402 wl->elp = false;
1387 wl->psm = 0; 1403 wl->station_mode = STATION_ACTIVE_MODE;
1388 wl->psm_requested = false; 1404 wl->psm_requested = false;
1389 wl->tx_queue_stopped = false; 1405 wl->tx_queue_stopped = false;
1390 wl->power_level = WL1251_DEFAULT_POWER_LEVEL; 1406 wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c
index 9cc514703d2..db719f7d269 100644
--- a/drivers/net/wireless/wl1251/ps.c
+++ b/drivers/net/wireless/wl1251/ps.c
@@ -39,7 +39,7 @@ void wl1251_elp_work(struct work_struct *work)
39 39
40 mutex_lock(&wl->mutex); 40 mutex_lock(&wl->mutex);
41 41
42 if (wl->elp || !wl->psm) 42 if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE)
43 goto out; 43 goto out;
44 44
45 wl1251_debug(DEBUG_PSM, "chip to elp"); 45 wl1251_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
57{ 57{
58 unsigned long delay; 58 unsigned long delay;
59 59
60 if (wl->psm) { 60 if (wl->station_mode != STATION_ACTIVE_MODE) {
61 delay = msecs_to_jiffies(ELP_ENTRY_DELAY); 61 delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); 62 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
63 } 63 }
@@ -104,7 +104,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
104 return 0; 104 return 0;
105} 105}
106 106
107int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) 107int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
108{ 108{
109 int ret; 109 int ret;
110 110
@@ -128,15 +128,24 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
128 if (ret < 0) 128 if (ret < 0)
129 return ret; 129 return ret;
130 130
131 ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); 131 ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE);
132 if (ret < 0) 132 if (ret < 0)
133 return ret; 133 return ret;
134 134
135 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); 135 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
136 if (ret < 0) 136 if (ret < 0)
137 return ret; 137 return ret;
138 break;
139 case STATION_IDLE:
140 wl1251_debug(DEBUG_PSM, "entering idle");
138 141
139 wl->psm = 1; 142 ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
143 if (ret < 0)
144 return ret;
145
146 ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0);
147 if (ret < 0)
148 return ret;
140 break; 149 break;
141 case STATION_ACTIVE_MODE: 150 case STATION_ACTIVE_MODE:
142 default: 151 default:
@@ -163,13 +172,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
163 if (ret < 0) 172 if (ret < 0)
164 return ret; 173 return ret;
165 174
166 ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE); 175 ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
167 if (ret < 0) 176 if (ret < 0)
168 return ret; 177 return ret;
169 178
170 wl->psm = 0;
171 break; 179 break;
172 } 180 }
181 wl->station_mode = mode;
173 182
174 return ret; 183 return ret;
175} 184}
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/wl1251/ps.h
index 55c3dda75e6..75efad246d6 100644
--- a/drivers/net/wireless/wl1251/ps.h
+++ b/drivers/net/wireless/wl1251/ps.h
@@ -26,7 +26,7 @@
26#include "wl1251.h" 26#include "wl1251.h"
27#include "acx.h" 27#include "acx.h"
28 28
29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); 29int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode);
30void wl1251_ps_elp_sleep(struct wl1251 *wl); 30void wl1251_ps_elp_sleep(struct wl1251 *wl);
31int wl1251_ps_elp_wakeup(struct wl1251 *wl); 31int wl1251_ps_elp_wakeup(struct wl1251 *wl);
32void wl1251_elp_work(struct work_struct *work); 32void wl1251_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h
index bb23cd522b2..a77f1bbbed0 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/wl1251/wl1251.h
@@ -129,6 +129,12 @@ enum wl1251_partition_type {
129 PART_TABLE_LEN 129 PART_TABLE_LEN
130}; 130};
131 131
132enum wl1251_station_mode {
133 STATION_ACTIVE_MODE,
134 STATION_POWER_SAVE_MODE,
135 STATION_IDLE,
136};
137
132struct wl1251_partition { 138struct wl1251_partition {
133 u32 size; 139 u32 size;
134 u32 start; 140 u32 start;
@@ -358,8 +364,7 @@ struct wl1251 {
358 364
359 struct delayed_work elp_work; 365 struct delayed_work elp_work;
360 366
361 /* we can be in psm, but not in elp, we have to differentiate */ 367 enum wl1251_station_mode station_mode;
362 bool psm;
363 368
364 /* PSM mode requested */ 369 /* PSM mode requested */
365 bool psm_requested; 370 bool psm_requested;