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 #include "../mt76x02_phy.h"
20 
21 void mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev)
22 {
23 	struct ieee80211_channel *chan = dev->mt76.chandef.chan;
24 	bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
25 
26 	if (mt76x2_channel_silent(dev))
27 		return;
28 
29 	mt76x2u_mac_stop(dev);
30 
31 	if (is_5ghz)
32 		mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0, false);
33 
34 	mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz, false);
35 	mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, false);
36 	mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz, false);
37 	mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, false);
38 
39 	mt76x2u_mac_resume(dev);
40 }
41 
42 static void
43 mt76x2u_phy_update_channel_gain(struct mt76x02_dev *dev)
44 {
45 	u8 channel = dev->mt76.chandef.chan->hw_value;
46 	int freq, freq1;
47 	u32 false_cca;
48 
49 	freq = dev->mt76.chandef.chan->center_freq;
50 	freq1 = dev->mt76.chandef.center_freq1;
51 
52 	switch (dev->mt76.chandef.width) {
53 	case NL80211_CHAN_WIDTH_80: {
54 		int ch_group_index;
55 
56 		ch_group_index = (freq - freq1 + 30) / 20;
57 		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
58 			ch_group_index = 0;
59 		channel += 6 - ch_group_index * 4;
60 		break;
61 	}
62 	case NL80211_CHAN_WIDTH_40:
63 		if (freq1 > freq)
64 			channel += 2;
65 		else
66 			channel -= 2;
67 		break;
68 	default:
69 		break;
70 	}
71 
72 	dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev);
73 	false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
74 			      mt76_rr(dev, MT_RX_STAT_1));
75 
76 	mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
77 				    dev->cal.avg_rssi_all, false_cca);
78 }
79 
80 void mt76x2u_phy_calibrate(struct work_struct *work)
81 {
82 	struct mt76x02_dev *dev;
83 
84 	dev = container_of(work, struct mt76x02_dev, cal_work.work);
85 	mt76x2_phy_tssi_compensate(dev, false);
86 	mt76x2u_phy_update_channel_gain(dev);
87 
88 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
89 				     MT_CALIBRATE_INTERVAL);
90 }
91 
92 int mt76x2u_phy_set_channel(struct mt76x02_dev *dev,
93 			    struct cfg80211_chan_def *chandef)
94 {
95 	u32 ext_cca_chan[4] = {
96 		[0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
97 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
98 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
99 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
100 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
101 		[1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
102 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
103 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
104 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
105 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
106 		[2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
107 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
108 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
109 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
110 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
111 		[3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
112 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
113 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
114 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
115 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
116 	};
117 	bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
118 	struct ieee80211_channel *chan = chandef->chan;
119 	u8 channel = chan->hw_value, bw, bw_index;
120 	int ch_group_index, freq, freq1, ret;
121 
122 	dev->cal.channel_cal_done = false;
123 	freq = chandef->chan->center_freq;
124 	freq1 = chandef->center_freq1;
125 
126 	switch (chandef->width) {
127 	case NL80211_CHAN_WIDTH_40:
128 		bw = 1;
129 		if (freq1 > freq) {
130 			bw_index = 1;
131 			ch_group_index = 0;
132 		} else {
133 			bw_index = 3;
134 			ch_group_index = 1;
135 		}
136 		channel += 2 - ch_group_index * 4;
137 		break;
138 	case NL80211_CHAN_WIDTH_80:
139 		ch_group_index = (freq - freq1 + 30) / 20;
140 		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
141 			ch_group_index = 0;
142 		bw = 2;
143 		bw_index = ch_group_index;
144 		channel += 6 - ch_group_index * 4;
145 		break;
146 	default:
147 		bw = 0;
148 		bw_index = 0;
149 		ch_group_index = 0;
150 		break;
151 	}
152 
153 	mt76x2_read_rx_gain(dev);
154 	mt76x2_phy_set_txpower_regs(dev, chan->band);
155 	mt76x2_configure_tx_delay(dev, chan->band, bw);
156 	mt76x2_phy_set_txpower(dev);
157 
158 	mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
159 	mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
160 
161 	mt76_rmw(dev, MT_EXT_CCA_CFG,
162 		 (MT_EXT_CCA_CFG_CCA0 |
163 		  MT_EXT_CCA_CFG_CCA1 |
164 		  MT_EXT_CCA_CFG_CCA2 |
165 		  MT_EXT_CCA_CFG_CCA3 |
166 		  MT_EXT_CCA_CFG_CCA_MASK),
167 		 ext_cca_chan[ch_group_index]);
168 
169 	ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
170 	if (ret)
171 		return ret;
172 
173 	mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
174 
175 	/* Enable LDPC Rx */
176 	if (mt76xx_rev(dev) >= MT76XX_REV_E3)
177 		mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
178 
179 	if (!dev->cal.init_cal_done) {
180 		u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
181 
182 		if (val != 0xff)
183 			mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, false);
184 	}
185 
186 	mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel, false);
187 
188 	/* Rx LPF calibration */
189 	if (!dev->cal.init_cal_done)
190 		mt76x02_mcu_calibrate(dev, 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, MCU_CAL_TSSI, flag, false);
223 			dev->cal.tssi_cal_done = true;
224 		}
225 	}
226 
227 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
228 				     MT_CALIBRATE_INTERVAL);
229 	return 0;
230 }
231