Merge wireless into wireless-next
authorKalle Valo <kvalo@kernel.org>
Tue, 17 Jan 2023 11:36:25 +0000 (13:36 +0200)
committerKalle Valo <kvalo@kernel.org>
Tue, 17 Jan 2023 11:36:25 +0000 (13:36 +0200)
Due to the two cherry picked commits from wireless to wireless-next we have
several conflicts in mt76. To avoid any bugs with conflicts merge wireless into
wireless-next.

96f134dc1964 wifi: mt76: handle possible mt76_rx_token_consume failures
fe13dad8992b wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails

1  2 
drivers/net/wireless/mediatek/mt76/dma.c
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/util.c

@@@ -206,6 -206,52 +206,52 @@@ mt76_dma_queue_reset(struct mt76_dev *d
  }
  
  static int
+ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+                   struct mt76_queue_buf *buf, void *data)
+ {
+       struct mt76_desc *desc = &q->desc[q->head];
+       struct mt76_queue_entry *entry = &q->entry[q->head];
+       struct mt76_txwi_cache *txwi = NULL;
+       u32 buf1 = 0, ctrl;
+       int idx = q->head;
+       int rx_token;
+       ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+       if ((q->flags & MT_QFLAG_WED) &&
+           FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
+               txwi = mt76_get_rxwi(dev);
+               if (!txwi)
+                       return -ENOMEM;
+               rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
+               if (rx_token < 0) {
+                       mt76_put_rxwi(dev, txwi);
+                       return -ENOMEM;
+               }
+               buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
+               ctrl |= MT_DMA_CTL_TO_HOST;
+       }
+       WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr));
+       WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
+       WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
+       WRITE_ONCE(desc->info, 0);
+       entry->dma_addr[0] = buf->addr;
+       entry->dma_len[0] = buf->len;
+       entry->txwi = txwi;
+       entry->buf = data;
+       entry->wcid = 0xffff;
+       entry->skip_buf1 = true;
+       q->head = (q->head + 1) % q->ndesc;
+       q->queued++;
+       return idx;
+ }
+ static int
  mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
                 struct mt76_queue_buf *buf, int nbufs, u32 info,
                 struct sk_buff *skb, void *txwi)
        int i, idx = -1;
        u32 ctrl, next;
  
