Skip to content

Commit b9a3473

Browse files
committed
wifi: mt76: mt7925: add handler to hif suspend/resume event
jira LE-3460 Rebuild_History Non-Buildable kernel-6.12.0-55.11.1.el10_0 commit-author Quan Zhou <[email protected]> commit 8f6571a When the system suspend or resume, the WiFi driver sends an hif_ctrl command to the firmware and waits for an event. Due to changes in the event format reported by the chip, the current mt7925's driver does not account for these changes, resulting in command timeout. Add flow to handle hif_ctrl event to avoid command timeout. We also exented API mt76_connac_mcu_set_hif_suspend for connac3 this time. Signed-off-by: Quan Zhou <[email protected]> Link: https://patch.msgid.link/3a0844ff5162142c4a9f3cf7104f75076ddd3b87.1735910562.git.quan.zhou@mediatek.com Signed-off-by: Felix Fietkau <[email protected]> (cherry picked from commit 8f6571a) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 8b6dfa2 commit b9a3473

File tree

14 files changed

+127
-34
lines changed

14 files changed

+127
-34
lines changed

drivers/net/wireless/mediatek/mt76/mt7615/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
12491249
phy->mt76);
12501250

12511251
if (!mt7615_dev_running(dev))
1252-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
1252+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
12531253

12541254
mt7615_mutex_release(dev);
12551255

@@ -1271,7 +1271,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
12711271
if (!running) {
12721272
int err;
12731273

1274-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
1274+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
12751275
if (err < 0) {
12761276
mt7615_mutex_release(dev);
12771277
return err;

drivers/net/wireless/mediatek/mt76/mt7615/pci.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
8383
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
8484
mt7615_firmware_offload(dev);
8585
if (hif_suspend) {
86-
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
86+
err = mt76_connac_mcu_set_hif_suspend(mdev, true, true);
8787
if (err)
8888
return err;
8989
}
@@ -131,7 +131,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
131131
}
132132
napi_enable(&mdev->tx_napi);
133133
if (hif_suspend)
134-
mt76_connac_mcu_set_hif_suspend(mdev, false);
134+
mt76_connac_mcu_set_hif_suspend(mdev, false, true);
135135

136136
return err;
137137
}
@@ -175,7 +175,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
175175

176176
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
177177
mt7615_firmware_offload(dev))
178-
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
178+
err = mt76_connac_mcu_set_hif_suspend(mdev, false, true);
179179

180180
return err;
181181
}

drivers/net/wireless/mediatek/mt76/mt7615/sdio.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static int mt7663s_suspend(struct device *dev)
191191
mt7615_firmware_offload(mdev)) {
192192
int err;
193193

194-
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, true);
194+
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, true, true);
195195
if (err < 0)
196196
return err;
197197
}
@@ -230,7 +230,7 @@ static int mt7663s_resume(struct device *dev)
230230

231231
if (!test_bit(MT76_STATE_SUSPEND, &mdev->mphy.state) &&
232232
mt7615_firmware_offload(mdev))
233-
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, false);
233+
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, false, true);
234234

235235
return err;
236236
}

drivers/net/wireless/mediatek/mt76/mt7615/usb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static int mt7663u_suspend(struct usb_interface *intf, pm_message_t state)
225225
mt7615_firmware_offload(dev)) {
226226
int err;
227227

228-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
228+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
229229
if (err < 0)
230230
return err;
231231
}
@@ -253,7 +253,7 @@ static int mt7663u_resume(struct usb_interface *intf)
253253

254254
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
255255
mt7615_firmware_offload(dev))
256-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
256+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
257257

258258
return err;
259259
}

drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2527,7 +2527,7 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
25272527
}
25282528
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_wow_ctrl);
25292529

2530-
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2530+
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp)
25312531
{
25322532
struct {
25332533
struct {
@@ -2559,7 +2559,7 @@ int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
25592559
req.hdr.hif_type = 0;
25602560

25612561
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
2562-
sizeof(req), true);
2562+
sizeof(req), wait_resp);
25632563
}
25642564
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
25652565

drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ enum {
10491049
/* unified event table */
10501050
enum {
10511051
MCU_UNI_EVENT_RESULT = 0x01,
1052+
MCU_UNI_EVENT_HIF_CTRL = 0x03,
10521053
MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04,
10531054
MCU_UNI_EVENT_ACCESS_REG = 0x6,
10541055
MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
@@ -1988,7 +1989,7 @@ int mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
19881989
struct ieee80211_vif *vif,
19891990
bool enable, u8 mdtim,
19901991
bool wow_suspend);
1991-
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
1992+
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp);
19921993
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
19931994
struct ieee80211_vif *vif);
19941995
int mt76_connac_sta_state_dp(struct mt76_dev *dev,

drivers/net/wireless/mediatek/mt76/mt7921/pci.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ static int mt7921_pci_suspend(struct device *device)
435435
if (err < 0)
436436
goto restore_suspend;
437437

438-
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
438+
err = mt76_connac_mcu_set_hif_suspend(mdev, true, true);
439439
if (err)
440440
goto restore_suspend;
441441

@@ -481,7 +481,7 @@ static int mt7921_pci_suspend(struct device *device)
481481
if (!pm->ds_enable)
482482
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
483483

484-
mt76_connac_mcu_set_hif_suspend(mdev, false);
484+
mt76_connac_mcu_set_hif_suspend(mdev, false, true);
485485

486486
restore_suspend:
487487
pm->suspended = false;
@@ -532,7 +532,7 @@ static int mt7921_pci_resume(struct device *device)
532532
if (!pm->ds_enable)
533533
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
534534

535-
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
535+
err = mt76_connac_mcu_set_hif_suspend(mdev, false, true);
536536
if (err < 0)
537537
goto failed;
538538

drivers/net/wireless/mediatek/mt76/mt7921/sdio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static int mt7921s_suspend(struct device *__dev)
240240
mt76s_txqs_empty(&dev->mt76), 5 * HZ);
241241

