/* The poll callback for the hardware button. */ void b43_rfkill_poll(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; bool enabled; bool brought_up = false; mutex_lock(&wl->mutex); if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { if (b43_bus_powerup(dev, 0)) { mutex_unlock(&wl->mutex); return; } b43_device_enable(dev, 0); brought_up = true; } enabled = b43_is_hw_radio_enabled(dev); if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; b43info(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); if (enabled != dev->phy.radio_on) b43_software_rfkill(dev, !enabled); } if (brought_up) { b43_device_disable(dev, 0); b43_bus_may_powerdown(dev); } mutex_unlock(&wl->mutex); }
/* Initialize a Broadcom 2055 N-radio */ static void b43_radio_init2055(struct b43_wldev *dev) { b43_radio_init2055_pre(dev); if (b43_status(dev) < B43_STAT_INITIALIZED) b2055_upload_inittab(dev, 0, 1); else b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0); b43_radio_init2055_post(dev); }
static inline void assert_mac_suspended(struct b43_wldev *dev) { if (!B43_DEBUG) return; if ((b43_status(dev) >= B43_STAT_INITIALIZED) && (dev->mac_suspended <= 0)) { b43dbg(dev->wl, "PHY/RADIO register access with " "enabled MAC.\n"); dump_stack(); } }
static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) { struct b43_sdio *sdio = sdio_get_drvdata(func); struct b43_wldev *dev = sdio->irq_handler_opaque; if (unlikely(b43_status(dev) < B43_STAT_STARTED)) return; sdio_release_host(func); sdio->irq_handler(dev); sdio_claim_host(func); }
/* Returns TRUE, if the radio is enabled in hardware. */ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) { if (dev->phy.rev >= 3) { if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) & B43_MMIO_RADIO_HWENABLED_HI_MASK)) return 1; } else { if (b43_status(dev) >= B43_STAT_STARTED && b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) & B43_MMIO_RADIO_HWENABLED_LO_MASK) return 1; } return 0; }
static void b43_leds_work(struct work_struct *work) { struct b43_leds *leds = container_of(work, struct b43_leds, work); struct b43_wl *wl = container_of(leds, struct b43_wl, leds); struct b43_wldev *dev; mutex_lock(&wl->mutex); dev = wl->current_dev; if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) goto out_unlock; b43_led_update(dev, &wl->leds.led_tx); b43_led_update(dev, &wl->leds.led_rx); b43_led_update(dev, &wl->leds.led_radio); b43_led_update(dev, &wl->leds.led_assoc); out_unlock: mutex_unlock(&wl->mutex); }
/* Callback from the LED subsystem. */ static void b43_led_brightness_set(struct led_classdev *led_dev, enum led_brightness brightness) { struct b43_led *led = container_of(led_dev, struct b43_led, led_dev); struct b43_wldev *dev = led->dev; bool radio_enabled; if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) return; /* Checking the radio-enabled status here is slightly racy, * but we want to avoid the locking overhead and we don't care * whether the LED has the wrong state for a second. */ radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable); if (brightness == LED_OFF || !radio_enabled) b43_led_turn_off(dev, led->index, led->activelow); else b43_led_turn_on(dev, led->index, led->activelow); }
/* Returns TRUE, if the radio is enabled in hardware. */ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) { if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) { if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) & B43_MMIO_RADIO_HWENABLED_HI_MASK)) return 1; } else { /* To prevent CPU fault on PPC, do not read a register * unless the interface is started; however, on resume * for hibernation, this routine is entered early. When * that happens, unconditionally return TRUE. */ if (b43_status(dev) < B43_STAT_STARTED) return 1; if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO) & B43_MMIO_RADIO_HWENABLED_LO_MASK) return 1; } return 0; }