GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / net / wireless / mediatek / mt76 / mt76x2u_phy.c
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 "mt76x2_eeprom.h"
19
20 void mt76x2u_phy_set_rxpath(struct mt76x2_dev *dev)
21 {
22         u32 val;
23
24         val = mt76_rr(dev, MT_BBP(AGC, 0));
25         val &= ~BIT(4);
26
27         switch (dev->chainmask & 0xf) {
28         case 2:
29                 val |= BIT(3);
30                 break;
31         default:
32                 val &= ~BIT(3);
33                 break;
34         }
35         mt76_wr(dev, MT_BBP(AGC, 0), val);
36 }
37
38 void mt76x2u_phy_set_txdac(struct mt76x2_dev *dev)
39 {
40         int txpath;
41
42         txpath = (dev->chainmask >> 8) & 0xf;
43         switch (txpath) {
44         case 2:
45                 mt76_set(dev, MT_BBP(TXBE, 5), 0x3);
46                 break;
47         default:
48                 mt76_clear(dev, MT_BBP(TXBE, 5), 0x3);
49                 break;
50         }
51 }
52
53 void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev)
54 {
55         struct ieee80211_channel *chan = dev->mt76.chandef.chan;
56         bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
57
58         if (mt76x2_channel_silent(dev))
59                 return;
60
61         mt76x2u_mac_stop(dev);
62
63         if (is_5ghz)
64                 mt76x2u_mcu_calibrate(dev, MCU_CAL_LC, 0);
65
66         mt76x2u_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz);
67         mt76x2u_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz);
68         mt76x2u_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz);
69         mt76x2u_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0);
70
71         mt76x2u_mac_resume(dev);
72 }
73
74 static void
75 mt76x2u_phy_tssi_compensate(struct mt76x2_dev *dev)
76 {
77         struct ieee80211_channel *chan = dev->mt76.chandef.chan;
78         struct mt76x2_tx_power_info txp;
79         struct mt76x2_tssi_comp t = {};
80
81         if (!dev->cal.tssi_cal_done)
82                 return;
83
84         if (!dev->cal.tssi_comp_pending) {
85                 /* TSSI trigger */
86                 t.cal_mode = BIT(0);
87                 mt76x2u_mcu_tssi_comp(dev, &t);
88                 dev->cal.tssi_comp_pending = true;
89         } else {
90                 if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4))
91                         return;
92
93                 dev->cal.tssi_comp_pending = false;
94                 mt76x2_get_power_info(dev, &txp, chan);
95
96                 if (mt76x2_ext_pa_enabled(dev, chan->band))
97                         t.pa_mode = 1;
98
99                 t.cal_mode = BIT(1);
100                 t.slope0 = txp.chain[0].tssi_slope;
101                 t.offset0 = txp.chain[0].tssi_offset;
102                 t.slope1 = txp.chain[1].tssi_slope;
103                 t.offset1 = txp.chain[1].tssi_offset;
104                 mt76x2u_mcu_tssi_comp(dev, &t);
105
106                 if (t.pa_mode || dev->cal.dpd_cal_done)
107                         return;
108
109                 usleep_range(10000, 20000);
110                 mt76x2u_mcu_calibrate(dev, MCU_CAL_DPD, chan->hw_value);
111                 dev->cal.dpd_cal_done = true;
112         }
113 }
114
115 static void
116 mt76x2u_phy_update_channel_gain(struct mt76x2_dev *dev)
117 {
118         u8 channel = dev->mt76.chandef.chan->hw_value;
119         int freq, freq1;
120         u32 false_cca;
121
122         freq = dev->mt76.chandef.chan->center_freq;
123         freq1 = dev->mt76.chandef.center_freq1;
124
125         switch (dev->mt76.chandef.width) {
126         case NL80211_CHAN_WIDTH_80: {
127                 int ch_group_index;
128
129                 ch_group_index = (freq - freq1 + 30) / 20;
130                 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
131                         ch_group_index = 0;
132                 channel += 6 - ch_group_index * 4;
133                 break;
134         }
135         case NL80211_CHAN_WIDTH_40:
136                 if (freq1 > freq)
137                         channel += 2;
138                 else
139                         channel -= 2;
140                 break;
141         default:
142                 break;
143         }
144
145         dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
146         false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
147                               mt76_rr(dev, MT_RX_STAT_1));
148
149         mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
150                                     dev->cal.avg_rssi_all, false_cca);
151 }
152
153 void mt76x2u_phy_calibrate(struct work_struct *work)
154 {
155         struct mt76x2_dev *dev;
156
157         dev = container_of(work, struct mt76x2_dev, cal_work.work);
158         mt76x2u_phy_tssi_compensate(dev);
159         mt76x2u_phy_update_channel_gain(dev);
160
161         ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
162                                      MT_CALIBRATE_INTERVAL);
163 }
164
165 int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
166                             struct cfg80211_chan_def *chandef)
167 {
168         u32 ext_cca_chan[4] = {
169                 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
170                       FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
171                       FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
172                       FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
173                       FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
174                 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
175                       FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
176                       FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
177                       FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
178                       FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
179                 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
180                       FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
181                       FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
182                       FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
183                       FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
184                 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
185                       FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
186                       FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
187                       FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
188                       FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
189         };
190         bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
191         struct ieee80211_channel *chan = chandef->chan;
192         u8 channel = chan->hw_value, bw, bw_index;
193         int ch_group_index, freq, freq1, ret;
194
195         dev->cal.channel_cal_done = false;
196         freq = chandef->chan->center_freq;
197         freq1 = chandef->center_freq1;
198
199         switch (chandef->width) {
200         case NL80211_CHAN_WIDTH_40:
201                 bw = 1;
202                 if (freq1 > freq) {
203                         bw_index = 1;
204                         ch_group_index = 0;
205                 } else {
206                         bw_index = 3;
207                         ch_group_index = 1;
208                 }
209                 channel += 2 - ch_group_index * 4;
210                 break;
211         case NL80211_CHAN_WIDTH_80:
212                 ch_group_index = (freq - freq1 + 30) / 20;
213                 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
214                         ch_group_index = 0;
215                 bw = 2;
216                 bw_index = ch_group_index;
217                 channel += 6 - ch_group_index * 4;
218                 break;
219         default:
220                 bw = 0;
221                 bw_index = 0;
222                 ch_group_index = 0;
223                 break;
224         }
225
226         mt76x2_read_rx_gain(dev);
227         mt76x2_phy_set_txpower_regs(dev, chan->band);
228         mt76x2_configure_tx_delay(dev, chan->band, bw);
229         mt76x2_phy_set_txpower(dev);
230
231         mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
232         mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
233
234         mt76_rmw(dev, MT_EXT_CCA_CFG,
235                  (MT_EXT_CCA_CFG_CCA0 |
236                   MT_EXT_CCA_CFG_CCA1 |
237                   MT_EXT_CCA_CFG_CCA2 |
238                   MT_EXT_CCA_CFG_CCA3 |
239                   MT_EXT_CCA_CFG_CCA_MASK),
240                  ext_cca_chan[ch_group_index]);
241
242         ret = mt76x2u_mcu_set_channel(dev, channel, bw, bw_index, scan);
243         if (ret)
244                 return ret;
245
246         mt76x2u_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
247
248         /* Enable LDPC Rx */
249         if (mt76xx_rev(dev) >= MT76XX_REV_E3)
250                 mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
251
252         if (!dev->cal.init_cal_done) {
253                 u8 val = mt76x2_eeprom_get(dev, MT_EE_BT_RCAL_RESULT);
254
255                 if (val != 0xff)
256                         mt76x2u_mcu_calibrate(dev, MCU_CAL_R, 0);
257         }
258
259         mt76x2u_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel);
260
261         /* Rx LPF calibration */
262         if (!dev->cal.init_cal_done)
263                 mt76x2u_mcu_calibrate(dev, MCU_CAL_RC, 0);
264         dev->cal.init_cal_done = true;
265
266         mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2);
267         mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
268         mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
269         mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
270         mt76_wr(dev, MT_TXOP_CTRL_CFG, 0X04101b3f);
271
272         mt76_set(dev, MT_BBP(TXO, 4), BIT(25));
273         mt76_set(dev, MT_BBP(RXO, 13), BIT(8));
274
275         if (scan)
276                 return 0;
277
278         if (mt76x2_tssi_enabled(dev)) {
279                 /* init default values for temp compensation */
280                 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
281                                0x38);
282                 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
283                                0x38);
284
285                 /* init tssi calibration */
286                 if (!mt76x2_channel_silent(dev)) {
287                         struct ieee80211_channel *chan;
288                         u32 flag = 0;
289
290                         chan = dev->mt76.chandef.chan;
291                         if (chan->band == NL80211_BAND_5GHZ)
292                                 flag |= BIT(0);
293                         if (mt76x2_ext_pa_enabled(dev, chan->band))
294                                 flag |= BIT(8);
295                         mt76x2u_mcu_calibrate(dev, MCU_CAL_TSSI, flag);
296                         dev->cal.tssi_cal_done = true;
297                 }
298         }
299
300         ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
301                                      MT_CALIBRATE_INTERVAL);
302         return 0;
303 }