1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2022 MediaTek Inc.
3  *
4  * Author: Lorenzo Bianconi <lorenzo@kernel.org>
5  */
6 
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/usb.h>
10 
11 #include "mt7921.h"
12 #include "mcu.h"
13 #include "mac.h"
14 
mt7921u_uhw_rr(struct mt76_dev * dev,u32 addr)15 static u32 mt7921u_uhw_rr(struct mt76_dev *dev, u32 addr)
16 {
17 	u32 ret;
18 
19 	mutex_lock(&dev->usb.usb_ctrl_mtx);
20 	ret = ___mt76u_rr(dev, MT_VEND_DEV_MODE,
21 			  USB_DIR_IN | MT_USB_TYPE_UHW_VENDOR, addr);
22 	mutex_unlock(&dev->usb.usb_ctrl_mtx);
23 
24 	return ret;
25 }
26 
mt7921u_uhw_wr(struct mt76_dev * dev,u32 addr,u32 val)27 static void mt7921u_uhw_wr(struct mt76_dev *dev, u32 addr, u32 val)
28 {
29 	mutex_lock(&dev->usb.usb_ctrl_mtx);
30 	___mt76u_wr(dev, MT_VEND_WRITE,
31 		    USB_DIR_OUT | MT_USB_TYPE_UHW_VENDOR, addr, val);
32 	mutex_unlock(&dev->usb.usb_ctrl_mtx);
33 }
34 
mt7921u_dma_prefetch(struct mt7921_dev * dev)35 static void mt7921u_dma_prefetch(struct mt7921_dev *dev)
36 {
37 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0),
38 		 MT_WPDMA0_MAX_CNT_MASK, 4);
39 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0),
40 		 MT_WPDMA0_BASE_PTR_MASK, 0x80);
41 
42 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1),
43 		 MT_WPDMA0_MAX_CNT_MASK, 4);
44 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1),
45 		 MT_WPDMA0_BASE_PTR_MASK, 0xc0);
46 
47 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2),
48 		 MT_WPDMA0_MAX_CNT_MASK, 4);
49 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2),
50 		 MT_WPDMA0_BASE_PTR_MASK, 0x100);
51 
52 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3),
53 		 MT_WPDMA0_MAX_CNT_MASK, 4);
54 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3),
55 		 MT_WPDMA0_BASE_PTR_MASK, 0x140);
56 
57 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4),
58 		 MT_WPDMA0_MAX_CNT_MASK, 4);
59 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4),
60 		 MT_WPDMA0_BASE_PTR_MASK, 0x180);
61 
62 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16),
63 		 MT_WPDMA0_MAX_CNT_MASK, 4);
64 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16),
65 		 MT_WPDMA0_BASE_PTR_MASK, 0x280);
66 
67 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17),
68 		 MT_WPDMA0_MAX_CNT_MASK, 4);
69 	mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17),
70 		 MT_WPDMA0_BASE_PTR_MASK,  0x2c0);
71 }
72 
mt7921u_wfdma_init(struct mt7921_dev * dev)73 static void mt7921u_wfdma_init(struct mt7921_dev *dev)
74 {
75 	mt7921u_dma_prefetch(dev);
76 
77 	mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_OMIT_RX_INFO);
78 	mt76_set(dev, MT_UWFDMA0_GLO_CFG,
79 		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
80 		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 |
81 		 MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL |
82 		 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
83 		 MT_WFDMA0_GLO_CFG_RX_DMA_EN);
84 
85 	/* disable dmashdl */
86 	mt76_clear(dev, MT_UWFDMA0_GLO_CFG_EXT0,
87 		   MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
88 	mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
89 
90 	mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
91 }
92 
mt7921u_dma_rx_evt_ep4(struct mt7921_dev * dev)93 static int mt7921u_dma_rx_evt_ep4(struct mt7921_dev *dev)
94 {
95 	if (!mt76_poll(dev, MT_UWFDMA0_GLO_CFG,
96 		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
97 		return -ETIMEDOUT;
98 
99 	mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN);
100 	mt76_set(dev, MT_WFDMA_HOST_CONFIG,
101 		 MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN);
102 	mt76_set(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN);
103 
104 	return 0;
105 }
106 
mt7921u_epctl_rst_opt(struct mt7921_dev * dev,bool reset)107 static void mt7921u_epctl_rst_opt(struct mt7921_dev *dev, bool reset)
108 {
109 	u32 val;
110 
111 	/* usb endpoint reset opt
112 	 * bits[4,9]: out blk ep 4-9
113 	 * bits[20,21]: in blk ep 4-5
114 	 * bits[22]: in int ep 6
115 	 */
116 	val = mt7921u_uhw_rr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT);
117 	if (reset)
118 		val |= GENMASK(9, 4) | GENMASK(22, 20);
119 	else
120 		val &= ~(GENMASK(9, 4) | GENMASK(22, 20));
121 	mt7921u_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val);
122 }
123 
mt7921u_dma_init(struct mt7921_dev * dev,bool resume)124 int mt7921u_dma_init(struct mt7921_dev *dev, bool resume)
125 {
126 	int err;
127 
128 	mt7921u_wfdma_init(dev);
129 
130 	mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH);
131 
132 	mt76_set(dev, MT_UDMA_WLCFG_0,
133 		 MT_WL_RX_EN | MT_WL_TX_EN |
134 		 MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN);
135 	mt76_clear(dev, MT_UDMA_WLCFG_0,
136 		   MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT);
137 	mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT);
138 
139 	if (resume)
140 		return 0;
141 
142 	err = mt7921u_dma_rx_evt_ep4(dev);
143 	if (err)
144 		return err;
145 
146 	mt7921u_epctl_rst_opt(dev, false);
147 
148 	return 0;
149 }
150 
mt7921u_wfsys_reset(struct mt7921_dev * dev)151 int mt7921u_wfsys_reset(struct mt7921_dev *dev)
152 {
153 	u32 val;
154 	int i;
155 
156 	mt7921u_epctl_rst_opt(dev, false);
157 
158 	val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST);
159 	val |= MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
160 	mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val);
161 
162 	usleep_range(10, 20);
163 
164 	val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST);
165 	val &= ~MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
166 	mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val);
167 
168 	mt7921u_uhw_wr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS_SEL, 0);
169 	for (i = 0; i < MT7921_WFSYS_INIT_RETRY_COUNT; i++) {
170 		val = mt7921u_uhw_rr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS);
171 		if (val & MT_UDMA_CONN_WFSYS_INIT_DONE)
172 			break;
173 
174 		msleep(100);
175 	}
176 
177 	if (i == MT7921_WFSYS_INIT_RETRY_COUNT)
178 		return -ETIMEDOUT;
179 
180 	return 0;
181 }
182 
mt7921u_init_reset(struct mt7921_dev * dev)183 int mt7921u_init_reset(struct mt7921_dev *dev)
184 {
185 	set_bit(MT76_RESET, &dev->mphy.state);
186 
187 	wake_up(&dev->mt76.mcu.wait);
188 	skb_queue_purge(&dev->mt76.mcu.res_q);
189 
190 	mt76u_stop_rx(&dev->mt76);
191 	mt76u_stop_tx(&dev->mt76);
192 
193 	mt7921u_wfsys_reset(dev);
194 
195 	clear_bit(MT76_RESET, &dev->mphy.state);
196 
197 	return mt76u_resume_rx(&dev->mt76);
198 }
199 
mt7921u_mac_reset(struct mt7921_dev * dev)200 int mt7921u_mac_reset(struct mt7921_dev *dev)
201 {
202 	int err;
203 
204 	mt76_txq_schedule_all(&dev->mphy);
205 	mt76_worker_disable(&dev->mt76.tx_worker);
206 
207 	set_bit(MT76_RESET, &dev->mphy.state);
208 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
209 
210 	wake_up(&dev->mt76.mcu.wait);
211 	skb_queue_purge(&dev->mt76.mcu.res_q);
212 
213 	mt76u_stop_rx(&dev->mt76);
214 	mt76u_stop_tx(&dev->mt76);
215 
216 	mt7921u_wfsys_reset(dev);
217 
218 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
219 	err = mt76u_resume_rx(&dev->mt76);
220 	if (err)
221 		goto out;
222 
223 	err = mt7921u_mcu_power_on(dev);
224 	if (err)
225 		goto out;
226 
227 	err = mt7921u_dma_init(dev, false);
228 	if (err)
229 		goto out;
230 
231 	mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
232 	mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
233 
234 	err = mt7921_run_firmware(dev);
235 	if (err)
236 		goto out;
237 
238 	mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
239 
240 	err = mt7921_mcu_set_eeprom(dev);
241 	if (err)
242 		goto out;
243 
244 	err = mt7921_mac_init(dev);
245 	if (err)
246 		goto out;
247 
248 	err = __mt7921_start(&dev->phy);
249 out:
250 	clear_bit(MT76_RESET, &dev->mphy.state);
251 
252 	mt76_worker_enable(&dev->mt76.tx_worker);
253 
254 	return err;
255 }
256