Skip to content

Commit ad380ad

Browse files
committed
mt76: mt7615: add support for applying DC offset calibration from EEPROM
When the EEPROM data is read from flash, it can contain DC offset calibration data. Add support for sending the data to the firmware. Signed-off-by: Felix Fietkau <[email protected]>
1 parent b90728f commit ad380ad

File tree

6 files changed

+200
-29
lines changed

6 files changed

+200
-29
lines changed

drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
7272
{
7373
int ret;
7474

75-
ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE);
75+
ret = mt76_eeprom_init(&dev->mt76, MT7615_EEPROM_SIZE +
76+
MT7615_EEPROM_EXTRA_DATA);
7677
if (ret < 0)
7778
return ret;
7879

@@ -280,11 +281,13 @@ int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
280281
return ret;
281282

282283
ret = mt7615_check_eeprom(&dev->mt76);
283-
if (ret && dev->mt76.otp.data)
284+
if (ret && dev->mt76.otp.data) {
284285
memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
285286
MT7615_EEPROM_SIZE);
286-
else
287+
} else {
288+
dev->flash_eeprom = true;
287289
mt7615_cal_free_data(dev);
290+
}
288291

289292
mt7615_eeprom_parse_hw_cap(dev);
290293
memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,

drivers/net/wireless/mediatek/mt76/mt7615/eeprom.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,29 @@
66

77
#include "mt7615.h"
88

9+
10+
#define MT7615_EEPROM_DCOC_OFFSET MT7615_EEPROM_SIZE
11+
#define MT7615_EEPROM_DCOC_SIZE 256
12+
#define MT7615_EEPROM_DCOC_COUNT 34
13+
14+
#define MT7615_EEPROM_TXDPD_OFFSET (MT7615_EEPROM_SIZE + \
15+
MT7615_EEPROM_DCOC_COUNT * \
16+
MT7615_EEPROM_DCOC_SIZE)
17+
#define MT7615_EEPROM_TXDPD_SIZE 216
18+
#define MT7615_EEPROM_TXDPD_COUNT (44 + 3)
19+
20+
#define MT7615_EEPROM_EXTRA_DATA (MT7615_EEPROM_TXDPD_OFFSET + \
21+
MT7615_EEPROM_TXDPD_COUNT * \
22+
MT7615_EEPROM_TXDPD_SIZE)
23+
924
enum mt7615_eeprom_field {
1025
MT_EE_CHIP_ID = 0x000,
1126
MT_EE_VERSION = 0x002,
1227
MT_EE_MAC_ADDR = 0x004,
1328
MT_EE_NIC_CONF_0 = 0x034,
1429
MT_EE_NIC_CONF_1 = 0x036,
1530
MT_EE_WIFI_CONF = 0x03e,
31+
MT_EE_CALDATA_FLASH = 0x052,
1632
MT_EE_TX0_2G_TARGET_POWER = 0x058,
1733
MT_EE_TX0_5G_G0_TARGET_POWER = 0x070,
1834
MT_EE_TX1_5G_G0_TARGET_POWER = 0x098,
@@ -27,6 +43,9 @@ enum mt7615_eeprom_field {
2743
MT7663_EE_MAX = 0x400,
2844
};
2945

46+
#define MT_EE_CALDATA_FLASH_TX_DPD BIT(0)
47+
#define MT_EE_CALDATA_FLASH_RX_CAL BIT(1)
48+
3049
#define MT_EE_NIC_CONF_TX_MASK GENMASK(7, 4)
3150
#define MT_EE_NIC_CONF_RX_MASK GENMASK(3, 0)
3251

drivers/net/wireless/mediatek/mt76/mt7615/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
253253
mt7615_init_dfs_state(phy);
254254
mt76_set_channel(phy->mt76);
255255

256+
if (is_mt7615(&dev->mt76) && dev->flash_eeprom)
257+
mt7615_mcu_apply_rx_dcoc(phy);
258+
256259
ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_CHANNEL_SWITCH);
257260
if (ret)
258261
goto out;

drivers/net/wireless/mediatek/mt76/mt7615/mcu.c

Lines changed: 169 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,25 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
24812481
}
24822482
}
24832483

