2 * This file is part of wl1251
4 * Copyright (C) 2008 Nokia Corporation
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 #define WL1251_WAKEUP_TIMEOUT 100
30 void wl1251_elp_work(struct work_struct
*work
)
32 struct delayed_work
*dwork
;
35 dwork
= to_delayed_work(work
);
36 wl
= container_of(dwork
, struct wl1251
, elp_work
);
38 wl1251_debug(DEBUG_PSM
, "elp work");
40 mutex_lock(&wl
->mutex
);
42 if (wl
->elp
|| wl
->station_mode
== STATION_ACTIVE_MODE
)
45 wl1251_debug(DEBUG_PSM
, "chip to elp");
46 wl1251_write_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
, ELPCTRL_SLEEP
);
50 mutex_unlock(&wl
->mutex
);
53 #define ELP_ENTRY_DELAY 5
55 /* Routines to toggle sleep mode while in ELP */
56 void wl1251_ps_elp_sleep(struct wl1251
*wl
)
60 if (wl
->station_mode
!= STATION_ACTIVE_MODE
) {
61 delay
= msecs_to_jiffies(ELP_ENTRY_DELAY
);
62 ieee80211_queue_delayed_work(wl
->hw
, &wl
->elp_work
, delay
);
66 int wl1251_ps_elp_wakeup(struct wl1251
*wl
)
68 unsigned long timeout
, start
;
71 cancel_delayed_work(&wl
->elp_work
);
76 wl1251_debug(DEBUG_PSM
, "waking up chip from elp");
79 timeout
= jiffies
+ msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT
);
81 wl1251_write_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
, ELPCTRL_WAKE_UP
);
83 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
86 * FIXME: we should wait for irq from chip but, as a temporary
87 * solution to simplify locking, let's poll instead
89 while (!(elp_reg
& ELPCTRL_WLAN_READY
)) {
90 if (time_after(jiffies
, timeout
)) {
91 wl1251_error("elp wakeup timeout");
95 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
98 wl1251_debug(DEBUG_PSM
, "wakeup time: %u ms",
99 jiffies_to_msecs(jiffies
- start
));
106 int wl1251_ps_set_mode(struct wl1251
*wl
, enum wl1251_station_mode mode
)
111 case STATION_POWER_SAVE_MODE
:
112 wl1251_debug(DEBUG_PSM
, "entering psm");
114 /* enable beacon filtering */
115 ret
= wl1251_acx_beacon_filter_opt(wl
, true);
119 ret
= wl1251_acx_wake_up_conditions(wl
,
120 WAKE_UP_EVENT_DTIM_BITMAP
,
125 ret
= wl1251_acx_bet_enable(wl
, WL1251_ACX_BET_ENABLE
,
126 WL1251_DEFAULT_BET_CONSECUTIVE
);
130 ret
= wl1251_cmd_ps_mode(wl
, CHIP_POWER_SAVE_MODE
);
134 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_ELP
);
139 wl1251_debug(DEBUG_PSM
, "entering idle");
141 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_ELP
);
145 ret
= wl1251_cmd_template_set(wl
, CMD_DISCONNECT
, NULL
, 0);
149 case STATION_ACTIVE_MODE
:
151 wl1251_debug(DEBUG_PSM
, "leaving psm");
153 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_CAM
);
158 ret
= wl1251_acx_bet_enable(wl
, WL1251_ACX_BET_DISABLE
,
159 WL1251_DEFAULT_BET_CONSECUTIVE
);
163 /* disable beacon filtering */
164 ret
= wl1251_acx_beacon_filter_opt(wl
, false);
168 ret
= wl1251_acx_wake_up_conditions(wl
,
169 WAKE_UP_EVENT_DTIM_BITMAP
,
174 ret
= wl1251_cmd_ps_mode(wl
, CHIP_ACTIVE_MODE
);
180 wl
->station_mode
= mode
;