Blame view
net/mac80211/led.c
9.97 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
f0706e828 [MAC80211]: Add m... |
2 3 |
/* * Copyright 2006, Johannes Berg <johannes@sipsolutions.net> |
f0706e828 [MAC80211]: Add m... |
4 5 6 7 |
*/ /* just for IFNAMSIZ */ #include <linux/if.h> |
5a0e3ad6a include cleanup: ... |
8 |
#include <linux/slab.h> |
bc3b2d7fb net: Add export.h... |
9 |
#include <linux/export.h> |
2c8dccc77 mac80211: rename ... |
10 |
#include "led.h" |
f0706e828 [MAC80211]: Add m... |
11 |
|
47f0c5022 [MAC80211]: Add a... |
12 13 |
void ieee80211_led_assoc(struct ieee80211_local *local, bool associated) { |
8d5c25856 mac80211: make LE... |
14 |
if (!atomic_read(&local->assoc_led_active)) |
47f0c5022 [MAC80211]: Add a... |
15 16 |
return; if (associated) |
8d5c25856 mac80211: make LE... |
17 |
led_trigger_event(&local->assoc_led, LED_FULL); |
47f0c5022 [MAC80211]: Add a... |
18 |
else |
8d5c25856 mac80211: make LE... |
19 |
led_trigger_event(&local->assoc_led, LED_OFF); |
47f0c5022 [MAC80211]: Add a... |
20 |
} |
cdcb006fb mac80211: Add rad... |
21 22 |
void ieee80211_led_radio(struct ieee80211_local *local, bool enabled) { |
8d5c25856 mac80211: make LE... |
23 |
if (!atomic_read(&local->radio_led_active)) |
cdcb006fb mac80211: Add rad... |
24 25 |
return; if (enabled) |
8d5c25856 mac80211: make LE... |
26 |
led_trigger_event(&local->radio_led, LED_FULL); |
cdcb006fb mac80211: Add rad... |
27 |
else |
8d5c25856 mac80211: make LE... |
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
led_trigger_event(&local->radio_led, LED_OFF); } void ieee80211_alloc_led_names(struct ieee80211_local *local) { local->rx_led.name = kasprintf(GFP_KERNEL, "%srx", wiphy_name(local->hw.wiphy)); local->tx_led.name = kasprintf(GFP_KERNEL, "%stx", wiphy_name(local->hw.wiphy)); local->assoc_led.name = kasprintf(GFP_KERNEL, "%sassoc", wiphy_name(local->hw.wiphy)); local->radio_led.name = kasprintf(GFP_KERNEL, "%sradio", wiphy_name(local->hw.wiphy)); } void ieee80211_free_led_names(struct ieee80211_local *local) { kfree(local->rx_led.name); kfree(local->tx_led.name); kfree(local->assoc_led.name); kfree(local->radio_led.name); } |
2282e125a leds: triggers: l... |
50 |
static int ieee80211_tx_led_activate(struct led_classdev *led_cdev) |
8d5c25856 mac80211: make LE... |
51 52 53 54 55 56 |
{ struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, tx_led); atomic_inc(&local->tx_led_active); |
2282e125a leds: triggers: l... |
57 58 |
return 0; |
8d5c25856 mac80211: make LE... |
59 60 61 62 63 64 65 66 67 68 |
} static void ieee80211_tx_led_deactivate(struct led_classdev *led_cdev) { struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, tx_led); atomic_dec(&local->tx_led_active); } |
2282e125a leds: triggers: l... |
69 |
static int ieee80211_rx_led_activate(struct led_classdev *led_cdev) |
8d5c25856 mac80211: make LE... |
70 71 72 73 74 75 |
{ struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, rx_led); atomic_inc(&local->rx_led_active); |
2282e125a leds: triggers: l... |
76 77 |
return 0; |
8d5c25856 mac80211: make LE... |
78 79 80 81 82 83 84 85 86 87 |
} static void ieee80211_rx_led_deactivate(struct led_classdev *led_cdev) { struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, rx_led); atomic_dec(&local->rx_led_active); } |
2282e125a leds: triggers: l... |
88 |
static int ieee80211_assoc_led_activate(struct led_classdev *led_cdev) |
8d5c25856 mac80211: make LE... |
89 90 91 92 93 94 |
{ struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, assoc_led); atomic_inc(&local->assoc_led_active); |
2282e125a leds: triggers: l... |
95 96 |
return 0; |
8d5c25856 mac80211: make LE... |
97 98 99 100 101 102 103 104 105 106 |
} static void ieee80211_assoc_led_deactivate(struct led_classdev *led_cdev) { struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, assoc_led); atomic_dec(&local->assoc_led_active); } |
2282e125a leds: triggers: l... |
107 |
static int ieee80211_radio_led_activate(struct led_classdev *led_cdev) |
8d5c25856 mac80211: make LE... |
108 109 110 111 112 113 |
{ struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, radio_led); atomic_inc(&local->radio_led_active); |
2282e125a leds: triggers: l... |
114 115 |
return 0; |
8d5c25856 mac80211: make LE... |
116 117 118 119 120 121 122 123 124 125 |
} static void ieee80211_radio_led_deactivate(struct led_classdev *led_cdev) { struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, radio_led); atomic_dec(&local->radio_led_active); } |
2282e125a leds: triggers: l... |
126 |
static int ieee80211_tpt_led_activate(struct led_classdev *led_cdev) |
8d5c25856 mac80211: make LE... |
127 128 129 130 131 132 |
{ struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, tpt_led); atomic_inc(&local->tpt_led_active); |
2282e125a leds: triggers: l... |
133 134 |
return 0; |
cdcb006fb mac80211: Add rad... |
135 |
} |
8d5c25856 mac80211: make LE... |
136 |
static void ieee80211_tpt_led_deactivate(struct led_classdev *led_cdev) |
fe67c913f mac80211: make LE... |
137 |
{ |
8d5c25856 mac80211: make LE... |
138 139 140 141 142 |
struct ieee80211_local *local = container_of(led_cdev->trigger, struct ieee80211_local, tpt_led); atomic_dec(&local->tpt_led_active); |
fe67c913f mac80211: make LE... |
143 |
} |
f0706e828 [MAC80211]: Add m... |
144 145 |
void ieee80211_led_init(struct ieee80211_local *local) { |
8d5c25856 mac80211: make LE... |
146 147 148 149 150 151 |
atomic_set(&local->rx_led_active, 0); local->rx_led.activate = ieee80211_rx_led_activate; local->rx_led.deactivate = ieee80211_rx_led_deactivate; if (local->rx_led.name && led_trigger_register(&local->rx_led)) { kfree(local->rx_led.name); local->rx_led.name = NULL; |
f0706e828 [MAC80211]: Add m... |
152 |
} |
8d5c25856 mac80211: make LE... |
153 154 155 156 157 158 |
atomic_set(&local->tx_led_active, 0); local->tx_led.activate = ieee80211_tx_led_activate; local->tx_led.deactivate = ieee80211_tx_led_deactivate; if (local->tx_led.name && led_trigger_register(&local->tx_led)) { kfree(local->tx_led.name); local->tx_led.name = NULL; |
47f0c5022 [MAC80211]: Add a... |
159 |
} |
8d5c25856 mac80211: make LE... |
160 161 162 163 164 165 |
atomic_set(&local->assoc_led_active, 0); local->assoc_led.activate = ieee80211_assoc_led_activate; local->assoc_led.deactivate = ieee80211_assoc_led_deactivate; if (local->assoc_led.name && led_trigger_register(&local->assoc_led)) { kfree(local->assoc_led.name); local->assoc_led.name = NULL; |
f0706e828 [MAC80211]: Add m... |
166 |
} |
cdcb006fb mac80211: Add rad... |
167 |
|
8d5c25856 mac80211: make LE... |
168 169 170 171 172 173 |
atomic_set(&local->radio_led_active, 0); local->radio_led.activate = ieee80211_radio_led_activate; local->radio_led.deactivate = ieee80211_radio_led_deactivate; if (local->radio_led.name && led_trigger_register(&local->radio_led)) { kfree(local->radio_led.name); local->radio_led.name = NULL; |
cdcb006fb mac80211: Add rad... |
174 |
} |
e1e540685 mac80211: add thr... |
175 |
|
8d5c25856 mac80211: make LE... |
176 |
atomic_set(&local->tpt_led_active, 0); |
e1e540685 mac80211: add thr... |
177 |
if (local->tpt_led_trigger) { |
8d5c25856 mac80211: make LE... |
178 179 180 |
local->tpt_led.activate = ieee80211_tpt_led_activate; local->tpt_led.deactivate = ieee80211_tpt_led_deactivate; if (led_trigger_register(&local->tpt_led)) { |
e1e540685 mac80211: add thr... |
181 182 183 184 |
kfree(local->tpt_led_trigger); local->tpt_led_trigger = NULL; } } |
f0706e828 [MAC80211]: Add m... |
185 186 187 188 |
} void ieee80211_led_exit(struct ieee80211_local *local) { |
8d5c25856 mac80211: make LE... |
189 190 191 192 193 194 195 196 |
if (local->radio_led.name) led_trigger_unregister(&local->radio_led); if (local->assoc_led.name) led_trigger_unregister(&local->assoc_led); if (local->tx_led.name) led_trigger_unregister(&local->tx_led); if (local->rx_led.name) led_trigger_unregister(&local->rx_led); |
e1e540685 mac80211: add thr... |
197 198 |
if (local->tpt_led_trigger) { |
8d5c25856 mac80211: make LE... |
199 |
led_trigger_unregister(&local->tpt_led); |
e1e540685 mac80211: add thr... |
200 201 |
kfree(local->tpt_led_trigger); } |
f0706e828 [MAC80211]: Add m... |
202 |
} |
f5c4ae079 mac80211: make LE... |
203 |
const char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw) |
cdcb006fb mac80211: Add rad... |
204 205 |
{ struct ieee80211_local *local = hw_to_local(hw); |
8d5c25856 mac80211: make LE... |
206 |
return local->radio_led.name; |
cdcb006fb mac80211: Add rad... |
207 208 |
} EXPORT_SYMBOL(__ieee80211_get_radio_led_name); |
f5c4ae079 mac80211: make LE... |
209 |
const char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw) |
47f0c5022 [MAC80211]: Add a... |
210 211 |
{ struct ieee80211_local *local = hw_to_local(hw); |
8d5c25856 mac80211: make LE... |
212 |
return local->assoc_led.name; |
47f0c5022 [MAC80211]: Add a... |
213 214 |
} EXPORT_SYMBOL(__ieee80211_get_assoc_led_name); |
f5c4ae079 mac80211: make LE... |
215 |
const char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw) |
f0706e828 [MAC80211]: Add m... |
216 217 |
{ struct ieee80211_local *local = hw_to_local(hw); |
8d5c25856 mac80211: make LE... |
218 |
return local->tx_led.name; |
f0706e828 [MAC80211]: Add m... |
219 220 |
} EXPORT_SYMBOL(__ieee80211_get_tx_led_name); |
f5c4ae079 mac80211: make LE... |
221 |
const char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw) |
f0706e828 [MAC80211]: Add m... |
222 223 |
{ struct ieee80211_local *local = hw_to_local(hw); |
8d5c25856 mac80211: make LE... |
224 |
return local->rx_led.name; |
f0706e828 [MAC80211]: Add m... |
225 226 |
} EXPORT_SYMBOL(__ieee80211_get_rx_led_name); |
e1e540685 mac80211: add thr... |
227 228 229 230 231 232 233 234 235 236 237 238 |
static unsigned long tpt_trig_traffic(struct ieee80211_local *local, struct tpt_led_trigger *tpt_trig) { unsigned long traffic, delta; traffic = tpt_trig->tx_bytes + tpt_trig->rx_bytes; delta = traffic - tpt_trig->prev_traffic; tpt_trig->prev_traffic = traffic; return DIV_ROUND_UP(delta, 1024 / 8); } |
34f11cd32 mac80211: Convert... |
239 |
static void tpt_trig_timer(struct timer_list *t) |
e1e540685 mac80211: add thr... |
240 |
{ |
34f11cd32 mac80211: Convert... |
241 242 |
struct tpt_led_trigger *tpt_trig = from_timer(tpt_trig, t, timer); struct ieee80211_local *local = tpt_trig->local; |
e1e540685 mac80211: add thr... |
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
struct led_classdev *led_cdev; unsigned long on, off, tpt; int i; if (!tpt_trig->running) return; mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); tpt = tpt_trig_traffic(local, tpt_trig); /* default to just solid on */ on = 1; off = 0; for (i = tpt_trig->blink_table_len - 1; i >= 0; i--) { if (tpt_trig->blink_table[i].throughput < 0 || tpt > tpt_trig->blink_table[i].throughput) { off = tpt_trig->blink_table[i].blink_time / 2; on = tpt_trig->blink_table[i].blink_time - off; break; } } |
658358cec mac80211: fix thr... |
266 267 |
read_lock(&local->tpt_led.leddev_list_lock); list_for_each_entry(led_cdev, &local->tpt_led.led_cdevs, trig_list) |
e1e540685 mac80211: add thr... |
268 |
led_blink_set(led_cdev, &on, &off); |
658358cec mac80211: fix thr... |
269 |
read_unlock(&local->tpt_led.leddev_list_lock); |
e1e540685 mac80211: add thr... |
270 |
} |
f5c4ae079 mac80211: make LE... |
271 272 273 274 275 |
const char * __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, unsigned int flags, const struct ieee80211_tpt_blink *blink_table, unsigned int blink_table_len) |
e1e540685 mac80211: add thr... |
276 277 278 279 280 281 282 283 284 285 286 287 288 |
{ struct ieee80211_local *local = hw_to_local(hw); struct tpt_led_trigger *tpt_trig; if (WARN_ON(local->tpt_led_trigger)) return NULL; tpt_trig = kzalloc(sizeof(struct tpt_led_trigger), GFP_KERNEL); if (!tpt_trig) return NULL; snprintf(tpt_trig->name, sizeof(tpt_trig->name), "%stpt", wiphy_name(local->hw.wiphy)); |
8d5c25856 mac80211: make LE... |
289 |
local->tpt_led.name = tpt_trig->name; |
e1e540685 mac80211: add thr... |
290 291 292 |
tpt_trig->blink_table = blink_table; tpt_trig->blink_table_len = blink_table_len; |
67408c8c7 mac80211: selecti... |
293 |
tpt_trig->want = flags; |
34f11cd32 mac80211: Convert... |
294 |
tpt_trig->local = local; |
e1e540685 mac80211: add thr... |
295 |
|
34f11cd32 mac80211: Convert... |
296 |
timer_setup(&tpt_trig->timer, tpt_trig_timer, 0); |
e1e540685 mac80211: add thr... |
297 298 299 300 301 302 |
local->tpt_led_trigger = tpt_trig; return tpt_trig->name; } EXPORT_SYMBOL(__ieee80211_create_tpt_led_trigger); |
67408c8c7 mac80211: selecti... |
303 |
static void ieee80211_start_tpt_led_trig(struct ieee80211_local *local) |
e1e540685 mac80211: add thr... |
304 305 |
{ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; |
67408c8c7 mac80211: selecti... |
306 |
if (tpt_trig->running) |
e1e540685 mac80211: add thr... |
307 308 309 310 311 |
return; /* reset traffic */ tpt_trig_traffic(local, tpt_trig); tpt_trig->running = true; |
34f11cd32 mac80211: Convert... |
312 |
tpt_trig_timer(&tpt_trig->timer); |
e1e540685 mac80211: add thr... |
313 314 |
mod_timer(&tpt_trig->timer, round_jiffies(jiffies + HZ)); } |
67408c8c7 mac80211: selecti... |
315 |
static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local) |
e1e540685 mac80211: add thr... |
316 317 318 |
{ struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; struct led_classdev *led_cdev; |
67408c8c7 mac80211: selecti... |
319 |
if (!tpt_trig->running) |
e1e540685 mac80211: add thr... |
320 321 322 323 |
return; tpt_trig->running = false; del_timer_sync(&tpt_trig->timer); |
658358cec mac80211: fix thr... |
324 325 |
read_lock(&local->tpt_led.leddev_list_lock); list_for_each_entry(led_cdev, &local->tpt_led.led_cdevs, trig_list) |
19cd67e2d leds: Rename led_... |
326 |
led_set_brightness(led_cdev, LED_OFF); |
658358cec mac80211: fix thr... |
327 |
read_unlock(&local->tpt_led.leddev_list_lock); |
e1e540685 mac80211: add thr... |
328 |
} |
67408c8c7 mac80211: selecti... |
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
void ieee80211_mod_tpt_led_trig(struct ieee80211_local *local, unsigned int types_on, unsigned int types_off) { struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger; bool allowed; WARN_ON(types_on & types_off); if (!tpt_trig) return; tpt_trig->active &= ~types_off; tpt_trig->active |= types_on; /* * Regardless of wanted state, we shouldn't blink when * the radio is disabled -- this can happen due to some * code ordering issues with __ieee80211_recalc_idle() * being called before the radio is started. */ allowed = tpt_trig->active & IEEE80211_TPT_LEDTRIG_FL_RADIO; if (!allowed || !(tpt_trig->active & tpt_trig->want)) ieee80211_stop_tpt_led_trig(local); else ieee80211_start_tpt_led_trig(local); } |