| From d3c4bfceae589098cb6cba5a3bb9125144df29fb Mon Sep 17 00:00:00 2001 |
| From: Michael-CY Lee <michael-cy.lee@mediatek.com> |
| Date: Tue, 14 May 2024 10:52:43 +0800 |
| Subject: [PATCH 131/199] mtk: mt76: mt7996: fix set beacon mcu command |
| |
| When stopping AP, mac80211 frees beacon template before it calls |
| driver's stop_ap operation. In other words, on the path of stopping |
| AP, ieee80211_beacon_get_template() must returns NULL in |
| mt7996_mcu_add_beacon(). In such case mt7996 immediately returns |
| -EINVAL without telling FW to disable the beacon. |
| |
| This commit refactors mt7996_mcu_add_beacon() so that FW can be |
| correctly informed when disabling AP interface. |
| |
| Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com> |
| --- |
| mt7996/mcu.c | 26 +++++++++++++++----------- |
| 1 file changed, 15 insertions(+), 11 deletions(-) |
| |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index 2a2e6116..0a0df745 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -3377,7 +3377,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, |
| struct sk_buff *skb, *rskb; |
| struct tlv *tlv; |
| struct bss_bcn_content_tlv *bcn; |
| - int len; |
| + int len, extra_len = 0; |
| |
| if (conf->nontransmitted) |
| return 0; |
| @@ -3388,28 +3388,32 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, |
| return PTR_ERR(rskb); |
| |
| skb = ieee80211_beacon_get_template(hw, conf->vif, &offs, conf->link_id); |
| - if (!skb) { |
| + if (en && !skb) { |
| dev_kfree_skb(rskb); |
| return -EINVAL; |
| } |
| |
| - if (skb->len > MT7996_MAX_BEACON_SIZE) { |
| - dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); |
| - dev_kfree_skb(rskb); |
| - dev_kfree_skb(skb); |
| - return -EINVAL; |
| - } |
| + if (skb) { |
| + if (skb->len > MT7996_MAX_BEACON_SIZE) { |
| + dev_err(dev->mt76.dev, "Bcn size limit exceed\n"); |
| + dev_kfree_skb(rskb); |
| + dev_kfree_skb(skb); |
| + return -EINVAL; |
| + } |
| |
| - info = IEEE80211_SKB_CB(skb); |
| - info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); |
| + extra_len = skb->len; |
| + } |
| |
| - len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4); |
| + len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + extra_len, 4); |
| tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len); |
| bcn = (struct bss_bcn_content_tlv *)tlv; |
| bcn->enable = en; |
| if (!en) |
| goto out; |
| |
| + info = IEEE80211_SKB_CB(skb); |
| + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); |
| + |
| mt7996_mcu_beacon_cont(dev, conf, rskb, skb, bcn, &offs); |
| mt7996_mcu_beacon_mbss(rskb, skb, conf, bcn, &offs); |
| mt7996_mcu_beacon_cntdwn(conf, rskb, skb, &offs); |
| -- |
| 2.18.0 |
| |