Linux Audio

Check our new training course

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