aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-10-02 16:44:03 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-07 16:39:45 -0400
commite932a609e9759cc75db0c234f465a5fd6e20d362 (patch)
treefb4f7d072aa527204f7db4fd11b155e3b12e0b74
parentbe1a71a128ed91372d4ad8d54d8fd972a1a356eb (diff)
iwlwifi: LED cleanup
The iwlwifi drivers have LED blinking requirements that mac80211 cannot fulfill due to the use of just a single LED instead of different ones for TX, RX, radio etc. Instead, the single LED blinks according to transfers and is solid on the rest of the time. As such, having LED class devices registered that mac80211 triggers are connected to is pointless as we don't use the triggers anyway. Remove all the useless code and add hooks into the driver itself. At the same time, make the LED code abstracted so the core code that determines blink rate etc. can be shared between 3945 and agn in iwlcore. At the same time, the fact that we removed the use of the mac80211 LED triggers means we can also remove the IWLWIFI_LEDS Kconfig symbol since the LED support is now self-contained. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c371
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.c85
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-led.h32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c285
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c8
21 files changed, 194 insertions, 721 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 48d8f2cf566c..c82c97be7bfa 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -2,15 +2,6 @@ config IWLWIFI
2 tristate "Intel Wireless Wifi" 2 tristate "Intel Wireless Wifi"
3 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL 3 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
4 select FW_LOADER 4 select FW_LOADER
5 select MAC80211_LEDS if IWLWIFI_LEDS
6 select LEDS_CLASS if IWLWIFI_LEDS
7
8config IWLWIFI_LEDS
9 bool "Enable LED support in iwlagn and iwl3945 drivers"
10 depends on IWLWIFI
11 default y
12 ---help---
13 Select this if you want LED support.
14 5
15config IWLWIFI_SPECTRUM_MEASUREMENT 6config IWLWIFI_SPECTRUM_MEASUREMENT
16 bool "Enable Spectrum Measurement in iwlagn driver" 7 bool "Enable Spectrum Measurement in iwlagn driver"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 3f31d866054b..7f82044af242 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,9 +1,8 @@
1obj-$(CONFIG_IWLWIFI) += iwlcore.o 1obj-$(CONFIG_IWLWIFI) += iwlcore.o
2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o 2iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o 3iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
4iwlcore-objs += iwl-scan.o 4iwlcore-objs += iwl-scan.o iwl-led.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
7iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o 6iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
8iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 7iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
9 8
@@ -11,7 +10,7 @@ CFLAGS_iwl-devtrace.o := -I$(src)
11 10
12# AGN 11# AGN
13obj-$(CONFIG_IWLAGN) += iwlagn.o 12obj-$(CONFIG_IWLAGN) += iwlagn.o
14iwlagn-objs := iwl-agn.o iwl-agn-rs.o 13iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
15 14
16iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 15iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
17iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 16iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index af91dbab255a..86d93b52c6fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -44,6 +44,7 @@
44#include "iwl-sta.h" 44#include "iwl-sta.h"
45#include "iwl-helpers.h" 45#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
47#include "iwl-agn-led.h"
47 48
48/* Highest firmware API version supported */ 49/* Highest firmware API version supported */
49#define IWL1000_UCODE_API_MAX 3 50#define IWL1000_UCODE_API_MAX 3
@@ -145,6 +146,7 @@ static struct iwl_ops iwl1000_ops = {
145 .lib = &iwl1000_lib, 146 .lib = &iwl1000_lib,
146 .hcmd = &iwl5000_hcmd, 147 .hcmd = &iwl5000_hcmd,
147 .utils = &iwl5000_hcmd_utils, 148 .utils = &iwl5000_hcmd_utils,
149 .led = &iwlagn_led_ops,
148}; 150};
149 151
150struct iwl_cfg iwl1000_bgn_cfg = { 152struct iwl_cfg iwl1000_bgn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 8c29ded7d02c..a871d09d598f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -24,8 +24,6 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#ifdef CONFIG_IWLWIFI_LEDS
28
29#include <linux/kernel.h> 27#include <linux/kernel.h>
30#include <linux/module.h> 28#include <linux/module.h>
31#include <linux/init.h> 29#include <linux/init.h>
@@ -43,388 +41,51 @@
43#include "iwl-3945.h" 41#include "iwl-3945.h"
44#include "iwl-core.h" 42#include "iwl-core.h"
45#include "iwl-dev.h" 43#include "iwl-dev.h"
44#include "iwl-3945-led.h"
46 45
47#ifdef CONFIG_IWLWIFI_DEBUG
48static const char *led_type_str[] = {
49 __stringify(IWL_LED_TRG_TX),
50 __stringify(IWL_LED_TRG_RX),
51 __stringify(IWL_LED_TRG_ASSOC),
52 __stringify(IWL_LED_TRG_RADIO),
53 NULL
54};
55#endif /* CONFIG_IWLWIFI_DEBUG */
56
57static const struct {
58 u16 brightness;
59 u8 on_time;
60 u8 off_time;
61} blink_tbl[] =
62{
63 {300, 25, 25},
64 {200, 40, 40},
65 {100, 55, 55},
66 {70, 65, 65},
67 {50, 75, 75},
68 {20, 85, 85},
69 {15, 95, 95 },
70 {10, 110, 110},
71 {5, 130, 130},
72 {0, 167, 167},
73 /* SOLID_ON */
74 {-1, IWL_LED_SOLID, 0}
75};
76
77#define IWL_1MB_RATE (128 * 1024)
78#define IWL_LED_THRESHOLD (16)
79#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
80#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
81
82static void iwl3945_led_cmd_callback(struct iwl_priv *priv,
83 struct iwl_device_cmd *cmd,
84 struct sk_buff *skb)
85{
86}
87
88static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
89{
90 return fls(0x000000FF & (u32)brightness);
91}
92 46
93/* Send led command */ 47/* Send led command */
94static int iwl_send_led_cmd(struct iwl_priv *priv, 48static int iwl3945_send_led_cmd(struct iwl_priv *priv,
95 struct iwl_led_cmd *led_cmd) 49 struct iwl_led_cmd *led_cmd)
96{ 50{
97 struct iwl_host_cmd cmd = { 51 struct iwl_host_cmd cmd = {
98 .id = REPLY_LEDS_CMD, 52 .id = REPLY_LEDS_CMD,
99 .len = sizeof(struct iwl_led_cmd), 53 .len = sizeof(struct iwl_led_cmd),
100 .data = led_cmd, 54 .data = led_cmd,
101 .flags = CMD_ASYNC, 55 .flags = CMD_ASYNC,
102 .callback = iwl3945_led_cmd_callback, 56 .callback = NULL,
103 }; 57 };
104 58
105 return iwl_send_cmd(priv, &cmd); 59 return iwl_send_cmd(priv, &cmd);
106} 60}
107 61
108
109
110/* Set led on command */
111static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
112 unsigned int idx)
113{
114 struct iwl_led_cmd led_cmd = {
115 .id = led_id,
116 .interval = IWL_DEF_LED_INTRVL
117 };
118
119 BUG_ON(idx > IWL_MAX_BLINK_TBL);
120
121 led_cmd.on = blink_tbl[idx].on_time;
122 led_cmd.off = blink_tbl[idx].off_time;
123
124 return iwl_send_led_cmd(priv, &led_cmd);
125}
126
127
128/* Set led on command */ 62/* Set led on command */
129static int iwl3945_led_on(struct iwl_priv *priv, int led_id) 63static int iwl3945_led_on(struct iwl_priv *priv)
130{ 64{
131 struct iwl_led_cmd led_cmd = { 65 struct iwl_led_cmd led_cmd = {
132 .id = led_id, 66 .id = IWL_LED_LINK,
133 .on = IWL_LED_SOLID, 67 .on = IWL_LED_SOLID,
134 .off = 0, 68 .off = 0,
135 .interval = IWL_DEF_LED_INTRVL 69 .interval = IWL_DEF_LED_INTRVL
136 }; 70 };
137 return iwl_send_led_cmd(priv, &led_cmd); 71 return iwl3945_send_led_cmd(priv, &led_cmd);
138} 72}
139 73
140/* Set led off command */ 74/* Set led off command */
141static int iwl3945_led_off(struct iwl_priv *priv, int led_id) 75static int iwl3945_led_off(struct iwl_priv *priv)
142{ 76{
143 struct iwl_led_cmd led_cmd = { 77 struct iwl_led_cmd led_cmd = {
144 .id = led_id, 78 .id = IWL_LED_LINK,
145 .on = 0, 79 .on = 0,
146 .off = 0, 80 .off = 0,
147 .interval = IWL_DEF_LED_INTRVL 81 .interval = IWL_DEF_LED_INTRVL
148 }; 82 };
149 IWL_DEBUG_LED(priv, "led off %d\n", led_id); 83 IWL_DEBUG_LED(priv, "led off\n");
150 return iwl_send_led_cmd(priv, &led_cmd); 84 return iwl3945_send_led_cmd(priv, &led_cmd);
151} 85}
152 86
153/* 87const struct iwl_led_ops iwl3945_led_ops = {
154 * Set led on in case of association 88 .cmd = iwl3945_send_led_cmd,
155 * */ 89 .on = iwl3945_led_on,
156static int iwl3945_led_associate(struct iwl_priv *priv, int led_id) 90 .off = iwl3945_led_off,
157{ 91};
158 IWL_DEBUG_LED(priv, "Associated\n");
159
160 priv->allow_blinking = 1;
161 return iwl3945_led_on(priv, led_id);
162}
163/* Set Led off in case of disassociation */
164static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
165{
166 IWL_DEBUG_LED(priv, "Disassociated\n");
167
168 priv->allow_blinking = 0;
169
170 return 0;
171}
172
173/*
174 * brightness call back function for Tx/Rx LED
175 */
176static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
177{
178 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
179 !test_bit(STATUS_READY, &priv->status))
180 return 0;
181
182
183 /* start counting Tx/Rx bytes */
184 if (!priv->last_blink_time && priv->allow_blinking)
185 priv->last_blink_time = jiffies;
186 return 0;
187}
188
189/*
190 * brightness call back for association and radio
191 */
192static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
193 enum led_brightness brightness)
194{
195 struct iwl_led *led = container_of(led_cdev,
196 struct iwl_led, led_dev);
197 struct iwl_priv *priv = led->priv;
198
199 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
200 return;
201
202 IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
203 led_type_str[led->type], brightness);
204
205 switch (brightness) {
206 case LED_FULL:
207 if (led->led_on)
208 led->led_on(priv, IWL_LED_LINK);
209 break;
210 case LED_OFF:
211 if (led->led_off)
212 led->led_off(priv, IWL_LED_LINK);
213 break;
214 default:
215 if (led->led_pattern) {
216 int idx = iwl3945_brightness_to_idx(brightness);
217 led->led_pattern(priv, IWL_LED_LINK, idx);
218 }
219 break;
220 }
221}
222
223/*
224 * Register led class with the system
225 */
226static int iwl3945_led_register_led(struct iwl_priv *priv,
227 struct iwl_led *led,
228 enum led_type type, u8 set_led,
229 char *trigger)
230{
231 struct device *device = wiphy_dev(priv->hw->wiphy);
232 int ret;
233
234 led->led_dev.name = led->name;
235 led->led_dev.brightness_set = iwl3945_led_brightness_set;
236 led->led_dev.default_trigger = trigger;
237
238 led->priv = priv;
239 led->type = type;
240
241 ret = led_classdev_register(device, &led->led_dev);
242 if (ret) {
243 IWL_ERR(priv, "Error: failed to register led handler.\n");
244 return ret;
245 }
246
247 led->registered = 1;
248
249 if (set_led && led->led_on)
250 led->led_on(priv, IWL_LED_LINK);
251 return 0;
252}
253
254
255/*
256 * calculate blink rate according to last 2 sec Tx/Rx activities
257 */
258static inline u8 get_blink_rate(struct iwl_priv *priv)
259{
260 int index;
261 s64 tpt = priv->rxtxpackets;
262
263 if (tpt < 0)
264 tpt = -tpt;
265
266 IWL_DEBUG_LED(priv, "tpt %lld \n", (long long)tpt);
267
268 if (!priv->allow_blinking)
269 index = IWL_MAX_BLINK_TBL;
270 else
271 for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
272 if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
273 break;
274
275 IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", index);
276 return index;
277}
278
279/*
280 * this function called from handler. Since setting Led command can
281 * happen very frequent we postpone led command to be called from
282 * REPLY handler so we know ucode is up
283 */
284void iwl3945_led_background(struct iwl_priv *priv)
285{
286 u8 blink_idx;
287
288 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
289 priv->last_blink_time = 0;
290 return;
291 }
292 if (iwl_is_rfkill(priv)) {
293 priv->last_blink_time = 0;
294 return;
295 }
296
297 if (!priv->allow_blinking) {
298 priv->last_blink_time = 0;
299 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
300 priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
301 iwl3945_led_pattern(priv, IWL_LED_LINK,
302 IWL_SOLID_BLINK_IDX);
303 }
304 return;
305 }
306 if (!priv->last_blink_time ||
307 !time_after(jiffies, priv->last_blink_time +
308 msecs_to_jiffies(1000)))
309 return;
310
311 blink_idx = get_blink_rate(priv);
312
313 /* call only if blink rate change */
314 if (blink_idx != priv->last_blink_rate)
315 iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx);
316
317 priv->last_blink_time = jiffies;
318 priv->last_blink_rate = blink_idx;
319 priv->rxtxpackets = 0;
320}
321
322
323/* Register all led handler */
324int iwl3945_led_register(struct iwl_priv *priv)
325{
326 char *trigger;
327 int ret;
328
329 priv->last_blink_rate = 0;
330 priv->rxtxpackets = 0;
331 priv->led_tpt = 0;
332 priv->last_blink_time = 0;
333 priv->allow_blinking = 0;
334
335 trigger = ieee80211_get_radio_led_name(priv->hw);
336 snprintf(priv->led[IWL_LED_TRG_RADIO].name,
337 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
338 wiphy_name(priv->hw->wiphy));
339
340 priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
341 priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
342 priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
343
344 ret = iwl3945_led_register_led(priv,
345 &priv->led[IWL_LED_TRG_RADIO],
346 IWL_LED_TRG_RADIO, 1, trigger);
347
348 if (ret)
349 goto exit_fail;
350
351 trigger = ieee80211_get_assoc_led_name(priv->hw);
352 snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
353 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
354 wiphy_name(priv->hw->wiphy));
355
356 ret = iwl3945_led_register_led(priv,
357 &priv->led[IWL_LED_TRG_ASSOC],
358 IWL_LED_TRG_ASSOC, 0, trigger);
359
360 /* for assoc always turn led on */
361 priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_associate;
362 priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_disassociate;
363 priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
364
365 if (ret)
366 goto exit_fail;
367
368 trigger = ieee80211_get_rx_led_name(priv->hw);
369 snprintf(priv->led[IWL_LED_TRG_RX].name,
370 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
371 wiphy_name(priv->hw->wiphy));
372
373 ret = iwl3945_led_register_led(priv,
374 &priv->led[IWL_LED_TRG_RX],
375 IWL_LED_TRG_RX, 0, trigger);
376
377 priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
378 priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
379 priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
380
381 if (ret)
382 goto exit_fail;
383
384 trigger = ieee80211_get_tx_led_name(priv->hw);
385 snprintf(priv->led[IWL_LED_TRG_TX].name,
386 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
387 wiphy_name(priv->hw->wiphy));
388
389 ret = iwl3945_led_register_led(priv,
390 &priv->led[IWL_LED_TRG_TX],
391 IWL_LED_TRG_TX, 0, trigger);
392
393 priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
394 priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
395 priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
396
397 if (ret)
398 goto exit_fail;
399
400 return 0;
401
402exit_fail:
403 iwl3945_led_unregister(priv);
404 return ret;
405}
406
407
408/* unregister led class */
409static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
410{
411 if (!led->registered)
412 return;
413
414 led_classdev_unregister(&led->led_dev);
415
416 if (set_led)
417 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
418 led->registered = 0;
419}
420
421/* Unregister all led handlers */
422void iwl3945_led_unregister(struct iwl_priv *priv)
423{
424 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
425 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
426 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
427 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
428}
429
430#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 3b65642258ca..5a1033ca7aaa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -24,23 +24,9 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#ifndef IWL3945_LEDS_H 27#ifndef __iwl_3945_led_h__
28#define IWL3945_LEDS_H 28#define __iwl_3945_led_h__
29 29
30struct iwl_priv; 30extern const struct iwl_led_ops iwl3945_led_ops;
31 31
32#ifdef CONFIG_IWLWIFI_LEDS 32#endif /* __iwl_3945_led_h__ */
33
34#include "iwl-led.h"
35
36extern int iwl3945_led_register(struct iwl_priv *priv);
37extern void iwl3945_led_unregister(struct iwl_priv *priv);
38extern void iwl3945_led_background(struct iwl_priv *priv);
39
40#else
41static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
42static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
43static inline void iwl3945_led_background(struct iwl_priv *priv) {}
44
45#endif /* IWLWIFI_LEDS*/
46#endif /* IWL3945_LEDS_H */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 33e40c21eb72..f0ce5c45ca05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -46,7 +46,8 @@
46#include "iwl-eeprom.h" 46#include "iwl-eeprom.h"
47#include "iwl-helpers.h" 47#include "iwl-helpers.h"
48#include "iwl-core.h" 48#include "iwl-core.h"
49#include "iwl-agn-rs.h" 49#include "iwl-led.h"
50#include "iwl-3945-led.h"
50 51
51#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ 52#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
52 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 53 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -359,7 +360,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
359 360
360 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); 361 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
361 362
362 iwl3945_led_background(priv); 363 iwl_leds_background(priv);
363 364
364 priv->last_statistics_time = jiffies; 365 priv->last_statistics_time = jiffies;
365} 366}
@@ -572,10 +573,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
572 (struct ieee80211_hdr *)rxb->skb->data, 573 (struct ieee80211_hdr *)rxb->skb->data,
573 le32_to_cpu(rx_end->status), stats); 574 le32_to_cpu(rx_end->status), stats);
574 575
575#ifdef CONFIG_IWLWIFI_LEDS
576 if (ieee80211_is_data(hdr->frame_control))
577 priv->rxtxpackets += len;
578#endif
579 iwl_update_stats(priv, false, hdr->frame_control, len); 576 iwl_update_stats(priv, false, hdr->frame_control, len);
580 577
581 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); 578 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
@@ -2880,6 +2877,7 @@ static struct iwl_ops iwl3945_ops = {
2880 .lib = &iwl3945_lib, 2877 .lib = &iwl3945_lib,
2881 .hcmd = &iwl3945_hcmd, 2878 .hcmd = &iwl3945_hcmd,
2882 .utils = &iwl3945_hcmd_utils, 2879 .utils = &iwl3945_hcmd_utils,
2880 .led = &iwl3945_led_ops,
2883}; 2881};
2884 2882
2885static struct iwl_cfg iwl3945_bg_cfg = { 2883static struct iwl_cfg iwl3945_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 21679bf3a1aa..f3907c1079f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -46,7 +46,7 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
46#include "iwl-debug.h" 46#include "iwl-debug.h"
47#include "iwl-power.h" 47#include "iwl-power.h"
48#include "iwl-dev.h" 48#include "iwl-dev.h"
49#include "iwl-3945-led.h" 49#include "iwl-led.h"
50 50
51/* Highest firmware API version supported */ 51/* Highest firmware API version supported */
52#define IWL3945_UCODE_API_MAX 2 52#define IWL3945_UCODE_API_MAX 2
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 0921e454185b..8717946de011 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -44,6 +44,7 @@
44#include "iwl-helpers.h" 44#include "iwl-helpers.h"
45#include "iwl-calib.h" 45#include "iwl-calib.h"
46#include "iwl-sta.h" 46#include "iwl-sta.h"
47#include "iwl-agn-led.h"
47 48
48static int iwl4965_send_tx_power(struct iwl_priv *priv); 49static int iwl4965_send_tx_power(struct iwl_priv *priv);
49static int iwl4965_hw_get_temperature(struct iwl_priv *priv); 50static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -2341,6 +2342,7 @@ static struct iwl_ops iwl4965_ops = {
2341 .lib = &iwl4965_lib, 2342 .lib = &iwl4965_lib,
2342 .hcmd = &iwl4965_hcmd, 2343 .hcmd = &iwl4965_hcmd,
2343 .utils = &iwl4965_hcmd_utils, 2344 .utils = &iwl4965_hcmd_utils,
2345 .led = &iwlagn_led_ops,
2344}; 2346};
2345 2347
2346struct iwl_cfg iwl4965_agn_cfg = { 2348struct iwl_cfg iwl4965_agn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 01d53ebb96ad..624853503db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -42,6 +42,7 @@
42#include "iwl-io.h" 42#include "iwl-io.h"
43#include "iwl-sta.h" 43#include "iwl-sta.h"
44#include "iwl-helpers.h" 44#include "iwl-helpers.h"
45#include "iwl-agn-led.h"
45#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
46#include "iwl-6000-hw.h" 47#include "iwl-6000-hw.h"
47 48
@@ -1641,11 +1642,12 @@ static struct iwl_lib_ops iwl5150_lib = {
1641 }, 1642 },
1642}; 1643};
1643 1644
1644struct iwl_ops iwl5000_ops = { 1645static struct iwl_ops iwl5000_ops = {
1645 .ucode = &iwl5000_ucode, 1646 .ucode = &iwl5000_ucode,
1646 .lib = &iwl5000_lib, 1647 .lib = &iwl5000_lib,
1647 .hcmd = &iwl5000_hcmd, 1648 .hcmd = &iwl5000_hcmd,
1648 .utils = &iwl5000_hcmd_utils, 1649 .utils = &iwl5000_hcmd_utils,
1650 .led = &iwlagn_led_ops,
1649}; 1651};
1650 1652
1651static struct iwl_ops iwl5150_ops = { 1653static struct iwl_ops iwl5150_ops = {
@@ -1653,6 +1655,7 @@ static struct iwl_ops iwl5150_ops = {
1653 .lib = &iwl5150_lib, 1655 .lib = &iwl5150_lib,
1654 .hcmd = &iwl5000_hcmd, 1656 .hcmd = &iwl5000_hcmd,
1655 .utils = &iwl5000_hcmd_utils, 1657 .utils = &iwl5000_hcmd_utils,
1658 .led = &iwlagn_led_ops,
1656}; 1659};
1657 1660
1658struct iwl_mod_params iwl50_mod_params = { 1661struct iwl_mod_params iwl50_mod_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 6f4ee27e07c9..a002214f4d49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -45,6 +45,7 @@
45#include "iwl-helpers.h" 45#include "iwl-helpers.h"
46#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
47#include "iwl-6000-hw.h" 47#include "iwl-6000-hw.h"
48#include "iwl-agn-led.h"
48 49
49/* Highest firmware API version supported */ 50/* Highest firmware API version supported */
50#define IWL6000_UCODE_API_MAX 4 51#define IWL6000_UCODE_API_MAX 4
@@ -227,6 +228,7 @@ static struct iwl_ops iwl6000_ops = {
227 .lib = &iwl6000_lib, 228 .lib = &iwl6000_lib,
228 .hcmd = &iwl5000_hcmd, 229 .hcmd = &iwl5000_hcmd,
229 .utils = &iwl5000_hcmd_utils, 230 .utils = &iwl5000_hcmd_utils,
231 .led = &iwlagn_led_ops,
230}; 232};
231 233
232 234
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
new file mode 100644
index 000000000000..3bccba20f6da
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c
@@ -0,0 +1,85 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/dma-mapping.h>
32#include <linux/delay.h>
33#include <linux/skbuff.h>
34#include <linux/netdevice.h>
35#include <linux/wireless.h>
36#include <net/mac80211.h>
37#include <linux/etherdevice.h>
38#include <asm/unaligned.h>
39
40#include "iwl-commands.h"
41#include "iwl-dev.h"
42#include "iwl-core.h"
43#include "iwl-io.h"
44#include "iwl-agn-led.h"
45
46/* Send led command */
47static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
48{
49 struct iwl_host_cmd cmd = {
50 .id = REPLY_LEDS_CMD,
51 .len = sizeof(struct iwl_led_cmd),
52 .data = led_cmd,
53 .flags = CMD_ASYNC,
54 .callback = NULL,
55 };
56 u32 reg;
57
58 reg = iwl_read32(priv, CSR_LED_REG);
59 if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
60 iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
61
62 return iwl_send_cmd(priv, &cmd);
63}
64
65/* Set led register off */
66static int iwl_led_on_reg(struct iwl_priv *priv)
67{
68 IWL_DEBUG_LED(priv, "led on\n");
69 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
70 return 0;
71}
72
73/* Set led register off */
74static int iwl_led_off_reg(struct iwl_priv *priv)
75{
76 IWL_DEBUG_LED(priv, "LED Reg off\n");
77 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
78 return 0;
79}
80
81const struct iwl_led_ops iwlagn_led_ops = {
82 .cmd = iwl_send_led_cmd,
83 .on = iwl_led_on_reg,
84 .off = iwl_led_off_reg,
85};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
new file mode 100644
index 000000000000..ab55f92a161d
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h
@@ -0,0 +1,32 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27#ifndef __iwl_agn_led_h__
28#define __iwl_agn_led_h__
29
30extern const struct iwl_led_ops iwlagn_led_ops;
31
32#endif /* __iwl_agn_led_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4fb50d0eb536..046b571fd9ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1801,7 +1801,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1801 /* At this point, the NIC is initialized and operational */ 1801 /* At this point, the NIC is initialized and operational */
1802 iwl_rf_kill_ct_config(priv); 1802 iwl_rf_kill_ct_config(priv);
1803 1803
1804 iwl_leds_register(priv); 1804 iwl_leds_init(priv);
1805 1805
1806 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); 1806 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
1807 set_bit(STATUS_READY, &priv->status); 1807 set_bit(STATUS_READY, &priv->status);
@@ -1839,8 +1839,6 @@ static void __iwl_down(struct iwl_priv *priv)
1839 if (!exit_pending) 1839 if (!exit_pending)
1840 set_bit(STATUS_EXIT_PENDING, &priv->status); 1840 set_bit(STATUS_EXIT_PENDING, &priv->status);
1841 1841
1842 iwl_leds_unregister(priv);
1843
1844 iwl_clear_stations_table(priv); 1842 iwl_clear_stations_table(priv);
1845 1843
1846 /* Unblock any waiting calls */ 1844 /* Unblock any waiting calls */
@@ -2339,6 +2337,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
2339 } 2337 }
2340 } 2338 }
2341 2339
2340 iwl_led_start(priv);
2341
2342out: 2342out:
2343 priv->is_open = 1; 2343 priv->is_open = 1;
2344 IWL_DEBUG_MAC80211(priv, "leave\n"); 2344 IWL_DEBUG_MAC80211(priv, "leave\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1cf2e04fe3f9..34547cf3a66e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2384,6 +2384,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2384 priv->timestamp = bss_conf->timestamp; 2384 priv->timestamp = bss_conf->timestamp;
2385 priv->assoc_capability = bss_conf->assoc_capability; 2385 priv->assoc_capability = bss_conf->assoc_capability;
2386 2386
2387 iwl_led_associate(priv);
2388
2387 /* 2389 /*
2388 * We have just associated, don't start scan too early 2390 * We have just associated, don't start scan too early
2389 * leave time for EAPOL exchange to complete. 2391 * leave time for EAPOL exchange to complete.
@@ -2394,9 +2396,10 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
2394 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; 2396 IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
2395 if (!iwl_is_rfkill(priv)) 2397 if (!iwl_is_rfkill(priv))
2396 priv->cfg->ops->lib->post_associate(priv); 2398 priv->cfg->ops->lib->post_associate(priv);
2397 } else 2399 } else {
2398 priv->assoc_id = 0; 2400 priv->assoc_id = 0;
2399 2401 iwl_led_disassociate(priv);
2402 }
2400 } 2403 }
2401 2404
2402 if (changes && iwl_is_associated(priv) && priv->assoc_id) { 2405 if (changes && iwl_is_associated(priv) && priv->assoc_id) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 3bd0e59bb5a4..eb586a546181 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -187,11 +187,18 @@ struct iwl_lib_ops {
187 struct iwl_temp_ops temp_ops; 187 struct iwl_temp_ops temp_ops;
188}; 188};
189 189
190struct iwl_led_ops {
191 int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
192 int (*on)(struct iwl_priv *priv);
193 int (*off)(struct iwl_priv *priv);
194};
195
190struct iwl_ops { 196struct iwl_ops {
191 const struct iwl_ucode_ops *ucode; 197 const struct iwl_ucode_ops *ucode;
192 const struct iwl_lib_ops *lib; 198 const struct iwl_lib_ops *lib;
193 const struct iwl_hcmd_ops *hcmd; 199 const struct iwl_hcmd_ops *hcmd;
194 const struct iwl_hcmd_utils_ops *utils; 200 const struct iwl_hcmd_utils_ops *utils;
201 const struct iwl_led_ops *led;
195}; 202};
196 203
197struct iwl_mod_params { 204struct iwl_mod_params {
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index cbc62904655d..b9ca475cc61c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -84,9 +84,7 @@ struct iwl_debugfs {
84 struct dentry *file_interrupt; 84 struct dentry *file_interrupt;
85 struct dentry *file_qos; 85 struct dentry *file_qos;
86 struct dentry *file_thermal_throttling; 86 struct dentry *file_thermal_throttling;
87#ifdef CONFIG_IWLWIFI_LEDS
88 struct dentry *file_led; 87 struct dentry *file_led;
89#endif
90 struct dentry *file_disable_ht40; 88 struct dentry *file_disable_ht40;
91 struct dentry *file_sleep_level_override; 89 struct dentry *file_sleep_level_override;
92 struct dentry *file_current_sleep_command; 90 struct dentry *file_current_sleep_command;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index fa6371d171c5..1794b9c4e6ac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -677,7 +677,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
677 return ret; 677 return ret;
678} 678}
679 679
680#ifdef CONFIG_IWLWIFI_LEDS
681static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 680static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
682 size_t count, loff_t *ppos) 681 size_t count, loff_t *ppos)
683{ 682{
@@ -702,7 +701,6 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
702 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 701 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
703 return ret; 702 return ret;
704} 703}
705#endif
706 704
707static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 705static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
708 char __user *user_buf, 706 char __user *user_buf,
@@ -866,9 +864,7 @@ DEBUGFS_READ_FILE_OPS(channels);
866DEBUGFS_READ_FILE_OPS(status); 864DEBUGFS_READ_FILE_OPS(status);
867DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 865DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
868DEBUGFS_READ_FILE_OPS(qos); 866DEBUGFS_READ_FILE_OPS(qos);
869#ifdef CONFIG_IWLWIFI_LEDS
870DEBUGFS_READ_FILE_OPS(led); 867DEBUGFS_READ_FILE_OPS(led);
871#endif
872DEBUGFS_READ_FILE_OPS(thermal_throttling); 868DEBUGFS_READ_FILE_OPS(thermal_throttling);
873DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 869DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
874DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 870DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
@@ -1666,9 +1662,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1666 DEBUGFS_ADD_FILE(status, data); 1662 DEBUGFS_ADD_FILE(status, data);
1667 DEBUGFS_ADD_FILE(interrupt, data); 1663 DEBUGFS_ADD_FILE(interrupt, data);
1668 DEBUGFS_ADD_FILE(qos, data); 1664 DEBUGFS_ADD_FILE(qos, data);
1669#ifdef CONFIG_IWLWIFI_LEDS
1670 DEBUGFS_ADD_FILE(led, data); 1665 DEBUGFS_ADD_FILE(led, data);
1671#endif
1672 DEBUGFS_ADD_FILE(sleep_level_override, data); 1666 DEBUGFS_ADD_FILE(sleep_level_override, data);
1673 DEBUGFS_ADD_FILE(current_sleep_command, data); 1667 DEBUGFS_ADD_FILE(current_sleep_command, data);
1674 DEBUGFS_ADD_FILE(thermal_throttling, data); 1668 DEBUGFS_ADD_FILE(thermal_throttling, data);
@@ -1721,9 +1715,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1721 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 1715 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
1722 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); 1716 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
1723 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos); 1717 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
1724#ifdef CONFIG_IWLWIFI_LEDS
1725 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led); 1718 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
1726#endif
1727 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); 1719 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
1728 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); 1720 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
1729 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 1721 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ad99ce7824c6..eabc55695aff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -43,7 +43,6 @@
43#include "iwl-debug.h" 43#include "iwl-debug.h"
44#include "iwl-4965-hw.h" 44#include "iwl-4965-hw.h"
45#include "iwl-3945-hw.h" 45#include "iwl-3945-hw.h"
46#include "iwl-3945-led.h"
47#include "iwl-led.h" 46#include "iwl-led.h"
48#include "iwl-power.h" 47#include "iwl-power.h"
49#include "iwl-agn-rs.h" 48#include "iwl-agn-rs.h"
@@ -73,7 +72,6 @@ struct iwl_tx_queue;
73 72
74/* shared structures from iwl-5000.c */ 73/* shared structures from iwl-5000.c */
75extern struct iwl_mod_params iwl50_mod_params; 74extern struct iwl_mod_params iwl50_mod_params;
76extern struct iwl_ops iwl5000_ops;
77extern struct iwl_ucode_ops iwl5000_ucode; 75extern struct iwl_ucode_ops iwl5000_ucode;
78extern struct iwl_lib_ops iwl5000_lib; 76extern struct iwl_lib_ops iwl5000_lib;
79extern struct iwl_hcmd_ops iwl5000_hcmd; 77extern struct iwl_hcmd_ops iwl5000_hcmd;
@@ -1066,14 +1064,11 @@ struct iwl_priv {
1066 struct iwl_init_alive_resp card_alive_init; 1064 struct iwl_init_alive_resp card_alive_init;
1067 struct iwl_alive_resp card_alive; 1065 struct iwl_alive_resp card_alive;
1068 1066
1069#ifdef CONFIG_IWLWIFI_LEDS
1070 unsigned long last_blink_time; 1067 unsigned long last_blink_time;
1071 u8 last_blink_rate; 1068 u8 last_blink_rate;
1072 u8 allow_blinking; 1069 u8 allow_blinking;
1073 u64 led_tpt; 1070 u64 led_tpt;
1074 struct iwl_led led[IWL_LED_TRG_MAX]; 1071
1075 unsigned int rxtxpackets;
1076#endif
1077 u16 active_rate; 1072 u16 active_rate;
1078 u16 active_rate_basic; 1073 u16 active_rate_basic;
1079 1074
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 685ba9d6f082..478c90511ebf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -48,16 +48,6 @@ module_param(led_mode, int, S_IRUGO);
48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " 48MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), "
49 "(default 0)\n"); 49 "(default 0)\n");
50 50
51#ifdef CONFIG_IWLWIFI_DEBUG
52static const char *led_type_str[] = {
53 __stringify(IWL_LED_TRG_TX),
54 __stringify(IWL_LED_TRG_RX),
55 __stringify(IWL_LED_TRG_ASSOC),
56 __stringify(IWL_LED_TRG_RADIO),
57 NULL
58};
59#endif /* CONFIG_IWLWIFI_DEBUG */
60
61 51
62static const struct { 52static const struct {
63 u16 tpt; /* Mb/s */ 53 u16 tpt; /* Mb/s */
@@ -75,7 +65,7 @@ static const struct {
75 {5, 110, 110}, 65 {5, 110, 110},
76 {1, 130, 130}, 66 {1, 130, 130},
77 {0, 167, 167}, 67 {0, 167, 167},
78/* SOLID_ON */ 68 /* SOLID_ON */
79 {-1, IWL_LED_SOLID, 0} 69 {-1, IWL_LED_SOLID, 0}
80}; 70};
81 71
@@ -107,37 +97,11 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv,
107 return (u8)((time * compensation) >> 6); 97 return (u8)((time * compensation) >> 6);
108} 98}
109 99
110/* [0-256] -> [0..8] FIXME: we need [0..10] */
111static inline int iwl_brightness_to_idx(enum led_brightness brightness)
112{
113 return fls(0x000000FF & (u32)brightness);
114}
115
116/* Send led command */
117static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
118{
119 struct iwl_host_cmd cmd = {
120 .id = REPLY_LEDS_CMD,
121 .len = sizeof(struct iwl_led_cmd),
122 .data = led_cmd,
123 .flags = CMD_ASYNC,
124 .callback = NULL,
125 };
126 u32 reg;
127
128 reg = iwl_read32(priv, CSR_LED_REG);
129 if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
130 iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
131
132 return iwl_send_cmd(priv, &cmd);
133}
134
135/* Set led pattern command */ 100/* Set led pattern command */
136static int iwl_led_pattern(struct iwl_priv *priv, int led_id, 101static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx)
137 unsigned int idx)
138{ 102{
139 struct iwl_led_cmd led_cmd = { 103 struct iwl_led_cmd led_cmd = {
140 .id = led_id, 104 .id = IWL_LED_LINK,
141 .interval = IWL_DEF_LED_INTRVL 105 .interval = IWL_DEF_LED_INTRVL
142 }; 106 };
143 107
@@ -152,153 +116,32 @@ static int iwl_led_pattern(struct iwl_priv *priv, int led_id,
152 iwl_blink_compensation(priv, blink_tbl[idx].off_time, 116 iwl_blink_compensation(priv, blink_tbl[idx].off_time,
153 priv->cfg->led_compensation); 117 priv->cfg->led_compensation);
154 118
155 return iwl_send_led_cmd(priv, &led_cmd); 119 return priv->cfg->ops->led->cmd(priv, &led_cmd);
156}
157
158/* Set led register off */
159static int iwl_led_on_reg(struct iwl_priv *priv, int led_id)
160{
161 IWL_DEBUG_LED(priv, "led on %d\n", led_id);
162 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
163 return 0;
164}
165
166#if 0
167/* Set led on command */
168static int iwl_led_on(struct iwl_priv *priv, int led_id)
169{
170 struct iwl_led_cmd led_cmd = {
171 .id = led_id,
172 .on = IWL_LED_SOLID,
173 .off = 0,
174 .interval = IWL_DEF_LED_INTRVL
175 };
176 return iwl_send_led_cmd(priv, &led_cmd);
177}
178
179/* Set led off command */
180int iwl_led_off(struct iwl_priv *priv, int led_id)
181{
182 struct iwl_led_cmd led_cmd = {
183 .id = led_id,
184 .on = 0,
185 .off = 0,
186 .interval = IWL_DEF_LED_INTRVL
187 };
188 IWL_DEBUG_LED(priv, "led off %d\n", led_id);
189 return iwl_send_led_cmd(priv, &led_cmd);
190} 120}
191#endif
192 121
193 122int iwl_led_start(struct iwl_priv *priv)
194/* Set led register off */
195static int iwl_led_off_reg(struct iwl_priv *priv, int led_id)
196{ 123{
197 IWL_DEBUG_LED(priv, "LED Reg off\n"); 124 return priv->cfg->ops->led->on(priv);
198 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
199 return 0;
200} 125}
126EXPORT_SYMBOL(iwl_led_start);
201 127
202/* 128int iwl_led_associate(struct iwl_priv *priv)
203 * Set led register in case of disassociation according to rfkill state
204 */
205static int iwl_led_associate(struct iwl_priv *priv, int led_id)
206{ 129{
207 IWL_DEBUG_LED(priv, "Associated\n"); 130 IWL_DEBUG_LED(priv, "Associated\n");
208 if (led_mode == IWL_LED_BLINK) 131 if (led_mode == IWL_LED_BLINK)
209 priv->allow_blinking = 1; 132 priv->allow_blinking = 1;
210 return iwl_led_on_reg(priv, led_id); 133 priv->last_blink_time = jiffies;
211}
212static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
213{
214 priv->allow_blinking = 0;
215
216 return 0;
217}
218
219/*
220 * brightness call back function for Tx/Rx LED
221 */
222static int iwl_led_associated(struct iwl_priv *priv, int led_id)
223{
224 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
225 !test_bit(STATUS_READY, &priv->status))
226 return 0;
227
228 134
229 /* start counting Tx/Rx bytes */
230 if (!priv->last_blink_time && priv->allow_blinking)
231 priv->last_blink_time = jiffies;
232 return 0; 135 return 0;
233} 136}
234 137
235/* 138int iwl_led_disassociate(struct iwl_priv *priv)
236 * brightness call back for association and radio
237 */
238static void iwl_led_brightness_set(struct led_classdev *led_cdev,
239 enum led_brightness brightness)
240{ 139{
241 struct iwl_led *led = container_of(led_cdev, struct iwl_led, led_dev); 140 priv->allow_blinking = 0;
242 struct iwl_priv *priv = led->priv;
243
244 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
245 return;
246
247
248 IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
249 led_type_str[led->type], brightness);
250 switch (brightness) {
251 case LED_FULL:
252 if (led->led_on)
253 led->led_on(priv, IWL_LED_LINK);
254 break;
255 case LED_OFF:
256 if (led->led_off)
257 led->led_off(priv, IWL_LED_LINK);
258 break;
259 default:
260 if (led->led_pattern) {
261 int idx = iwl_brightness_to_idx(brightness);
262 led->led_pattern(priv, IWL_LED_LINK, idx);
263 }
264 break;
265 }
266}
267
268
269
270/*
271 * Register led class with the system
272 */
273static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
274 enum led_type type, u8 set_led,
275 char *trigger)
276{
277 struct device *device = wiphy_dev(priv->hw->wiphy);
278 int ret;
279
280 led->led_dev.name = led->name;
281 led->led_dev.brightness_set = iwl_led_brightness_set;
282 led->led_dev.default_trigger = trigger;
283
284 led->priv = priv;
285 led->type = type;
286
287 ret = led_classdev_register(device, &led->led_dev);
288 if (ret) {
289 IWL_ERR(priv, "Error: failed to register led handler.\n");
290 return ret;
291 }
292
293 led->registered = 1;
294
295 if (set_led && led->led_on)
296 led->led_on(priv, IWL_LED_LINK);
297 141
298 return 0; 142 return 0;
299} 143}
300 144
301
302/* 145/*
303 * calculate blink rate according to last second Tx/Rx activities 146 * calculate blink rate according to last second Tx/Rx activities
304 */ 147 */
@@ -324,7 +167,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
324 i = IWL_MAX_BLINK_TBL; 167 i = IWL_MAX_BLINK_TBL;
325 else 168 else
326 for (i = 0; i < IWL_MAX_BLINK_TBL; i++) 169 for (i = 0; i < IWL_MAX_BLINK_TBL; i++)
327 if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) 170 if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
328 break; 171 break;
329 172
330 IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i); 173 IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
@@ -353,8 +196,7 @@ void iwl_leds_background(struct iwl_priv *priv)
353 priv->last_blink_time = 0; 196 priv->last_blink_time = 0;
354 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { 197 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
355 priv->last_blink_rate = IWL_SOLID_BLINK_IDX; 198 priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
356 iwl_led_pattern(priv, IWL_LED_LINK, 199 iwl_led_pattern(priv, IWL_SOLID_BLINK_IDX);
357 IWL_SOLID_BLINK_IDX);
358 } 200 }
359 return; 201 return;
360 } 202 }
@@ -367,111 +209,18 @@ void iwl_leds_background(struct iwl_priv *priv)
367 209
368 /* call only if blink rate change */ 210 /* call only if blink rate change */
369 if (blink_idx != priv->last_blink_rate) 211 if (blink_idx != priv->last_blink_rate)
370 iwl_led_pattern(priv, IWL_LED_LINK, blink_idx); 212 iwl_led_pattern(priv, blink_idx);
371 213
372 priv->last_blink_time = jiffies; 214 priv->last_blink_time = jiffies;
373 priv->last_blink_rate = blink_idx; 215 priv->last_blink_rate = blink_idx;
374} 216}
217EXPORT_SYMBOL(iwl_leds_background);
375 218
376/* Register all led handler */ 219void iwl_leds_init(struct iwl_priv *priv)
377int iwl_leds_register(struct iwl_priv *priv)
378{ 220{
379 char *trigger;
380 int ret;
381
382 priv->last_blink_rate = 0; 221 priv->last_blink_rate = 0;
383 priv->led_tpt = 0; 222 priv->led_tpt = 0;
384 priv->last_blink_time = 0; 223 priv->last_blink_time = 0;
385 priv->allow_blinking = 0; 224 priv->allow_blinking = 0;
386
387 trigger = ieee80211_get_radio_led_name(priv->hw);
388 snprintf(priv->led[IWL_LED_TRG_RADIO].name,
389 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
390 wiphy_name(priv->hw->wiphy));
391
392 priv->led[IWL_LED_TRG_RADIO].led_on = iwl_led_on_reg;
393 priv->led[IWL_LED_TRG_RADIO].led_off = iwl_led_off_reg;
394 priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
395
396 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
397 IWL_LED_TRG_RADIO, 1, trigger);
398 if (ret)
399 goto exit_fail;
400
401 trigger = ieee80211_get_assoc_led_name(priv->hw);
402 snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
403 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
404 wiphy_name(priv->hw->wiphy));
405
406 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
407 IWL_LED_TRG_ASSOC, 0, trigger);
408
409 /* for assoc always turn led on */
410 priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
411 priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
412 priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
413
414 if (ret)
415 goto exit_fail;
416
417 trigger = ieee80211_get_rx_led_name(priv->hw);
418 snprintf(priv->led[IWL_LED_TRG_RX].name,
419 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
420 wiphy_name(priv->hw->wiphy));
421
422 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
423 IWL_LED_TRG_RX, 0, trigger);
424
425 priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
426 priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
427 priv->led[IWL_LED_TRG_RX].led_pattern = iwl_led_pattern;
428
429 if (ret)
430 goto exit_fail;
431
432 trigger = ieee80211_get_tx_led_name(priv->hw);
433 snprintf(priv->led[IWL_LED_TRG_TX].name,
434 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
435 wiphy_name(priv->hw->wiphy));
436
437 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
438 IWL_LED_TRG_TX, 0, trigger);
439
440 priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
441 priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
442 priv->led[IWL_LED_TRG_TX].led_pattern = iwl_led_pattern;
443
444 if (ret)
445 goto exit_fail;
446
447 return 0;
448
449exit_fail:
450 iwl_leds_unregister(priv);
451 return ret;
452} 225}
453EXPORT_SYMBOL(iwl_leds_register); 226EXPORT_SYMBOL(iwl_leds_init);
454
455/* unregister led class */
456static void iwl_leds_unregister_led(struct iwl_led *led, u8 set_led)
457{
458 if (!led->registered)
459 return;
460
461 led_classdev_unregister(&led->led_dev);
462
463 if (set_led)
464 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
465 led->registered = 0;
466}
467
468/* Unregister all led handlers */
469void iwl_leds_unregister(struct iwl_priv *priv)
470{
471 iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
472 iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
473 iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
474 iwl_leds_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
475}
476EXPORT_SYMBOL(iwl_leds_unregister);
477
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index dd76b266c633..f47f053f02ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -30,9 +30,6 @@
30 30
31struct iwl_priv; 31struct iwl_priv;
32 32
33#ifdef CONFIG_IWLWIFI_LEDS
34#include <linux/leds.h>
35
36#define IWL_LED_SOLID 11 33#define IWL_LED_SOLID 11
37#define IWL_LED_NAME_LEN 31 34#define IWL_LED_NAME_LEN 31
38#define IWL_DEF_LED_INTRVL cpu_to_le32(1000) 35#define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
@@ -59,38 +56,11 @@ enum iwl_led_mode {
59 IWL_LED_BLINK, 56 IWL_LED_BLINK,
60 IWL_LED_RF_STATE, 57 IWL_LED_RF_STATE,
61}; 58};
62#endif
63
64#ifdef CONFIG_IWLWIFI_LEDS
65
66struct iwl_led {
67 struct iwl_priv *priv;
68 struct led_classdev led_dev;
69 char name[32];
70
71 int (*led_on) (struct iwl_priv *priv, int led_id);
72 int (*led_off) (struct iwl_priv *priv, int led_id);
73 int (*led_pattern) (struct iwl_priv *priv, int led_id, unsigned int idx);
74 59
75 enum led_type type; 60void iwl_leds_init(struct iwl_priv *priv);
76 unsigned int registered;
77};
78
79int iwl_leds_register(struct iwl_priv *priv);
80void iwl_leds_unregister(struct iwl_priv *priv);
81void iwl_leds_background(struct iwl_priv *priv); 61void iwl_leds_background(struct iwl_priv *priv);
62int iwl_led_start(struct iwl_priv *priv);
63int iwl_led_associate(struct iwl_priv *priv);
64int iwl_led_disassociate(struct iwl_priv *priv);
82 65
83#else
84static inline int iwl_leds_register(struct iwl_priv *priv)
85{
86 return 0;
87}
88static inline void iwl_leds_unregister(struct iwl_priv *priv)
89{
90}
91static inline void iwl_leds_background(struct iwl_priv *priv)
92{
93}
94
95#endif /* CONFIG_IWLWIFI_LEDS */
96#endif /* __iwl_leds_h__ */ 66#endif /* __iwl_leds_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d0d1b7f4c396..ecbe036ecb63 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -455,9 +455,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
455 tx->timeout.pm_frame_timeout = cpu_to_le16(2); 455 tx->timeout.pm_frame_timeout = cpu_to_le16(2);
456 } else { 456 } else {
457 tx->timeout.pm_frame_timeout = 0; 457 tx->timeout.pm_frame_timeout = 0;
458#ifdef CONFIG_IWLWIFI_LEDS
459 priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
460#endif
461 } 458 }
462 459
463 tx->driver_txop = 0; 460 tx->driver_txop = 0;
@@ -2483,7 +2480,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2483 2480
2484 iwl3945_reg_txpower_periodic(priv); 2481 iwl3945_reg_txpower_periodic(priv);
2485 2482
2486 iwl3945_led_register(priv); 2483 iwl_leds_init(priv);
2487 2484
2488 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); 2485 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
2489 set_bit(STATUS_READY, &priv->status); 2486 set_bit(STATUS_READY, &priv->status);
@@ -2521,7 +2518,6 @@ static void __iwl3945_down(struct iwl_priv *priv)
2521 if (!exit_pending) 2518 if (!exit_pending)
2522 set_bit(STATUS_EXIT_PENDING, &priv->status); 2519 set_bit(STATUS_EXIT_PENDING, &priv->status);
2523 2520
2524 iwl3945_led_unregister(priv);
2525 iwl_clear_stations_table(priv); 2521 iwl_clear_stations_table(priv);
2526 2522
2527 /* Unblock any waiting calls */ 2523 /* Unblock any waiting calls */
@@ -3156,6 +3152,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
3156 * no need to poll the killswitch state anymore */ 3152 * no need to poll the killswitch state anymore */
3157 cancel_delayed_work(&priv->rfkill_poll); 3153 cancel_delayed_work(&priv->rfkill_poll);
3158 3154
3155 iwl_led_start(priv);
3156
3159 priv->is_open = 1; 3157 priv->is_open = 1;
3160 IWL_DEBUG_MAC80211(priv, "leave\n"); 3158 IWL_DEBUG_MAC80211(priv, "leave\n");
3161 return 0; 3159 return 0;