242242
/* It is supposed that SDIO bus is idle at the point */
243-
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
243+
err = mt76_connac_mcu_set_hif_suspend(mdev, true, true);
244244
if (err)
245245
goto restore_worker;
246246

@@ -258,7 +258,7 @@ static int mt7921s_suspend(struct device *__dev)
258258
restore_txrx_worker:
259259
mt76_worker_enable(&mdev->sdio.net_worker);
260260
mt76_worker_enable(&mdev->sdio.txrx_worker);
261-
mt76_connac_mcu_set_hif_suspend(mdev, false);
261+
mt76_connac_mcu_set_hif_suspend(mdev, false, true);
262262

263263
restore_worker:
264264
mt76_worker_enable(&mdev->tx_worker);
@@ -302,7 +302,7 @@ static int mt7921s_resume(struct device *__dev)
302302
if (!pm->ds_enable)
303303
mt76_connac_mcu_set_deep_sleep(mdev, false);
304304

305-
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
305+
err = mt76_connac_mcu_set_hif_suspend(mdev, false, true);
306306
failed:
307307
pm->suspended = false;
308308

drivers/net/wireless/mediatek/mt76/mt7921/usb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
257257
pm->suspended = true;
258258
flush_work(&dev->reset_work);
259259

260-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
260+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
261261
if (err)
262262
goto failed;
263263

@@ -307,7 +307,7 @@ static int mt7921u_resume(struct usb_interface *intf)
307307
if (err < 0)
308308
goto failed;
309309

310-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
310+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
311311
failed:
312312
pm->suspended = false;
313313

drivers/net/wireless/mediatek/mt76/mt7925/mcu.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd,
3939
} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
4040
cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
4141
cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
42-
cmd == MCU_UNI_CMD(HIF_CTRL) ||
4342
cmd == MCU_UNI_CMD(OFFLOAD) ||
4443
cmd == MCU_UNI_CMD(SUSPEND)) {
4544
struct mt7925_mcu_uni_event *event;
@@ -343,6 +342,51 @@ static void mt7925_mcu_roc_handle_grant(struct mt792x_dev *dev,
343342
jiffies + msecs_to_jiffies(duration));
344343
}
345344

345+
static void
346+
mt7925_mcu_handle_hif_ctrl_basic(struct mt792x_dev *dev, struct tlv *tlv)
347+
{
348+
struct mt7925_mcu_hif_ctrl_basic_tlv *basic;
349+
350+
basic = (struct mt7925_mcu_hif_ctrl_basic_tlv *)tlv;
351+
352+
if (basic->hifsuspend) {
353+
if (basic->hif_tx_traffic_status == HIF_TRAFFIC_IDLE &&
354+
basic->hif_rx_traffic_status == HIF_TRAFFIC_IDLE)
355+
/* success */
356+
dev->hif_idle = true;
357+
else
358+
/* busy */
359+
/* invalid */
360+
dev->hif_idle = false;
361+
} else {
362+
dev->hif_resumed = true;
363+
}
364+
wake_up(&dev->wait);
365+
}
366+
367+
static void
368+
mt7925_mcu_uni_hif_ctrl_event(struct mt792x_dev *dev, struct sk_buff *skb)
369+
{
370+
struct tlv *tlv;
371+
u32 tlv_len;
372+
373+
skb_pull(skb, sizeof(struct mt7925_mcu_rxd) + 4);
374+
tlv = (struct tlv *)skb->data;
375+
tlv_len = skb->len;
376+
377+
while (tlv_len > 0 && le16_to_cpu(tlv->len) <= tlv_len) {
378+
switch (le16_to_cpu(tlv->tag)) {
379+
case UNI_EVENT_HIF_CTRL_BASIC:
380+
mt7925_mcu_handle_hif_ctrl_basic(dev, tlv);
381+
break;
382+
default:
383+
break;
384+
}
385+
tlv_len -= le16_to_cpu(tlv->len);
386+
tlv = (struct tlv *)((char *)(tlv) + le16_to_cpu(tlv->len));
387+
}
388+
}
389+
346390
static void
347391
mt7925_mcu_uni_roc_event(struct mt792x_dev *dev, struct sk_buff *skb)
348392
{
@@ -489,6 +533,9 @@ mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
489533
rxd = (struct mt7925_mcu_rxd *)skb->data;
490534

491535
switch (rxd->eid) {
536+
case MCU_UNI_EVENT_HIF_CTRL:
537+
mt7925_mcu_uni_hif_ctrl_event(dev, skb);
538+
break;
492539
case MCU_UNI_EVENT_FW_LOG_2_HOST:
493540
mt7925_mcu_uni_debug_msg_event(dev, skb);
494541
break;

0 commit comments

Comments
 (0)