1 /* SPDX-License-Identifier: ISC */
5 struct beacon_bc_data
{
6 struct mt7603_dev
*dev
;
8 struct sk_buff
*tail
[MT7603_MAX_INTERFACES
];
9 int count
[MT7603_MAX_INTERFACES
];
13 mt7603_update_beacon_iter(void *priv
, u8
*mac
, struct ieee80211_vif
*vif
)
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
;
19 if (!(dev
->beacon_mask
& BIT(mvif
->idx
)))
22 skb
= ieee80211_beacon_get(mt76_hw(dev
), vif
);
26 mt76_dma_tx_queue_skb(&dev
->mt76
, &dev
->mt76
.q_tx
[MT_TXQ_BEACON
], skb
,
27 &mvif
->sta
.wcid
, NULL
);
29 spin_lock_bh(&dev
->ps_lock
);
30 mt76_wr(dev
, MT_DMA_FQCR0
, MT_DMA_FQCR0_BUSY
|
31 FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID
, mvif
->sta
.wcid
.idx
) |
32 FIELD_PREP(MT_DMA_FQCR0_TARGET_QID
,
33 dev
->mt76
.q_tx
[MT_TXQ_CAB
].hw_idx
) |
34 FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID
, 3) |
35 FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID
, 8));
37 if (!mt76_poll(dev
, MT_DMA_FQCR0
, MT_DMA_FQCR0_BUSY
, 0, 5000))
38 dev
->beacon_check
= MT7603_WATCHDOG_TIMEOUT
;
40 spin_unlock_bh(&dev
->ps_lock
);
44 mt7603_add_buffered_bc(void *priv
, u8
*mac
, struct ieee80211_vif
*vif
)
46 struct beacon_bc_data
*data
= priv
;
47 struct mt7603_dev
*dev
= data
->dev
;
48 struct mt7603_vif
*mvif
= (struct mt7603_vif
*)vif
->drv_priv
;
49 struct ieee80211_tx_info
*info
;
52 if (!(dev
->beacon_mask
& BIT(mvif
->idx
)))
55 skb
= ieee80211_get_buffered_bc(mt76_hw(dev
), vif
);
59 info
= IEEE80211_SKB_CB(skb
);
60 info
->control
.vif
= vif
;
61 info
->flags
|= IEEE80211_TX_CTL_ASSIGN_SEQ
;
62 mt76_skb_set_moredata(skb
, true);
63 __skb_queue_tail(&data
->q
, skb
);
64 data
->tail
[mvif
->idx
] = skb
;
65 data
->count
[mvif
->idx
]++;
68 void mt7603_pre_tbtt_tasklet(unsigned long arg
)
70 struct mt7603_dev
*dev
= (struct mt7603_dev
*)arg
;
72 struct beacon_bc_data data
= {};
77 __skb_queue_head_init(&data
.q
);
79 q
= &dev
->mt76
.q_tx
[MT_TXQ_BEACON
];
80 spin_lock_bh(&q
->lock
);
81 ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev
),
82 IEEE80211_IFACE_ITER_RESUME_ALL
,
83 mt7603_update_beacon_iter
, dev
);
84 mt76_queue_kick(dev
, q
);
85 spin_unlock_bh(&q
->lock
);
87 /* Flush all previous CAB queue packets */
88 mt76_wr(dev
, MT_WF_ARB_CAB_FLUSH
, GENMASK(30, 16) | BIT(0));
90 mt76_queue_tx_cleanup(dev
, MT_TXQ_CAB
, false);
92 mt76_csa_check(&dev
->mt76
);
93 if (dev
->mt76
.csa_complete
)
96 q
= &dev
->mt76
.q_tx
[MT_TXQ_CAB
];
98 nframes
= skb_queue_len(&data
.q
);
99 ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev
),
100 IEEE80211_IFACE_ITER_RESUME_ALL
,
101 mt7603_add_buffered_bc
, &data
);
102 } while (nframes
!= skb_queue_len(&data
.q
) &&
103 skb_queue_len(&data
.q
) < 8);
105 if (skb_queue_empty(&data
.q
))
108 for (i
= 0; i
< ARRAY_SIZE(data
.tail
); i
++) {
112 mt76_skb_set_moredata(data
.tail
[i
], false);
115 spin_lock_bh(&q
->lock
);
116 while ((skb
= __skb_dequeue(&data
.q
)) != NULL
) {
117 struct ieee80211_tx_info
*info
= IEEE80211_SKB_CB(skb
);
118 struct ieee80211_vif
*vif
= info
->control
.vif
;
119 struct mt7603_vif
*mvif
= (struct mt7603_vif
*)vif
->drv_priv
;
121 mt76_dma_tx_queue_skb(&dev
->mt76
, q
, skb
, &mvif
->sta
.wcid
,
124 mt76_queue_kick(dev
, q
);
125 spin_unlock_bh(&q
->lock
);
127 for (i
= 0; i
< ARRAY_SIZE(data
.count
); i
++)
128 mt76_wr(dev
, MT_WF_ARB_CAB_COUNT_B0_REG(i
),
129 data
.count
[i
] << MT_WF_ARB_CAB_COUNT_B0_SHIFT(i
));
131 mt76_wr(dev
, MT_WF_ARB_CAB_START
,
132 MT_WF_ARB_CAB_START_BSSn(0) |
133 (MT_WF_ARB_CAB_START_BSS0n(1) *
134 ((1 << (MT7603_MAX_INTERFACES
- 1)) - 1)));
137 mt76_queue_tx_cleanup(dev
, MT_TXQ_BEACON
, false);
138 if (dev
->mt76
.q_tx
[MT_TXQ_BEACON
].queued
> hweight8(dev
->beacon_mask
))
142 void mt7603_beacon_set_timer(struct mt7603_dev
*dev
, int idx
, int intval
)
144 u32 pre_tbtt
= MT7603_PRE_TBTT_TIME
/ 64;
148 dev
->beacon_mask
|= BIT(idx
);
150 dev
->beacon_mask
&= ~BIT(idx
);
153 if (!dev
->beacon_mask
|| (!intval
&& idx
< 0)) {
154 mt7603_irq_disable(dev
, MT_INT_MAC_IRQ3
);
155 mt76_clear(dev
, MT_ARB_SCR
, MT_ARB_SCR_BCNQ_OPMODE_MASK
);
156 mt76_wr(dev
, MT_HW_INT_MASK(3), 0);
160 dev
->beacon_int
= intval
;
161 mt76_wr(dev
, MT_TBTT
,
162 FIELD_PREP(MT_TBTT_PERIOD
, intval
) | MT_TBTT_CAL_ENABLE
);
164 mt76_wr(dev
, MT_TBTT_TIMER_CFG
, 0x99); /* start timer */
166 mt76_rmw_field(dev
, MT_ARB_SCR
, MT_ARB_SCR_BCNQ_OPMODE_MASK
,
168 mt76_clear(dev
, MT_ARB_SCR
, MT_ARB_SCR_TBTT_BCN_PRIO
);
169 mt76_set(dev
, MT_ARB_SCR
, MT_ARB_SCR_TBTT_BCAST_PRIO
);
171 mt76_wr(dev
, MT_PRE_TBTT
, pre_tbtt
);
173 mt76_set(dev
, MT_HW_INT_MASK(3),
174 MT_HW_INT3_PRE_TBTT0
| MT_HW_INT3_TBTT0
);
176 mt76_set(dev
, MT_WF_ARB_BCN_START
,
177 MT_WF_ARB_BCN_START_BSSn(0) |
178 ((dev
->beacon_mask
>> 1) * MT_WF_ARB_BCN_START_BSS0n(1)));
179 mt7603_irq_enable(dev
, MT_INT_MAC_IRQ3
);
181 if (dev
->beacon_mask
& ~BIT(0))
182 mt76_set(dev
, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN
);
184 mt76_clear(dev
, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN
);