1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
3 
4 #include "mt7921.h"
5 #include "eeprom.h"
6 
mt7921_eeprom_read(struct mt7921_dev * dev,u32 offset)7 static u32 mt7921_eeprom_read(struct mt7921_dev *dev, u32 offset)
8 {
9 	u8 *data = dev->mt76.eeprom.data;
10 
11 	if (data[offset] == 0xff)
12 		mt7921_mcu_get_eeprom(dev, offset);
13 
14 	return data[offset];
15 }
16 
mt7921_eeprom_load(struct mt7921_dev * dev)17 static int mt7921_eeprom_load(struct mt7921_dev *dev)
18 {
19 	int ret;
20 
21 	ret = mt76_eeprom_init(&dev->mt76, MT7921_EEPROM_SIZE);
22 	if (ret < 0)
23 		return ret;
24 
25 	memset(dev->mt76.eeprom.data, -1, MT7921_EEPROM_SIZE);
26 
27 	return 0;
28 }
29 
mt7921_check_eeprom(struct mt7921_dev * dev)30 static int mt7921_check_eeprom(struct mt7921_dev *dev)
31 {
32 	u8 *eeprom = dev->mt76.eeprom.data;
33 	u16 val;
34 
35 	mt7921_eeprom_read(dev, MT_EE_CHIP_ID);
36 	val = get_unaligned_le16(eeprom);
37 
38 	switch (val) {
39 	case 0x7961:
40 		return 0;
41 	default:
42 		return -EINVAL;
43 	}
44 }
45 
mt7921_eeprom_parse_band_config(struct mt7921_phy * phy)46 void mt7921_eeprom_parse_band_config(struct mt7921_phy *phy)
47 {
48 	struct mt7921_dev *dev = phy->dev;
49 	u32 val;
50 
51 	val = mt7921_eeprom_read(dev, MT_EE_WIFI_CONF);
52 	val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val);
53 
54 	switch (val) {
55 	case MT_EE_5GHZ:
56 		phy->mt76->cap.has_5ghz = true;
57 		break;
58 	case MT_EE_2GHZ:
59 		phy->mt76->cap.has_2ghz = true;
60 		break;
61 	default:
62 		phy->mt76->cap.has_2ghz = true;
63 		phy->mt76->cap.has_5ghz = true;
64 		break;
65 	}
66 }
67 
mt7921_eeprom_parse_hw_cap(struct mt7921_dev * dev)68 static void mt7921_eeprom_parse_hw_cap(struct mt7921_dev *dev)
69 {
70 	u8 tx_mask;
71 
72 	mt7921_eeprom_parse_band_config(&dev->phy);
73 
74 	/* TODO: read NSS with MCU_CMD_NIC_CAPV2 */
75 	tx_mask = 2;
76 	dev->chainmask = BIT(tx_mask) - 1;
77 	dev->mphy.antenna_mask = dev->chainmask;
78 	dev->mphy.chainmask = dev->mphy.antenna_mask;
79 }
80 
mt7921_eeprom_init(struct mt7921_dev * dev)81 int mt7921_eeprom_init(struct mt7921_dev *dev)
82 {
83 	int ret;
84 
85 	ret = mt7921_eeprom_load(dev);
86 	if (ret < 0)
87 		return ret;
88 
89 	ret = mt7921_check_eeprom(dev);
90 	if (ret)
91 		return ret;
92 
93 	mt7921_eeprom_parse_hw_cap(dev);
94 	memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
95 	       ETH_ALEN);
96 
97 	mt76_eeprom_override(&dev->mphy);
98 
99 	return 0;
100 }
101