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
= container_of(work
, struct 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
->psm
)
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
)
61 cancel_delayed_work(&wl
->elp_work
);
62 delay
= msecs_to_jiffies(ELP_ENTRY_DELAY
);
63 ieee80211_queue_delayed_work(wl
->hw
, &wl
->elp_work
, delay
);
67 int wl1251_ps_elp_wakeup(struct wl1251
*wl
)
69 unsigned long timeout
, start
;
75 wl1251_debug(DEBUG_PSM
, "waking up chip from elp");
78 timeout
= jiffies
+ msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT
);
80 wl1251_write_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
, ELPCTRL_WAKE_UP
);
82 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
85 * FIXME: we should wait for irq from chip but, as a temporary
86 * solution to simplify locking, let's poll instead
88 while (!(elp_reg
& ELPCTRL_WLAN_READY
)) {
89 if (time_after(jiffies
, timeout
)) {
90 wl1251_error("elp wakeup timeout");
94 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
97 wl1251_debug(DEBUG_PSM
, "wakeup time: %u ms",
98 jiffies_to_msecs(jiffies
- start
));
105 static int wl1251_ps_set_elp(struct wl1251
*wl
, bool enable
)
110 wl1251_debug(DEBUG_PSM
, "sleep auth psm/elp");
112 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_ELP
);
116 wl1251_ps_elp_sleep(wl
);
118 wl1251_debug(DEBUG_PSM
, "sleep auth cam");
121 * When the target is in ELP, we can only
122 * access the ELP control register. Thus,
123 * we have to wake the target up before
124 * changing the power authorization.
127 wl1251_ps_elp_wakeup(wl
);
129 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_CAM
);
137 int wl1251_ps_set_mode(struct wl1251
*wl
, enum wl1251_cmd_ps_mode mode
)
142 case STATION_POWER_SAVE_MODE
:
143 wl1251_debug(DEBUG_PSM
, "entering psm");
145 /* enable beacon filtering */
146 ret
= wl1251_acx_beacon_filter_opt(wl
, true);
150 ret
= wl1251_acx_wake_up_conditions(wl
,
151 WAKE_UP_EVENT_DTIM_BITMAP
,
156 ret
= wl1251_cmd_ps_mode(wl
, STATION_POWER_SAVE_MODE
);
160 ret
= wl1251_ps_set_elp(wl
, true);
166 case STATION_ACTIVE_MODE
:
168 wl1251_debug(DEBUG_PSM
, "leaving psm");
169 ret
= wl1251_ps_set_elp(wl
, false);
173 /* disable beacon filtering */
174 ret
= wl1251_acx_beacon_filter_opt(wl
, false);
178 ret
= wl1251_acx_wake_up_conditions(wl
,
179 WAKE_UP_EVENT_DTIM_BITMAP
,
184 ret
= wl1251_cmd_ps_mode(wl
, STATION_ACTIVE_MODE
);