1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
3  *
4  * Author: Roy Luo <royluo@google.com>
5  *         Ryder Lee <ryder.lee@mediatek.com>
6  *         Felix Fietkau <nbd@nbd.name>
7  */
8 
9 #include <linux/etherdevice.h>
10 #include "mt7615.h"
11 #include "mac.h"
12 #include "eeprom.h"
13 
14 static void mt7615_phy_init(struct mt7615_dev *dev)
15 {
16 	/* disable band 0 rf low power beacon mode */
17 	mt76_rmw(dev, MT_WF_PHY_WF2_RFCTRL0, MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN,
18 		 MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN);
19 }
20 
21 static void mt7615_mac_init(struct mt7615_dev *dev)
22 {
23 	/* enable band 0 clk */
24 	mt76_rmw(dev, MT_CFG_CCR,
25 		 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN,
26 		 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN);
27 
28 	mt76_rmw_field(dev, MT_TMAC_CTCR0,
29 		       MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
30 	mt76_rmw_field(dev, MT_TMAC_CTCR0,
31 		       MT_TMAC_CTCR0_INS_DDLMT_DENSITY, 0x3);
32 	mt76_rmw(dev, MT_TMAC_CTCR0,
33 		 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
34 		 MT_TMAC_CTCR0_INS_DDLMT_EN,
35 		 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
36 		 MT_TMAC_CTCR0_INS_DDLMT_EN);
37 
38 	mt7615_mcu_set_rts_thresh(dev, 0x92b);
39 
40 	mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
41 		 MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
42 
43 	mt7615_mcu_init_mac(dev);
44 
45 	mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP |
46 		FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072));
47 
48 	mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7));
49 	mt76_wr(dev, MT_AGG_ARDCR,
50 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) |
51 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(1),
52 			   max_t(int, 0, MT7615_RATE_RETRY - 2)) |
53 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) |
54 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) |
55 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) |
56 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), MT7615_RATE_RETRY - 1) |
57 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), MT7615_RATE_RETRY - 1) |
58 		FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1));
59 
60 	mt76_wr(dev, MT_AGG_ARCR,
61 		(MT_AGG_ARCR_INIT_RATE1 |
62 		 FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
63 		 MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
64 		 FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
65 		 FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
66 }
67 
68 static int mt7615_init_hardware(struct mt7615_dev *dev)
69 {
70 	int ret, idx;
71 
72 	mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
73 
74 	spin_lock_init(&dev->token_lock);
75 	idr_init(&dev->token);
76 
77 	ret = mt7615_eeprom_init(dev);
78 	if (ret < 0)
79 		return ret;
80 
81 	ret = mt7615_dma_init(dev);
82 	if (ret)
83 		return ret;
84 
85 	set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
86 
87 	ret = mt7615_mcu_init(dev);
88 	if (ret)
89 		return ret;
90 
91 	mt7615_mcu_set_eeprom(dev);
92 	mt7615_mac_init(dev);
93 	mt7615_phy_init(dev);
94 	mt7615_mcu_ctrl_pm_state(dev, 0);
95 	mt7615_mcu_del_wtbl_all(dev);
96 
97 	/* Beacon and mgmt frames should occupy wcid 0 */
98 	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
99 	if (idx)
100 		return -ENOSPC;
101 
102 	dev->mt76.global_wcid.idx = idx;
103 	dev->mt76.global_wcid.hw_key_idx = -1;
104 	rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
105 
106 	return 0;
107 }
108 
109 #define CCK_RATE(_idx, _rate) {						\
110 	.bitrate = _rate,						\
111 	.flags = IEEE80211_RATE_SHORT_PREAMBLE,				\
112 	.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx),			\
113 	.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)),	\
114 }
115 
116 #define OFDM_RATE(_idx, _rate) {					\
117 	.bitrate = _rate,						\
118 	.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx),			\
119 	.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx),		\
120 }
121 
122 static struct ieee80211_rate mt7615_rates[] = {
123 	CCK_RATE(0, 10),
124 	CCK_RATE(1, 20),
125 	CCK_RATE(2, 55),
126 	CCK_RATE(3, 110),
127 	OFDM_RATE(11, 60),
128 	OFDM_RATE(15, 90),
129 	OFDM_RATE(10, 120),
130 	OFDM_RATE(14, 180),
131 	OFDM_RATE(9,  240),
132 	OFDM_RATE(13, 360),
133 	OFDM_RATE(8,  480),
134 	OFDM_RATE(12, 540),
135 };
136 
137 static const struct ieee80211_iface_limit if_limits[] = {
138 	{
139 		.max = MT7615_MAX_INTERFACES,
140 		.types = BIT(NL80211_IFTYPE_AP) |
141 #ifdef CONFIG_MAC80211_MESH
142 			 BIT(NL80211_IFTYPE_MESH_POINT) |
143 #endif
144 			 BIT(NL80211_IFTYPE_STATION)
145 	}
146 };
147 
148 static const struct ieee80211_iface_combination if_comb[] = {
149 	{
150 		.limits = if_limits,
151 		.n_limits = ARRAY_SIZE(if_limits),
152 		.max_interfaces = 4,
153 		.num_different_channels = 1,
154 		.beacon_int_infra_match = true,
155 	}
156 };
157 
158 static int mt7615_init_debugfs(struct mt7615_dev *dev)
159 {
160 	struct dentry *dir;
161 
162 	dir = mt76_register_debugfs(&dev->mt76);
163 	if (!dir)
164 		return -ENOMEM;
165 
166 	return 0;
167 }
168 
169 static void
170 mt7615_init_txpower(struct mt7615_dev *dev,
171 		    struct ieee80211_supported_band *sband)
172 {
173 	int i, n_chains = hweight8(dev->mt76.antenna_mask), target_chains;
174 	u8 *eep = (u8 *)dev->mt76.eeprom.data;
175 	enum nl80211_band band = sband->band;
176 
177 	target_chains = mt7615_ext_pa_enabled(dev, band) ? 1 : n_chains;
178 	for (i = 0; i < sband->n_channels; i++) {
179 		struct ieee80211_channel *chan = &sband->channels[i];
180 		u8 target_power = 0;
181 		int j;
182 
183 		for (j = 0; j < target_chains; j++) {
184 			int index;
185 
186 			index = mt7615_eeprom_get_power_index(dev, chan, j);
187 			target_power = max(target_power, eep[index]);
188 		}
189 
190 		target_power = DIV_ROUND_UP(target_power, 2);
191 		switch (n_chains) {
192 		case 4:
193 			target_power += 6;
194 			break;
195 		case 3:
196 			target_power += 4;
197 			break;
198 		case 2:
199 			target_power += 3;
200 			break;
201 		default:
202 			break;
203 		}
204 
205 		chan->max_power = min_t(int, chan->max_reg_power,
206 					target_power);
207 		chan->orig_mpwr = target_power;
208 	}
209 }
210 
211 int mt7615_register_device(struct mt7615_dev *dev)
212 {
213 	struct ieee80211_hw *hw = mt76_hw(dev);
214 	struct wiphy *wiphy = hw->wiphy;
215 	int ret;
216 
217 	ret = mt7615_init_hardware(dev);
218 	if (ret)
219 		return ret;
220 
221 	INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7615_mac_work);
222 
223 	hw->queues = 4;
224 	hw->max_rates = 3;
225 	hw->max_report_rates = 7;
226 	hw->max_rate_tries = 11;
227 
228 	hw->sta_data_size = sizeof(struct mt7615_sta);
229 	hw->vif_data_size = sizeof(struct mt7615_vif);
230 
231 	wiphy->iface_combinations = if_comb;
232 	wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
233 
234 	ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
235 	ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
236 
237 	dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
238 	dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
239 	dev->mt76.sband_5g.sband.vht_cap.cap |=
240 			IEEE80211_VHT_CAP_SHORT_GI_160 |
241 			IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
242 			IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
243 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
244 	dev->mt76.chainmask = 0x404;
245 	dev->mt76.antenna_mask = 0xf;
246 
247 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
248 #ifdef CONFIG_MAC80211_MESH
249 				 BIT(NL80211_IFTYPE_MESH_POINT) |
250 #endif
251 				 BIT(NL80211_IFTYPE_AP);
252 
253 	ret = mt76_register_device(&dev->mt76, true, mt7615_rates,
254 				   ARRAY_SIZE(mt7615_rates));
255 	if (ret)
256 		return ret;
257 
258 	mt7615_init_txpower(dev, &dev->mt76.sband_2g.sband);
259 	mt7615_init_txpower(dev, &dev->mt76.sband_5g.sband);
260 
261 	hw->max_tx_fragments = MT_TXP_MAX_BUF_NUM;
262 
263 	return mt7615_init_debugfs(dev);
264 }
265 
266 void mt7615_unregister_device(struct mt7615_dev *dev)
267 {
268 	struct mt76_txwi_cache *txwi;
269 	int id;
270 
271 	mt76_unregister_device(&dev->mt76);
272 	mt7615_mcu_exit(dev);
273 	mt7615_dma_cleanup(dev);
274 
275 	spin_lock_bh(&dev->token_lock);
276 	idr_for_each_entry(&dev->token, txwi, id) {
277 		mt7615_txp_skb_unmap(&dev->mt76, txwi);
278 		if (txwi->skb)
279 			dev_kfree_skb_any(txwi->skb);
280 		mt76_put_txwi(&dev->mt76, txwi);
281 	}
282 	spin_unlock_bh(&dev->token_lock);
283 	idr_destroy(&dev->token);
284 
285 	mt76_free_device(&dev->mt76);
286 }
287