Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[sfrench/cifs-2.6.git] / drivers / net / wireless / b43 / main.c
index 4c41cfe44f261494eceaa4080d85d7889344b42c..1521b1e78d2194309a0b12cd836925b07b9d5a85 100644 (file)
@@ -67,7 +67,12 @@ MODULE_AUTHOR("Gábor Stefanik");
 MODULE_LICENSE("GPL");
 
 MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
-
+MODULE_FIRMWARE("b43/ucode11.fw");
+MODULE_FIRMWARE("b43/ucode13.fw");
+MODULE_FIRMWARE("b43/ucode14.fw");
+MODULE_FIRMWARE("b43/ucode15.fw");
+MODULE_FIRMWARE("b43/ucode5.fw");
+MODULE_FIRMWARE("b43/ucode9.fw");
 
 static int modparam_bad_frames_preempt;
 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
@@ -102,6 +107,9 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
 module_param_named(verbose, b43_modparam_verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
 
+int b43_modparam_pio = B43_PIO_DEFAULT;
+module_param_named(pio, b43_modparam_pio, int, 0644);
+MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -110,6 +118,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 12),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
@@ -628,10 +637,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev)
 static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
 {
        /* slot_time is in usec. */
-       if (dev->phy.type != B43_PHYTYPE_G)
+       /* This test used to exit for all but a G PHY. */
+       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
                return;
-       b43_write16(dev, 0x684, 510 + slot_time);
-       b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+       b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
+       /* Shared memory location 0x0010 is the slot time and should be
+        * set to slot_time; however, this register is initially 0 and changing
+        * the value adversely affects the transmit rate for BCM4311
+        * devices. Until this behavior is unterstood, delete this step
+        *
+        * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
+        */
 }
 
 static void b43_short_slot_timing_enable(struct b43_wldev *dev)
@@ -835,8 +851,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
 }
 
 static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
-                       struct ieee80211_key_conf *keyconf, const u8 *addr,
-                       u32 iv32, u16 *phase1key)
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_key_conf *keyconf,
+                                  struct ieee80211_sta *sta,
+                                  u32 iv32, u16 *phase1key)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
@@ -845,19 +863,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
        if (B43_WARN_ON(!modparam_hwtkip))
                return;
 
-       mutex_lock(&wl->mutex);
-
+       /* This is only called from the RX path through mac80211, where
+        * our mutex is already locked. */
+       B43_WARN_ON(!mutex_is_locked(&wl->mutex));
        dev = wl->current_dev;
-       if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
-               goto out_unlock;
+       B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
 
        keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
 
        rx_tkip_phase1_write(dev, index, iv32, phase1key);
-       keymac_write(dev, index, addr);
-
-out_unlock:
-       mutex_unlock(&wl->mutex);
+       /* only pairwise TKIP keys are supported right now */
+       if (WARN_ON(!sta))
+               return;
+       keymac_write(dev, index, sta->addr);
 }
 
 static void do_key_write(struct b43_wldev *dev,
@@ -1786,8 +1804,9 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
                               dma_reason[4], dma_reason[5]);
                        b43err(dev->wl, "This device does not support DMA "
                               "on your system. Please use PIO instead.\n");
-                       b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in "
-                              "your kernel configuration.\n");
+                       /* Fall back to PIO transfers if we get fatal DMA errors! */
+                       dev->use_pio = 1;
+                       b43_controller_restart(dev, "DMA error");
                        return;
                }
                if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -3338,27 +3357,6 @@ out_unlock:
        return err;
 }
 
