aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c68
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.h2
3 files changed, 50 insertions, 21 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index b1a24de0b7b0..6af0f3f71f3a 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -108,6 +108,7 @@ struct rtl8187_priv {
108 struct delayed_work work; 108 struct delayed_work work;
109 struct ieee80211_hw *dev; 109 struct ieee80211_hw *dev;
110#ifdef CONFIG_RTL8187_LEDS 110#ifdef CONFIG_RTL8187_LEDS
111 struct rtl8187_led led_radio;
111 struct rtl8187_led led_tx; 112 struct rtl8187_led led_tx;
112 struct rtl8187_led led_rx; 113 struct rtl8187_led led_rx;
113 struct delayed_work led_on; 114 struct delayed_work led_on;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index cf8a4a40fdf6..ded44c045eb2 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -105,19 +105,36 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
105 struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, 105 struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
106 led_dev); 106 led_dev);
107 struct ieee80211_hw *hw = led->dev; 107 struct ieee80211_hw *hw = led->dev;
108 struct rtl8187_priv *priv = hw->priv; 108 struct rtl8187_priv *priv;
109 static bool radio_on;
109 110
110 if (brightness == LED_OFF) { 111 if (!hw)
111 ieee80211_queue_delayed_work(hw, &priv->led_off, 0); 112 return;
112 /* The LED is off for 1/20 sec so that it just blinks. */ 113 priv = hw->priv;
113 ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20); 114 if (led->is_radio) {
114 } else 115 if (brightness == LED_FULL) {
115 ieee80211_queue_delayed_work(hw, &priv->led_on, 0); 116 ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
117 radio_on = true;
118 } else if (radio_on) {
119 radio_on = false;
120 cancel_delayed_work_sync(&priv->led_on);
121 ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
122 }
123 } else if (radio_on) {
124 if (brightness == LED_OFF) {
125 ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
126 /* The LED is off for 1/20 sec - it just blinks. */
127 ieee80211_queue_delayed_work(hw, &priv->led_on,
128 HZ / 20);
129 } else
130 ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
131 }
116} 132}
117 133
118static int rtl8187_register_led(struct ieee80211_hw *dev, 134static int rtl8187_register_led(struct ieee80211_hw *dev,
119 struct rtl8187_led *led, const char *name, 135 struct rtl8187_led *led, const char *name,
120 const char *default_trigger, u8 ledpin) 136 const char *default_trigger, u8 ledpin,
137 bool is_radio)
121{ 138{
122 int err; 139 int err;
123 struct rtl8187_priv *priv = dev->priv; 140 struct rtl8187_priv *priv = dev->priv;
@@ -128,6 +145,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev,
128 return -EINVAL; 145 return -EINVAL;
129 led->dev = dev; 146 led->dev = dev;
130 led->ledpin = ledpin; 147 led->ledpin = ledpin;
148 led->is_radio = is_radio;
131 strncpy(led->name, name, sizeof(led->name)); 149 strncpy(led->name, name, sizeof(led->name));
132 150
133 led->led_dev.name = led->name; 151 led->led_dev.name = led->name;
@@ -145,7 +163,11 @@ static int rtl8187_register_led(struct ieee80211_hw *dev,
145 163
146static void rtl8187_unregister_led(struct rtl8187_led *led) 164static void rtl8187_unregister_led(struct rtl8187_led *led)
147{ 165{
166 struct ieee80211_hw *hw = led->dev;
167 struct rtl8187_priv *priv = hw->priv;
168
148 led_classdev_unregister(&led->led_dev); 169 led_classdev_unregister(&led->led_dev);
170 flush_delayed_work(&priv->led_off);
149 led->dev = NULL; 171 led->dev = NULL;
150} 172}
151 173
@@ -183,33 +205,37 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
183 INIT_DELAYED_WORK(&priv->led_off, led_turn_off); 205 INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
184 206
185 snprintf(name, sizeof(name), 207 snprintf(name, sizeof(name),
208 "rtl8187-%s::radio", wiphy_name(dev->wiphy));
209 err = rtl8187_register_led(dev, &priv->led_radio, name,
210 ieee80211_get_radio_led_name(dev), ledpin, true);
211 if (err)
212 return;
213
214 snprintf(name, sizeof(name),
186 "rtl8187-%s::tx", wiphy_name(dev->wiphy)); 215 "rtl8187-%s::tx", wiphy_name(dev->wiphy));
187 err = rtl8187_register_led(dev, &priv->led_tx, name, 216 err = rtl8187_register_led(dev, &priv->led_tx, name,
188 ieee80211_get_tx_led_name(dev), ledpin); 217 ieee80211_get_tx_led_name(dev), ledpin, false);
189 if (err) 218 if (err)
190 goto error; 219 goto err_tx;
220
191 snprintf(name, sizeof(name), 221 snprintf(name, sizeof(name),
192 "rtl8187-%s::rx", wiphy_name(dev->wiphy)); 222 "rtl8187-%s::rx", wiphy_name(dev->wiphy));
193 err = rtl8187_register_led(dev, &priv->led_rx, name, 223 err = rtl8187_register_led(dev, &priv->led_rx, name,
194 ieee80211_get_rx_led_name(dev), ledpin); 224 ieee80211_get_rx_led_name(dev), ledpin, false);
195 if (!err) { 225 if (!err)
196 ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
197 return; 226 return;
198 } 227
199 /* registration of RX LED failed - unregister TX */ 228 /* registration of RX LED failed - unregister */
200 rtl8187_unregister_led(&priv->led_tx); 229 rtl8187_unregister_led(&priv->led_tx);
201error: 230err_tx:
202 /* If registration of either failed, cancel delayed work */ 231 rtl8187_unregister_led(&priv->led_radio);
203 cancel_delayed_work_sync(&priv->led_off);
204 cancel_delayed_work_sync(&priv->led_on);
205} 232}
206 233
207void rtl8187_leds_exit(struct ieee80211_hw *dev) 234void rtl8187_leds_exit(struct ieee80211_hw *dev)
208{ 235{
209 struct rtl8187_priv *priv = dev->priv; 236 struct rtl8187_priv *priv = dev->priv;
210 237
211 /* turn the LED off before exiting */ 238 rtl8187_unregister_led(&priv->led_radio);
212 ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
213 rtl8187_unregister_led(&priv->led_rx); 239 rtl8187_unregister_led(&priv->led_rx);
214 rtl8187_unregister_led(&priv->led_tx); 240 rtl8187_unregister_led(&priv->led_tx);
215 cancel_delayed_work_sync(&priv->led_off); 241 cancel_delayed_work_sync(&priv->led_off);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
index a0332027aead..efe8041bdda4 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.h
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h
@@ -47,6 +47,8 @@ struct rtl8187_led {
47 u8 ledpin; 47 u8 ledpin;
48 /* The unique name string for this LED device. */ 48 /* The unique name string for this LED device. */
49 char name[RTL8187_LED_MAX_NAME_LEN + 1]; 49 char name[RTL8187_LED_MAX_NAME_LEN + 1];
50 /* If the LED is radio or tx/rx */
51 bool is_radio;
50}; 52};
51 53
52void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); 54void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);