]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'wireless-drivers-next-for-davem-2015-03-06' of git://git.kernel.org/pub...
authorDavid S. Miller <davem@davemloft.net>
Fri, 6 Mar 2015 20:46:08 +0000 (15:46 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Mar 2015 20:46:08 +0000 (15:46 -0500)
Major changes:

brcmfmac:

* sdio improvements
* add a debugfs file so users can provide us all the revinfo we could
  ask for

iwlwifi:

* add triggers for firmware dump collection
* remove support for -9.ucode
* new statitics API
* rate control improvements

ath9k:

* add per-vif TX power capability
* BT coexistance fixes

ath10k:

* qca6174: enable STA transmit beamforming (TxBF) support
* disable multi-vif power save by default

bcma:

* enable support for PCIe Gen 2 host devices

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/init.c

index 6c364bb989241f555963f5898ef1f001d2fa7cfd,8ef64a6d931e68af78c455a8476de2e80f23a31f..5d2db069d46e439b83e77557940d4e854da91399
@@@ -611,7 -611,7 +611,7 @@@ static int ath10k_monitor_vdev_start(st
  
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
                            vdev_id, ret);
                return ret;
        }
@@@ -658,7 -658,7 +658,7 @@@ static int ath10k_monitor_vdev_stop(str
  
        ret = ath10k_vdev_setup_sync(ar);
        if (ret)
-               ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
                            ar->monitor_vdev_id, ret);
  
        ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
@@@ -927,8 -927,9 +927,9 @@@ static int ath10k_vdev_start_restart(st
  
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n",
-                           arg.vdev_id, ret);
+               ath10k_warn(ar,
+                           "failed to synchronize setup for vdev %i restart %d: %d\n",
+                           arg.vdev_id, restart, ret);
                return ret;
        }
  
@@@ -966,7 -967,7 +967,7 @@@ static int ath10k_vdev_stop(struct ath1
  
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronize setup for vdev %i stop: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@@ -1182,7 -1183,7 +1183,7 @@@ static void ath10k_control_ibss(struct 
                if (is_zero_ether_addr(arvif->bssid))
                        return;
  
 -              memset(arvif->bssid, 0, ETH_ALEN);
 +              eth_zero_addr(arvif->bssid);
  
                return;
        }
@@@ -1253,6 -1254,20 +1254,20 @@@ static int ath10k_mac_vif_recalc_ps_pol
        return 0;
  }
  
+ static int ath10k_mac_ps_vif_count(struct ath10k *ar)
+ {
+       struct ath10k_vif *arvif;
+       int num = 0;
+       lockdep_assert_held(&ar->conf_mutex);
+       list_for_each_entry(arvif, &ar->arvifs, list)
+               if (arvif->ps)
+                       num++;
+       return num;
+ }
  static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
  {
        struct ath10k *ar = arvif->ar;
        enum wmi_sta_ps_mode psmode;
        int ret;
        int ps_timeout;
+       bool enable_ps;
  
        lockdep_assert_held(&arvif->ar->conf_mutex);
  
        if (arvif->vif->type != NL80211_IFTYPE_STATION)
                return 0;
  
-       if (vif->bss_conf.ps) {
+       enable_ps = arvif->ps;
+       if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
+           !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
+                     ar->fw_features)) {
+               ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
+                           arvif->vdev_id);
+               enable_ps = false;
+       }
+       if (enable_ps) {
                psmode = WMI_STA_PS_MODE_ENABLED;
                param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
  
@@@ -1781,6 -1807,68 +1807,68 @@@ static int ath10k_setup_peer_smps(struc
                                         ath10k_smps_map[smps]);
  }
  
