ath10k: migrate to mac80211 txq scheduling
[platform/kernel/linux-rpi.git] / drivers / net / wireless / ath / ath10k / mac.c
index c8af35f..0d5215d 100644 (file)
@@ -3890,7 +3890,6 @@ static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
 
 static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
 {
-       struct ath10k_txq *artxq;
        struct ath10k_skb_cb *cb;
        struct sk_buff *msdu;
        int msdu_id;
@@ -3898,12 +3897,6 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
        if (!txq)
                return;
 
-       artxq = (void *)txq->drv_priv;
-       spin_lock_bh(&ar->txqs_lock);
-       if (!list_empty(&artxq->list))
-               list_del_init(&artxq->list);
-       spin_unlock_bh(&ar->txqs_lock);
-
        spin_lock_bh(&ar->htt.tx_lock);
        idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
                cb = ATH10K_SKB_CB(msdu);
@@ -3943,7 +3936,6 @@ static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
        struct ath10k_txq *artxq = (void *)txq->drv_priv;
 
        /* No need to get locks */
-
        if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
                return true;
 
@@ -4030,48 +4022,45 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
        return skb_len;
 }
 
-void ath10k_mac_tx_push_pending(struct ath10k *ar)
+static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
 {
-       struct ieee80211_hw *hw = ar->hw;
        struct ieee80211_txq *txq;
-       struct ath10k_txq *artxq;
-       struct ath10k_txq *last;
-       int ret;
-       int max;
-
-       if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
-               return;
-
-       spin_lock_bh(&ar->txqs_lock);
-       rcu_read_lock();
-
-       last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
-       while (!list_empty(&ar->txqs)) {
-               artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
-               txq = container_of((void *)artxq, struct ieee80211_txq,
-                                  drv_priv);
+       int ret = 0;
 
-               /* Prevent aggressive sta/tid taking over tx queue */
-               max = HTC_HOST_MAX_MSG_PER_TX_BUNDLE;
-               ret = 0;
-               while (ath10k_mac_tx_can_push(hw, txq) && max--) {
+       ieee80211_txq_schedule_start(hw, ac);
+       while ((txq = ieee80211_next_txq(hw, ac))) {
+               while (ath10k_mac_tx_can_push(hw, txq)) {
                        ret = ath10k_mac_tx_push_txq(hw, txq);
                        if (ret < 0)
                                break;
                }
+               ieee80211_return_txq(hw, txq);
+               ath10k_htt_tx_txq_update(hw, txq);
+               if (ret == -EBUSY)
+                       break;
+       }
+       ieee80211_txq_schedule_end(hw, ac);
+
+       return ret;
+}
 
-               list_del_init(&artxq->list);
-               if (ret != -ENOENT)
-                       list_add_tail(&artxq->list, &ar->txqs);
+void ath10k_mac_tx_push_pending(struct ath10k *ar)
+{
+       struct ieee80211_hw *hw = ar->hw;
+       u32 ac;
 
-               ath10k_htt_tx_txq_update(hw, txq);
+       if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
+               return;
 
-               if (artxq == last || (ret < 0 && ret != -ENOENT))
+       if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
+               return;
+
+       rcu_read_lock();
+       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+               if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)
                        break;
        }
-
        rcu_read_unlock();
-       spin_unlock_bh(&ar->txqs_lock);
 }
 EXPORT_SYMBOL(ath10k_mac_tx_push_pending);
 
@@ -4310,31 +4299,28 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
                                        struct ieee80211_txq *txq)
 {
        struct ath10k *ar = hw->priv;
-       struct ath10k_txq *artxq = (void *)txq->drv_priv;
-       struct ieee80211_txq *f_txq;
-       struct ath10k_txq *f_artxq;
-       int ret = 0;
-       int max = HTC_HOST_MAX_MSG_PER_TX_BUNDLE;
+       int ret;
+       u8 ac;
 
-       spin_lock_bh(&ar->txqs_lock);
-       if (list_empty(&artxq->list))
-               list_add_tail(&artxq->list, &ar->txqs);
+       ath10k_htt_tx_txq_update(hw, txq);
+       if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
+               return;
 
-       f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
-       f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
-       list_del_init(&f_artxq->list);
+       ac = txq->ac;
+       ieee80211_txq_schedule_start(hw, ac);
+       txq = ieee80211_next_txq(hw, ac);
+       if (!txq)
+               goto out;
 
-       while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
-               ret = ath10k_mac_tx_push_txq(hw, f_txq);
+       while (ath10k_mac_tx_can_push(hw, txq)) {
+               ret = ath10k_mac_tx_push_txq(hw, txq);
                if (ret < 0)
                        break;
        }
-       if (ret != -ENOENT)
-               list_add_tail(&f_artxq->list, &ar->txqs);
-       spin_unlock_bh(&ar->txqs_lock);
-
-       ath10k_htt_tx_txq_update(hw, f_txq);
+       ieee80211_return_txq(hw, txq);
        ath10k_htt_tx_txq_update(hw, txq);
+out:
+       ieee80211_txq_schedule_end(hw, ac);
 }
 
 /* Must not be called with conf_mutex held as workers can use that also. */
@@ -8727,6 +8713,8 @@ int ath10k_mac_register(struct ath10k *ar)
 
        wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 
+       ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
+
        ret = ieee80211_register_hw(ar->hw);
        if (ret) {
                ath10k_err(ar, "failed to register ieee80211: %d\n", ret);