Skip to content

Commit 8f6571a

Browse files
Quanzhoucennbd168
authored andcommitted
wifi: mt76: mt7925: add handler to hif suspend/resume event
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]>
1 parent a0f721b commit 8f6571a

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
@@ -1248,7 +1248,7 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
12481248
phy->mt76);
12491249

12501250
if (!mt7615_dev_running(dev))
1251-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
1251+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
12521252

12531253
mt7615_mutex_release(dev);
12541254

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

1273-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
1273+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
12741274
if (err < 0) {
12751275
mt7615_mutex_release(dev);
12761276
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
@@ -2534,7 +2534,7 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
25342534
}
25352535
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_wow_ctrl);
25362536

2537-
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2537+
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp)
25382538
{
25392539
struct {
25402540
struct {
@@ -2566,7 +2566,7 @@ int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
25662566
req.hdr.hif_type = 0;
25672567

25682568
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
2569-
sizeof(req), true);
2569+
sizeof(req), wait_resp);
25702570
}
25712571
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
25722572

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ enum {
10501050
/* unified event table */
10511051
enum {
10521052
MCU_UNI_EVENT_RESULT = 0x01,
1053+
MCU_UNI_EVENT_HIF_CTRL = 0x03,
10531054
MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04,
10541055
MCU_UNI_EVENT_ACCESS_REG = 0x6,
10551056
MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
@@ -1992,7 +1993,7 @@ int mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
19921993
struct ieee80211_vif *vif,
19931994
bool enable, u8 mdtim,
19941995
bool wow_suspend);
1995-
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
1996+
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp);
19961997
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
19971998
struct ieee80211_vif *vif);
19981999
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
@@ -439,7 +439,7 @@ static int mt7921_pci_suspend(struct device *device)
439439
if (err < 0)
440440
goto restore_suspend;
441441

442-
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
442+
err = mt76_connac_mcu_set_hif_suspend(mdev, true, true);
443443
if (err)
444444
goto restore_suspend;
445445

@@ -485,7 +485,7 @@ static int mt7921_pci_suspend(struct device *device)
485485
if (!pm->ds_enable)
486486
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
487487

488-
mt76_connac_mcu_set_hif_suspend(mdev, false);
488+
mt76_connac_mcu_set_hif_suspend(mdev, false, true);
489489

490490
restore_suspend:
491491
pm->suspended = false;
@@ -536,7 +536,7 @@ static int mt7921_pci_resume(struct device *device)
536536
if (!pm->ds_enable)
537537
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
538538

539-
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
539+
err = mt76_connac_mcu_set_hif_suspend(mdev, false, true);
540540
if (err < 0)
541541
goto failed;
542542

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
@@ -260,7 +260,7 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
260260
pm->suspended = true;
261261
flush_work(&dev->reset_work);
262262

263-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
263+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true, true);
264264
if (err)
265265
goto failed;
266266

@@ -310,7 +310,7 @@ static int mt7921u_resume(struct usb_interface *intf)
310310
if (err < 0)
311311
goto failed;
312312

313-
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
313+
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false, true);
314314
failed:
315315
pm->suspended = false;
316316

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;
@@ -341,6 +340,51 @@ static void mt7925_mcu_roc_handle_grant(struct mt792x_dev *dev,
341340
jiffies + msecs_to_jiffies(duration));
342341
}
343342

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

489533
switch (rxd->eid) {
534+
case MCU_UNI_EVENT_HIF_CTRL:
535+
mt7925_mcu_uni_hif_ctrl_event(dev, skb);
536+
break;
490537
case MCU_UNI_EVENT_FW_LOG_2_HOST:
491538
mt7925_mcu_uni_debug_msg_event(dev, skb);
492539
break;

0 commit comments

Comments
 (0)