+ static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
+                                     struct ieee80211_vif *vif,
+                                     struct ieee80211_sta_vht_cap vht_cap)
+ {
+       struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+       int ret;
+       u32 param;
+       u32 value;
+       if (!(ar->vht_cap_info &
+             (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+              IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
+              IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+              IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
+               return 0;
+       param = ar->wmi.vdev_param->txbf;
+       value = 0;
+       if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
+               return 0;
+       /* The following logic is correct. If a remote STA advertises support
+        * for being a beamformer then we should enable us being a beamformee.
+        */
+       if (ar->vht_cap_info &
+           (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+            IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
+               if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
+                       value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
+               if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
+                       value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
+       }
+       if (ar->vht_cap_info &
+           (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+            IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
+               if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
+                       value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
+               if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
+                       value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
+       }
+       if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
+               value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
+       if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
+               value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
+       ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
+       if (ret) {
+               ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
+                           value, ret);
+               return ret;
+       }
+       return 0;
+ }
  /* can be called only in mac80211 callbacks due to `key_count` usage */
  static void ath10k_bss_assoc(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif,
        struct ath10k *ar = hw->priv;
        struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
        struct ieee80211_sta_ht_cap ht_cap;
+       struct ieee80211_sta_vht_cap vht_cap;
        struct wmi_peer_assoc_complete_arg peer_arg;
        struct ieee80211_sta *ap_sta;
        int ret;
        /* ap_sta must be accessed only within rcu section which must be left
         * before calling ath10k_setup_peer_smps() which might sleep. */
        ht_cap = ap_sta->ht_cap;
+       vht_cap = ap_sta->vht_cap;
  
        ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
        if (ret) {
                return;
        }
  
+       ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
+       if (ret) {
+               ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
+                           arvif->vdev_id, bss_conf->bssid, ret);
+               return;
+       }
        ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac vdev %d up (associated) bssid %pM aid %d\n",
                   arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
        }
  
        arvif->is_up = true;
+       /* Workaround: Some firmware revisions (tested with qca6174
+        * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
+        * poked with peer param command.
+        */
+       ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
+                                       WMI_PEER_DUMMY_VAR, 1);
+       if (ret) {
+               ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
+                           arvif->bssid, arvif->vdev_id, ret);
+               return;
+       }
  }
  
  static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
  {
        struct ath10k *ar = hw->priv;
        struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+       struct ieee80211_sta_vht_cap vht_cap = {};
        int ret;
  
        lockdep_assert_held(&ar->conf_mutex);
  
        arvif->def_wep_key_idx = -1;
  
+       ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
+       if (ret) {
+               ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
+                           arvif->vdev_id, ret);
+               return;
+       }
        arvif->is_up = false;
  }
  
@@@ -2554,6 -2671,17 +2671,17 @@@ static int ath10k_start_scan(struct ath
                return -ETIMEDOUT;
        }
  
+       /* If we failed to start the scan, return error code at
+        * this point.  This is probably due to some issue in the
+        * firmware, but no need to wedge the driver due to that...
+        */
+       spin_lock_bh(&ar->data_lock);
+       if (ar->scan.state == ATH10K_SCAN_IDLE) {
+               spin_unlock_bh(&ar->data_lock);
+               return -EINVAL;
+       }
+       spin_unlock_bh(&ar->data_lock);
        /* Add a 200ms margin to account for event/command processing */
        ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
                                     msecs_to_jiffies(arg->max_scan_time+200));
@@@ -3323,9 -3451,10 +3451,10 @@@ static void ath10k_remove_interface(str
        list_del(&arvif->list);
  
        if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
-               ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr);
+               ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
+                                            vif->addr);
                if (ret)
-                       ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
                                    arvif->vdev_id, ret);
  
                kfree(arvif->u.ap.noa_data);
                ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
                            arvif->vdev_id, ret);
  
+       /* Some firmware revisions don't notify host about self-peer removal
+        * until after associated vdev is deleted.
+        */
+       if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+               ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
+                                                  vif->addr);
+               if (ret)
+                       ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
+                                   arvif->vdev_id, ret);
+               spin_lock_bh(&ar->data_lock);
+               ar->num_peers--;
+               spin_unlock_bh(&ar->data_lock);
+       }
        ath10k_peer_cleanup(ar, arvif->vdev_id);
  
        mutex_unlock(&ar->conf_mutex);
