Merge branch 'ttm-prot-fix' of git://people.freedesktop.org/~thomash/linux into drm...
[platform/kernel/linux-starfive.git] / net / mac80211 / sta_info.c
index 8d3a238..0f5f406 100644 (file)
@@ -210,6 +210,20 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        return NULL;
 }
 
+struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local,
+                                      const u8 *sta_addr, const u8 *vif_addr)
+{
+       struct rhlist_head *tmp;
+       struct sta_info *sta;
+
+       for_each_sta_info(local, sta_addr, sta, tmp) {
+               if (ether_addr_equal(vif_addr, sta->sdata->vif.addr))
+                       return sta;
+       }
+
+       return NULL;
+}
+
 struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
                                     int idx)
 {
@@ -396,6 +410,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
                skb_queue_head_init(&sta->ps_tx_buf[i]);
                skb_queue_head_init(&sta->tx_filtered[i]);
                sta->airtime[i].deficit = sta->airtime_weight;
+               atomic_set(&sta->airtime[i].aql_tx_pending, 0);
+               sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i];
+               sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i];
        }
 
        for (i = 0; i < IEEE80211_NUM_TIDS; i++)
@@ -1893,6 +1910,44 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
 }
 EXPORT_SYMBOL(ieee80211_sta_register_airtime);
 
+void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
+                                         struct sta_info *sta, u8 ac,
+                                         u16 tx_airtime, bool tx_completed)
+{
+       int tx_pending;
+
+       if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
+               return;
+
+       if (!tx_completed) {
+               if (sta)
+                       atomic_add(tx_airtime,
+                                  &sta->airtime[ac].aql_tx_pending);
+
+               atomic_add(tx_airtime, &local->aql_total_pending_airtime);
+               return;
+       }
+
+       if (sta) {
+               tx_pending = atomic_sub_return(tx_airtime,
+                                              &sta->airtime[ac].aql_tx_pending);
+               if (WARN_ONCE(tx_pending < 0,
+                             "STA %pM AC %d txq pending airtime underflow: %u, %u",
+                             sta->addr, ac, tx_pending, tx_airtime))
+                       atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
+                                      tx_pending, 0);
+       }
+
+       tx_pending = atomic_sub_return(tx_airtime,
+                                      &local->aql_total_pending_airtime);
+       if (WARN_ONCE(tx_pending < 0,
+                     "Device %s AC %d pending airtime underflow: %u, %u",
+                     wiphy_name(local->hw.wiphy), ac, tx_pending,
+                     tx_airtime))
+               atomic_cmpxchg(&local->aql_total_pending_airtime,
+                              tx_pending, 0);
+}
+
 int sta_info_move_state(struct sta_info *sta,
                        enum ieee80211_sta_state new_state)
 {