1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2021 MediaTek Inc. */
4 #include <linux/iopoll.h>
5 #include <linux/mmc/sdio_func.h>
7 #include "../mt76_connac2_mac.h"
10 static void mt7921s_enable_irq(struct mt76_dev
*dev
)
12 struct mt76_sdio
*sdio
= &dev
->sdio
;
14 sdio_claim_host(sdio
->func
);
15 sdio_writel(sdio
->func
, WHLPCR_INT_EN_SET
, MCR_WHLPCR
, NULL
);
16 sdio_release_host(sdio
->func
);
19 static void mt7921s_disable_irq(struct mt76_dev
*dev
)
21 struct mt76_sdio
*sdio
= &dev
->sdio
;
23 sdio_claim_host(sdio
->func
);
24 sdio_writel(sdio
->func
, WHLPCR_INT_EN_CLR
, MCR_WHLPCR
, NULL
);
25 sdio_release_host(sdio
->func
);
28 static u32
mt7921s_read_whcr(struct mt76_dev
*dev
)
30 return sdio_readl(dev
->sdio
.func
, MCR_WHCR
, NULL
);
33 int mt7921s_wfsys_reset(struct mt792x_dev
*dev
)
35 struct mt76_sdio
*sdio
= &dev
->mt76
.sdio
;
38 mt7921s_mcu_drv_pmctrl(dev
);
40 sdio_claim_host(sdio
->func
);
42 val
= sdio_readl(sdio
->func
, MCR_WHCR
, NULL
);
43 val
&= ~WF_WHOLE_PATH_RSTB
;
44 sdio_writel(sdio
->func
, val
, MCR_WHCR
, NULL
);
48 val
= sdio_readl(sdio
->func
, MCR_WHCR
, NULL
);
49 val
&= ~WF_SDIO_WF_PATH_RSTB
;
50 sdio_writel(sdio
->func
, val
, MCR_WHCR
, NULL
);
52 usleep_range(1000, 2000);
54 val
= sdio_readl(sdio
->func
, MCR_WHCR
, NULL
);
55 val
|= WF_WHOLE_PATH_RSTB
;
56 sdio_writel(sdio
->func
, val
, MCR_WHCR
, NULL
);
58 readx_poll_timeout(mt7921s_read_whcr
, &dev
->mt76
, status
,
59 status
& WF_RST_DONE
, 50000, 2000000);
61 sdio_release_host(sdio
->func
);
63 clear_bit(MT76_STATE_MCU_RUNNING
, &dev
->mphy
.state
);
65 /* activate mt7921s again */
66 mt7921s_mcu_drv_pmctrl(dev
);
67 mt76_clear(dev
, MT_CONN_STATUS
, MT_WIFI_PATCH_DL_STATE
);
68 mt7921s_mcu_fw_pmctrl(dev
);
69 mt7921s_mcu_drv_pmctrl(dev
);
74 int mt7921s_init_reset(struct mt792x_dev
*dev
)
76 set_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
78 wake_up(&dev
->mt76
.mcu
.wait
);
79 skb_queue_purge(&dev
->mt76
.mcu
.res_q
);
80 wait_event_timeout(dev
->mt76
.sdio
.wait
,
81 mt76s_txqs_empty(&dev
->mt76
), 5 * HZ
);
82 mt76_worker_disable(&dev
->mt76
.sdio
.txrx_worker
);
84 mt7921s_disable_irq(&dev
->mt76
);
85 mt7921s_wfsys_reset(dev
);
87 mt76_worker_enable(&dev
->mt76
.sdio
.txrx_worker
);
88 clear_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
89 mt7921s_enable_irq(&dev
->mt76
);
94 int mt7921s_mac_reset(struct mt792x_dev
*dev
)
98 mt76_connac_free_pending_tx_skbs(&dev
->pm
, NULL
);
99 mt76_txq_schedule_all(&dev
->mphy
);
100 mt76_worker_disable(&dev
->mt76
.tx_worker
);
101 set_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
102 wake_up(&dev
->mt76
.mcu
.wait
);
103 skb_queue_purge(&dev
->mt76
.mcu
.res_q
);
104 wait_event_timeout(dev
->mt76
.sdio
.wait
,
105 mt76s_txqs_empty(&dev
->mt76
), 5 * HZ
);
106 mt76_worker_disable(&dev
->mt76
.sdio
.txrx_worker
);
107 mt76_worker_disable(&dev
->mt76
.sdio
.status_worker
);
108 mt76_worker_disable(&dev
->mt76
.sdio
.net_worker
);
109 mt76_worker_disable(&dev
->mt76
.sdio
.stat_worker
);
111 mt7921s_disable_irq(&dev
->mt76
);
112 mt7921s_wfsys_reset(dev
);
114 mt76_worker_enable(&dev
->mt76
.sdio
.txrx_worker
);
115 mt76_worker_enable(&dev
->mt76
.sdio
.status_worker
);
116 mt76_worker_enable(&dev
->mt76
.sdio
.net_worker
);
117 mt76_worker_enable(&dev
->mt76
.sdio
.stat_worker
);
119 dev
->fw_assert
= false;
120 clear_bit(MT76_MCU_RESET
, &dev
->mphy
.state
);
121 mt7921s_enable_irq(&dev
->mt76
);
123 err
= mt7921_run_firmware(dev
);
127 err
= mt7921_mcu_set_eeprom(dev
);
131 err
= mt7921_mac_init(dev
);
135 err
= __mt7921_start(&dev
->phy
);
138 mt76_worker_enable(&dev
->mt76
.tx_worker
);