@@@ -3534,7 -3678,9 +3678,9 @@@ static void ath10k_bss_info_changed(str
        }
  
        if (changed & BSS_CHANGED_PS) {
-               ret = ath10k_mac_vif_setup_ps(arvif);
+               arvif->ps = vif->bss_conf.ps;
+               ret = ath10k_config_ps(ar);
                if (ret)
                        ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
                                    arvif->vdev_id, ret);
index 93ed99a72542da796d85ad4cfc55d975fd7e1e2d,40dc582f1f38dae10247faeca27ff876f5e9f1b7..b0badef71ce793e5bc85358e0166208edbb9688b
@@@ -994,7 -994,7 +994,7 @@@ void ath9k_calculate_iter_data(struct a
         * BSSID mask when matching addresses.
         */
        memset(iter_data, 0, sizeof(*iter_data));
 -      memset(&iter_data->mask, 0xff, ETH_ALEN);
 +      eth_broadcast_addr(iter_data->mask);
        iter_data->slottime = ATH9K_SLOT_TIME_9;
  
        list_for_each_entry(avp, &ctx->vifs, list)
@@@ -1139,7 -1139,7 +1139,7 @@@ void ath9k_calculate_summary_state(stru
                        ctx->primary_sta = iter_data.primary_sta;
                } else {
                        ctx->primary_sta = NULL;
 -                      memset(common->curbssid, 0, ETH_ALEN);
 +                      eth_zero_addr(common->curbssid);
                        common->curaid = 0;
                        ath9k_hw_write_associd(sc->sc_ah);
                        if (ath9k_hw_mci_is_enabled(sc->sc_ah))
        ath9k_ps_restore(sc);
  }
  
+ static void ath9k_tpc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+ {
+       int *power = (int *)data;
+       if (*power < vif->bss_conf.txpower)
+               *power = vif->bss_conf.txpower;
+ }
+ /* Called with sc->mutex held. */
+ void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif)
+ {
+       int power;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       ath9k_ps_wakeup(sc);
+       if (ah->tpc_enabled) {
+               power = (vif) ? vif->bss_conf.txpower : -1;
+               ieee80211_iterate_active_interfaces_atomic(
+                               sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                               ath9k_tpc_vif_iter, &power);
+               if (power == -1)
+                       power = sc->hw->conf.power_level;
+       } else {
+               power = sc->hw->conf.power_level;
+       }
+       sc->cur_chan->txpower = 2 * power;
+       ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
+       sc->cur_chan->cur_txpower = reg->max_power_level;
+       ath9k_ps_restore(sc);
+ }
  static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif)
  {
@@@ -1225,6 -1257,8 +1257,8 @@@ static int ath9k_add_interface(struct i
  
        ath9k_assign_hw_queues(hw, vif);
  
+       ath9k_set_txpower(sc, vif);
        an->sc = sc;
        an->sta = NULL;
        an->vif = vif;
@@@ -1265,6 -1299,8 +1299,8 @@@ static int ath9k_change_interface(struc
        ath9k_assign_hw_queues(hw, vif);
        ath9k_calculate_summary_state(sc, avp->chanctx);
  
+       ath9k_set_txpower(sc, vif);
        mutex_unlock(&sc->mutex);
        return 0;
  }
@@@ -1294,6 -1330,8 +1330,8 @@@ static void ath9k_remove_interface(stru
  
        ath9k_calculate_summary_state(sc, avp->chanctx);
  
+       ath9k_set_txpower(sc, NULL);
        mutex_unlock(&sc->mutex);
  }
  
@@@ -1397,14 -1435,6 +1435,6 @@@ static int ath9k_config(struct ieee8021
                ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
        }
  
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
-               sc->cur_chan->txpower = 2 * conf->power_level;
-               ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
-                                      sc->cur_chan->txpower,
-                                      &sc->cur_chan->cur_txpower);
-       }
        mutex_unlock(&sc->mutex);
        ath9k_ps_restore(sc);
  
