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
->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 if (delayed_work_pending(&wl
->elp_work
))
72 cancel_delayed_work(&wl
->elp_work
);
77 wl1251_debug(DEBUG_PSM
, "waking up chip from elp");
80 timeout
= jiffies
+ msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT
);
82 wl1251_write_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
, ELPCTRL_WAKE_UP
);
84 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
87 * FIXME: we should wait for irq from chip but, as a temporary
88 * solution to simplify locking, let's poll instead
90 while (!(elp_reg
& ELPCTRL_WLAN_READY
)) {
91 if (time_after(jiffies
, timeout
)) {
92 wl1251_error("elp wakeup timeout");
96 elp_reg
= wl1251_read_elp(wl
, HW_ACCESS_ELP_CTRL_REG_ADDR
);
99 wl1251_debug(DEBUG_PSM
, "wakeup time: %u ms",
100 jiffies_to_msecs(jiffies
- start
));
107 int wl1251_ps_set_mode(struct wl1251
*wl
, enum wl1251_station_mode mode
)
112 case STATION_POWER_SAVE_MODE
:
113 wl1251_debug(DEBUG_PSM
, "entering psm");
115 /* enable beacon filtering */
116 ret
= wl1251_acx_beacon_filter_opt(wl
, true);
120 ret
= wl1251_acx_wake_up_conditions(wl
,
121 WAKE_UP_EVENT_DTIM_BITMAP
,
126 ret
= wl1251_acx_bet_enable(wl
, WL1251_ACX_BET_ENABLE
,
127 WL1251_DEFAULT_BET_CONSECUTIVE
);
131 ret
= wl1251_cmd_ps_mode(wl
, CHIP_POWER_SAVE_MODE
);
135 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_ELP
);
140 wl1251_debug(DEBUG_PSM
, "entering idle");
142 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_ELP
);
146 ret
= wl1251_cmd_template_set(wl
, CMD_DISCONNECT
, NULL
, 0);
150 case STATION_ACTIVE_MODE
:
152 wl1251_debug(DEBUG_PSM
, "leaving psm");
154 ret
= wl1251_acx_sleep_auth(wl
, WL1251_PSM_CAM
);
159 ret
= wl1251_acx_bet_enable(wl
, WL1251_ACX_BET_DISABLE
,
160 WL1251_DEFAULT_BET_CONSECUTIVE
);
164 /* disable beacon filtering */
165 ret
= wl1251_acx_beacon_filter_opt(wl
, false);
169 ret
= wl1251_acx_wake_up_conditions(wl
,
170 WAKE_UP_EVENT_DTIM_BITMAP
,
175 ret
= wl1251_cmd_ps_mode(wl
, CHIP_ACTIVE_MODE
);
181 wl
->station_mode
= mode
;