Merge tag 'wireless-drivers-next-for-davem-2015-03-06' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
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>
此提交包含在:
@@ -611,7 +611,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
|
||||
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 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
|
||||
|
||||
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 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
|
||||
|
||||
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 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1253,6 +1254,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
|
||||
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;
|
||||
@@ -1262,13 +1277,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
|
||||
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 @@ static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
|
||||
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,
|
||||
@@ -1789,6 +1877,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
|
||||
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;
|
||||
@@ -1811,6 +1900,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
|
||||
/* 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) {
|
||||
@@ -1836,6 +1926,13 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
|
||||
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);
|
||||
@@ -1853,6 +1950,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -1860,6 +1969,7 @@ 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);
|
||||
@@ -1874,6 +1984,13 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
|
||||
|
||||
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 @@ static int ath10k_start_scan(struct ath10k *ar,
|
||||
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 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
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);
|
||||
@@ -3339,6 +3468,21 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
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 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
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);
|
||||
|
新增問題並參考
封鎖使用者