summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl1251
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488 /drivers/net/wireless/wl1251
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
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 {
} __packed;
enum wl1251_cmd_ps_mode {
- STATION_ACTIVE_MODE,
- STATION_POWER_SAVE_MODE
+ CHIP_ACTIVE_MODE,
+ CHIP_POWER_SAVE_MODE
};
struct 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)
if (vector & BSS_LOSE_EVENT_ID) {
wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
- if (wl->psm_requested && wl->psm) {
+ if (wl->psm_requested &&
+ wl->station_mode != STATION_ACTIVE_MODE) {
ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
if (ret < 0)
return ret;
}
}
- if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
+ if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
+ wl->station_mode != STATION_ACTIVE_MODE) {
wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
/* 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)
wl->rx_last_id = 0;
wl->next_tx_complete = 0;
wl->elp = false;
- wl->psm = 0;
+ wl->station_mode = STATION_ACTIVE_MODE;
wl->tx_queue_stopped = false;
wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
wl->rssi_thold = 0;
@@ -632,13 +632,29 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
wl->psm_requested = false;
- if (wl->psm) {
+ if (wl->station_mode != STATION_ACTIVE_MODE) {
ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
if (ret < 0)
goto out_sleep;
}
}
+ if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+ if (conf->flags & IEEE80211_CONF_IDLE) {
+ ret = wl1251_ps_set_mode(wl, STATION_IDLE);
+ if (ret < 0)
+ goto out_sleep;
+ } else {
+ ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+ if (ret < 0)
+ goto out_sleep;
+ ret = wl1251_join(wl, wl->bss_type, wl->channel,
+ wl->beacon_int, wl->dtim_period);
+ if (ret < 0)
+ goto out_sleep;
+ }
+ }
+
if (conf->power_level != wl->power_level) {
ret = wl1251_acx_tx_power(wl, conf->power_level);
if (ret < 0)
@@ -1384,7 +1400,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
wl->elp = false;
- wl->psm = 0;
+ wl->station_mode = STATION_ACTIVE_MODE;
wl->psm_requested = false;
wl->tx_queue_stopped = false;
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)
mutex_lock(&wl->mutex);
- if (wl->elp || !wl->psm)
+ if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE)
goto out;
wl1251_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
{
unsigned long delay;
- if (wl->psm) {
+ if (wl->station_mode != STATION_ACTIVE_MODE) {
delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
}
@@ -104,7 +104,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
return 0;
}
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
{
int ret;
@@ -128,15 +128,24 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
if (ret < 0)
return ret;
- ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+ ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE);
if (ret < 0)
return ret;
ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
if (ret < 0)
return ret;
+ break;
+ case STATION_IDLE:
+ wl1251_debug(DEBUG_PSM, "entering idle");
- wl->psm = 1;
+ ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
+ if (ret < 0)
+ return ret;
+
+ ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0);
+ if (ret < 0)
+ return ret;
break;
case STATION_ACTIVE_MODE:
default:
@@ -163,13 +172,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
if (ret < 0)
return ret;
- ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+ ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
if (ret < 0)
return ret;
- wl->psm = 0;
break;
}
+ wl->station_mode = mode;
return ret;
}
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 @@
#include "wl1251.h"
#include "acx.h"
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode);
void wl1251_ps_elp_sleep(struct wl1251 *wl);
int wl1251_ps_elp_wakeup(struct wl1251 *wl);
void 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 {
PART_TABLE_LEN
};
+enum wl1251_station_mode {
+ STATION_ACTIVE_MODE,
+ STATION_POWER_SAVE_MODE,
+ STATION_IDLE,
+};
+
struct wl1251_partition {
u32 size;
u32 start;
@@ -358,8 +364,7 @@ struct wl1251 {
struct delayed_work elp_work;
- /* we can be in psm, but not in elp, we have to differentiate */
- bool psm;
+ enum wl1251_station_mode station_mode;
/* PSM mode requested */
bool psm_requested;