+       if (txwi) {
+               q->entry[q->head].txwi = DMA_DUMMY_DATA;
+               q->entry[q->head].skip_buf0 = true;
+       }
        for (i = 0; i < nbufs; i += 2, buf += 2) {
                u32 buf0 = buf[0].addr, buf1 = 0;
  
                desc = &q->desc[idx];
                entry = &q->entry[idx];
  
-               if ((q->flags & MT_QFLAG_WED) &&
-                   FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
-                       struct mt76_txwi_cache *t = txwi;
-                       int rx_token;
-                       if (!t)
-                               return -ENOMEM;
-                       rx_token = mt76_rx_token_consume(dev, (void *)skb, t,
-                                                        buf[0].addr);
-                       if (rx_token < 0)
-                               return -ENOMEM;
-                       buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
-                       ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) |
-                              MT_DMA_CTL_TO_HOST;
-               } else {
-                       if (txwi) {
-                               q->entry[next].txwi = DMA_DUMMY_DATA;
-                               q->entry[next].skip_buf0 = true;
-                       }
-                       if (buf[0].skip_unmap)
-                               entry->skip_buf0 = true;
-                       entry->skip_buf1 = i == nbufs - 1;
-                       entry->dma_addr[0] = buf[0].addr;
-                       entry->dma_len[0] = buf[0].len;
-                       ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
-                       if (i < nbufs - 1) {
-                               entry->dma_addr[1] = buf[1].addr;
-                               entry->dma_len[1] = buf[1].len;
-                               buf1 = buf[1].addr;
-                               ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
-                               if (buf[1].skip_unmap)
-                                       entry->skip_buf1 = true;
-                       }
-                       if (i == nbufs - 1)
-                               ctrl |= MT_DMA_CTL_LAST_SEC0;
-                       else if (i == nbufs - 2)
-                               ctrl |= MT_DMA_CTL_LAST_SEC1;
+               if (buf[0].skip_unmap)
+                       entry->skip_buf0 = true;
+               entry->skip_buf1 = i == nbufs - 1;
+               entry->dma_addr[0] = buf[0].addr;
+               entry->dma_len[0] = buf[0].len;
+               ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+               if (i < nbufs - 1) {
+                       entry->dma_addr[1] = buf[1].addr;
+                       entry->dma_len[1] = buf[1].len;
+                       buf1 = buf[1].addr;
+                       ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
+                       if (buf[1].skip_unmap)
+                               entry->skip_buf1 = true;
                }
  
+               if (i == nbufs - 1)
+                       ctrl |= MT_DMA_CTL_LAST_SEC0;
+               else if (i == nbufs - 2)
+                       ctrl |= MT_DMA_CTL_LAST_SEC1;
                WRITE_ONCE(desc->buf0, cpu_to_le32(buf0));
                WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
                WRITE_ONCE(desc->info, cpu_to_le32(info));
@@@ -554,9 -582,23 +582,9 @@@ free_skb
        return ret;
  }
  
 -static struct page_frag_cache *
 -mt76_dma_rx_get_frag_cache(struct mt76_dev *dev, struct mt76_queue *q)
 -{
 -      struct page_frag_cache *rx_page = &q->rx_page;
 -
 -#ifdef CONFIG_NET_MEDIATEK_SOC_WED
 -      if ((q->flags & MT_QFLAG_WED) &&
 -          FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX)
 -              rx_page = &dev->mmio.wed.rx_buf_ring.rx_page;
 -#endif
 -      return rx_page;
 -}
 -
  static int
  mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  {
 -      struct page_frag_cache *rx_page = mt76_dma_rx_get_frag_cache(dev, q);
        int len = SKB_WITH_OVERHEAD(q->buf_size);
        int frames = 0, offset = q->buf_offset;
        dma_addr_t addr;
        spin_lock_bh(&q->lock);
  
        while (q->queued < q->ndesc - 1) {
-               struct mt76_txwi_cache *t = NULL;
                struct mt76_queue_buf qbuf;
                void *buf = NULL;
  
-               if ((q->flags & MT_QFLAG_WED) &&
-                   FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
-                       t = mt76_get_rxwi(dev);
-                       if (!t)
-                               break;
-               }
 -              buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC);
 +              buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
                if (!buf)
                        break;
  
                qbuf.addr = addr + offset;
                qbuf.len = len - offset;
                qbuf.skip_unmap = false;
-               if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) {
+               if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
                        dma_unmap_single(dev->dma_dev, addr, len,
                                         DMA_FROM_DEVICE);
                        skb_free_frag(buf);
diff --combined include/net/mac80211.h
@@@ -1832,8 -1832,6 +1832,6 @@@ struct ieee80211_vif_cfg 
   * @drv_priv: data area for driver use, will always be aligned to
   *    sizeof(void \*).
   * @txq: the multicast data TX queue
-  * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped,
-  *    protected by fq->lock.
   * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see
   *    &enum ieee80211_offload_flags.
   * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled.
@@@ -1863,8 -1861,6 +1861,6 @@@ struct ieee80211_vif 
        bool probe_req_reg;
        bool rx_mcast_action_reg;
  
-       bool txqs_stopped[IEEE80211_NUM_ACS];
        struct ieee80211_vif *mbssid_tx_vif;
  
        /* must be last */
@@@ -5888,6 -5884,9 +5884,6 @@@ void ieee80211_iterate_active_interface
   * This function iterates over the interfaces associated with a given
   * hardware that are currently active and calls the callback for them.
   * This version can only be used while holding the wiphy mutex.
 - * The driver must not call this with a lock held that it can also take in
 - * response to callbacks from mac80211, and it must not call this within
 - * callbacks made by mac80211 - both would result in deadlocks.
   *
   * @hw: the hardware struct of which the interfaces should be iterated over
   * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
@@@ -5902,6 -5901,24 +5898,6 @@@ void ieee80211_iterate_active_interface
                                             void *data);
  
  /**
 - * ieee80211_iterate_stations - iterate stations
 - *
 - * This function iterates over all stations associated with a given
 - * hardware that are currently uploaded to the driver and calls the callback
 - * function for them.
 - * This function allows the iterator function to sleep, when the iterator
 - * function is atomic @ieee80211_iterate_stations_atomic can be used.
 - *
 - * @hw: the hardware struct of which the interfaces should be iterated over
 - * @iterator: the iterator function to call, cannot sleep
 - * @data: first argument of the iterator function
 - */
 -void ieee80211_iterate_stations(struct ieee80211_hw *hw,
 -                              void (*iterator)(void *data,
 -                                               struct ieee80211_sta *sta),
 -                              void *data);
 -
 -/**
   * ieee80211_iterate_stations_atomic - iterate stations
   *
   * This function iterates over all stations associated with a given
diff --combined net/mac80211/cfg.c
@@@ -147,6 -147,7 +147,7 @@@ static int ieee80211_set_ap_mbssid_opti
        link_conf->bssid_index = 0;
        link_conf->nontransmitted = false;
        link_conf->ema_ap = false;
+       link_conf->bssid_indicator = 0;
  
        if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev)
                return -EINVAL;
@@@ -1511,6 -1512,12 +1512,12 @@@ static int ieee80211_stop_ap(struct wip
        kfree(link_conf->ftmr_params);
        link_conf->ftmr_params = NULL;
  
+       sdata->vif.mbssid_tx_vif = NULL;
+       link_conf->bssid_index = 0;
+       link_conf->nontransmitted = false;
+       link_conf->ema_ap = false;
+       link_conf->bssid_indicator = 0;
        __sta_info_flush(sdata, true);
        ieee80211_free_keys(sdata, true);
  
@@@ -2727,7 -2734,7 +2734,7 @@@ static int ieee80211_scan(struct wiphy 
                 * If the scan has been forced (and the driver supports
                 * forcing), don't care about being beaconing already.
                 * This will create problems to the attached stations (e.g. all
 -               * the  frames sent while scanning on other channel will be
 +               * the frames sent while scanning on other channel will be
                 * lost)
                 */
                if (sdata->deflink.u.ap.beacon &&
diff --combined net/mac80211/util.c
@@@ -292,22 -292,12 +292,12 @@@ static void wake_tx_push_queue(struct i
                               struct ieee80211_sub_if_data *sdata,
                               struct ieee80211_txq *queue)
  {
-       int q = sdata->vif.hw_queue[queue->ac];
        struct ieee80211_tx_control control = {
                .sta = queue->sta,
        };
        struct sk_buff *skb;
-       unsigned long flags;
-       bool q_stopped;
  
        while (1) {
-               spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-               q_stopped = local->queue_stop_reasons[q];
-               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-               if (q_stopped)
-                       break;
                skb = ieee80211_tx_dequeue(&local->hw, queue);
                if (!skb)
                        break;
@@@ -347,8 -337,6 +337,6 @@@ static void __ieee80211_wake_txqs(struc
        local_bh_disable();
        spin_lock(&fq->lock);
  
-       sdata->vif.txqs_stopped[ac] = false;
        if (!test_bit(SDATA_STATE_RUNNING, &sdata->state))
                goto out;
  
                        if (ac != txq->ac)
                                continue;
  
-                       if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX,
+                       if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY,
                                                &txqi->flags))
                                continue;
  
  
        txqi = to_txq_info(vif->txq);
  
-       if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) ||
+       if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) ||
            (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
                goto out;
  
@@@ -517,8 -505,6 +505,6 @@@ static void __ieee80211_stop_queue(stru
                                   bool refcounted)
  {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_sub_if_data *sdata;
-       int n_acs = IEEE80211_NUM_ACS;
  
        trace_stop_queue(local, queue, reason);
  
        else
                local->q_stop_reasons[queue][reason]++;
  
-       if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
-               return;
-       if (local->hw.queues < IEEE80211_NUM_ACS)
-               n_acs = 1;
-       rcu_read_lock();
-       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-               int ac;
-               if (!sdata->dev)
-                       continue;
-               for (ac = 0; ac < n_acs; ac++) {
-                       if (sdata->vif.hw_queue[ac] == queue ||
-                           sdata->vif.cab_queue == queue) {
-                               spin_lock(&local->fq.lock);
-                               sdata->vif.txqs_stopped[ac] = true;
-                               spin_unlock(&local->fq.lock);
-                       }
-               }
-       }
-       rcu_read_unlock();
+       set_bit(reason, &local->queue_stop_reasons[queue]);
  }
  
  void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@@ -868,6 -832,19 +832,6 @@@ static void __iterate_stations(struct i
        }
  }
  
 -void ieee80211_iterate_stations(struct ieee80211_hw *hw,
 -                              void (*iterator)(void *data,
 -                                               struct ieee80211_sta *sta),
 -                              void *data)
 -{
 -      struct ieee80211_local *local = hw_to_local(hw);
 -
 -      mutex_lock(&local->sta_mtx);
 -      __iterate_stations(local, iterator, data);
 -      mutex_unlock(&local->sta_mtx);
 -}
 -EXPORT_SYMBOL_GPL(ieee80211_iterate_stations);
 -
  void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
                        void (*iterator)(void *data,
                                         struct ieee80211_sta *sta),