@@@ -1764,6 -1794,12 +1794,12 @@@ static void ath9k_bss_info_changed(stru
        if (changed & CHECK_ANI)
                ath_check_ani(sc);
  
+       if (changed & BSS_CHANGED_TXPOWER) {
+               ath_dbg(common, CONFIG, "vif %pM power %d dbm power_type %d\n",
+                       vif->addr, bss_conf->txpower, bss_conf->txpower_type);
+               ath9k_set_txpower(sc, vif);
+       }
        mutex_unlock(&sc->mutex);
        ath9k_ps_restore(sc);
  
index 31c7e4d41a9ab6d7439e45940ebb859dae7ae157,f34aa67f3179324c1a97a7a6384b22855b5b3581..ac99798570e8d8dfdfcf3260312c48376f74903e
@@@ -4132,7 -4132,7 +4132,7 @@@ static void b43_op_bss_info_changed(str
                if (conf->bssid)
                        memcpy(wl->bssid, conf->bssid, ETH_ALEN);
                else
 -                      memset(wl->bssid, 0, ETH_ALEN);
 +                      eth_zero_addr(wl->bssid);
        }
  
        if (b43_status(dev) >= B43_STAT_INITIALIZED) {
@@@ -4819,7 -4819,7 +4819,7 @@@ static void b43_wireless_core_exit(stru
        switch (dev->dev->bus_type) {
  #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
-               bcma_core_pci_down(dev->dev->bdev->bus);
+               bcma_host_pci_down(dev->dev->bdev->bus);
                break;
  #endif
  #ifdef CONFIG_B43_SSB
@@@ -4866,9 -4866,9 +4866,9 @@@ static int b43_wireless_core_init(struc
        switch (dev->dev->bus_type) {
  #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
-               bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
+               bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
                                      dev->dev->bdev, true);
-               bcma_core_pci_up(dev->dev->bdev->bus);
+               bcma_host_pci_up(dev->dev->bdev->bus);
                break;
  #endif
  #ifdef CONFIG_B43_SSB
@@@ -5051,7 -5051,7 +5051,7 @@@ static void b43_op_remove_interface(str
        wl->operating = false;
  
        b43_adjust_opmode(dev);
 -      memset(wl->mac_addr, 0, ETH_ALEN);
 +      eth_zero_addr(wl->mac_addr);
        b43_upload_card_macaddress(dev);
  
        mutex_unlock(&wl->mutex);
@@@ -5067,8 -5067,8 +5067,8 @@@ static int b43_op_start(struct ieee8021
        /* 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);
 +      eth_zero_addr(wl->bssid);
 +      eth_zero_addr(wl->mac_addr);
        wl->filter_flags = 0;
        wl->radiotap_enabled = false;
        b43_qos_clear(wl);
index 06727a61b438f19dc551f442f16d082f2deb9a19,a4d456c50d2f47033c82765ec9b92967388420cf..9b805c9fd51eb3b474d2ebdac942ba1b8c27645b
@@@ -700,7 -700,7 +700,7 @@@ s32 brcmf_notify_escan_complete(struct 
                /* Do a scan abort to stop the driver's scan engine */
                brcmf_dbg(SCAN, "ABORT scan in firmware\n");
                memset(&params_le, 0, sizeof(params_le));
 -              memset(params_le.bssid, 0xFF, ETH_ALEN);
 +              eth_broadcast_addr(params_le.bssid);
                params_le.bss_type = DOT11_BSSTYPE_ANY;
                params_le.scan_type = 0;
                params_le.channel_num = cpu_to_le32(1);
@@@ -866,7 -866,7 +866,7 @@@ static void brcmf_escan_prep(struct brc
        char *ptr;
        struct brcmf_ssid_le ssid_le;
  
 -      memset(params_le->bssid, 0xFF, ETH_ALEN);
 +      eth_broadcast_addr(params_le->bssid);
        params_le->bss_type = DOT11_BSSTYPE_ANY;
        params_le->scan_type = 0;
        params_le->channel_num = 0;
@@@ -1050,10 -1050,6 +1050,6 @@@ brcmf_cfg80211_escan(struct wiphy *wiph
        if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
                vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
  
-       /* Arm scan timeout timer */
-       mod_timer(&cfg->escan_timeout, jiffies +
-                       WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
        escan_req = false;
        if (request) {
                /* scan bss */
                }
        }
  
+       /* Arm scan timeout timer */
+       mod_timer(&cfg->escan_timeout, jiffies +
+                       WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
        return 0;
  
  scan_out:
        clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
-       if (timer_pending(&cfg->escan_timeout))
-               del_timer_sync(&cfg->escan_timeout);
        cfg->scan_request = NULL;
        return err;
  }
@@@ -1375,8 -1373,8 +1373,8 @@@ brcmf_cfg80211_join_ibss(struct wiphy *
                                   BRCMF_ASSOC_PARAMS_FIXED_SIZE;
                memcpy(profile->bssid, params->bssid, ETH_ALEN);
        } else {
 -              memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
 -              memset(profile->bssid, 0, ETH_ALEN);
 +              eth_broadcast_addr(join_params.params_le.bssid);
 +              eth_zero_addr(profile->bssid);
        }
  
        /* Channel */
@@@ -1850,7 -1848,7 +1848,7 @@@ brcmf_cfg80211_connect(struct wiphy *wi
        if (sme->bssid)
                memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
        else
 -              memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
 +              eth_broadcast_addr(ext_join_params->assoc_le.bssid);
  
        if (cfg->channel) {
                ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
        if (sme->bssid)
                memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
        else
 -              memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
 +              eth_broadcast_addr(join_params.params_le.bssid);
  
        if (cfg->channel) {
                join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
@@@ -2252,7 -2250,6 +2250,6 @@@ brcmf_cfg80211_del_key(struct wiphy *wi
  
        if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
                /* we ignore this key index in this case */
-               brcmf_err("invalid key index (%d)\n", key_idx);
                return -EINVAL;
        }
  
@@@ -4272,7 -4269,7 +4269,7 @@@ brcmf_cfg80211_del_station(struct wiph
                return -EIO;
  
        memcpy(&scbval.ea, params->mac, ETH_ALEN);
-       scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
+       scbval.val = cpu_to_le32(params->reason_code);
        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
                                     &scbval, sizeof(scbval));
        if (err)
index 7c3ca2f50186d968db55fe84651568145c4b0295,5f3c1d3c52e0664b74dd9cb4341c3656290ac71d..8e1f681f960b73e02385d74a48b9e0b4efde16b3
@@@ -1563,7 -1563,7 +1563,7 @@@ mwifiex_cfg80211_del_station(struct wip
  
        wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, params->mac);
  
 -      memset(deauth_mac, 0, ETH_ALEN);
 +      eth_zero_addr(deauth_mac);
  
        spin_lock_irqsave(&priv->sta_list_spinlock, flags);
        sta_node = mwifiex_get_sta_entry(priv, params->mac);
@@@ -1786,7 -1786,7 +1786,7 @@@ mwifiex_cfg80211_disconnect(struct wiph
        wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
                " reason code %d\n", priv->cfg_bssid, reason_code);
  
 -      memset(priv->cfg_bssid, 0, ETH_ALEN);
 +      eth_zero_addr(priv->cfg_bssid);
        priv->hs2_enabled = false;
  
        return 0;
@@@ -2046,7 -2046,7 +2046,7 @@@ mwifiex_cfg80211_connect(struct wiphy *
                dev_dbg(priv->adapter->dev,
                        "info: association to bssid %pM failed\n",
                        priv->cfg_bssid);
 -              memset(priv->cfg_bssid, 0, ETH_ALEN);
 +              eth_zero_addr(priv->cfg_bssid);
  
                if (ret > 0)
                        cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
@@@ -2194,7 -2194,7 +2194,7 @@@ mwifiex_cfg80211_leave_ibss(struct wiph
        if (mwifiex_deauthenticate(priv, NULL))
                return -EFAULT;
  
 -      memset(priv->cfg_bssid, 0, ETH_ALEN);
 +      eth_zero_addr(priv->cfg_bssid);
  
        return 0;
  }
@@@ -2397,7 -2397,6 +2397,6 @@@ mwifiex_setup_ht_caps(struct ieee80211_
        ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  }
  
- #define MWIFIEX_MAX_WQ_LEN  30
  /*
   *  create a new virtual interface with the given name
   */
@@@ -2411,7 -2410,6 +2410,6 @@@ struct wireless_dev *mwifiex_add_virtua
        struct mwifiex_private *priv;
        struct net_device *dev;
        void *mdev_priv;
-       char dfs_cac_str[MWIFIEX_MAX_WQ_LEN], dfs_chsw_str[MWIFIEX_MAX_WQ_LEN];
  
        if (!adapter)
                return ERR_PTR(-EFAULT);
                return ERR_PTR(-EFAULT);
        }
  
-       strcpy(dfs_cac_str, "MWIFIEX_DFS_CAC");
-       strcat(dfs_cac_str, name);
-       priv->dfs_cac_workqueue = alloc_workqueue(dfs_cac_str,
+       priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s",
                                                  WQ_HIGHPRI |
                                                  WQ_MEM_RECLAIM |
-                                                 WQ_UNBOUND, 1);
+                                                 WQ_UNBOUND, 1, name);
        if (!priv->dfs_cac_workqueue) {
                wiphy_err(wiphy, "cannot register virtual network device\n");
                free_netdev(dev);
  
        INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
  
-       strcpy(dfs_chsw_str, "MWIFIEX_DFS_CHSW");
-       strcat(dfs_chsw_str, name);
-       priv->dfs_chan_sw_workqueue = alloc_workqueue(dfs_chsw_str,
+       priv->dfs_chan_sw_workqueue = alloc_workqueue("MWIFIEX_DFS_CHSW%s",
                                                      WQ_HIGHPRI | WQ_UNBOUND |
-                                                     WQ_MEM_RECLAIM, 1);
+                                                     WQ_MEM_RECLAIM, 1, name);
        if (!priv->dfs_chan_sw_workqueue) {
                wiphy_err(wiphy, "cannot register virtual network device\n");
                free_netdev(dev);
index 0978b1cc58b699810395f0b5c628ed88a0f94e6f,2e1df027b204f875841c90330c4c92c88e84a8d8..0153ce6d5879bacd48d6d42aaca3d0ddec5412cb
@@@ -76,7 -76,7 +76,7 @@@ int mwifiex_init_priv(struct mwifiex_pr
        u32 i;
  
        priv->media_connected = false;
 -      memset(priv->curr_addr, 0xff, ETH_ALEN);
 +      eth_broadcast_addr(priv->curr_addr);
  
        priv->pkt_tx_ctrl = 0;
        priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@@ -296,10 -296,9 +296,9 @@@ static void mwifiex_init_adapter(struc
        memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
        adapter->arp_filter_size = 0;
        adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
-       adapter->ext_scan = false;
        adapter->key_api_major_ver = 0;
        adapter->key_api_minor_ver = 0;
 -      memset(adapter->perm_addr, 0xff, ETH_ALEN);
 +      eth_broadcast_addr(adapter->perm_addr);
        adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM;
        adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM;
        adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM;