1 /*
2  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "mt76x2u.h"
18 #include "eeprom.h"
19 
20 void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev)
21 {
22 	struct ieee80211_channel *chan = dev->mt76.chandef.chan;
23 	bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
24 
25 	if (mt76x2_channel_silent(dev))
26 		return;
27 
28 	mt76x2u_mac_stop(dev);
29 
30 	if (is_5ghz)
31 		mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, false);
32 
33 	mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, false);
34 	mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false);
35 	mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, false);
36 	mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, false);
37 
38 	mt76x2u_mac_resume(dev);
39 }
40 
41 static void
42 mt76x2u_phy_update_channel_gain(struct mt76x2_dev *dev)
43 {
44 	u8 channel = dev->mt76.chandef.chan->hw_value;
45 	int freq, freq1;
46 	u32 false_cca;
47 
48 	freq = dev->mt76.chandef.chan->center_freq;
49 	freq1 = dev->mt76.chandef.center_freq1;
50 
51 	switch (dev->mt76.chandef.width) {
52 	case NL80211_CHAN_WIDTH_80: {
53 		int ch_group_index;
54 
55 		ch_group_index = (freq - freq1 + 30) / 20;
56 		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
57 			ch_group_index = 0;
58 		channel += 6 - ch_group_index * 4;
59 		break;
60 	}
61 	case NL80211_CHAN_WIDTH_40:
62 		if (freq1 > freq)
63 			channel += 2;
64 		else
65 			channel -= 2;
66 		break;
67 	default:
68 		break;
69 	}
70 
71 	dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
72 	false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
73 			      mt76_rr(dev, MT_RX_STAT_1));
74 
75 	mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
76 				    dev->cal.avg_rssi_all, false_cca);
77 }
78 
79 void mt76x2u_phy_calibrate(struct work_struct *work)
80 {
81 	struct mt76x2_dev *dev;
82 
83 	dev = container_of(work, struct mt76x2_dev, cal_work.work);
84 	mt76x2_phy_tssi_compensate(dev, false);
85 	mt76x2u_phy_update_channel_gain(dev);
86 
87 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
88 				     MT_CALIBRATE_INTERVAL);
89 }
90 
91 int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
92 			    struct cfg80211_chan_def *chandef)
93 {
94 	u32 ext_cca_chan[4] = {
95 		[0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
96 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
97 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
98 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
99 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
100 		[1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
101 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
102 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
103 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
104 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
105 		[2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
106 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
107 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
108 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
109 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
110 		[3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
111 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
112 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
113 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
114 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
115 	};
116 	bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
117 	struct ieee80211_channel *chan = chandef->chan;
118 	u8 channel = chan->hw_value, bw, bw_index;
119 	int ch_group_index, freq, freq1, ret;
120 
121 	dev->cal.channel_cal_done = false;
122 	freq = chandef->chan->center_freq;
123 	freq1 = chandef->center_freq1;
124 
125 	switch (chandef->width) {
126 	case NL80211_CHAN_WIDTH_40:
127 		bw = 1;
128 		if (freq1 > freq) {
129 			bw_index = 1;
130 			ch_group_index = 0;
131 		} else {
132 			bw_index = 3;
133 			ch_group_index = 1;
134 		}
135 		channel += 2 - ch_group_index * 4;
136 		break;
137 	case NL80211_CHAN_WIDTH_80:
138 		ch_group_index = (freq - freq1 + 30) / 20;
139 		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
140 			ch_group_index = 0;
141 		bw = 2;
142 		bw_index = ch_group_index;
143 		channel += 6 - ch_group_index * 4;
144 		break;
145 	default:
146 		bw = 0;
147 		bw_index = 0;
148 		ch_group_index = 0;
149 		break;
150 	}
151 
152 	mt76x2_read_rx_gain(dev);
153 	mt76x2_phy_set_txpower_regs(dev, chan->band);
154 	mt76x2_configure_tx_delay(dev, chan->band, bw);
155 	mt76x2_phy_set_txpower(dev);
156 
157 	mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
158 	mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
159 
160 	mt76_rmw(dev, MT_EXT_CCA_CFG,
161 		 (MT_EXT_CCA_CFG_CCA0 |
162 		  MT_EXT_CCA_CFG_CCA1 |
163 		  MT_EXT_CCA_CFG_CCA2 |
164 		  MT_EXT_CCA_CFG_CCA3 |
165 		  MT_EXT_CCA_CFG_CCA_MASK),
166 		 ext_cca_chan[ch_group_index]);
167 
168 	ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
169 	if (ret)
170 		return ret;
171 
172 	mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
173 
174 	/* Enable LDPC Rx */
175 	if (mt76xx_rev(dev) >= MT76XX_REV_E3)
176 		mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
177 
178 	if (!dev->cal.init_cal_done) {
179 		u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
180 
181 		if (val != 0xff)
182 			mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R,
183 					      0, false);
184 	}
185 
186 	mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, false);
187 
188 	/* Rx LPF calibration */
189 	if (!dev->cal.init_cal_done)
190 		mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, false);
191 	dev->cal.init_cal_done = true;
192 
193 	mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2);
194 	mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
195 	mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
196 	mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
197 	mt76_wr(dev, MT_TXOP_CTRL_CFG, 0X04101b3f);
198 
199 	mt76_set(dev, MT_BBP(TXO, 4), BIT(25));
200 	mt76_set(dev, MT_BBP(RXO, 13), BIT(8));
201 
202 	if (scan)
203 		return 0;
204 
205 	if (mt76x02_tssi_enabled(&dev->mt76)) {
206 		/* init default values for temp compensation */
207 		mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
208 			       0x38);
209 		mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
210 			       0x38);
211 
212 		/* init tssi calibration */
213 		if (!mt76x2_channel_silent(dev)) {
214 			struct ieee80211_channel *chan;
215 			u32 flag = 0;
216 
217 			chan = dev->mt76.chandef.chan;
218 			if (chan->band == NL80211_BAND_5GHZ)
219 				flag |= BIT(0);
220 			if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
221 				flag |= BIT(8);
222 			mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI,
223 					      flag, false);
224 			dev->cal.tssi_cal_done = true;
225 		}
226 	}
227 
228 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
229 				     MT_CALIBRATE_INTERVAL);
230 	return 0;
231 }
232