blob: 1b39d7fdb56daa91b4bda70e94a16ffbe2041c4b [file] [log] [blame]
developerd0c89452024-10-11 16:53:27 +08001From 50cf21c286aa55676fa5a341781c5e72aa4758f5 Mon Sep 17 00:00:00 2001
developer05f3b2b2024-08-19 19:17:34 +08002From: Michael-CY Lee <michael-cy.lee@mediatek.com>
3Date: Tue, 14 May 2024 10:52:43 +0800
developerd0c89452024-10-11 16:53:27 +08004Subject: [PATCH 119/223] mtk: mt76: mt7996: fix set beacon mcu command
developer05f3b2b2024-08-19 19:17:34 +08005
6When stopping AP, mac80211 frees beacon template before it calls
7driver's stop_ap operation. In other words, on the path of stopping
8AP, ieee80211_beacon_get_template() must returns NULL in
9mt7996_mcu_add_beacon(). In such case mt7996 immediately returns
10-EINVAL without telling FW to disable the beacon.
11
12This commit refactors mt7996_mcu_add_beacon() so that FW can be
13correctly informed when disabling AP interface.
14
developerd0c89452024-10-11 16:53:27 +080015Change-Id: I7a381f959e50579266aa1fa4c2a3f9a907f4318e
developer05f3b2b2024-08-19 19:17:34 +080016Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
17---
18 mt7996/mcu.c | 26 +++++++++++++++-----------
19 1 file changed, 15 insertions(+), 11 deletions(-)
20
21diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +080022index 76f0bb7e..1dcc367e 100644
developer05f3b2b2024-08-19 19:17:34 +080023--- a/mt7996/mcu.c
24+++ b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +080025@@ -3384,7 +3384,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
developer05f3b2b2024-08-19 19:17:34 +080026 struct sk_buff *skb, *rskb;
27 struct tlv *tlv;
28 struct bss_bcn_content_tlv *bcn;
29- int len;
30+ int len, extra_len = 0;
31
32 if (conf->nontransmitted)
33 return 0;
developerd0c89452024-10-11 16:53:27 +080034@@ -3395,28 +3395,32 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
developer05f3b2b2024-08-19 19:17:34 +080035 return PTR_ERR(rskb);
36
37 skb = ieee80211_beacon_get_template(hw, conf->vif, &offs, conf->link_id);
38- if (!skb) {
39+ if (en && !skb) {
40 dev_kfree_skb(rskb);
41 return -EINVAL;
42 }
43
44- if (skb->len > MT7996_MAX_BEACON_SIZE) {
45- dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
46- dev_kfree_skb(rskb);
47- dev_kfree_skb(skb);
48- return -EINVAL;
49- }
50+ if (skb) {
51+ if (skb->len > MT7996_MAX_BEACON_SIZE) {
52+ dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
53+ dev_kfree_skb(rskb);
54+ dev_kfree_skb(skb);
55+ return -EINVAL;
56+ }
57
58- info = IEEE80211_SKB_CB(skb);
59- info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
60+ extra_len = skb->len;
61+ }
62
63- len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4);
64+ len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + extra_len, 4);
65 tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);
66 bcn = (struct bss_bcn_content_tlv *)tlv;
67 bcn->enable = en;
68 if (!en)
69 goto out;
70
71+ info = IEEE80211_SKB_CB(skb);
72+ info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
73+
74 mt7996_mcu_beacon_cont(dev, conf, rskb, skb, bcn, &offs);
75 mt7996_mcu_beacon_mbss(rskb, skb, conf, bcn, &offs);
76 mt7996_mcu_beacon_cntdwn(conf, rskb, skb, &offs);
77--
developerd0c89452024-10-11 16:53:27 +0800782.45.2
developer05f3b2b2024-08-19 19:17:34 +080079