iwl-led.c revision 3862241945026a8fa165ab73c57739df77b8e1fb
1ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas/******************************************************************************
2ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
3901069c71415a76d731857ccda814e18ded062f7Wey-Yi Guy * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
5ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * This program is free software; you can redistribute it and/or modify it
6ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * under the terms of version 2 of the GNU General Public License as
7ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * published by the Free Software Foundation.
8ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
9ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * This program is distributed in the hope that it will be useful, but WITHOUT
10ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * more details.
13ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
14ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * You should have received a copy of the GNU General Public License along with
15ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * this program; if not, write to the Free Software Foundation, Inc.,
16ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
18ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * The full GNU General Public License is included in this distribution in the
19ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * file called LICENSE.
20ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
21ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * Contact Information:
22759ef89fb096c4a6ef078d3cfd5682ac037bd789Winkler, Tomas *  Intel Linux Wireless <ilw@linux.intel.com>
23ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *
25ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas *****************************************************************************/
26ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
27ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
28ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/kernel.h>
29ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/module.h>
30ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/init.h>
31ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/delay.h>
32ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/skbuff.h>
33ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/netdevice.h>
34ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <net/mac80211.h>
35ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/etherdevice.h>
36ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <asm/unaligned.h>
37ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
383e0d4cb12f6fd97193a455b49125398b2231c87cTomas Winkler#include "iwl-dev.h"
39ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include "iwl-core.h"
406b0184c4c62beb15443fd6dd5080f0e18941b67bWey-Yi Guy#include "iwl-agn.h"
41fee1247a30e5b3d48fe985b4a935eb6818f3b464Tomas Winkler#include "iwl-io.h"
42bdfbf0924ab05e02d28e50bd2d5024097642a78dEmmanuel Grumbach#include "iwl-trans.h"
4348f20d354e729afcfb29ff41aca7583ebb94613dEmmanuel Grumbach#include "iwl-shared.h"
44ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
453782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy/* Throughput		OFF time(ms)	ON time (ms)
463782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>300			25		25
473782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>200 to 300		40		40
483782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>100 to 200		55		55
493782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>70 to 100		65		65
503782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>50 to 70		75		75
513782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>20 to 50		85		85
523782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>10 to 20		95		95
533782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>5 to 10		110		110
543782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>1 to 5			130		130
553782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	>0 to 1			167		167
563782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy *	<=0					SOLID ON
573782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy */
585ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic const struct ieee80211_tpt_blink iwl_blink[] = {
593782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy	{ .throughput = 0, .blink_time = 334 },
605ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 1 * 1024 - 1, .blink_time = 260 },
615ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 5 * 1024 - 1, .blink_time = 220 },
625ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 10 * 1024 - 1, .blink_time = 190 },
635ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 20 * 1024 - 1, .blink_time = 170 },
645ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 50 * 1024 - 1, .blink_time = 150 },
655ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 70 * 1024 - 1, .blink_time = 130 },
665ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 100 * 1024 - 1, .blink_time = 110 },
675ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 200 * 1024 - 1, .blink_time = 80 },
685ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	{ .throughput = 300 * 1024 - 1, .blink_time = 50 },
69ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas};
70ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
71e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy/* Set led register off */
72e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guyvoid iwlagn_led_enable(struct iwl_priv *priv)
73e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy{
7483ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach	iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON);
75e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy}
76e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
77f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy/*
78f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy * Adjust led blink rate to compensate on a MAC Clock difference on every HW
796bb64697ed58909985487e885c269dafd09583f1Wey-Yi Guy * Led blink rate analysis showed an average deviation of 20% on 5000 series
806bb64697ed58909985487e885c269dafd09583f1Wey-Yi Guy * and up.
81f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy * Need to compensate on the led on/off time per HW according to the deviation
82f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy * to achieve the desired led frequency
83f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy * The calculation is: (100-averageDeviation)/100 * blinkTime
84f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy * For code efficiency the calculation will be:
85f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy *     compensation = (100 - averageDeviation) * 64 / 100
86f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy *     NewBlinkTime = (compensation * BlinkTime) / 64
87f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy */
88f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guystatic inline u8 iwl_blink_compensation(struct iwl_priv *priv,
89f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy				    u8 time, u16 compensation)
90f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy{
91f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy	if (!compensation) {
92f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy		IWL_ERR(priv, "undefined blink compensation: "
93f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy			"use pre-defined blinking time\n");
94f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy		return time;
95f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy	}
96f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy
97f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy	return (u8)((time * compensation) >> 6);
98f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy}
99f2d0d0e2bab7a325071dbaba3bef51c90868e1e6Wey-Yi Guy
100e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guystatic int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
101e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy{
102e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	struct iwl_host_cmd cmd = {
103e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy		.id = REPLY_LEDS_CMD,
1043fa507386dc4cdf731344cb9361e9cca373cedb9Johannes Berg		.len = { sizeof(struct iwl_led_cmd), },
1053fa507386dc4cdf731344cb9361e9cca373cedb9Johannes Berg		.data = { led_cmd, },
106e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy		.flags = CMD_ASYNC,
107e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	};
108e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	u32 reg;
109e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
11083ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach	reg = iwl_read32(bus(priv), CSR_LED_REG);
111e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
11283ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach		iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
113e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
114e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach	return iwl_trans_send_cmd(trans(priv), &cmd);
115e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy}
116e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
117ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler/* Set led pattern command */
1185ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic int iwl_led_cmd(struct iwl_priv *priv,
1195ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		       unsigned long on,
1205ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		       unsigned long off)
121ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
122ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler	struct iwl_led_cmd led_cmd = {
123e932a609e9759cc75db0c234f465a5fd6e20d362Johannes Berg		.id = IWL_LED_LINK,
124ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas		.interval = IWL_DEF_LED_INTRVL
125ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	};
1265ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	int ret;
127ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
12863013ae30159c90d2a873e20e680e7810fa533faEmmanuel Grumbach	if (!test_bit(STATUS_READY, &priv->shrd->status))
1295ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return -EBUSY;
130ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler
1315ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (priv->blink_on == on && priv->blink_off == off)
1325ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return 0;
1335ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1343782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy	if (off == 0) {
1353782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy		/* led is SOLID_ON */
1363782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy		on = IWL_LED_SOLID;
1373782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy	}
1383782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy
1395ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
1403862241945026a8fa165ab73c57739df77b8e1fbDon Fry			cfg(priv)->base_params->led_compensation);
1415ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_cmd.on = iwl_blink_compensation(priv, on,
1423862241945026a8fa165ab73c57739df77b8e1fbDon Fry				cfg(priv)->base_params->led_compensation);
1435ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_cmd.off = iwl_blink_compensation(priv, off,
1443862241945026a8fa165ab73c57739df77b8e1fbDon Fry				cfg(priv)->base_params->led_compensation);
145ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler
146e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	ret = iwl_send_led_cmd(priv, &led_cmd);
1475ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (!ret) {
1485ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->blink_on = on;
1495ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->blink_off = off;
1505ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	}
1515ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	return ret;
152ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
153ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1545ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic void iwl_led_brightness_set(struct led_classdev *led_cdev,
1555ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy				   enum led_brightness brightness)
156ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1575ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
1585ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	unsigned long on = 0;
159ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1605ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (brightness > 0)
1615ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		on = IWL_LED_SOLID;
162ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1635ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	iwl_led_cmd(priv, on, 0);
164ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
165ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1665ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic int iwl_led_blink_set(struct led_classdev *led_cdev,
1675ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			     unsigned long *delay_on,
1685ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			     unsigned long *delay_off)
169ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1705ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
171a571ea4eb34adbf33bbaf4bdc6db6037b1a93e0fTomas Winkler
1725ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	return iwl_led_cmd(priv, *delay_on, *delay_off);
173ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
174ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1755ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guyvoid iwl_leds_init(struct iwl_priv *priv)
176ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1776b0184c4c62beb15443fd6dd5080f0e18941b67bWey-Yi Guy	int mode = iwlagn_mod_params.led_mode;
1785ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	int ret;
1795ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1805ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (mode == IWL_LED_DEFAULT)
1813862241945026a8fa165ab73c57739df77b8e1fbDon Fry		mode = cfg(priv)->led_mode;
1825ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1835ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
1845ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy				   wiphy_name(priv->hw->wiphy));
1855ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.brightness_set = iwl_led_brightness_set;
1865ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.blink_set = iwl_led_blink_set;
1875ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.max_brightness = 1;
1885ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1895ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	switch (mode) {
1905ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_DEFAULT:
1915ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		WARN_ON(1);
1925ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
1935ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_BLINK:
1945ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->led.default_trigger =
1955ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			ieee80211_create_tpt_led_trigger(priv->hw,
1965ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy					IEEE80211_TPT_LEDTRIG_FL_CONNECTED,
1975ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy					iwl_blink, ARRAY_SIZE(iwl_blink));
1985ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
1995ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_RF_STATE:
2005ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->led.default_trigger =
2015ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			ieee80211_get_radio_led_name(priv->hw);
2025ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
203ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	}
204ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
20526bfc0cfdb6b9a12911f8dde4f96c958aef357aeDon Fry	ret = led_classdev_register(bus(priv)->dev, &priv->led);
2065ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (ret) {
2075ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		kfree(priv->led.name);
208ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas		return;
209ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	}
210ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
2115ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led_registered = true;
212ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
213ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
2145ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guyvoid iwl_leds_exit(struct iwl_priv *priv)
215ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
2165ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (!priv->led_registered)
2175ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return;
2185ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
2195ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_classdev_unregister(&priv->led);
2205ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	kfree(priv->led.name);
221ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
222