1 /*
2  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
3  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "mt76x2.h"
19 #include "eeprom.h"
20 #include "../mt76x02_phy.h"
21 
22 static void
23 mt76x2_set_wlan_state(struct mt76x02_dev *dev, bool enable)
24 {
25 	u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
26 
27 	if (enable)
28 		val |= (MT_WLAN_FUN_CTRL_WLAN_EN |
29 			MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
30 	else
31 		val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN |
32 			 MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
33 
34 	mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
35 	udelay(20);
36 }
37 
38 void mt76x2_reset_wlan(struct mt76x02_dev *dev, bool enable)
39 {
40 	u32 val;
41 
42 	if (!enable)
43 		goto out;
44 
45 	val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
46 
47 	val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL;
48 
49 	if (val & MT_WLAN_FUN_CTRL_WLAN_EN) {
50 		val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
51 		mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
52 		udelay(20);
53 
54 		val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
55 	}
56 
57 	mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
58 	udelay(20);
59 
60 out:
61 	mt76x2_set_wlan_state(dev, enable);
62 }
63 EXPORT_SYMBOL_GPL(mt76x2_reset_wlan);
64 
65 void mt76_write_mac_initvals(struct mt76x02_dev *dev)
66 {
67 #define DEFAULT_PROT_CFG_CCK				\
68 	(FIELD_PREP(MT_PROT_CFG_RATE, 0x3) |		\
69 	 FIELD_PREP(MT_PROT_CFG_NAV, 1) |		\
70 	 FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |	\
71 	 MT_PROT_CFG_RTS_THRESH)
72 
73 #define DEFAULT_PROT_CFG_OFDM				\
74 	(FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |		\
75 	 FIELD_PREP(MT_PROT_CFG_NAV, 1) |			\
76 	 FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |	\
77 	 MT_PROT_CFG_RTS_THRESH)
78 
79 #define DEFAULT_PROT_CFG_20				\
80 	(FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |		\
81 	 FIELD_PREP(MT_PROT_CFG_CTRL, 1) |		\
82 	 FIELD_PREP(MT_PROT_CFG_NAV, 1) |			\
83 	 FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17))
84 
85 #define DEFAULT_PROT_CFG_40				\
86 	(FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) |		\
87 	 FIELD_PREP(MT_PROT_CFG_CTRL, 1) |		\
88 	 FIELD_PREP(MT_PROT_CFG_NAV, 1) |			\
89 	 FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f))
90 
91 	static const struct mt76_reg_pair vals[] = {
92 		/* Copied from MediaTek reference source */
93 		{ MT_PBF_SYS_CTRL,		0x00080c00 },
94 		{ MT_PBF_CFG,			0x1efebcff },
95 		{ MT_FCE_PSE_CTRL,		0x00000001 },
96 		{ MT_MAC_SYS_CTRL,		0x0000000c },
97 		{ MT_MAX_LEN_CFG,		0x003e3f00 },
98 		{ MT_AMPDU_MAX_LEN_20M1S,	0xaaa99887 },
99 		{ MT_AMPDU_MAX_LEN_20M2S,	0x000000aa },
100 		{ MT_XIFS_TIME_CFG,		0x33a40d0a },
101 		{ MT_BKOFF_SLOT_CFG,		0x00000209 },
102 		{ MT_TBTT_SYNC_CFG,		0x00422010 },
103 		{ MT_PWR_PIN_CFG,		0x00000000 },
104 		{ 0x1238,			0x001700c8 },
105 		{ MT_TX_SW_CFG0,		0x00101001 },
106 		{ MT_TX_SW_CFG1,		0x00010000 },
107 		{ MT_TX_SW_CFG2,		0x00000000 },
108 		{ MT_TXOP_CTRL_CFG,		0x0400583f },
109 		{ MT_TX_RTS_CFG,		0x00ffff20 },
110 		{ MT_TX_TIMEOUT_CFG,		0x000a2290 },
111 		{ MT_TX_RETRY_CFG,		0x47f01f0f },
112 		{ MT_EXP_ACK_TIME,		0x002c00dc },
113 		{ MT_TX_PROT_CFG6,		0xe3f42004 },
114 		{ MT_TX_PROT_CFG7,		0xe3f42084 },
115 		{ MT_TX_PROT_CFG8,		0xe3f42104 },
116 		{ MT_PIFS_TX_CFG,		0x00060fff },
117 		{ MT_RX_FILTR_CFG,		0x00015f97 },
118 		{ MT_LEGACY_BASIC_RATE,		0x0000017f },
119 		{ MT_HT_BASIC_RATE,		0x00004003 },
120 		{ MT_PN_PAD_MODE,		0x00000003 },
121 		{ MT_TXOP_HLDR_ET,		0x00000002 },
122 		{ 0xa44,			0x00000000 },
123 		{ MT_HEADER_TRANS_CTRL_REG,	0x00000000 },
124 		{ MT_TSO_CTRL,			0x00000000 },
125 		{ MT_AUX_CLK_CFG,		0x00000000 },
126 		{ MT_DACCLK_EN_DLY_CFG,		0x00000000 },
127 		{ MT_TX_ALC_CFG_4,		0x00000000 },
128 		{ MT_TX_ALC_VGA3,		0x00000000 },
129 		{ MT_TX_PWR_CFG_0,		0x3a3a3a3a },
130 		{ MT_TX_PWR_CFG_1,		0x3a3a3a3a },
131 		{ MT_TX_PWR_CFG_2,		0x3a3a3a3a },
132 		{ MT_TX_PWR_CFG_3,		0x3a3a3a3a },
133 		{ MT_TX_PWR_CFG_4,		0x3a3a3a3a },
134 		{ MT_TX_PWR_CFG_7,		0x3a3a3a3a },
135 		{ MT_TX_PWR_CFG_8,		0x0000003a },
136 		{ MT_TX_PWR_CFG_9,		0x0000003a },
137 		{ MT_EFUSE_CTRL,		0x0000d000 },
138 		{ MT_PAUSE_ENABLE_CONTROL1,	0x0000000a },
139 		{ MT_FCE_WLAN_FLOW_CONTROL1,	0x60401c18 },
140 		{ MT_WPDMA_DELAY_INT_CFG,	0x94ff0000 },
141 		{ MT_TX_SW_CFG3,		0x00000004 },
142 		{ MT_HT_FBK_TO_LEGACY,		0x00001818 },
143 		{ MT_VHT_HT_FBK_CFG1,		0xedcba980 },
144 		{ MT_PROT_AUTO_TX_CFG,		0x00830083 },
145 		{ MT_HT_CTRL_CFG,		0x000001ff },
146 		{ MT_TX_LINK_CFG,		0x00001020 },
147 	};
148 	struct mt76_reg_pair prot_vals[] = {
149 		{ MT_CCK_PROT_CFG,		DEFAULT_PROT_CFG_CCK },
150 		{ MT_OFDM_PROT_CFG,		DEFAULT_PROT_CFG_OFDM },
151 		{ MT_MM20_PROT_CFG,		DEFAULT_PROT_CFG_20 },
152 		{ MT_MM40_PROT_CFG,		DEFAULT_PROT_CFG_40 },
153 		{ MT_GF20_PROT_CFG,		DEFAULT_PROT_CFG_20 },
154 		{ MT_GF40_PROT_CFG,		DEFAULT_PROT_CFG_40 },
155 	};
156 
157 	mt76_wr_rp(dev, 0, vals, ARRAY_SIZE(vals));
158 	mt76_wr_rp(dev, 0, prot_vals, ARRAY_SIZE(prot_vals));
159 }
160 EXPORT_SYMBOL_GPL(mt76_write_mac_initvals);
161 
162 void mt76x2_init_txpower(struct mt76x02_dev *dev,
163 			 struct ieee80211_supported_band *sband)
164 {
165 	struct ieee80211_channel *chan;
166 	struct mt76x2_tx_power_info txp;
167 	struct mt76_rate_power t = {};
168 	int i;
169 
170 	for (i = 0; i < sband->n_channels; i++) {
171 		chan = &sband->channels[i];
172 
173 		mt76x2_get_power_info(dev, &txp, chan);
174 		mt76x2_get_rate_power(dev, &t, chan);
175 
176 		chan->max_power = mt76x02_get_max_rate_power(&t) +
177 				  txp.target_power;
178 		chan->max_power = DIV_ROUND_UP(chan->max_power, 2);
179 
180 		/* convert to combined output power on 2x2 devices */
181 		chan->max_power += 3;
182 		chan->orig_mpwr = chan->max_power;
183 	}
184 }
185 EXPORT_SYMBOL_GPL(mt76x2_init_txpower);
186