ath9k: add some more fixes for the tx queueing rework
[openwrt.git] / package / kernel / mac80211 / patches / 572-ath9k_multicast_node.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -265,6 +265,7 @@ struct ath_node {
4         u8 mpdudensity;
5  
6         bool sleeping;
7 +       bool no_ps_filter;
8  
9  #if defined(CPTCFG_MAC80211_DEBUGFS) && defined(CPTCFG_ATH9K_DEBUGFS)
10         struct dentry *node_stat;
11 @@ -364,6 +365,7 @@ void ath9k_release_buffered_frames(struc
12  /********/
13  
14  struct ath_vif {
15 +       struct ath_node mcast_node;
16         int av_bslot;
17         bool primary_sta_vif;
18         __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
19 --- a/drivers/net/wireless/ath/ath9k/main.c
20 +++ b/drivers/net/wireless/ath/ath9k/main.c
21 @@ -971,6 +971,8 @@ static int ath9k_add_interface(struct ie
22         struct ath_softc *sc = hw->priv;
23         struct ath_hw *ah = sc->sc_ah;
24         struct ath_common *common = ath9k_hw_common(ah);
25 +       struct ath_vif *avp = (void *)vif->drv_priv;
26 +       struct ath_node *an = &avp->mcast_node;
27  
28         mutex_lock(&sc->mutex);
29  
30 @@ -984,6 +986,12 @@ static int ath9k_add_interface(struct ie
31         if (ath9k_uses_beacons(vif->type))
32                 ath9k_beacon_assign_slot(sc, vif);
33  
34 +       an->sc = sc;
35 +       an->sta = NULL;
36 +       an->vif = vif;
37 +       an->no_ps_filter = true;
38 +       ath_tx_node_init(sc, an);
39 +
40         mutex_unlock(&sc->mutex);
41         return 0;
42  }
43 @@ -1021,6 +1029,7 @@ static void ath9k_remove_interface(struc
44  {
45         struct ath_softc *sc = hw->priv;
46         struct ath_common *common = ath9k_hw_common(sc->sc_ah);
47 +       struct ath_vif *avp = (void *)vif->drv_priv;
48  
49         ath_dbg(common, CONFIG, "Detach Interface\n");
50  
51 @@ -1035,6 +1044,8 @@ static void ath9k_remove_interface(struc
52         ath9k_calculate_summary_state(hw, NULL);
53         ath9k_ps_restore(sc);
54  
55 +       ath_tx_node_cleanup(sc, &avp->mcast_node);
56 +
57         mutex_unlock(&sc->mutex);
58  }
59  
60 --- a/drivers/net/wireless/ath/ath9k/xmit.c
61 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
62 @@ -135,6 +135,9 @@ static struct ath_frame_info *get_frame_
63  
64  static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
65  {
66 +       if (!tid->an->sta)
67 +               return;
68 +
69         ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno,
70                            seqno << IEEE80211_SEQ_SEQ_SHIFT);
71  }
72 @@ -1354,7 +1357,7 @@ static bool ath_tx_sched_aggr(struct ath
73         if (list_empty(&bf_q))
74                 return false;
75  
76 -       if (tid->ac->clear_ps_filter) {
77 +       if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) {
78                 tid->ac->clear_ps_filter = false;
79                 tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
80         }
81 @@ -1544,7 +1547,7 @@ void ath9k_release_buffered_frames(struc
82                         sent++;
83                         TX_STAT_INC(txq->axq_qnum, a_queued_hw);
84  
85 -                       if (!ath_tid_has_buffered(tid))
86 +                       if (an->sta && !ath_tid_has_buffered(tid))
87                                 ieee80211_sta_set_buffered(an->sta, i, false);
88                 }
89                 ath_txq_unlock_complete(sc, tid->ac->txq);
90 @@ -2076,6 +2079,7 @@ static int ath_tx_prepare(struct ieee802
91         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
92         struct ieee80211_sta *sta = txctl->sta;
93         struct ieee80211_vif *vif = info->control.vif;
94 +       struct ath_vif *avp;
95         struct ath_softc *sc = hw->priv;
96         int frmlen = skb->len + FCS_LEN;
97         int padpos, padsize;
98 @@ -2083,6 +2087,10 @@ static int ath_tx_prepare(struct ieee802
99         /* NOTE:  sta can be NULL according to net/mac80211.h */
100         if (sta)
101                 txctl->an = (struct ath_node *)sta->drv_priv;
102 +       else if (vif && ieee80211_is_data(hdr->frame_control)) {
103 +               avp = (void *)vif->drv_priv;
104 +               txctl->an = &avp->mcast_node;
105 +       }
106  
107         if (info->control.hw_key)
108                 frmlen += info->control.hw_key->icv_len;