diff options
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 | |||
8 | config 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 | ||
15 | config IWLWIFI_SPECTRUM_MEASUREMENT | 6 | config 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 @@ | |||
1 | obj-$(CONFIG_IWLWIFI) += iwlcore.o | 1 | obj-$(CONFIG_IWLWIFI) += iwlcore.o |
2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o | 2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o |
3 | iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o | 3 | iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o |
4 | iwlcore-objs += iwl-scan.o | 4 | iwlcore-objs += iwl-scan.o iwl-led.o |
5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | ||
7 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o | 6 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o |
8 | iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 7 | iwlcore-$(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 |
13 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 12 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
14 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o | 13 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o |
15 | 14 | ||
16 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o | 15 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o |
17 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o | 16 | iwlagn-$(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 | ||
150 | struct iwl_cfg iwl1000_bgn_cfg = { | 152 | struct 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 | ||
48 | static 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 | |||
57 | static 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 | |||
82 | static void iwl3945_led_cmd_callback(struct iwl_priv *priv, | ||
83 | struct iwl_device_cmd *cmd, | ||
84 | struct sk_buff *skb) | ||
85 | { | ||
86 | } | ||
87 | |||
88 | static 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 */ |
94 | static int iwl_send_led_cmd(struct iwl_priv *priv, | 48 | static 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 */ | ||
111 | static 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 */ |
129 | static int iwl3945_led_on(struct iwl_priv *priv, int led_id) | 63 | static 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 */ |
141 | static int iwl3945_led_off(struct iwl_priv *priv, int led_id) | 75 | static 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 | /* | 87 | const 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, |
156 | static 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 */ | ||
164 | static 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 | */ | ||
176 | static 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 | */ | ||
192 | static 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 | */ | ||
226 | static 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 | */ | ||
258 | static 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 | */ | ||
284 | void 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 */ | ||
324 | int 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 | |||
402 | exit_fail: | ||
403 | iwl3945_led_unregister(priv); | ||
404 | return ret; | ||
405 | } | ||
406 | |||
407 | |||
408 | /* unregister led class */ | ||
409 | static 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 */ | ||
422 | void 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 | ||
30 | struct iwl_priv; | 30 | extern 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 | |||
36 | extern int iwl3945_led_register(struct iwl_priv *priv); | ||
37 | extern void iwl3945_led_unregister(struct iwl_priv *priv); | ||
38 | extern void iwl3945_led_background(struct iwl_priv *priv); | ||
39 | |||
40 | #else | ||
41 | static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; } | ||
42 | static inline void iwl3945_led_unregister(struct iwl_priv *priv) {} | ||
43 | static 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 | ||
2885 | static struct iwl_cfg iwl3945_bg_cfg = { | 2883 | static 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 | ||
48 | static int iwl4965_send_tx_power(struct iwl_priv *priv); | 49 | static int iwl4965_send_tx_power(struct iwl_priv *priv); |
49 | static int iwl4965_hw_get_temperature(struct iwl_priv *priv); | 50 | static 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 | ||
2346 | struct iwl_cfg iwl4965_agn_cfg = { | 2348 | struct 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 | ||
1644 | struct iwl_ops iwl5000_ops = { | 1645 | static 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 | ||
1651 | static struct iwl_ops iwl5150_ops = { | 1653 | static 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 | ||
1658 | struct iwl_mod_params iwl50_mod_params = { | 1661 | struct 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 */ | ||
47 | static 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 */ | ||
66 | static 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 */ | ||
74 | static 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 | |||
81 | const 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 | |||
30 | extern 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 | |||
2342 | out: | 2342 | out: |
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 | ||
190 | struct 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 | |||
190 | struct iwl_ops { | 196 | struct 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 | ||
197 | struct iwl_mod_params { | 204 | struct 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 | ||
681 | static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, | 680 | static 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 | ||
707 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | 705 | static 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); | |||
866 | DEBUGFS_READ_FILE_OPS(status); | 864 | DEBUGFS_READ_FILE_OPS(status); |
867 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 865 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
868 | DEBUGFS_READ_FILE_OPS(qos); | 866 | DEBUGFS_READ_FILE_OPS(qos); |
869 | #ifdef CONFIG_IWLWIFI_LEDS | ||
870 | DEBUGFS_READ_FILE_OPS(led); | 867 | DEBUGFS_READ_FILE_OPS(led); |
871 | #endif | ||
872 | DEBUGFS_READ_FILE_OPS(thermal_throttling); | 868 | DEBUGFS_READ_FILE_OPS(thermal_throttling); |
873 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); | 869 | DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); |
874 | DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); | 870 | DEBUGFS_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 */ |
75 | extern struct iwl_mod_params iwl50_mod_params; | 74 | extern struct iwl_mod_params iwl50_mod_params; |
76 | extern struct iwl_ops iwl5000_ops; | ||
77 | extern struct iwl_ucode_ops iwl5000_ucode; | 75 | extern struct iwl_ucode_ops iwl5000_ucode; |
78 | extern struct iwl_lib_ops iwl5000_lib; | 76 | extern struct iwl_lib_ops iwl5000_lib; |
79 | extern struct iwl_hcmd_ops iwl5000_hcmd; | 77 | extern 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); | |||
48 | MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " | 48 | MODULE_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 | ||
52 | static 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 | ||
62 | static const struct { | 52 | static 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] */ | ||
111 | static inline int iwl_brightness_to_idx(enum led_brightness brightness) | ||
112 | { | ||
113 | return fls(0x000000FF & (u32)brightness); | ||
114 | } | ||
115 | |||
116 | /* Send led command */ | ||
117 | static 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 */ |
136 | static int iwl_led_pattern(struct iwl_priv *priv, int led_id, | 101 | static 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 */ | ||
159 | static 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 */ | ||
168 | static 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 */ | ||
180 | int 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 | 122 | int iwl_led_start(struct iwl_priv *priv) | |
194 | /* Set led register off */ | ||
195 | static 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 | } |
126 | EXPORT_SYMBOL(iwl_led_start); | ||
201 | 127 | ||
202 | /* | 128 | int iwl_led_associate(struct iwl_priv *priv) |
203 | * Set led register in case of disassociation according to rfkill state | ||
204 | */ | ||
205 | static 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 | } | ||
212 | static 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 | */ | ||
222 | static 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 | /* | 138 | int iwl_led_disassociate(struct iwl_priv *priv) |
236 | * brightness call back for association and radio | ||
237 | */ | ||
238 | static 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 | */ | ||
273 | static 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 | } |
217 | EXPORT_SYMBOL(iwl_leds_background); | ||
375 | 218 | ||
376 | /* Register all led handler */ | 219 | void iwl_leds_init(struct iwl_priv *priv) |
377 | int 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 | |||
449 | exit_fail: | ||
450 | iwl_leds_unregister(priv); | ||
451 | return ret; | ||
452 | } | 225 | } |
453 | EXPORT_SYMBOL(iwl_leds_register); | 226 | EXPORT_SYMBOL(iwl_leds_init); |
454 | |||
455 | /* unregister led class */ | ||
456 | static 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 */ | ||
469 | void 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 | } | ||
476 | EXPORT_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 | ||
31 | struct iwl_priv; | 31 | struct 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 | |||
66 | struct 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; | 60 | void iwl_leds_init(struct iwl_priv *priv); |
76 | unsigned int registered; | ||
77 | }; | ||
78 | |||
79 | int iwl_leds_register(struct iwl_priv *priv); | ||
80 | void iwl_leds_unregister(struct iwl_priv *priv); | ||
81 | void iwl_leds_background(struct iwl_priv *priv); | 61 | void iwl_leds_background(struct iwl_priv *priv); |
62 | int iwl_led_start(struct iwl_priv *priv); | ||
63 | int iwl_led_associate(struct iwl_priv *priv); | ||
64 | int iwl_led_disassociate(struct iwl_priv *priv); | ||
82 | 65 | ||
83 | #else | ||
84 | static inline int iwl_leds_register(struct iwl_priv *priv) | ||
85 | { | ||
86 | return 0; | ||
87 | } | ||
88 | static inline void iwl_leds_unregister(struct iwl_priv *priv) | ||
89 | { | ||
90 | } | ||
91 | static 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; |