cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcu.c (10338B)


      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		.mcu_restart = mt7603_mcu_restart,
    225	};
    226
    227	dev->mt76.mcu_ops = &mt7603_mcu_ops;
    228	return mt7603_load_firmware(dev);
    229}
    230
    231void mt7603_mcu_exit(struct mt7603_dev *dev)
    232{
    233	__mt76_mcu_restart(&dev->mt76);
    234	skb_queue_purge(&dev->mt76.mcu.res_q);
    235}
    236
    237int mt7603_mcu_set_eeprom(struct mt7603_dev *dev)
    238{
    239	static const u16 req_fields[] = {
    240#define WORD(_start)			\
    241		_start,			\
    242		_start + 1
    243#define GROUP_2G(_start)		\
    244		WORD(_start),		\
    245		WORD(_start + 2),	\
    246		WORD(_start + 4)
    247
    248		MT_EE_NIC_CONF_0 + 1,
    249		WORD(MT_EE_NIC_CONF_1),
    250		MT_EE_WIFI_RF_SETTING,
    251		MT_EE_TX_POWER_DELTA_BW40,
    252		MT_EE_TX_POWER_DELTA_BW80 + 1,
    253		MT_EE_TX_POWER_EXT_PA_5G,
    254		MT_EE_TEMP_SENSOR_CAL,
    255		GROUP_2G(MT_EE_TX_POWER_0_START_2G),
    256		GROUP_2G(MT_EE_TX_POWER_1_START_2G),
    257		WORD(MT_EE_TX_POWER_CCK),
    258		WORD(MT_EE_TX_POWER_OFDM_2G_6M),
    259		WORD(MT_EE_TX_POWER_OFDM_2G_24M),
    260		WORD(MT_EE_TX_POWER_OFDM_2G_54M),
    261		WORD(MT_EE_TX_POWER_HT_BPSK_QPSK),
    262		WORD(MT_EE_TX_POWER_HT_16_64_QAM),
    263		WORD(MT_EE_TX_POWER_HT_64_QAM),
    264		MT_EE_ELAN_RX_MODE_GAIN,
    265		MT_EE_ELAN_RX_MODE_NF,
    266		MT_EE_ELAN_RX_MODE_P1DB,
    267		MT_EE_ELAN_BYPASS_MODE_GAIN,
    268		MT_EE_ELAN_BYPASS_MODE_NF,
    269		MT_EE_ELAN_BYPASS_MODE_P1DB,
    270		WORD(MT_EE_STEP_NUM_NEG_6_7),
    271		WORD(MT_EE_STEP_NUM_NEG_4_5),
    272		WORD(MT_EE_STEP_NUM_NEG_2_3),
    273		WORD(MT_EE_STEP_NUM_NEG_0_1),
    274		WORD(MT_EE_REF_STEP_24G),
    275		WORD(MT_EE_STEP_NUM_PLUS_1_2),
    276		WORD(MT_EE_STEP_NUM_PLUS_3_4),
    277		WORD(MT_EE_STEP_NUM_PLUS_5_6),
    278		MT_EE_STEP_NUM_PLUS_7,
    279		MT_EE_XTAL_FREQ_OFFSET,
    280		MT_EE_XTAL_TRIM_2_COMP,
    281		MT_EE_XTAL_TRIM_3_COMP,
    282		MT_EE_XTAL_WF_RFCAL,
    283
    284		/* unknown fields below */
    285		WORD(0x24),
    286		0x34,
    287		0x39,
    288		0x3b,
    289		WORD(0x42),
    290		WORD(0x9e),
    291		0xf2,
    292		WORD(0xf8),
    293		0xfa,
    294		0x12e,
    295		WORD(0x130), WORD(0x132), WORD(0x134), WORD(0x136),
    296		WORD(0x138), WORD(0x13a), WORD(0x13c), WORD(0x13e),
    297
    298#undef GROUP_2G
    299#undef WORD
    300
    301	};
    302	struct req_data {
    303		__le16 addr;
    304		u8 val;
    305		u8 pad;
    306	} __packed;
    307	struct {
    308		u8 buffer_mode;
    309		u8 len;
    310		u8 pad[2];
    311	} req_hdr = {
    312		.buffer_mode = 1,
    313		.len = ARRAY_SIZE(req_fields) - 1,
    314	};
    315	const int size = 0xff * sizeof(struct req_data);
    316	u8 *req, *eep = (u8 *)dev->mt76.eeprom.data;
    317	int i, ret, len = sizeof(req_hdr) + size;
    318	struct req_data *data;
    319
    320	BUILD_BUG_ON(ARRAY_SIZE(req_fields) * sizeof(*data) > size);
    321
    322	req = kmalloc(len, GFP_KERNEL);
    323	if (!req)
    324		return -ENOMEM;
    325
    326	memcpy(req, &req_hdr, sizeof(req_hdr));
    327	data = (struct req_data *)(req + sizeof(req_hdr));
    328	memset(data, 0, size);
    329	for (i = 0; i < ARRAY_SIZE(req_fields); i++) {
    330		data[i].addr = cpu_to_le16(req_fields[i]);
    331		data[i].val = eep[req_fields[i]];
    332	}
    333
    334	ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
    335				req, len, true);
    336	kfree(req);
    337
    338	return ret;
    339}
    340
    341static int mt7603_mcu_set_tx_power(struct mt7603_dev *dev)
    342{
    343	struct {
    344		u8 center_channel;
    345		u8 tssi;
    346		u8 temp_comp;
    347		u8 target_power[2];
    348		u8 rate_power_delta[14];
    349		u8 bw_power_delta;
    350		u8 ch_power_delta[6];
    351		u8 temp_comp_power[17];
    352		u8 reserved;
    353	} req = {
    354		.center_channel = dev->mphy.chandef.chan->hw_value,
    355#define EEP_VAL(n) ((u8 *)dev->mt76.eeprom.data)[n]
    356		.tssi = EEP_VAL(MT_EE_NIC_CONF_1 + 1),
    357		.temp_comp = EEP_VAL(MT_EE_NIC_CONF_1),
    358		.target_power = {
    359			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 2),
    360			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 2)
    361		},
    362		.bw_power_delta = EEP_VAL(MT_EE_TX_POWER_DELTA_BW40),
    363		.ch_power_delta = {
    364			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 3),
    365			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 4),
    366			EEP_VAL(MT_EE_TX_POWER_0_START_2G + 5),
    367			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 3),
    368			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 4),
    369			EEP_VAL(MT_EE_TX_POWER_1_START_2G + 5)
    370		},
    371#undef EEP_VAL
    372	};
    373	u8 *eep = (u8 *)dev->mt76.eeprom.data;
    374
    375	memcpy(req.rate_power_delta, eep + MT_EE_TX_POWER_CCK,
    376	       sizeof(req.rate_power_delta));
    377
    378	memcpy(req.temp_comp_power, eep + MT_EE_STEP_NUM_NEG_6_7,
    379	       sizeof(req.temp_comp_power));
    380
    381	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_TX_POWER_CTRL,
    382				 &req, sizeof(req), true);
    383}
    384
    385int mt7603_mcu_set_channel(struct mt7603_dev *dev)
    386{
    387	struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
    388	struct ieee80211_hw *hw = mt76_hw(dev);
    389	int n_chains = hweight8(dev->mphy.antenna_mask);
    390	struct {
    391		u8 control_chan;
    392		u8 center_chan;
    393		u8 bw;
    394		u8 tx_streams;
    395		u8 rx_streams;
    396		u8 _res0[7];
    397		u8 txpower[21];
    398		u8 _res1[3];
    399	} req = {
    400		.control_chan = chandef->chan->hw_value,
    401		.center_chan = chandef->chan->hw_value,
    402		.bw = MT_BW_20,
    403		.tx_streams = n_chains,
    404		.rx_streams = n_chains,
    405	};
    406	s8 tx_power = hw->conf.power_level * 2;
    407	int i, ret;
    408
    409	if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_40) {
    410		req.bw = MT_BW_40;
    411		if (chandef->center_freq1 > chandef->chan->center_freq)
    412			req.center_chan += 2;
    413		else
    414			req.center_chan -= 2;
    415	}
    416
    417	tx_power = mt76_get_sar_power(&dev->mphy, chandef->chan, tx_power);
    418	if (dev->mphy.antenna_mask == 3)
    419		tx_power -= 6;
    420	tx_power = min(tx_power, dev->tx_power_limit);
    421
    422	dev->mphy.txpower_cur = tx_power;
    423
    424	for (i = 0; i < ARRAY_SIZE(req.txpower); i++)
    425		req.txpower[i] = tx_power;
    426
    427	ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CHANNEL_SWITCH, &req,
    428				sizeof(req), true);
    429	if (ret)
    430		return ret;
    431
    432	return mt7603_mcu_set_tx_power(dev);
    433}