18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci Broadcom B43 wireless driver 58c2ecf20Sopenharmony_ci LED control 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, 88c2ecf20Sopenharmony_ci Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it> 98c2ecf20Sopenharmony_ci Copyright (c) 2005-2007 Michael Buesch <m@bues.ch> 108c2ecf20Sopenharmony_ci Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> 118c2ecf20Sopenharmony_ci Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci*/ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "b43.h" 178c2ecf20Sopenharmony_ci#include "leds.h" 188c2ecf20Sopenharmony_ci#include "rfkill.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, 228c2ecf20Sopenharmony_ci bool activelow) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci u16 ctl; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL); 278c2ecf20Sopenharmony_ci if (activelow) 288c2ecf20Sopenharmony_ci ctl &= ~(1 << led_index); 298c2ecf20Sopenharmony_ci else 308c2ecf20Sopenharmony_ci ctl |= (1 << led_index); 318c2ecf20Sopenharmony_ci b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic void b43_led_turn_off(struct b43_wldev *dev, u8 led_index, 358c2ecf20Sopenharmony_ci bool activelow) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci u16 ctl; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL); 408c2ecf20Sopenharmony_ci if (activelow) 418c2ecf20Sopenharmony_ci ctl |= (1 << led_index); 428c2ecf20Sopenharmony_ci else 438c2ecf20Sopenharmony_ci ctl &= ~(1 << led_index); 448c2ecf20Sopenharmony_ci b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic void b43_led_update(struct b43_wldev *dev, 488c2ecf20Sopenharmony_ci struct b43_led *led) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci bool radio_enabled; 518c2ecf20Sopenharmony_ci bool turn_on; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (!led->wl) 548c2ecf20Sopenharmony_ci return; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci /* The led->state read is racy, but we don't care. In case we raced 598c2ecf20Sopenharmony_ci * with the brightness_set handler, we will be called again soon 608c2ecf20Sopenharmony_ci * to fixup our state. */ 618c2ecf20Sopenharmony_ci if (radio_enabled) 628c2ecf20Sopenharmony_ci turn_on = atomic_read(&led->state) != LED_OFF; 638c2ecf20Sopenharmony_ci else 648c2ecf20Sopenharmony_ci turn_on = false; 658c2ecf20Sopenharmony_ci if (turn_on == led->hw_state) 668c2ecf20Sopenharmony_ci return; 678c2ecf20Sopenharmony_ci led->hw_state = turn_on; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci if (turn_on) 708c2ecf20Sopenharmony_ci b43_led_turn_on(dev, led->index, led->activelow); 718c2ecf20Sopenharmony_ci else 728c2ecf20Sopenharmony_ci b43_led_turn_off(dev, led->index, led->activelow); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic void b43_leds_work(struct work_struct *work) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci struct b43_leds *leds = container_of(work, struct b43_leds, work); 788c2ecf20Sopenharmony_ci struct b43_wl *wl = container_of(leds, struct b43_wl, leds); 798c2ecf20Sopenharmony_ci struct b43_wldev *dev; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci mutex_lock(&wl->mutex); 828c2ecf20Sopenharmony_ci dev = wl->current_dev; 838c2ecf20Sopenharmony_ci if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) 848c2ecf20Sopenharmony_ci goto out_unlock; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci b43_led_update(dev, &wl->leds.led_tx); 878c2ecf20Sopenharmony_ci b43_led_update(dev, &wl->leds.led_rx); 888c2ecf20Sopenharmony_ci b43_led_update(dev, &wl->leds.led_radio); 898c2ecf20Sopenharmony_ci b43_led_update(dev, &wl->leds.led_assoc); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciout_unlock: 928c2ecf20Sopenharmony_ci mutex_unlock(&wl->mutex); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* Callback from the LED subsystem. */ 968c2ecf20Sopenharmony_cistatic void b43_led_brightness_set(struct led_classdev *led_dev, 978c2ecf20Sopenharmony_ci enum led_brightness brightness) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci struct b43_led *led = container_of(led_dev, struct b43_led, led_dev); 1008c2ecf20Sopenharmony_ci struct b43_wl *wl = led->wl; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci if (likely(!wl->leds.stop)) { 1038c2ecf20Sopenharmony_ci atomic_set(&led->state, brightness); 1048c2ecf20Sopenharmony_ci ieee80211_queue_work(wl->hw, &wl->leds.work); 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic int b43_register_led(struct b43_wldev *dev, struct b43_led *led, 1098c2ecf20Sopenharmony_ci const char *name, const char *default_trigger, 1108c2ecf20Sopenharmony_ci u8 led_index, bool activelow) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci int err; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci if (led->wl) 1158c2ecf20Sopenharmony_ci return -EEXIST; 1168c2ecf20Sopenharmony_ci if (!default_trigger) 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci led->wl = dev->wl; 1198c2ecf20Sopenharmony_ci led->index = led_index; 1208c2ecf20Sopenharmony_ci led->activelow = activelow; 1218c2ecf20Sopenharmony_ci strlcpy(led->name, name, sizeof(led->name)); 1228c2ecf20Sopenharmony_ci atomic_set(&led->state, 0); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci led->led_dev.name = led->name; 1258c2ecf20Sopenharmony_ci led->led_dev.default_trigger = default_trigger; 1268c2ecf20Sopenharmony_ci led->led_dev.brightness_set = b43_led_brightness_set; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci err = led_classdev_register(dev->dev->dev, &led->led_dev); 1298c2ecf20Sopenharmony_ci if (err) { 1308c2ecf20Sopenharmony_ci b43warn(dev->wl, "LEDs: Failed to register %s\n", name); 1318c2ecf20Sopenharmony_ci led->wl = NULL; 1328c2ecf20Sopenharmony_ci return err; 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci return 0; 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic void b43_unregister_led(struct b43_led *led) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci if (!led->wl) 1418c2ecf20Sopenharmony_ci return; 1428c2ecf20Sopenharmony_ci led_classdev_unregister(&led->led_dev); 1438c2ecf20Sopenharmony_ci led->wl = NULL; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic void b43_map_led(struct b43_wldev *dev, 1478c2ecf20Sopenharmony_ci u8 led_index, 1488c2ecf20Sopenharmony_ci enum b43_led_behaviour behaviour, 1498c2ecf20Sopenharmony_ci bool activelow) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct ieee80211_hw *hw = dev->wl->hw; 1528c2ecf20Sopenharmony_ci char name[B43_LED_MAX_NAME_LEN + 1]; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci /* Map the b43 specific LED behaviour value to the 1558c2ecf20Sopenharmony_ci * generic LED triggers. */ 1568c2ecf20Sopenharmony_ci switch (behaviour) { 1578c2ecf20Sopenharmony_ci case B43_LED_INACTIVE: 1588c2ecf20Sopenharmony_ci case B43_LED_OFF: 1598c2ecf20Sopenharmony_ci case B43_LED_ON: 1608c2ecf20Sopenharmony_ci break; 1618c2ecf20Sopenharmony_ci case B43_LED_ACTIVITY: 1628c2ecf20Sopenharmony_ci case B43_LED_TRANSFER: 1638c2ecf20Sopenharmony_ci case B43_LED_APTRANSFER: 1648c2ecf20Sopenharmony_ci snprintf(name, sizeof(name), 1658c2ecf20Sopenharmony_ci "b43-%s::tx", wiphy_name(hw->wiphy)); 1668c2ecf20Sopenharmony_ci b43_register_led(dev, &dev->wl->leds.led_tx, name, 1678c2ecf20Sopenharmony_ci ieee80211_get_tx_led_name(hw), 1688c2ecf20Sopenharmony_ci led_index, activelow); 1698c2ecf20Sopenharmony_ci snprintf(name, sizeof(name), 1708c2ecf20Sopenharmony_ci "b43-%s::rx", wiphy_name(hw->wiphy)); 1718c2ecf20Sopenharmony_ci b43_register_led(dev, &dev->wl->leds.led_rx, name, 1728c2ecf20Sopenharmony_ci ieee80211_get_rx_led_name(hw), 1738c2ecf20Sopenharmony_ci led_index, activelow); 1748c2ecf20Sopenharmony_ci break; 1758c2ecf20Sopenharmony_ci case B43_LED_RADIO_ALL: 1768c2ecf20Sopenharmony_ci case B43_LED_RADIO_A: 1778c2ecf20Sopenharmony_ci case B43_LED_RADIO_B: 1788c2ecf20Sopenharmony_ci case B43_LED_MODE_BG: 1798c2ecf20Sopenharmony_ci snprintf(name, sizeof(name), 1808c2ecf20Sopenharmony_ci "b43-%s::radio", wiphy_name(hw->wiphy)); 1818c2ecf20Sopenharmony_ci b43_register_led(dev, &dev->wl->leds.led_radio, name, 1828c2ecf20Sopenharmony_ci ieee80211_get_radio_led_name(hw), 1838c2ecf20Sopenharmony_ci led_index, activelow); 1848c2ecf20Sopenharmony_ci break; 1858c2ecf20Sopenharmony_ci case B43_LED_WEIRD: 1868c2ecf20Sopenharmony_ci case B43_LED_ASSOC: 1878c2ecf20Sopenharmony_ci snprintf(name, sizeof(name), 1888c2ecf20Sopenharmony_ci "b43-%s::assoc", wiphy_name(hw->wiphy)); 1898c2ecf20Sopenharmony_ci b43_register_led(dev, &dev->wl->leds.led_assoc, name, 1908c2ecf20Sopenharmony_ci ieee80211_get_assoc_led_name(hw), 1918c2ecf20Sopenharmony_ci led_index, activelow); 1928c2ecf20Sopenharmony_ci break; 1938c2ecf20Sopenharmony_ci default: 1948c2ecf20Sopenharmony_ci b43warn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n", 1958c2ecf20Sopenharmony_ci behaviour); 1968c2ecf20Sopenharmony_ci break; 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic void b43_led_get_sprominfo(struct b43_wldev *dev, 2018c2ecf20Sopenharmony_ci unsigned int led_index, 2028c2ecf20Sopenharmony_ci enum b43_led_behaviour *behaviour, 2038c2ecf20Sopenharmony_ci bool *activelow) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci u8 sprom[4]; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci sprom[0] = dev->dev->bus_sprom->gpio0; 2088c2ecf20Sopenharmony_ci sprom[1] = dev->dev->bus_sprom->gpio1; 2098c2ecf20Sopenharmony_ci sprom[2] = dev->dev->bus_sprom->gpio2; 2108c2ecf20Sopenharmony_ci sprom[3] = dev->dev->bus_sprom->gpio3; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci if ((sprom[0] & sprom[1] & sprom[2] & sprom[3]) == 0xff) { 2138c2ecf20Sopenharmony_ci /* There is no LED information in the SPROM 2148c2ecf20Sopenharmony_ci * for this LED. Hardcode it here. */ 2158c2ecf20Sopenharmony_ci *activelow = false; 2168c2ecf20Sopenharmony_ci switch (led_index) { 2178c2ecf20Sopenharmony_ci case 0: 2188c2ecf20Sopenharmony_ci *behaviour = B43_LED_ACTIVITY; 2198c2ecf20Sopenharmony_ci *activelow = true; 2208c2ecf20Sopenharmony_ci if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ) 2218c2ecf20Sopenharmony_ci *behaviour = B43_LED_RADIO_ALL; 2228c2ecf20Sopenharmony_ci break; 2238c2ecf20Sopenharmony_ci case 1: 2248c2ecf20Sopenharmony_ci *behaviour = B43_LED_RADIO_B; 2258c2ecf20Sopenharmony_ci if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK) 2268c2ecf20Sopenharmony_ci *behaviour = B43_LED_ASSOC; 2278c2ecf20Sopenharmony_ci break; 2288c2ecf20Sopenharmony_ci case 2: 2298c2ecf20Sopenharmony_ci *behaviour = B43_LED_RADIO_A; 2308c2ecf20Sopenharmony_ci break; 2318c2ecf20Sopenharmony_ci case 3: 2328c2ecf20Sopenharmony_ci *behaviour = B43_LED_OFF; 2338c2ecf20Sopenharmony_ci break; 2348c2ecf20Sopenharmony_ci default: 2358c2ecf20Sopenharmony_ci *behaviour = B43_LED_OFF; 2368c2ecf20Sopenharmony_ci B43_WARN_ON(1); 2378c2ecf20Sopenharmony_ci return; 2388c2ecf20Sopenharmony_ci } 2398c2ecf20Sopenharmony_ci } else { 2408c2ecf20Sopenharmony_ci /* keep LED disabled if no mapping is defined */ 2418c2ecf20Sopenharmony_ci if (sprom[led_index] == 0xff) 2428c2ecf20Sopenharmony_ci *behaviour = B43_LED_OFF; 2438c2ecf20Sopenharmony_ci else 2448c2ecf20Sopenharmony_ci *behaviour = sprom[led_index] & B43_LED_BEHAVIOUR; 2458c2ecf20Sopenharmony_ci *activelow = !!(sprom[led_index] & B43_LED_ACTIVELOW); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_civoid b43_leds_init(struct b43_wldev *dev) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci struct b43_led *led; 2528c2ecf20Sopenharmony_ci unsigned int i; 2538c2ecf20Sopenharmony_ci enum b43_led_behaviour behaviour; 2548c2ecf20Sopenharmony_ci bool activelow; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci /* Sync the RF-kill LED state (if we have one) with radio and switch states. */ 2578c2ecf20Sopenharmony_ci led = &dev->wl->leds.led_radio; 2588c2ecf20Sopenharmony_ci if (led->wl) { 2598c2ecf20Sopenharmony_ci if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) { 2608c2ecf20Sopenharmony_ci b43_led_turn_on(dev, led->index, led->activelow); 2618c2ecf20Sopenharmony_ci led->hw_state = true; 2628c2ecf20Sopenharmony_ci atomic_set(&led->state, 1); 2638c2ecf20Sopenharmony_ci } else { 2648c2ecf20Sopenharmony_ci b43_led_turn_off(dev, led->index, led->activelow); 2658c2ecf20Sopenharmony_ci led->hw_state = false; 2668c2ecf20Sopenharmony_ci atomic_set(&led->state, 0); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* Initialize TX/RX/ASSOC leds */ 2718c2ecf20Sopenharmony_ci led = &dev->wl->leds.led_tx; 2728c2ecf20Sopenharmony_ci if (led->wl) { 2738c2ecf20Sopenharmony_ci b43_led_turn_off(dev, led->index, led->activelow); 2748c2ecf20Sopenharmony_ci led->hw_state = false; 2758c2ecf20Sopenharmony_ci atomic_set(&led->state, 0); 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci led = &dev->wl->leds.led_rx; 2788c2ecf20Sopenharmony_ci if (led->wl) { 2798c2ecf20Sopenharmony_ci b43_led_turn_off(dev, led->index, led->activelow); 2808c2ecf20Sopenharmony_ci led->hw_state = false; 2818c2ecf20Sopenharmony_ci atomic_set(&led->state, 0); 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci led = &dev->wl->leds.led_assoc; 2848c2ecf20Sopenharmony_ci if (led->wl) { 2858c2ecf20Sopenharmony_ci b43_led_turn_off(dev, led->index, led->activelow); 2868c2ecf20Sopenharmony_ci led->hw_state = false; 2878c2ecf20Sopenharmony_ci atomic_set(&led->state, 0); 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci /* Initialize other LED states. */ 2918c2ecf20Sopenharmony_ci for (i = 0; i < B43_MAX_NR_LEDS; i++) { 2928c2ecf20Sopenharmony_ci b43_led_get_sprominfo(dev, i, &behaviour, &activelow); 2938c2ecf20Sopenharmony_ci switch (behaviour) { 2948c2ecf20Sopenharmony_ci case B43_LED_OFF: 2958c2ecf20Sopenharmony_ci b43_led_turn_off(dev, i, activelow); 2968c2ecf20Sopenharmony_ci break; 2978c2ecf20Sopenharmony_ci case B43_LED_ON: 2988c2ecf20Sopenharmony_ci b43_led_turn_on(dev, i, activelow); 2998c2ecf20Sopenharmony_ci break; 3008c2ecf20Sopenharmony_ci default: 3018c2ecf20Sopenharmony_ci /* Leave others as-is. */ 3028c2ecf20Sopenharmony_ci break; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci dev->wl->leds.stop = 0; 3078c2ecf20Sopenharmony_ci} 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_civoid b43_leds_exit(struct b43_wldev *dev) 3108c2ecf20Sopenharmony_ci{ 3118c2ecf20Sopenharmony_ci struct b43_leds *leds = &dev->wl->leds; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci b43_led_turn_off(dev, leds->led_tx.index, leds->led_tx.activelow); 3148c2ecf20Sopenharmony_ci b43_led_turn_off(dev, leds->led_rx.index, leds->led_rx.activelow); 3158c2ecf20Sopenharmony_ci b43_led_turn_off(dev, leds->led_assoc.index, leds->led_assoc.activelow); 3168c2ecf20Sopenharmony_ci b43_led_turn_off(dev, leds->led_radio.index, leds->led_radio.activelow); 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_civoid b43_leds_stop(struct b43_wldev *dev) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci struct b43_leds *leds = &dev->wl->leds; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci leds->stop = 1; 3248c2ecf20Sopenharmony_ci cancel_work_sync(&leds->work); 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_civoid b43_leds_register(struct b43_wldev *dev) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci unsigned int i; 3308c2ecf20Sopenharmony_ci enum b43_led_behaviour behaviour; 3318c2ecf20Sopenharmony_ci bool activelow; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci INIT_WORK(&dev->wl->leds.work, b43_leds_work); 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci /* Register the LEDs to the LED subsystem. */ 3368c2ecf20Sopenharmony_ci for (i = 0; i < B43_MAX_NR_LEDS; i++) { 3378c2ecf20Sopenharmony_ci b43_led_get_sprominfo(dev, i, &behaviour, &activelow); 3388c2ecf20Sopenharmony_ci b43_map_led(dev, i, behaviour, activelow); 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_civoid b43_leds_unregister(struct b43_wl *wl) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci struct b43_leds *leds = &wl->leds; 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci b43_unregister_led(&leds->led_tx); 3478c2ecf20Sopenharmony_ci b43_unregister_led(&leds->led_rx); 3488c2ecf20Sopenharmony_ci b43_unregister_led(&leds->led_assoc); 3498c2ecf20Sopenharmony_ci b43_unregister_led(&leds->led_radio); 3508c2ecf20Sopenharmony_ci} 351