iwl-led.c revision bdfbf0924ab05e02d28e50bd2d5024097642a78d
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 <linux/wireless.h>
35ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <net/mac80211.h>
36ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <linux/etherdevice.h>
37ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include <asm/unaligned.h>
38ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
393e0d4cb12f6fd97193a455b49125398b2231c87cTomas Winkler#include "iwl-dev.h"
40ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas#include "iwl-core.h"
416b0184c4c62beb15443fd6dd5080f0e18941b67bWey-Yi Guy#include "iwl-agn.h"
42fee1247a30e5b3d48fe985b4a935eb6818f3b464Tomas Winkler#include "iwl-io.h"
43bdfbf0924ab05e02d28e50bd2d5024097642a78dEmmanuel Grumbach#include "iwl-trans.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{
74e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	iwl_write32(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		.callback = NULL,
108e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	};
109e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	u32 reg;
110e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
111e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	reg = iwl_read32(priv, CSR_LED_REG);
112e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
113e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
114e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
115bdfbf0924ab05e02d28e50bd2d5024097642a78dEmmanuel Grumbach	return trans_send_cmd(priv, &cmd);
116e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy}
117e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy
118ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler/* Set led pattern command */
1195ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic int iwl_led_cmd(struct iwl_priv *priv,
1205ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		       unsigned long on,
1215ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		       unsigned long off)
122ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
123ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler	struct iwl_led_cmd led_cmd = {
124e932a609e9759cc75db0c234f465a5fd6e20d362Johannes Berg		.id = IWL_LED_LINK,
125ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas		.interval = IWL_DEF_LED_INTRVL
126ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	};
1275ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	int ret;
128ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1295ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (!test_bit(STATUS_READY, &priv->status))
1305ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return -EBUSY;
131ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler
1325ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (priv->blink_on == on && priv->blink_off == off)
1335ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return 0;
1345ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1353782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy	if (off == 0) {
1363782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy		/* led is SOLID_ON */
1373782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy		on = IWL_LED_SOLID;
1383782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy	}
1393782cf4a04c272bdaa8476463b1d0208edbc505dWey-Yi Guy
1405ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
1417cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			priv->cfg->base_params->led_compensation);
1425ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_cmd.on = iwl_blink_compensation(priv, on,
1437cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				priv->cfg->base_params->led_compensation);
1445ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_cmd.off = iwl_blink_compensation(priv, off,
1457cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				priv->cfg->base_params->led_compensation);
146ec1a746042ea4c1c93065185897d6e8d3e7de894Tomas Winkler
147e79b1ca75bb48111e8d93fc576f50e24671f5f9dWey-Yi Guy	ret = iwl_send_led_cmd(priv, &led_cmd);
1485ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (!ret) {
1495ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->blink_on = on;
1505ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->blink_off = off;
1515ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	}
1525ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	return ret;
153ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
154ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1555ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic void iwl_led_brightness_set(struct led_classdev *led_cdev,
1565ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy				   enum led_brightness brightness)
157ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1585ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
1595ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	unsigned long on = 0;
160ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1615ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (brightness > 0)
1625ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		on = IWL_LED_SOLID;
163ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1645ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	iwl_led_cmd(priv, on, 0);
165ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
166ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1675ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guystatic int iwl_led_blink_set(struct led_classdev *led_cdev,
1685ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			     unsigned long *delay_on,
1695ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			     unsigned long *delay_off)
170ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1715ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led);
172a571ea4eb34adbf33bbaf4bdc6db6037b1a93e0fTomas Winkler
1735ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	return iwl_led_cmd(priv, *delay_on, *delay_off);
174ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
175ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
1765ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guyvoid iwl_leds_init(struct iwl_priv *priv)
177ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
1786b0184c4c62beb15443fd6dd5080f0e18941b67bWey-Yi Guy	int mode = iwlagn_mod_params.led_mode;
1795ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	int ret;
1805ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1815ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (mode == IWL_LED_DEFAULT)
1825ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		mode = priv->cfg->led_mode;
1835ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1845ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
1855ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy				   wiphy_name(priv->hw->wiphy));
1865ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.brightness_set = iwl_led_brightness_set;
1875ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.blink_set = iwl_led_blink_set;
1885ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led.max_brightness = 1;
1895ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
1905ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	switch (mode) {
1915ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_DEFAULT:
1925ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		WARN_ON(1);
1935ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
1945ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_BLINK:
1955ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->led.default_trigger =
1965ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			ieee80211_create_tpt_led_trigger(priv->hw,
1975ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy					IEEE80211_TPT_LEDTRIG_FL_CONNECTED,
1985ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy					iwl_blink, ARRAY_SIZE(iwl_blink));
1995ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
2005ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	case IWL_LED_RF_STATE:
2015ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		priv->led.default_trigger =
2025ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy			ieee80211_get_radio_led_name(priv->hw);
2035ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		break;
204ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	}
205ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
2063599d39a8525b01540e2c7ec8c5d0df0dd11d6cfEmmanuel Grumbach	ret = led_classdev_register(priv->bus.dev,
2073599d39a8525b01540e2c7ec8c5d0df0dd11d6cfEmmanuel Grumbach				    &priv->led);
2085ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (ret) {
2095ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		kfree(priv->led.name);
210ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas		return;
211ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas	}
212ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
2135ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	priv->led_registered = true;
214ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
215ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas
2165ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guyvoid iwl_leds_exit(struct iwl_priv *priv)
217ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas{
2185ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	if (!priv->led_registered)
2195ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy		return;
2205ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy
2215ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	led_classdev_unregister(&priv->led);
2225ed540aecc2aae92d5c97b9a9306a5bf88ad5574Wey-Yi Guy	kfree(priv->led.name);
223ab53d8af6772b22d4d68b1bcd74f7a5dba693983Mohamed Abbas}
224