X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fb43legacy%2Fmain.c;h=5f3f34e1dbfdc140f426c4660258ba54029780fd;hb=d55a4528f7f607ca2872fec18574bc8cec060f05;hp=92c03b0336a4f0374bfe1635928faff3225ae9de;hpb=5be3bda8987b12a87863c89b74b136fdb1f072db;p=linux-2.6 diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 92c03b0336..5f3f34e1db 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3,7 +3,7 @@ * Broadcom B43legacy wireless driver * * Copyright (c) 2005 Martin Langer - * Copyright (c) 2005-2007 Stefano Brivio + * Copyright (c) 2005-2008 Stefano Brivio * Copyright (c) 2005, 2006 Michael Buesch * Copyright (c) 2005 Danny van Dyk * Copyright (c) 2005 Andreas Jaggi @@ -60,6 +60,8 @@ MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); + #if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO) static int modparam_pio; module_param_named(pio, modparam_pio, int, 0444); @@ -225,8 +227,8 @@ static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset, B43legacy_WARN_ON(offset % 4 != 0); - status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); - if (status & B43legacy_SBF_XFER_REG_BYTESWAP) + status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + if (status & B43legacy_MACCTL_BE) val = swab32(val); b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset); @@ -434,9 +436,9 @@ static void b43legacy_time_lock(struct b43legacy_wldev *dev) { u32 status; - status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); - status |= B43legacy_SBF_TIME_UPDATE; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); + status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + status |= B43legacy_MACCTL_TBTTHOLD; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status); mmiowb(); } @@ -444,9 +446,9 @@ static void b43legacy_time_unlock(struct b43legacy_wldev *dev) { u32 status; - status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); - status &= ~B43legacy_SBF_TIME_UPDATE; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); + status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + status &= ~B43legacy_MACCTL_TBTTHOLD; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status); } static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf) @@ -647,7 +649,7 @@ void b43legacy_dummy_transmission(struct b43legacy_wldev *dev) b43legacy_ram_write(dev, i * 4, buffer[i]); /* dummy read follows */ - b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); + b43legacy_read32(dev, B43legacy_MMIO_MACCTL); b43legacy_write16(dev, 0x0568, 0x0000); b43legacy_write16(dev, 0x07C0, 0x0000); @@ -794,9 +796,9 @@ static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi) static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev) { b43legacy_jssi_write(dev, 0x7F7F7F7F); - b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, b43legacy_read32(dev, - B43legacy_MMIO_STATUS2_BITFIELD) + B43legacy_MMIO_MACCMD) | (1 << 4)); B43legacy_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel); @@ -895,8 +897,8 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev) { if (!dev->reg124_set_0x4) /*FIXME rename this variable*/ return; - b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, - b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD) + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, + b43legacy_read32(dev, B43legacy_MMIO_MACCMD) | 0x4); } @@ -976,7 +978,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, plcp.data = 0; b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); dur = ieee80211_generic_frame_duration(dev->wl->hw, - dev->wl->if_id, + dev->wl->vif, size, B43legacy_RATE_TO_100KBPS(rate)); /* Write PLCP in two parts and timing for packet transfer */ @@ -1042,7 +1044,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); dur = ieee80211_generic_frame_duration(dev->wl->hw, - dev->wl->if_id, + dev->wl->vif, *dest_size, B43legacy_RATE_TO_100KBPS(rate)); hdr->duration_id = dur; @@ -1106,9 +1108,9 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev) b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, B43legacy_CCK_RATE_11MB); - status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD); + status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); status |= 0x03; - b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, status); + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status); } static void b43legacy_refresh_templates(struct b43legacy_wldev *dev, @@ -1166,7 +1168,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) return; dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; - status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD); + status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) { /* ACK beacon IRQ. */ @@ -1182,14 +1184,14 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) b43legacy_write_beacon_template(dev, 0x68, 0x18, B43legacy_CCK_RATE_1MB); status |= 0x1; - b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status); } if (!(status & 0x2)) { b43legacy_write_beacon_template(dev, 0x468, 0x1A, B43legacy_CCK_RATE_1MB); status |= 0x2; - b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status); } } @@ -1221,8 +1223,15 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) if (unlikely(reason & B43legacy_IRQ_MAC_TXERR)) b43legacyerr(dev->wl, "MAC transmission error\n"); - if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) + if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) { b43legacyerr(dev->wl, "PHY transmission error\n"); + rmb(); + if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) { + b43legacyerr(dev->wl, "Too many PHY TX errors, " + "restarting the controller\n"); + b43legacy_controller_restart(dev, "PHY TX errors"); + } + } if (unlikely(merged_dma_reason & (B43legacy_DMAIRQ_FATALMASK | B43legacy_DMAIRQ_NONFATALMASK))) { @@ -1541,9 +1550,20 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) u16 fwpatch; u16 fwdate; u16 fwtime; - u32 tmp; + u32 tmp, macctl; int err = 0; + /* Jump the microcode PSM to offset 0 */ + macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN); + macctl |= B43legacy_MACCTL_PSM_JMP0; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); + /* Zero out all microcode PSM registers and shared memory. */ + for (i = 0; i < 64; i++) + b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0); + for (i = 0; i < 4096; i += 2) + b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0); + /* Upload Microcode. */ data = (__be32 *) (dev->fw.ucode->data + hdr_len); len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32); @@ -1574,7 +1594,12 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_ALL); - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0x00020402); + + /* Start the microcode PSM */ + macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + macctl &= ~B43legacy_MACCTL_PSM_JMP0; + macctl |= B43legacy_MACCTL_PSM_RUN; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); /* Wait for the microcode to load and respond */ i = 0; @@ -1587,9 +1612,13 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) b43legacyerr(dev->wl, "Microcode not responding\n"); b43legacy_print_fw_helptext(dev->wl); err = -ENODEV; - goto out; + goto error; + } + msleep_interruptible(50); + if (signal_pending(current)) { + err = -EINTR; + goto error; } - udelay(10); } /* dummy read follows */ b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); @@ -1610,19 +1639,26 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) " is supported. You must change your firmware" " files.\n"); b43legacy_print_fw_helptext(dev->wl); - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0); err = -EOPNOTSUPP; - goto out; + goto error; } - b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u " - "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, - (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, - (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F); + b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u " + "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, + (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF, + (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, + fwtime & 0x1F); dev->fw.rev = fwrev; dev->fw.patch = fwpatch; -out: + return 0; + +error: + macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + macctl &= ~B43legacy_MACCTL_PSM_RUN; + macctl |= B43legacy_MACCTL_PSM_JMP0; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); + return err; } @@ -1729,9 +1765,9 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev) u32 mask; u32 set; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, b43legacy_read32(dev, - B43legacy_MMIO_STATUS_BITFIELD) + B43legacy_MMIO_MACCTL) & 0xFFFF3FFF); b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, @@ -1791,14 +1827,14 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev) B43legacy_WARN_ON(dev->mac_suspended < 0); B43legacy_WARN_ON(irqs_disabled()); if (dev->mac_suspended == 0) { - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, b43legacy_read32(dev, - B43legacy_MMIO_STATUS_BITFIELD) - | B43legacy_SBF_MAC_ENABLED); + B43legacy_MMIO_MACCTL) + | B43legacy_MACCTL_ENABLED); b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_MAC_SUSPENDED); /* the next two are dummy reads */ - b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); + b43legacy_read32(dev, B43legacy_MMIO_MACCTL); b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); b43legacy_power_saving_ctl_bits(dev, -1, -1); @@ -1829,10 +1865,10 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev) dev->irq_savedstate = tmp; b43legacy_power_saving_ctl_bits(dev, -1, 1); - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, b43legacy_read32(dev, - B43legacy_MMIO_STATUS_BITFIELD) - & ~B43legacy_SBF_MAC_ENABLED); + B43legacy_MMIO_MACCTL) + & ~B43legacy_MACCTL_ENABLED); b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); for (i = 40; i; i--) { tmp = b43legacy_read32(dev, @@ -1988,7 +2024,6 @@ static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev, static void b43legacy_chip_exit(struct b43legacy_wldev *dev) { b43legacy_radio_turn_off(dev, 1); - b43legacy_leds_exit(dev); b43legacy_gpio_cleanup(dev); /* firmware is released later */ } @@ -2001,12 +2036,15 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) struct b43legacy_phy *phy = &dev->phy; int err; int tmp; - u32 value32; + u32 value32, macctl; u16 value16; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, - B43legacy_SBF_CORE_READY - | B43legacy_SBF_400); + /* Initialize the MAC control */ + macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED; + if (dev->phy.gmode) + macctl |= B43legacy_MACCTL_GMODE; + macctl |= B43legacy_MACCTL_INFRA; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); err = b43legacy_request_firmware(dev); if (err) @@ -2018,11 +2056,10 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) err = b43legacy_gpio_init(dev); if (err) goto out; /* firmware is released later */ - b43legacy_leds_init(dev); err = b43legacy_upload_initvals(dev); if (err) - goto err_leds_exit; + goto err_gpio_clean; b43legacy_radio_turn_on(dev); b43legacy_write16(dev, 0x03E6, 0x0000); @@ -2047,12 +2084,12 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) if (dev->dev->id.revision < 5) b43legacy_write32(dev, 0x010C, 0x01000000); - value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); - value32 &= ~B43legacy_SBF_MODE_NOTADHOC; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32); - value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); - value32 |= B43legacy_SBF_MODE_NOTADHOC; - b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32); + value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + value32 &= ~B43legacy_MACCTL_INFRA; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32); + value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + value32 |= B43legacy_MACCTL_INFRA; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32); if (b43legacy_using_pio(dev)) { b43legacy_write32(dev, 0x0210, 0x00000100); @@ -2094,6 +2131,9 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY, dev->dev->bus->chipco.fast_pwrup_delay); + /* PHY TX errors counter. */ + atomic_set(&phy->txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT); + B43legacy_WARN_ON(err != 0); b43legacydbg(dev->wl, "Chip initialized\n"); out: @@ -2101,8 +2141,7 @@ out: err_radio_off: b43legacy_radio_turn_off(dev, 1); -err_leds_exit: - b43legacy_leds_exit(dev); +err_gpio_clean: b43legacy_gpio_cleanup(dev); goto out; } @@ -2138,6 +2177,9 @@ static void b43legacy_periodic_every30sec(struct b43legacy_wldev *dev) static void b43legacy_periodic_every15sec(struct b43legacy_wldev *dev) { b43legacy_phy_xmitpower(dev); /* FIXME: unless scanning? */ + + atomic_set(&dev->phy.txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT); + wmb(); } static void do_periodic_work(struct b43legacy_wldev *dev) @@ -2637,7 +2679,7 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, } static int b43legacy_op_config_interface(struct ieee80211_hw *hw, - int if_id, + struct ieee80211_vif *vif, struct ieee80211_if_conf *conf) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); @@ -2648,7 +2690,7 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw, return -ENODEV; mutex_lock(&wl->mutex); spin_lock_irqsave(&wl->irq_lock, flags); - B43legacy_WARN_ON(wl->if_id != if_id); + B43legacy_WARN_ON(wl->vif != vif); if (conf->bssid) memcpy(wl->bssid, conf->bssid, ETH_ALEN); else @@ -2837,8 +2879,6 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig)); memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos)); - /* Flags */ - phy->locked = 0; /* Assume the radio is enabled. If it's not enabled, the state will * immediately get fixed on the first periodic work run. */ dev->radio_hw_enable = 1; @@ -2871,7 +2911,6 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, phy->lofcal = 0xFFFF; phy->initval = 0xFFFF; - spin_lock_init(&phy->lock); phy->interfmode = B43legacy_INTERFMODE_NONE; phy->channel = 0xFF; } @@ -2944,22 +2983,26 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) { struct b43legacy_wl *wl = dev->wl; struct b43legacy_phy *phy = &dev->phy; + u32 macctl; B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED); if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED) return; b43legacy_set_status(dev, B43legacy_STAT_UNINIT); + /* Stop the microcode PSM. */ + macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL); + macctl &= ~B43legacy_MACCTL_PSM_RUN; + macctl |= B43legacy_MACCTL_PSM_JMP0; + b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); + mutex_unlock(&wl->mutex); /* Must unlock as it would otherwise deadlock. No races here. * Cancel possibly pending workqueues. */ cancel_work_sync(&dev->restart_work); mutex_lock(&wl->mutex); - mutex_unlock(&dev->wl->mutex); - b43legacy_rfkill_exit(dev); - mutex_lock(&dev->wl->mutex); - + b43legacy_leds_exit(dev); b43legacy_rng_exit(dev->wl); b43legacy_pio_free(dev); b43legacy_dma_free(dev); @@ -3006,7 +3049,6 @@ static void prepare_phy_data_for_init(struct b43legacy_wldev *dev) /* Flags */ phy->calibrated = 0; - phy->locked = 0; if (phy->_lo_pairs) memset(phy->_lo_pairs, 0, @@ -3121,15 +3163,13 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0414, 0x01F4); ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ - memset(wl->bssid, 0, ETH_ALEN); - memset(wl->mac_addr, 0, ETH_ALEN); b43legacy_upload_card_macaddress(dev); b43legacy_security_init(dev); - b43legacy_rfkill_init(dev); b43legacy_rng_init(wl); b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); + b43legacy_leds_init(dev); out: return err; @@ -3170,7 +3210,7 @@ static int b43legacy_op_add_interface(struct ieee80211_hw *hw, dev = wl->current_dev; wl->operating = 1; - wl->if_id = conf->if_id; + wl->vif = conf->vif; wl->if_type = conf->type; memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); @@ -3198,7 +3238,8 @@ static void b43legacy_op_remove_interface(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); B43legacy_WARN_ON(!wl->operating); - B43legacy_WARN_ON(wl->if_id != conf->if_id); + B43legacy_WARN_ON(wl->vif != conf->vif); + wl->vif = NULL; wl->operating = 0; @@ -3217,13 +3258,27 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) struct b43legacy_wldev *dev = wl->current_dev; int did_init = 0; int err = 0; + bool do_rfkill_exit = 0; + + /* First register RFkill. + * LEDs that are registered later depend on it. */ + b43legacy_rfkill_init(dev); + + /* Kill all old instance specific information to make sure + * the card won't use it in the short timeframe between start + * and mac80211 reconfiguring it. */ + memset(wl->bssid, 0, ETH_ALEN); + memset(wl->mac_addr, 0, ETH_ALEN); + wl->filter_flags = 0; mutex_lock(&wl->mutex); if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { err = b43legacy_wireless_core_init(dev); - if (err) + if (err) { + do_rfkill_exit = 1; goto out_mutex_unlock; + } did_init = 1; } @@ -3232,6 +3287,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) if (err) { if (did_init) b43legacy_wireless_core_exit(dev); + do_rfkill_exit = 1; goto out_mutex_unlock; } } @@ -3239,6 +3295,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) out_mutex_unlock: mutex_unlock(&wl->mutex); + if (do_rfkill_exit) + b43legacy_rfkill_exit(dev); + return err; } @@ -3247,6 +3306,8 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; + b43legacy_rfkill_exit(dev); + mutex_lock(&wl->mutex); if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) b43legacy_wireless_core_stop(dev); @@ -3559,11 +3620,6 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus) bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; - - /* Convert Antennagain values to Q5.2 */ - if (bus->sprom.antenna_gain_bg == 0xFF) - bus->sprom.antenna_gain_bg = 2; /* if unset, use 2 dBm */ - bus->sprom.antenna_gain_bg <<= 2; } static void b43legacy_wireless_exit(struct ssb_device *dev, @@ -3753,6 +3809,32 @@ static struct ssb_driver b43legacy_ssb_driver = { .resume = b43legacy_resume, }; +static void b43legacy_print_driverinfo(void) +{ + const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "", + *feat_pio = "", *feat_dma = ""; + +#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT + feat_pci = "P"; +#endif +#ifdef CONFIG_B43LEGACY_LEDS + feat_leds = "L"; +#endif +#ifdef CONFIG_B43LEGACY_RFKILL + feat_rfkill = "R"; +#endif +#ifdef CONFIG_B43LEGACY_PIO + feat_pio = "I"; +#endif +#ifdef CONFIG_B43LEGACY_DMA + feat_dma = "D"; +#endif + printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " + "[ Features: %s%s%s%s%s, Firmware-ID: " + B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", + feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); +} + static int __init b43legacy_init(void) { int err; @@ -3763,6 +3845,8 @@ static int __init b43legacy_init(void) if (err) goto err_dfs_exit; + b43legacy_print_driverinfo(); + return err; err_dfs_exit: