summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl1251
diff options
context:
space:
mode:
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 e5c74c631374..79ca5273c9e9 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 dfc4579acb06..9f15ccaf8f05 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 12c9e635a6d6..a14a48c99cdc 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 9cc514703d2a..db719f7d2692 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 55c3dda75e69..75efad246d67 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 bb23cd522b22..a77f1bbbed0a 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;