void
 mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 {
-       struct mt76x02_dev *dev = (struct mt76x02_dev *)priv;
+       struct beacon_bc_data *data = priv;
+       struct mt76x02_dev *dev = data->dev;
        struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
        struct sk_buff *skb = NULL;
 
        if (!skb)
                return;
 
-       mt76x02_mac_set_beacon(dev, skb);
+       __skb_queue_tail(&data->q, skb);
 }
 EXPORT_SYMBOL_GPL(mt76x02_update_beacon_iter);
 
 {
        int i, nframes;
 
-       data->dev = dev;
-       __skb_queue_head_init(&data->q);
-
        do {
                nframes = skb_queue_len(&data->q);
                ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
 
        struct mt76x02_dev *dev = from_tasklet(dev, t, mt76.pre_tbtt_tasklet);
        struct mt76_dev *mdev = &dev->mt76;
        struct mt76_queue *q = dev->mphy.q_tx[MT_TXQ_PSD];
-       struct beacon_bc_data data = {};
+       struct beacon_bc_data data = {
+               .dev = dev,
+       };
        struct sk_buff *skb;
        int i;
 
        if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
                return;
 
+       __skb_queue_head_init(&data.q);
+
        mt76x02_resync_beacon_timer(dev);
 
        /* Prevent corrupt transmissions during update */
 
        ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
                IEEE80211_IFACE_ITER_RESUME_ALL,
-               mt76x02_update_beacon_iter, dev);
+               mt76x02_update_beacon_iter, &data);
+
+       while ((skb = __skb_dequeue(&data.q)) != NULL)
+               mt76x02_mac_set_beacon(dev, skb);
 
        mt76_wr(dev, MT_BCN_BYPASS_MASK,
                0xff00 | ~(0xff00 >> dev->beacon_data_count));
 
 {
        struct mt76x02_dev *dev =
                container_of(work, struct mt76x02_dev, pre_tbtt_work);
-       struct beacon_bc_data data = {};
+       struct beacon_bc_data data = {
+               .dev = dev,
+       };
        struct sk_buff *skb;
        int nbeacons;
 
        if (mt76_hw(dev)->conf.flags & IEEE80211_CONF_OFFCHANNEL)
                return;
 
+       __skb_queue_head_init(&data.q);
+
        mt76x02_resync_beacon_timer(dev);
 
        /* Prevent corrupt transmissions during update */
        mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff);
        dev->beacon_data_count = 0;
 
-       ieee80211_iterate_active_interfaces(mt76_hw(dev),
+       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
                IEEE80211_IFACE_ITER_RESUME_ALL,
-               mt76x02_update_beacon_iter, dev);
+               mt76x02_update_beacon_iter, &data);
+
+       while ((skb = __skb_dequeue(&data.q)) != NULL)
+               mt76x02_mac_set_beacon(dev, skb);
 
        mt76_csa_check(&dev->mt76);