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
->mt76
.beacon_mask
& BIT(mvif
->idx
)))
22 skb
= ieee80211_beacon_get(mt76_hw(dev
), vif
);
26 mt76_tx_queue_skb(dev
, MT_TXQ_BEACON
, skb
, &mvif
->sta
.wcid
, NULL
);
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));
36 if (!mt76_poll(dev
, MT_DMA_FQCR0
, MT_DMA_FQCR0_BUSY
, 0, 5000))
37 dev
->beacon_check
= MT7603_WATCHDOG_TIMEOUT
;
39 spin_unlock_bh(&dev
->ps_lock
);
43 mt7603_add_buffered_bc(void *priv
, u8
*mac
, struct ieee80211_vif
*vif
)
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
;
51 if (!(dev
->mt76
.beacon_mask
& BIT(mvif
->idx
)))
54 skb
= ieee80211_get_buffered_bc(mt76_hw(dev
), vif
);
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
]++;
67 void mt7603_pre_tbtt_tasklet(unsigned long arg
)
69 struct mt7603_dev
*dev
= (struct mt7603_dev
*)arg
;
71 struct beacon_bc_data data
= {};
75 if (mt76_hw(dev
)->conf
.flags
& IEEE80211_CONF_OFFCHANNEL
)
79 __skb_queue_head_init(&data
.q
);
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
);
89 /* Flush all previous CAB queue packets */
90 mt76_wr(dev
, MT_WF_ARB_CAB_FLUSH
, GENMASK(30, 16) | BIT(0));
92 mt76_queue_tx_cleanup(dev
, MT_TXQ_CAB
, false);
94 mt76_csa_check(&dev
->mt76
);
95 if (dev
->mt76
.csa_complete
)
98 q
= dev
->mt76
.q_tx
[MT_TXQ_CAB
].q
;
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);
107 if (skb_queue_empty(&data
.q
))
110 for (i
= 0; i
< ARRAY_SIZE(data
.tail
); i
++) {
114 mt76_skb_set_moredata(data
.tail
[i
], false);
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
;
123 mt76_tx_queue_skb(dev
, MT_TXQ_CAB
, skb
, &mvif
->sta
.wcid
, NULL
);
125 mt76_queue_kick(dev
, q
);
126 spin_unlock_bh(&q
->lock
);
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
));
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)));
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
))
144 void mt7603_beacon_set_timer(struct mt7603_dev
*dev
, int idx
, int intval
)
146 u32 pre_tbtt
= MT7603_PRE_TBTT_TIME
/ 64;
150 dev
->mt76
.beacon_mask
|= BIT(idx
);
152 dev
->mt76
.beacon_mask
&= ~BIT(idx
);
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);
162 dev
->mt76
.beacon_int
= intval
;
163 mt76_wr(dev
, MT_TBTT
,
164 FIELD_PREP(MT_TBTT_PERIOD
, intval
) | MT_TBTT_CAL_ENABLE
);
166 mt76_wr(dev
, MT_TBTT_TIMER_CFG
, 0x99); /* start timer */
168 mt76_rmw_field(dev
, MT_ARB_SCR
, MT_ARB_SCR_BCNQ_OPMODE_MASK
,
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
);
173 mt76_wr(dev
, MT_PRE_TBTT
, pre_tbtt
);
175 mt76_set(dev
, MT_HW_INT_MASK(3),
176 MT_HW_INT3_PRE_TBTT0
| MT_HW_INT3_TBTT0
);
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
);
184 if (dev
->mt76
.beacon_mask
& ~BIT(0))
185 mt76_set(dev
, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN
);
187 mt76_clear(dev
, MT_LPON_SBTOR(0), MT_LPON_SBTOR_SUB_BSS_EN
);