2484+
static u8 mt7615_mcu_chan_bw(struct cfg80211_chan_def *chandef)
2485+
{
2486+
static const u8 width_to_bw[] = {
2487+
[NL80211_CHAN_WIDTH_40] = CMD_CBW_40MHZ,
2488+
[NL80211_CHAN_WIDTH_80] = CMD_CBW_80MHZ,
2489+
[NL80211_CHAN_WIDTH_80P80] = CMD_CBW_8080MHZ,
2490+
[NL80211_CHAN_WIDTH_160] = CMD_CBW_160MHZ,
2491+
[NL80211_CHAN_WIDTH_5] = CMD_CBW_5MHZ,
2492+
[NL80211_CHAN_WIDTH_10] = CMD_CBW_10MHZ,
2493+
[NL80211_CHAN_WIDTH_20] = CMD_CBW_20MHZ,
2494+
[NL80211_CHAN_WIDTH_20_NOHT] = CMD_CBW_20MHZ,
2495+
};
2496+
2497+
if (chandef->width >= ARRAY_SIZE(width_to_bw))
2498+
return 0;
2499+
2500+
return width_to_bw[chandef->width];
2501+
}
2502+
24842503
int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
24852504
{
24862505
struct mt7615_dev *dev = phy->dev;
@@ -2521,32 +2540,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
25212540
req.switch_reason = CH_SWITCH_NORMAL;
25222541

25232542
req.band_idx = phy != &dev->phy;
2524-
2525-
switch (chandef->width) {
2526-
case NL80211_CHAN_WIDTH_40:
2527-
req.bw = CMD_CBW_40MHZ;
2528-
break;
2529-
case NL80211_CHAN_WIDTH_80:
2530-
req.bw = CMD_CBW_80MHZ;
2531-
break;
2532-
case NL80211_CHAN_WIDTH_80P80:
2533-
req.bw = CMD_CBW_8080MHZ;
2534-
break;
2535-
case NL80211_CHAN_WIDTH_160:
2536-
req.bw = CMD_CBW_160MHZ;
2537-
break;
2538-
case NL80211_CHAN_WIDTH_5:
2539-
req.bw = CMD_CBW_5MHZ;
2540-
break;
2541-
case NL80211_CHAN_WIDTH_10:
2542-
req.bw = CMD_CBW_10MHZ;
2543-
break;
2544-
case NL80211_CHAN_WIDTH_20_NOHT:
2545-
case NL80211_CHAN_WIDTH_20:
2546-
default:
2547-
req.bw = CMD_CBW_20MHZ;
2548-
break;
2549-
}
2543+
req.bw = mt7615_mcu_chan_bw(chandef);
25502544

25512545
mt7615_mcu_set_txpower_sku(phy, req.txpower_sku);
25522546

@@ -2836,3 +2830,152 @@ int mt7615_mcu_sched_scan_enable(struct mt7615_phy *phy,
28362830
return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SCHED_SCAN_ENABLE,
28372831
&req, sizeof(req), false);
28382832
}
2833+
2834+
static int mt7615_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
2835+
{
2836+
int i;
2837+
2838+
for (i = 0; i < n_freqs; i++)
2839+
if (cur == freqs[i])
2840+
return i;
2841+
2842+
return -1;
2843+
}
2844+
2845+
static int mt7615_dcoc_freq_idx(u16 freq, u8 bw)
2846+
{
2847+
static const u16 freq_list[] = {
2848+
4980, 5805, 5905, 5190,
2849+
5230, 5270, 5310, 5350,
2850+
5390, 5430, 5470, 5510,
2851+
5550, 5590, 5630, 5670,
2852+
5710, 5755, 5795, 5835,
2853+
5875, 5210, 5290, 5370,
2854+
5450, 5530, 5610, 5690,
2855+
5775, 5855
2856+
};
2857+
static const u16 freq_bw40[] = {
2858+
5190, 5230, 5270, 5310,
2859+
5350, 5390, 5430, 5470,
2860+
5510, 5550, 5590, 5630,
2861+
5670, 5710, 5755, 5795,
2862+
5835, 5875
2863+
};
2864+
int offset_2g = ARRAY_SIZE(freq_list);
2865+
int idx;
2866+
2867+
if (freq < 4000) {
2868+
if (freq < 2427)
2869+
return offset_2g;
2870+
if (freq < 2442)
2871+
return offset_2g + 1;
2872+
if (freq < 2457)
2873+
return offset_2g + 2;
2874+
2875+
return offset_2g + 3;
2876+
}
2877+
2878+
switch (bw) {
2879+
case NL80211_CHAN_WIDTH_80:
2880+
case NL80211_CHAN_WIDTH_80P80:
2881+
case NL80211_CHAN_WIDTH_160:
2882+
break;
2883+
default:
2884+
idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),
2885+
freq + 10);
2886+
if (idx >= 0) {
2887+
freq = freq_bw40[idx];
2888+
break;
2889+
}
2890+
2891+
idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),
2892+
freq - 10);
2893+
if (idx >= 0) {
2894+
freq = freq_bw40[idx];
2895+
break;
2896+
}
2897+
/* fall through */
2898+
case NL80211_CHAN_WIDTH_40:
2899+
idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),
2900+
freq);
2901+
if (idx >= 0)
2902+
break;
2903+
2904+
return -1;
2905+
2906+
}
2907+
2908+
return mt7615_find_freq_idx(freq_list, ARRAY_SIZE(freq_list), freq);
2909+
}
2910+
2911+
int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy)
2912+
{
2913+
struct mt7615_dev *dev = phy->dev;
2914+
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
2915+
int freq2 = chandef->center_freq2;
2916+
int ret;
2917+
struct {
2918+
u8 direction;
2919+
u8 runtime_calibration;
2920+
u8 _rsv[2];
2921+
2922+
__le16 center_freq;
2923+
u8 bw;
2924+
u8 band;
2925+
u8 is_freq2;
2926+
u8 success;
2927+
u8 dbdc_en;
2928+
2929+
u8 _rsv2;
2930+
2931+
struct {
2932+
__le32 sx0_i_lna[4];
2933+
__le32 sx0_q_lna[4];
2934+
2935+
__le32 sx2_i_lna[4];
2936+
__le32 sx2_q_lna[4];
2937+
} dcoc_data[4];
2938+
} req = {
2939+
.direction = 1,
2940+
2941+
.bw = mt7615_mcu_chan_bw(chandef),
2942+
.band = chandef->center_freq1 > 4000,
2943+
.dbdc_en = !!dev->mt76.phy2,
2944+
};
2945+
u16 center_freq = chandef->center_freq1;
2946+
int freq_idx;
2947+
u8 *eep = dev->mt76.eeprom.data;
2948+
2949+
if (!(eep[MT_EE_CALDATA_FLASH] & MT_EE_CALDATA_FLASH_RX_CAL))
2950+
return 0;
2951+
2952+
if (chandef->width == NL80211_CHAN_WIDTH_160) {
2953+
freq2 = center_freq + 40;
2954+
center_freq -= 40;
2955+
}
2956+
2957+
again:
2958+
req.runtime_calibration = 1;
2959+
freq_idx = mt7615_dcoc_freq_idx(center_freq, chandef->width);
2960+
if (freq_idx < 0)
2961+
goto out;
2962+
2963+
memcpy(req.dcoc_data, eep + MT7615_EEPROM_DCOC_OFFSET +
2964+
freq_idx * MT7615_EEPROM_DCOC_SIZE,
2965+
sizeof(req.dcoc_data));
2966+
req.runtime_calibration = 0;
2967+
2968+
out:
2969+
req.center_freq = cpu_to_le16(center_freq);
2970+
ret = __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RXDCOC_CAL, &req,
2971+
sizeof(req), true);
2972+
2973+
if ((chandef->width == NL80211_CHAN_WIDTH_80P80 ||
2974+
chandef->width == NL80211_CHAN_WIDTH_160) && !req.is_freq2) {
2975+
req.is_freq2 = true;
2976+
center_freq = freq2;
2977+
goto again;
2978+
}
2979+
2980+
return ret;
2981+
}

drivers/net/wireless/mediatek/mt76/mt7615/mcu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ enum {
270270
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
271271
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
272272
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
273+
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
273274
MCU_EXT_CMD_SET_RDD_TH = 0x7c,
274275
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
275276
};

drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ struct mt7615_dev {
258258

259259
u8 mac_work_count;
260260
bool fw_debug;
261+
bool flash_eeprom;
261262

262263
spinlock_t token_lock;
263264
struct idr token;
@@ -494,6 +495,7 @@ int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
494495
int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,
495496
const struct mt7615_dfs_pattern *pattern);
496497
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable);
498+
int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy);
497499
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);
498500

499501
int mt7615_init_debugfs(struct mt7615_dev *dev);

0 commit comments

Comments
 (0)