WIP FPC-III support
[linux/fpc-iii.git] / drivers / net / wireless / mediatek / mt76 / mt7603 / mcu.c
blob96b6c89167305ccd10adf19374f478aa728d2587
1 // SPDX-License-Identifier: ISC
3 #include <linux/firmware.h>
4 #include "mt7603.h"
5 #include "mcu.h"
6 #include "eeprom.h"
8 #define MCU_SKB_RESERVE 8
10 struct mt7603_fw_trailer {
11 char fw_ver[10];
12 char build_date[15];
13 __le32 dl_len;
14 } __packed;
16 static int
17 mt7603_mcu_parse_response(struct mt76_dev *mdev, int cmd,
18 struct sk_buff *skb, int seq)
20 struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
21 struct mt7603_mcu_rxd *rxd;
23 if (!skb) {
24 dev_err(mdev->dev,
25 "MCU message %d (seq %d) timed out\n",
26 cmd, seq);
27 dev->mcu_hang = MT7603_WATCHDOG_TIMEOUT;
28 return -ETIMEDOUT;
31 rxd = (struct mt7603_mcu_rxd *)skb->data;
32 if (seq != rxd->seq)
33 return -EAGAIN;
35 return 0;
38 static int
39 mt7603_mcu_skb_send_msg(struct mt76_dev *mdev, struct sk_buff *skb,
40 int cmd, int *wait_seq)
42 struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
43 int hdrlen = dev->mcu_running ? sizeof(struct mt7603_mcu_txd) : 12;
44 struct mt7603_mcu_txd *txd;
45 u8 seq;
47 mdev->mcu.timeout = 3 * HZ;
49 seq = ++mdev->mcu.msg_seq & 0xf;
50 if (!seq)
51 seq = ++mdev->mcu.msg_seq & 0xf;
53 txd = (struct mt7603_mcu_txd *)skb_push(skb, hdrlen);
55 txd->len = cpu_to_le16(skb->len);
56 if (cmd == -MCU_CMD_FW_SCATTER)
57 txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE_FW);
58 else
59 txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE);
60 txd->pkt_type = MCU_PKT_ID;
61 txd->seq = seq;
63 if (cmd < 0) {
64 txd->cid = -cmd;
65 txd->set_query = MCU_Q_NA;
66 } else {
67 txd->cid = MCU_CMD_EXT_CID;
68 txd->ext_cid = cmd;
69 txd->set_query = MCU_Q_SET;
70 txd->ext_cid_ack = 1;
73 if (wait_seq)
74 *wait_seq = seq;
76 return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
79 static int
80 mt7603_mcu_init_download(struct mt7603_dev *dev, u32 addr, u32 len)
82 struct {
83 __le32 addr;
84 __le32 len;
85 __le32 mode;
86 } req = {
87 .addr = cpu_to_le32(addr),
88 .len = cpu_to_le32(len),
89 .mode = cpu_to_le32(BIT(31)),
92 return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_TARGET_ADDRESS_LEN_REQ,
93 &req, sizeof(req), true);
96 static int
97 mt7603_mcu_start_firmware(struct mt7603_dev *dev, u32 addr)
99 struct {
100 __le32 override;
101 __le32 addr;
102 } req = {
103 .override = cpu_to_le32(addr ? 1 : 0),
104 .addr = cpu_to_le32(addr),
107 return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_FW_START_REQ, &req,
108 sizeof(req), true);
111 static int
112 mt7603_mcu_restart(struct mt76_dev *dev)
114 return mt76_mcu_send_msg(dev, -MCU_CMD_RESTART_DL_REQ, NULL, 0, true);
117 static int mt7603_load_firmware(struct mt7603_dev *dev)
119 const struct firmware *fw;
120 const struct mt7603_fw_trailer *hdr;
121 const char *firmware;
122 int dl_len;
123 u32 addr, val;
124 int ret;
126 if (is_mt7628(dev)) {
127 if (mt76xx_rev(dev) == MT7628_REV_E1)
128 firmware = MT7628_FIRMWARE_E1;
129 else
130 firmware = MT7628_FIRMWARE_E2;
131 } else {
132 if (mt76xx_rev(dev) < MT7603_REV_E2)
133 firmware = MT7603_FIRMWARE_E1;
134 else
135 firmware = MT7603_FIRMWARE_E2;
138 ret = request_firmware(&fw, firmware, dev->mt76.dev);
139 if (ret)
140 return ret;
142 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
143 dev_err(dev->mt76.dev, "Invalid firmware\n");
144 ret = -EINVAL;
145 goto out;
148 hdr = (const struct mt7603_fw_trailer *)(fw->data + fw->size -
149 sizeof(*hdr));
151 dev_info(dev->mt76.dev, "Firmware Version: %.10s\n", hdr->fw_ver);
152 dev_info(dev->mt76.dev, "Build Time: %.15s\n", hdr->build_date);
154 addr = mt7603_reg_map(dev, 0x50012498);
155 mt76_wr(dev, addr, 0x5);
156 mt76_wr(dev, addr, 0x5);
157 udelay(1);
159 /* switch to bypass mode */
160 mt76_rmw(dev, MT_SCH_4, MT_SCH_4_FORCE_QID,
161 MT_SCH_4_BYPASS | FIELD_PREP(MT_SCH_4_FORCE_QID, 5));
163 val = mt76_rr(dev, MT_TOP_MISC2);
164 if (val & BIT(1)) {
165 dev_info(dev->mt76.dev, "Firmware already running...\n");
166 goto running;
169 if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(0) | BIT(1), BIT(0), 500)) {
170 dev_err(dev->mt76.dev, "Timeout waiting for ROM code to become ready\n");
171 ret = -EIO;
172 goto out;
175 dl_len = le32_to_cpu(hdr->dl_len) + 4;
176 ret = mt7603_mcu_init_download(dev, MCU_FIRMWARE_ADDRESS, dl_len);
177 if (ret) {
178 dev_err(dev->mt76.dev, "Download request failed\n");
179 goto out;
182 ret = mt76_mcu_send_firmware(&dev->mt76, -MCU_CMD_FW_SCATTER,
183 fw->data, dl_len);
184 if (ret) {
185 dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
186 goto out;
189 ret = mt7603_mcu_start_firmware(dev, MCU_FIRMWARE_ADDRESS);
190 if (ret) {
191 dev_err(dev->mt76.dev, "Failed to start firmware\n");
192 goto out;
195 if (!mt76_poll_msec(dev, MT_TOP_MISC2, BIT(1), BIT(1), 500)) {
196 dev_err(dev->mt76.dev, "Timeout waiting for firmware to initialize\n");
197 ret = -EIO;
198 goto out;
201 running:
202 mt76_clear(dev, MT_SCH_4, MT_SCH_4_FORCE_QID | MT_SCH_4_BYPASS);
204 mt76_set(dev, MT_SCH_4, BIT(8));
205 mt76_clear(dev, MT_SCH_4, BIT(8));
207 dev->mcu_running = true;
208 snprintf(dev->mt76.hw->wiphy->fw_version,
209 sizeof(dev->mt76.hw->wiphy->fw_version),
210 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
211 dev_info(dev->mt76.dev, "firmware init done\n");
213 out:
214 release_firmware(fw);
216 return ret;
219 int mt7603_mcu_init(struct mt7603_dev *dev)
221 static const struct mt76_mcu_ops mt7603_mcu_ops = {
222 .headroom = sizeof(struct mt7603_mcu_txd),
223 .mcu_skb_send_msg = mt7603_mcu_skb_send_msg,
224 .mcu_parse_response = mt7603_mcu_parse_response,
225 .mcu_restart = mt7603_mcu_restart,
228 dev->mt76.mcu_ops = &mt7603_mcu_ops;
229 return mt7603_load_firmware(dev);
232 void mt7603_mcu_exit(struct mt7603_dev *dev)
234 __mt76_mcu_restart(&dev->mt76);
235 skb_queue_purge(&dev->mt76.mcu.res_q);
238 int mt7603_mcu_set_eeprom(struct mt7603_dev *dev)
240 static const u16 req_fields[] = {
241 #define WORD(_start) \
242 _start, \
243 _start + 1
244 #define GROUP_2G(_start) \
245 WORD(_start), \
246 WORD(_start + 2), \
247 WORD(_start + 4)
249 MT_EE_NIC_CONF_0 + 1,
250 WORD(MT_EE_NIC_CONF_1),
251 MT_EE_WIFI_RF_SETTING,
252 MT_EE_TX_POWER_DELTA_BW40,
253 MT_EE_TX_POWER_DELTA_BW80 + 1,
254 MT_EE_TX_POWER_EXT_PA_5G,
255 MT_EE_TEMP_SENSOR_CAL,
256 GROUP_2G(MT_EE_TX_POWER_0_START_2G),
257 GROUP_2G(MT_EE_TX_POWER_1_START_2G),
258 WORD(MT_EE_TX_POWER_CCK),
259 WORD(MT_EE_TX_POWER_OFDM_2G_6M),
260 WORD(MT_EE_TX_POWER_OFDM_2G_24M),
261 WORD(MT_EE_TX_POWER_OFDM_2G_54M),
262 WORD(MT_EE_TX_POWER_HT_BPSK_QPSK),
263 WORD(MT_EE_TX_POWER_HT_16_64_QAM),
264 WORD(MT_EE_TX_POWER_HT_64_QAM),
265 MT_EE_ELAN_RX_MODE_GAIN,
266 MT_EE_ELAN_RX_MODE_NF,
267 MT_EE_ELAN_RX_MODE_P1DB,
268 MT_EE_ELAN_BYPASS_MODE_GAIN,
269 MT_EE_ELAN_BYPASS_MODE_NF,
270 MT_EE_ELAN_BYPASS_MODE_P1DB,
271 WORD(MT_EE_STEP_NUM_NEG_6_7),
272 WORD(MT_EE_STEP_NUM_NEG_4_5),
273 WORD(MT_EE_STEP_NUM_NEG_2_3),
274 WORD(MT_EE_STEP_NUM_NEG_0_1),
275 WORD(MT_EE_REF_STEP_24G),
276 WORD(MT_EE_STEP_NUM_PLUS_1_2),
277 WORD(MT_EE_STEP_NUM_PLUS_3_4),
278 WORD(MT_EE_STEP_NUM_PLUS_5_6),
279 MT_EE_STEP_NUM_PLUS_7,
280 MT_EE_XTAL_FREQ_OFFSET,
281 MT_EE_XTAL_TRIM_2_COMP,
282 MT_EE_XTAL_TRIM_3_COMP,
283 MT_EE_XTAL_WF_RFCAL,
285 /* unknown fields below */
286 WORD(0x24),
287 0x34,
288 0x39,
289 0x3b,
290 WORD(0x42),
291 WORD(0x9e),
292 0xf2,
293 WORD(0xf8),
294 0xfa,
295 0x12e,
296 WORD(0x130), WORD(0x132), WORD(0x134), WORD(0x136),
297 WORD(0x138), WORD(0x13a), WORD(0x13c), WORD(0x13e),
299 #undef GROUP_2G
300 #undef WORD
303 struct req_data {
304 __le16 addr;
305 u8 val;
306 u8 pad;
307 } __packed;
308 struct {
309 u8 buffer_mode;
310 u8 len;
311 u8 pad[2];
312 } req_hdr = {
313 .buffer_mode = 1,
314 .len = ARRAY_SIZE(req_fields) - 1,
316 const int size = 0xff * sizeof(struct req_data);
317 u8 *req, *eep = (u8 *)dev->mt76.eeprom.data;
318 int i, ret, len = sizeof(req_hdr) + size;
319 struct req_data *data;
321 BUILD_BUG_ON(ARRAY_SIZE(req_fields) * sizeof(*data) > size);
323 req = kmalloc(len, GFP_KERNEL);
324 if (!req)
325 return -ENOMEM;
327 memcpy(req, &req_hdr, sizeof(req_hdr));
328 data = (struct req_data *)(req + sizeof(req_hdr));
329 memset(data, 0, size);
330 for (i = 0; i < ARRAY_SIZE(req_fields); i++) {
331 data[i].addr = cpu_to_le16(req_fields[i]);
332 data[i].val = eep[req_fields[i]];
335 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
336 req, len, true);
337 kfree(req);
339 return ret;
342 static int mt7603_mcu_set_tx_power(struct mt7603_dev *dev)
344 struct {
345 u8 center_channel;
346 u8 tssi;
347 u8 temp_comp;
348 u8 target_power[2];
349 u8 rate_power_delta[14];
350 u8 bw_power_delta;
351 u8 ch_power_delta[6];
352 u8 temp_comp_power[17];
353 u8 reserved;
354 } req = {
355 .center_channel = dev->mphy.chandef.chan->hw_value,
356 #define EEP_VAL(n) ((u8 *)dev->mt76.eeprom.data)[n]
357 .tssi = EEP_VAL(MT_EE_NIC_CONF_1 + 1),
358 .temp_comp = EEP_VAL(MT_EE_NIC_CONF_1),
359 .target_power = {
360 EEP_VAL(MT_EE_TX_POWER_0_START_2G + 2),
361 EEP_VAL(MT_EE_TX_POWER_1_START_2G + 2)
363 .bw_power_delta = EEP_VAL(MT_EE_TX_POWER_DELTA_BW40),
364 .ch_power_delta = {
365 EEP_VAL(MT_EE_TX_POWER_0_START_2G + 3),
366 EEP_VAL(MT_EE_TX_POWER_0_START_2G + 4),
367 EEP_VAL(MT_EE_TX_POWER_0_START_2G + 5),
368 EEP_VAL(MT_EE_TX_POWER_1_START_2G + 3),
369 EEP_VAL(MT_EE_TX_POWER_1_START_2G + 4),
370 EEP_VAL(MT_EE_TX_POWER_1_START_2G + 5)
372 #undef EEP_VAL
374 u8 *eep = (u8 *)dev->mt76.eeprom.data;
376 memcpy(req.rate_power_delta, eep + MT_EE_TX_POWER_CCK,
377 sizeof(req.rate_power_delta));
379 memcpy(req.temp_comp_power, eep + MT_EE_STEP_NUM_NEG_6_7,
380 sizeof(req.temp_comp_power));
382 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_TX_POWER_CTRL,
383 &req, sizeof(req), true);
386 int mt7603_mcu_set_channel(struct mt7603_dev *dev)
388 struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
389 struct ieee80211_hw *hw = mt76_hw(dev);
390 int n_chains = hweight8(dev->mphy.antenna_mask);
391 struct {
392 u8 control_chan;
393 u8 center_chan;
394 u8 bw;
395 u8 tx_streams;
396 u8 rx_streams;
397 u8 _res0[7];
398 u8 txpower[21];
399 u8 _res1[3];
400 } req = {
401 .control_chan = chandef->chan->hw_value,
402 .center_chan = chandef->chan->hw_value,
403 .bw = MT_BW_20,
404 .tx_streams = n_chains,
405 .rx_streams = n_chains,
407 s8 tx_power;
408 int i, ret;
410 if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_40) {
411 req.bw = MT_BW_40;
412 if (chandef->center_freq1 > chandef->chan->center_freq)
413 req.center_chan += 2;
414 else
415 req.center_chan -= 2;
418 tx_power = hw->conf.power_level * 2;
419 if (dev->mphy.antenna_mask == 3)
420 tx_power -= 6;
421 tx_power = min(tx_power, dev->tx_power_limit);
423 dev->mphy.txpower_cur = tx_power;
425 for (i = 0; i < ARRAY_SIZE(req.txpower); i++)
426 req.txpower[i] = tx_power;
428 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CHANNEL_SWITCH, &req,
429 sizeof(req), true);
430 if (ret)
431 return ret;
433 return mt7603_mcu_set_tx_power(dev);