aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/mac.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ebc12c521fe0..55c823f983c7 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
802{ 802{
803 struct ath10k_peer *peer, *tmp; 803 struct ath10k_peer *peer, *tmp;
804 int peer_id; 804 int peer_id;
805 int i;
805 806
806 lockdep_assert_held(&ar->conf_mutex); 807 lockdep_assert_held(&ar->conf_mutex);
807 808
@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
818 ar->peer_map[peer_id] = NULL; 819 ar->peer_map[peer_id] = NULL;
819 } 820 }
820 821
822 /* Double check that peer is properly un-referenced from
823 * the peer_map
824 */
825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
826 if (ar->peer_map[i] == peer) {
827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
828 peer->addr, peer, i);
829 ar->peer_map[i] = NULL;
830 }
831 }
832
821 list_del(&peer->list); 833 list_del(&peer->list);
822 kfree(peer); 834 kfree(peer);
823 ar->num_peers--; 835 ar->num_peers--;
@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
828static void ath10k_peer_cleanup_all(struct ath10k *ar) 840static void ath10k_peer_cleanup_all(struct ath10k *ar)
829{ 841{
830 struct ath10k_peer *peer, *tmp; 842 struct ath10k_peer *peer, *tmp;
843 int i;
831 844
832 lockdep_assert_held(&ar->conf_mutex); 845 lockdep_assert_held(&ar->conf_mutex);
833 846
@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
836 list_del(&peer->list); 849 list_del(&peer->list);
837 kfree(peer); 850 kfree(peer);
838 } 851 }
852
853 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
854 ar->peer_map[i] = NULL;
855
839 spin_unlock_bh(&ar->data_lock); 856 spin_unlock_bh(&ar->data_lock);
840 857
841 ar->num_peers = 0; 858 ar->num_peers = 0;
@@ -2939,7 +2956,7 @@ static int ath10k_update_channel_list(struct ath10k *ar)
2939 if (channel->flags & IEEE80211_CHAN_DISABLED) 2956 if (channel->flags & IEEE80211_CHAN_DISABLED)
2940 continue; 2957 continue;
2941 2958
2942 ch->allow_ht = true; 2959 ch->allow_ht = true;
2943 2960
2944 /* FIXME: when should we really allow VHT? */ 2961 /* FIXME: when should we really allow VHT? */
2945 ch->allow_vht = true; 2962 ch->allow_vht = true;
@@ -3675,17 +3692,18 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3675 3692
3676static void ath10k_mac_txq_init(struct ieee80211_txq *txq) 3693static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3677{ 3694{
3678 struct ath10k_txq *artxq = (void *)txq->drv_priv; 3695 struct ath10k_txq *artxq;
3679 3696
3680 if (!txq) 3697 if (!txq)
3681 return; 3698 return;
3682 3699
3700 artxq = (void *)txq->drv_priv;
3683 INIT_LIST_HEAD(&artxq->list); 3701 INIT_LIST_HEAD(&artxq->list);
3684} 3702}
3685 3703
3686static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) 3704static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3687{ 3705{
3688 struct ath10k_txq *artxq = (void *)txq->drv_priv; 3706 struct ath10k_txq *artxq;
3689 struct ath10k_skb_cb *cb; 3707 struct ath10k_skb_cb *cb;
3690 struct sk_buff *msdu; 3708 struct sk_buff *msdu;
3691 int msdu_id; 3709 int msdu_id;
@@ -3693,6 +3711,7 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3693 if (!txq) 3711 if (!txq)
3694 return; 3712 return;
3695 3713
3714 artxq = (void *)txq->drv_priv;
3696 spin_lock_bh(&ar->txqs_lock); 3715 spin_lock_bh(&ar->txqs_lock);
3697 if (!list_empty(&artxq->list)) 3716 if (!list_empty(&artxq->list))
3698 list_del_init(&artxq->list); 3717 list_del_init(&artxq->list);
@@ -4228,6 +4247,9 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4228 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); 4247 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4229 } 4248 }
4230 4249
4250 if (ar->cfg_tx_chainmask <= 1)
4251 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4252
4231 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); 4253 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4232 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); 4254 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4233 4255
@@ -4265,7 +4287,7 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4265 ht_cap.cap |= smps; 4287 ht_cap.cap |= smps;
4266 } 4288 }
4267 4289
4268 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC) 4290 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
4269 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; 4291 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4270 4292
4271 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { 4293 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
@@ -5979,9 +6001,17 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
5979 continue; 6001 continue;
5980 6002
5981 if (peer->sta == sta) { 6003 if (peer->sta == sta) {
5982 ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n", 6004 ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",
5983 sta->addr, arvif->vdev_id); 6005 sta->addr, peer, i, arvif->vdev_id);
5984 peer->sta = NULL; 6006 peer->sta = NULL;
6007
6008 /* Clean up the peer object as well since we
6009 * must have failed to do this above.
6010 */
6011 list_del(&peer->list);
6012 ar->peer_map[i] = NULL;
6013 kfree(peer);
6014 ar->num_peers--;
5985 } 6015 }
5986 } 6016 }
5987 spin_unlock_bh(&ar->data_lock); 6017 spin_unlock_bh(&ar->data_lock);
@@ -7406,6 +7436,7 @@ static const struct ieee80211_ops ath10k_ops = {
7406#endif 7436#endif
7407#ifdef CONFIG_MAC80211_DEBUGFS 7437#ifdef CONFIG_MAC80211_DEBUGFS
7408 .sta_add_debugfs = ath10k_sta_add_debugfs, 7438 .sta_add_debugfs = ath10k_sta_add_debugfs,
7439 .sta_statistics = ath10k_sta_statistics,
7409#endif 7440#endif
7410}; 7441};
7411 7442