summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/led.c239
-rw-r--r--net/mac80211/led.h44
-rw-r--r--net/mac80211/main.c4
4 files changed, 194 insertions, 100 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ca00127497f8..241b74f3bd81 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1260,10 +1260,11 @@ struct ieee80211_local {
1260 struct mutex chanctx_mtx; 1260 struct mutex chanctx_mtx;
1261 1261
1262#ifdef CONFIG_MAC80211_LEDS 1262#ifdef CONFIG_MAC80211_LEDS
1263 struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; 1263 struct led_trigger tx_led, rx_led, assoc_led, radio_led;
1264 struct led_trigger tpt_led;
1265 atomic_t tx_led_active, rx_led_active, assoc_led_active;
1266 atomic_t radio_led_active, tpt_led_active;
1264 struct tpt_led_trigger *tpt_led_trigger; 1267 struct tpt_led_trigger *tpt_led_trigger;
1265 char tx_led_name[32], rx_led_name[32],
1266 assoc_led_name[32], radio_led_name[32];
1267#endif 1268#endif
1268 1269
1269#ifdef CONFIG_MAC80211_DEBUG_COUNTERS 1270#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 3e13eb86f85d..38f05565eaac 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -12,96 +12,175 @@
12#include <linux/export.h> 12#include <linux/export.h>
13#include "led.h" 13#include "led.h"
14 14
15#define MAC80211_BLINK_DELAY 50 /* ms */
16
17void ieee80211_led_rx(struct ieee80211_local *local)
18{
19 unsigned long led_delay = MAC80211_BLINK_DELAY;
20 if (unlikely(!local->rx_led))
21 return;
22 led_trigger_blink_oneshot(local->rx_led, &led_delay, &led_delay, 0);
23}
24
25void ieee80211_led_tx(struct ieee80211_local *local)
26{
27 unsigned long led_delay = MAC80211_BLINK_DELAY;
28 if (unlikely(!local->tx_led))
29 return;
30 led_trigger_blink_oneshot(local->tx_led, &led_delay, &led_delay, 0);
31}
32
33void ieee80211_led_assoc(struct ieee80211_local *local, bool associated) 15void ieee80211_led_assoc(struct ieee80211_local *local, bool associated)
34{ 16{
35 if (unlikely(!local->assoc_led)) 17 if (!atomic_read(&local->assoc_led_active))
36 return; 18 return;
37 if (associated) 19 if (associated)
38 led_trigger_event(local->assoc_led, LED_FULL); 20 led_trigger_event(&local->assoc_led, LED_FULL);
39 else 21 else
40 led_trigger_event(local->assoc_led, LED_OFF); 22 led_trigger_event(&local->assoc_led, LED_OFF);
41} 23}
42 24
43void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) 25void ieee80211_led_radio(struct ieee80211_local *local, bool enabled)
44{ 26{
45 if (unlikely(!local->radio_led)) 27 if (!atomic_read(&local->radio_led_active))
46 return; 28 return;
47 if (enabled) 29 if (enabled)
48 led_trigger_event(local->radio_led, LED_FULL); 30 led_trigger_event(&local->radio_led, LED_FULL);
49 else 31 else
50 led_trigger_event(local->radio_led, LED_OFF); 32 led_trigger_event(&local->radio_led, LED_OFF);
33}
34
35void ieee80211_alloc_led_names(struct ieee80211_local *local)
36{
37 local->rx_led.name = kasprintf(GFP_KERNEL, "%srx",
38 wiphy_name(local->hw.wiphy));
39 local->tx_led.name = kasprintf(GFP_KERNEL, "%stx",
40 wiphy_name(local->hw.wiphy));
41 local->assoc_led.name = kasprintf(GFP_KERNEL, "%sassoc",
42 wiphy_name(local->hw.wiphy));
43 local->radio_led.name = kasprintf(GFP_KERNEL, "%sradio",
44 wiphy_name(local->hw.wiphy));
45}
46
47void ieee80211_free_led_names(struct ieee80211_local *local)
48{
49 kfree(local->rx_led.name);
50 kfree(local->tx_led.name);
51 kfree(local->assoc_led.name);
52 kfree(local->radio_led.name);
53}
54
55static void ieee80211_tx_led_activate(struct led_classdev *led_cdev)
56{
57 struct ieee80211_local *local = container_of(led_cdev->trigger,
58 struct ieee80211_local,
59 tx_led);
60
61 atomic_inc(&local->tx_led_active);
62}
63
64static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev)
65{
66 struct ieee80211_local *local = container_of(led_cdev->trigger,
67 struct ieee80211_local,
68 tx_led);
69
70 atomic_dec(&local->tx_led_active);
71}
72
73static void ieee80211_rx_led_activate(struct led_classdev *led_cdev)
74{
75 struct ieee80211_local *local = container_of(led_cdev->trigger,
76 struct ieee80211_local,
77 rx_led);
78
79 atomic_inc(&local->rx_led_active);
80}
81
82static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev)
83{
84 struct ieee80211_local *local = container_of(led_cdev->trigger,
85 struct ieee80211_local,
86 rx_led);
87
88 atomic_dec(&local->rx_led_active);
89}
90
91static void ieee80211_assoc_led_activate(struct led_classdev *led_cdev)
92{
93 struct ieee80211_local *local = container_of(led_cdev->trigger,
94 struct ieee80211_local,
95 assoc_led);
96
97 atomic_inc(&local->assoc_led_active);
98}
99
100static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev)
101{
102 struct ieee80211_local *local = container_of(led_cdev->trigger,
103 struct ieee80211_local,
104 assoc_led);
105
106 atomic_dec(&local->assoc_led_active);
107}
108
109static void ieee80211_radio_led_activate(struct led_classdev *led_cdev)
110{
111 struct ieee80211_local *local = container_of(led_cdev->trigger,
112 struct ieee80211_local,
113 radio_led);
114
115 atomic_inc(&local->radio_led_active);
116}
117
118static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev)
119{
120 struct ieee80211_local *local = container_of(led_cdev->trigger,
121 struct ieee80211_local,
122 radio_led);
123
124 atomic_dec(&local->radio_led_active);
125}
126
127static void ieee80211_tpt_led_activate(struct led_classdev *led_cdev)
128{
129 struct ieee80211_local *local = container_of(led_cdev->trigger,
130 struct ieee80211_local,
131 tpt_led);
132
133 atomic_inc(&local->tpt_led_active);
51} 134}
52 135
53void ieee80211_led_names(struct ieee80211_local *local) 136static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev)
54{ 137{
55 snprintf(local->rx_led_name, sizeof(local->rx_led_name), 138 struct ieee80211_local *local = container_of(led_cdev->trigger,
56 "%srx", wiphy_name(local->hw.wiphy)); 139 struct ieee80211_local,
57 snprintf(local->tx_led_name, sizeof(local->tx_led_name), 140 tpt_led);
58 "%stx", wiphy_name(local->hw.wiphy)); 141
59 snprintf(local->assoc_led_name, sizeof(local->assoc_led_name), 142 atomic_dec(&local->tpt_led_active);
60 "%sassoc", wiphy_name(local->hw.wiphy));
61 snprintf(local->radio_led_name, sizeof(local->radio_led_name),
62 "%sradio", wiphy_name(local->hw.wiphy));
63} 143}
64 144
65void ieee80211_led_init(struct ieee80211_local *local) 145void ieee80211_led_init(struct ieee80211_local *local)
66{ 146{
67 local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 147 atomic_set(&local->rx_led_active, 0);
68 if (local->rx_led) { 148 local->rx_led.activate = ieee80211_rx_led_activate;
69 local->rx_led->name = local->rx_led_name; 149 local->rx_led.deactivate = ieee80211_rx_led_deactivate;
70 if (led_trigger_register(local->rx_led)) { 150 if (local->rx_led.name && led_trigger_register(&local->rx_led)) {
71 kfree(local->rx_led); 151 kfree(local->rx_led.name);
72 local->rx_led = NULL; 152 local->rx_led.name = NULL;
73 }
74 } 153 }
75 154
76 local->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 155 atomic_set(&local->tx_led_active, 0);
77 if (local->tx_led) { 156 local->tx_led.activate = ieee80211_tx_led_activate;
78 local->tx_led->name = local->tx_led_name; 157 local->tx_led.deactivate = ieee80211_tx_led_deactivate;
79 if (led_trigger_register(local->tx_led)) { 158 if (local->tx_led.name && led_trigger_register(&local->tx_led)) {
80 kfree(local->tx_led); 159 kfree(local->tx_led.name);
81 local->tx_led = NULL; 160 local->tx_led.name = NULL;
82 }
83 } 161 }
84 162
85 local->assoc_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 163 atomic_set(&local->assoc_led_active, 0);
86 if (local->assoc_led) { 164 local->assoc_led.activate = ieee80211_assoc_led_activate;
87 local->assoc_led->name = local->assoc_led_name; 165 local->assoc_led.deactivate = ieee80211_assoc_led_deactivate;
88 if (led_trigger_register(local->assoc_led)) { 166 if (local->assoc_led.name && led_trigger_register(&local->assoc_led)) {
89 kfree(local->assoc_led); 167 kfree(local->assoc_led.name);
90 local->assoc_led = NULL; 168 local->assoc_led.name = NULL;
91 }
92 } 169 }
93 170
94 local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 171 atomic_set(&local->radio_led_active, 0);
95 if (local->radio_led) { 172 local->radio_led.activate = ieee80211_radio_led_activate;
96 local->radio_led->name = local->radio_led_name; 173 local->radio_led.deactivate = ieee80211_radio_led_deactivate;
97 if (led_trigger_register(local->radio_led)) { 174 if (local->radio_led.name && led_trigger_register(&local->radio_led)) {
98 kfree(local->radio_led); 175 kfree(local->radio_led.name);
99 local->radio_led = NULL; 176 local->radio_led.name = NULL;
100 }
101 } 177 }
102 178
179 atomic_set(&local->tpt_led_active, 0);
103 if (local->tpt_led_trigger) { 180 if (local->tpt_led_trigger) {
104 if (led_trigger_register(&local->tpt_led_trigger->trig)) { 181 local->tpt_led.activate = ieee80211_tpt_led_activate;
182 local->tpt_led.deactivate = ieee80211_tpt_led_deactivate;
183 if (led_trigger_register(&local->tpt_led)) {
105 kfree(local->tpt_led_trigger); 184 kfree(local->tpt_led_trigger);
106 local->tpt_led_trigger = NULL; 185 local->tpt_led_trigger = NULL;
107 } 186 }
@@ -110,25 +189,17 @@ void ieee80211_led_init(struct ieee80211_local *local)
110 189
111void ieee80211_led_exit(struct ieee80211_local *local) 190void ieee80211_led_exit(struct ieee80211_local *local)
112{ 191{
113 if (local->radio_led) { 192 if (local->radio_led.name)
114 led_trigger_unregister(local->radio_led); 193 led_trigger_unregister(&local->radio_led);
115 kfree(local->radio_led); 194 if (local->assoc_led.name)
116 } 195 led_trigger_unregister(&local->assoc_led);
117 if (local->assoc_led) { 196 if (local->tx_led.name)
118 led_trigger_unregister(local->assoc_led); 197 led_trigger_unregister(&local->tx_led);
119 kfree(local->assoc_led); 198 if (local->rx_led.name)
120 } 199 led_trigger_unregister(&local->rx_led);
121 if (local->tx_led) {
122 led_trigger_unregister(local->tx_led);
123 kfree(local->tx_led);
124 }
125 if (local->rx_led) {
126 led_trigger_unregister(local->rx_led);
127 kfree(local->rx_led);
128 }
129 200
130 if (local->tpt_led_trigger) { 201 if (local->tpt_led_trigger) {
131 led_trigger_unregister(&local->tpt_led_trigger->trig); 202 led_trigger_unregister(&local->tpt_led);
132 kfree(local->tpt_led_trigger); 203 kfree(local->tpt_led_trigger);
133 } 204 }
134} 205}
@@ -137,7 +208,7 @@ const char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
137{ 208{
138 struct ieee80211_local *local = hw_to_local(hw); 209 struct ieee80211_local *local = hw_to_local(hw);
139 210
140 return local->radio_led_name; 211 return local->radio_led.name;
141} 212}
142EXPORT_SYMBOL(__ieee80211_get_radio_led_name); 213EXPORT_SYMBOL(__ieee80211_get_radio_led_name);
143 214
@@ -145,7 +216,7 @@ const char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
145{ 216{
146 struct ieee80211_local *local = hw_to_local(hw); 217 struct ieee80211_local *local = hw_to_local(hw);
147 218
148 return local->assoc_led_name; 219 return local->assoc_led.name;
149} 220}
150EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); 221EXPORT_SYMBOL(__ieee80211_get_assoc_led_name);
151 222
@@ -153,7 +224,7 @@ const char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw)
153{ 224{
154 struct ieee80211_local *local = hw_to_local(hw); 225 struct ieee80211_local *local = hw_to_local(hw);
155 226
156 return local->tx_led_name; 227 return local->tx_led.name;
157} 228}
158EXPORT_SYMBOL(__ieee80211_get_tx_led_name); 229EXPORT_SYMBOL(__ieee80211_get_tx_led_name);
159 230
@@ -161,7 +232,7 @@ const char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
161{ 232{
162 struct ieee80211_local *local = hw_to_local(hw); 233 struct ieee80211_local *local = hw_to_local(hw);
163 234
164 return local->rx_led_name; 235 return local->rx_led.name;
165} 236}
166EXPORT_SYMBOL(__ieee80211_get_rx_led_name); 237EXPORT_SYMBOL(__ieee80211_get_rx_led_name);
167 238
@@ -230,7 +301,7 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
230 snprintf(tpt_trig->name, sizeof(tpt_trig->name), 301 snprintf(tpt_trig->name, sizeof(tpt_trig->name),
231 "%stpt", wiphy_name(local->hw.wiphy)); 302 "%stpt", wiphy_name(local->hw.wiphy));
232 303
233 tpt_trig->trig.name = tpt_trig->name; 304 local->tpt_led.name = tpt_trig->name;
234 305
235 tpt_trig->blink_table = blink_table; 306 tpt_trig->blink_table = blink_table;
236 tpt_trig->blink_table_len = blink_table_len; 307 tpt_trig->blink_table_len = blink_table_len;
diff --git a/net/mac80211/led.h b/net/mac80211/led.h
index 89f4344f13b9..a7893a1ac98b 100644
--- a/net/mac80211/led.h
+++ b/net/mac80211/led.h
@@ -11,25 +11,42 @@
11#include <linux/leds.h> 11#include <linux/leds.h>
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13 13
14#define MAC80211_BLINK_DELAY 50 /* ms */
15
16static inline void ieee80211_led_rx(struct ieee80211_local *local)
17{
18#ifdef CONFIG_MAC80211_LEDS
19 unsigned long led_delay = MAC80211_BLINK_DELAY;
20
21 if (!atomic_read(&local->rx_led_active))
22 return;
23 led_trigger_blink_oneshot(&local->rx_led, &led_delay, &led_delay, 0);
24#endif
25}
26
27static inline void ieee80211_led_tx(struct ieee80211_local *local)
28{
29#ifdef CONFIG_MAC80211_LEDS
30 unsigned long led_delay = MAC80211_BLINK_DELAY;
31
32 if (!atomic_read(&local->tx_led_active))
33 return;
34 led_trigger_blink_oneshot(&local->tx_led, &led_delay, &led_delay, 0);
35#endif
36}
37
14#ifdef CONFIG_MAC80211_LEDS 38#ifdef CONFIG_MAC80211_LEDS
15void ieee80211_led_rx(struct ieee80211_local *local);
16void ieee80211_led_tx(struct ieee80211_local *local);
17void ieee80211_led_assoc(struct ieee80211_local *local, 39void ieee80211_led_assoc(struct ieee80211_local *local,
18 bool associated); 40 bool associated);
19void ieee80211_led_radio(struct ieee80211_local *local, 41void ieee80211_led_radio(struct ieee80211_local *local,
20 bool enabled); 42 bool enabled);
21void ieee80211_led_names(struct ieee80211_local *local); 43void ieee80211_alloc_led_names(struct ieee80211_local *local);
44void ieee80211_free_led_names(struct ieee80211_local *local);
22void ieee80211_led_init(struct ieee80211_local *local); 45void ieee80211_led_init(struct ieee80211_local *local);
23void ieee80211_led_exit(struct ieee80211_local *local); 46void ieee80211_led_exit(struct ieee80211_local *local);
24void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, 47void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local,
25 unsigned int types_on, unsigned int types_off); 48 unsigned int types_on, unsigned int types_off);
26#else 49#else
27static inline void ieee80211_led_rx(struct ieee80211_local *local)
28{
29}
30static inline void ieee80211_led_tx(struct ieee80211_local *local)
31{
32}
33static inline void ieee80211_led_assoc(struct ieee80211_local *local, 50static inline void ieee80211_led_assoc(struct ieee80211_local *local,
34 bool associated) 51 bool associated)
35{ 52{
@@ -38,7 +55,10 @@ static inline void ieee80211_led_radio(struct ieee80211_local *local,
38 bool enabled) 55 bool enabled)
39{ 56{
40} 57}
41static inline void ieee80211_led_names(struct ieee80211_local *local) 58static inline void ieee80211_alloc_led_names(struct ieee80211_local *local)
59{
60}
61static inline void ieee80211_free_led_names(struct ieee80211_local *local)
42{ 62{
43} 63}
44static inline void ieee80211_led_init(struct ieee80211_local *local) 64static inline void ieee80211_led_init(struct ieee80211_local *local)
@@ -58,7 +78,7 @@ static inline void
58ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes) 78ieee80211_tpt_led_trig_tx(struct ieee80211_local *local, __le16 fc, int bytes)
59{ 79{
60#ifdef CONFIG_MAC80211_LEDS 80#ifdef CONFIG_MAC80211_LEDS
61 if (local->tpt_led_trigger && ieee80211_is_data(fc)) 81 if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active))
62 local->tpt_led_trigger->tx_bytes += bytes; 82 local->tpt_led_trigger->tx_bytes += bytes;
63#endif 83#endif
64} 84}
@@ -67,7 +87,7 @@ static inline void
67ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes) 87ieee80211_tpt_led_trig_rx(struct ieee80211_local *local, __le16 fc, int bytes)
68{ 88{
69#ifdef CONFIG_MAC80211_LEDS 89#ifdef CONFIG_MAC80211_LEDS
70 if (local->tpt_led_trigger && ieee80211_is_data(fc)) 90 if (ieee80211_is_data(fc) && atomic_read(&local->tpt_led_active))
71 local->tpt_led_trigger->rx_bytes += bytes; 91 local->tpt_led_trigger->rx_bytes += bytes;
72#endif 92#endif
73} 93}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b144de971366..effe9d39cd7e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -643,7 +643,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
643 skb_queue_head_init(&local->skb_queue); 643 skb_queue_head_init(&local->skb_queue);
644 skb_queue_head_init(&local->skb_queue_unreliable); 644 skb_queue_head_init(&local->skb_queue_unreliable);
645 645
646 ieee80211_led_names(local); 646 ieee80211_alloc_led_names(local);
647 647
648 ieee80211_roc_setup(local); 648 ieee80211_roc_setup(local);
649 649
@@ -1207,6 +1207,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1207 1207
1208 sta_info_stop(local); 1208 sta_info_stop(local);
1209 1209
1210 ieee80211_free_led_names(local);
1211
1210 wiphy_free(local->hw.wiphy); 1212 wiphy_free(local->hw.wiphy);
1211} 1213}
1212EXPORT_SYMBOL(ieee80211_free_hw); 1214EXPORT_SYMBOL(ieee80211_free_hw);