-static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
-                              struct ieee80211_tx_queue_stats *stats)
-{
-       struct b43_wl *wl = hw_to_b43_wl(hw);
-       struct b43_wldev *dev;
-       int err = -ENODEV;
-
-       mutex_lock(&wl->mutex);
-       dev = wl->current_dev;
-       if (dev && b43_status(dev) >= B43_STAT_STARTED) {
-               if (b43_using_pio_transfers(dev))
-                       b43_pio_get_tx_stats(dev, stats);
-               else
-                       b43_dma_get_tx_stats(dev, stats);
-               err = 0;
-       }
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
 static int b43_op_get_stats(struct ieee80211_hw *hw,
                            struct ieee80211_low_level_stats *stats)
 {
@@ -3562,6 +3560,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       if (conf_is_ht(conf))
+               phy->is_40mhz =
+                       (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
+       else
+               phy->is_40mhz = false;
+
        b43_mac_suspend(dev);
 
        if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
@@ -3963,6 +3967,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
        }
 
        /* We are ready to run. */
+       ieee80211_wake_queues(dev->wl->hw);
        b43_set_status(dev, B43_STAT_STARTED);
 
        /* Start data flow (TX/RX). */
@@ -4353,7 +4358,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 
        if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
            (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
-           B43_FORCE_PIO) {
+           dev->use_pio) {
                dev->__using_pio_transfers = 1;
                err = b43_pio_init(dev);
        } else {
@@ -4372,8 +4377,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 
        ieee80211_wake_queues(dev->wl->hw);
 
-       ieee80211_wake_queues(dev->wl->hw);
-
        b43_set_status(dev, B43_STAT_INITIALIZED);
 
 out:
@@ -4388,7 +4391,7 @@ err_busdown:
 }
 
 static int b43_op_add_interface(struct ieee80211_hw *hw,
-                               struct ieee80211_if_init_conf *conf)
+                               struct ieee80211_vif *vif)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
@@ -4396,24 +4399,24 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
 
        /* TODO: allow WDS/AP devices to coexist */
 
-       if (conf->type != NL80211_IFTYPE_AP &&
-           conf->type != NL80211_IFTYPE_MESH_POINT &&
-           conf->type != NL80211_IFTYPE_STATION &&
-           conf->type != NL80211_IFTYPE_WDS &&
-           conf->type != NL80211_IFTYPE_ADHOC)
+       if (vif->type != NL80211_IFTYPE_AP &&
+           vif->type != NL80211_IFTYPE_MESH_POINT &&
+           vif->type != NL80211_IFTYPE_STATION &&
+           vif->type != NL80211_IFTYPE_WDS &&
+           vif->type != NL80211_IFTYPE_ADHOC)
                return -EOPNOTSUPP;
 
        mutex_lock(&wl->mutex);
        if (wl->operating)
                goto out_mutex_unlock;
 
-       b43dbg(wl, "Adding Interface type %d\n", conf->type);
+       b43dbg(wl, "Adding Interface type %d\n", vif->type);
 
        dev = wl->current_dev;
        wl->operating = 1;
-       wl->vif = conf->vif;
-       wl->if_type = conf->type;
-       memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+       wl->vif = vif;
+       wl->if_type = vif->type;
+       memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
 
        b43_adjust_opmode(dev);
        b43_set_pretbtt(dev);
@@ -4428,17 +4431,17 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
 }
 
 static void b43_op_remove_interface(struct ieee80211_hw *hw,
-                                   struct ieee80211_if_init_conf *conf)
+                                   struct ieee80211_vif *vif)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
 
-       b43dbg(wl, "Removing Interface type %d\n", conf->type);
+       b43dbg(wl, "Removing Interface type %d\n", vif->type);
 
        mutex_lock(&wl->mutex);
 
        B43_WARN_ON(!wl->operating);
-       B43_WARN_ON(wl->vif != conf->vif);
+       B43_WARN_ON(wl->vif != vif);
        wl->vif = NULL;
 
        wl->operating = 0;
@@ -4579,7 +4582,6 @@ static const struct ieee80211_ops b43_hw_ops = {
        .set_key                = b43_op_set_key,
        .update_tkip_key        = b43_op_update_tkip_key,
        .get_stats              = b43_op_get_stats,
-       .get_tx_stats           = b43_op_get_tx_stats,
        .get_tsf                = b43_op_get_tsf,
        .set_tsf                = b43_op_set_tsf,
        .start                  = b43_op_start,
@@ -4823,6 +4825,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
        if (!wldev)
                goto out;
 
+       wldev->use_pio = b43_modparam_pio;
        wldev->dev = dev;
        wldev->wl = wl;
        b43_set_status(wldev, B43_STAT_UNINIT);