root/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt7603_update_beacon_iter
  2. mt7603_add_buffered_bc
  3. mt7603_pre_tbtt_tasklet
  4. mt7603_beacon_set_timer

   1 // SPDX-License-Identifier: ISC
   2 
   3 #include "mt7603.h"
   4 
   5 struct beacon_bc_data {
   6         struct mt7603_dev *dev;
   7         struct sk_buff_head q;
   8         struct sk_buff *tail[MT7603_MAX_INTERFACES];
   9         int count[MT7603_MAX_INTERFACES];
  10 };
  11 
  12 static void
  13 mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
  14 {
  15         struct mt7603_dev *dev = (struct mt7603_dev *)priv;
  16         struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
  17         struct sk_buff *skb = NULL;
  18 
  19         if (!(dev->mt76.beacon_mask & BIT(mvif->idx)))
  20                 return;
  21 
  22         skb = ieee80211_beacon_get(mt76_hw(dev), vif);
  23         if (!skb)
  24                 return;
  25 
  26         mt76_tx_queue_skb(dev, MT_TXQ_BEACON, skb, &mvif->sta.wcid, NULL);
  27 
  28         spin_lock_bh(&dev->ps_lock);
  29         mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY |
  30                 FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) |
  31                 FIELD_PREP(MT_DMA_FQCR0_TARGET_QID,
  32                            dev->mt76.q_tx[MT_TXQ_CAB].q->hw_idx) |
  33                 FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
  34                 FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8));
  35 
  36         if (!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 5000))
  37                 dev->beacon_check = MT7603_WATCHDOG_TIMEOUT;
  38 
  39         spin_unlock_bh(&dev->ps_lock);
  40 }
  41 
  42 static void
  43 mt7603_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
  44 {
  45         struct beacon_bc_data *data = priv;
  46         struct mt7603_dev *dev = data->dev;
  47         struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
  48         struct ieee80211_tx_info *info;
  49         struct sk_buff *skb;
  50 
  51         if (!(dev->mt76.beacon_mask & BIT(mvif->idx)))
  52                 return;
  53 
  54         skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
  55         if (!skb)
  56                 return;
  57 
  58         info = IEEE80211_SKB_CB(skb);
  59         info->control.vif = vif;
  60         info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
  61         mt76_skb_set_moredata(skb, true);
  62         __skb_queue_tail(&data->q, skb);
  63         data->tail[mvif->idx] = skb;
  64         data->count[mvif->idx]++;
  65 }
  66 
  67 void mt7603_pre_tbtt_tasklet(unsigned long arg)
  68 {
  69         struct mt7603_dev *dev = (struct mt7603_dev *)arg;
  70         struct mt76_queue *q;
  71         struct beacon_bc_data data = {};
  72         struct sk_buff *skb;
  73         int i, nframes;
  74 
  75         if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
  76                 return;
  77 
  78         data.dev = dev;
  79         __skb_queue_head_init(&data.q);
  80 
  81         q = dev->mt76.q_tx[MT_TXQ_BEACON].q;
  82         spin_lock_bh(&q->lock);
  83         ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
  84                 IEEE80211_IFACE_ITER_RESUME_ALL,
  85                 mt7603_update_beacon_iter, dev);
  86         mt76_queue_kick(dev, q);
  87         spin_unlock_bh(&q->lock);
  88 
  89         /* Flush all previous CAB queue packets */
  90         mt76_wr(dev, MT_WF_ARB_CAB_FLUSH, GENMASK(30, 16) | BIT(0));
  91 
  92         mt76_queue_tx_cleanup(dev, MT_TXQ_CAB, false);
  93 
  94         mt76_csa_check(&dev->mt76);
  95         if (dev->mt76.csa_complete)
  96                 goto out;
  97 
  98         q = dev->mt76.q_tx[MT_TXQ_CAB].q;
  99         do {
 100                 nframes = skb_queue_len(&data.q);
 101                 ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
 102                         IEEE80211_IFACE_ITER_RESUME_ALL,
 103                         mt7603_add_buffered_bc, &data);
 104         } while (nframes != skb_queue_len(&data.q) &&
 105                  skb_queue_len(&data.q) < 8);
 106 
 107         if (skb_queue_empty(&data.q))
 108                 goto out;
 109 
 110         for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
 111                 if (!data.tail[i])
 112                         continue;
 113 
 114                 mt76_skb_set_moredata(data.tail[i], false);
 115         }
 116 
 117         spin_lock_bh(&q->lock);
 118         while ((skb = __skb_dequeue(&data.q)) != NULL) {
 119                 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 120                 struct ieee80211_vif *vif = info->control.vif;
 121                 struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
 122 
 123                 mt76_tx_queue_skb(dev, MT_TXQ_CAB, skb, &mvif->sta.wcid, NULL);
 124         }
 125         mt76_queue_kick(dev, q);
 126         spin_unlock_bh(&q->lock);
 127 
 128         for (i = 0; i < ARRAY_SIZE(data.count); i++)
 129                 mt76_wr(dev, MT_WF_ARB_CAB_COUNT_B0_REG(i),
 130                         data.count[i] << MT_WF_ARB_CAB_COUNT_B0_SHIFT(i));
 131 
 132         mt76_wr(dev, MT_WF_ARB_CAB_START,
 133                 MT_WF_ARB_CAB_START_BSSn(0) |
 134                 (MT_WF_ARB_CAB_START_BSS0n(1) *
 135                  ((1 << (MT7603_MAX_INTERFACES - 1)) - 1)));
 136 
 137 out:
 138         mt76_queue_tx_cleanup(dev, MT_TXQ_BEACON, false);
 139         if (dev->mt76.q_tx[MT_TXQ_BEACON].q->queued >
 140             hweight8(dev->mt76.beacon_mask))
 141                 dev->beacon_check++;
 142 }
 143 
 144 void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval)
 145 {
 146         u32 pre_tbtt = MT7603_PRE_TBTT_TIME / 64;
 147 
 148         if (idx >= 0) {
 149                 if (intval)
 150                         dev->mt76.beacon_mask |= BIT(idx);
 151                 else
 152                         dev->mt76.beacon_mask &= ~BIT(idx);
 153         }
 154 
 155         if (!dev->mt76.beacon_mask || (!intval && idx < 0)) {
 156                 mt7603_irq_disable(dev, MT_INT_MAC_IRQ3);
 157                 mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_BCNQ_OPMODE_MASK);
 158                 mt76_wr(dev, MT_HW_INT_MASK(3), 0);
 159                 return;
 160         }
 161 
 162         dev->mt76.beacon_int = intval;
 163         mt76_wr(dev, MT_TBTT,
 164                 FIELD_PREP(MT_TBTT_PERIOD, intval) | MT_TBTT_CAL_ENABLE);
 165 
 166         mt76_wr(dev, MT_TBTT_TIMER_CFG, 0x99); /* start timer */
 167 
 168         mt76_rmw_field(dev, MT_ARB_SCR, MT_ARB_SCR_BCNQ_OPMODE_MASK,
 169                        MT_BCNQ_OPMODE_AP);
 170         mt76_clear(dev, MT_ARB_SCR, MT_ARB_SCR_TBTT_BCN_PRIO);
 171         mt76_set(dev, MT_ARB_SCR, MT_ARB_SCR_TBTT_BCAST_PRIO);
 172 
 173         mt76_wr(dev, MT_PRE_TBTT, pre_tbtt);
 174 
 175         mt76_set(dev, MT_HW_INT_MASK(3),
 176                  MT_HW_INT3_PRE_TBTT0 | MT_HW_INT3_TBTT0);
 177 
 178         mt76_set(dev, MT_WF_ARB_BCN_START,
 179                  MT_WF_ARB_BCN_START_BSSn(0) |
 180                  ((dev->mt76.beacon_mask >> 1) *
 181                   MT_WF_ARB_BCN_START_BSS0n(1)));
 182         mt7603_irq_enable(dev, MT_INT_MAC_IRQ3);
 183 
 184         if (dev->mt76.beacon_mask & ~BIT(0))
 185                 mt76_set(dev, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN);
 186         else
 187                 mt76_clear(dev, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN);
 188 }

/* [<][>][^][v][top][bottom][index][help] */