brintos

brintos / linux-shallow public Read only

0
0
Text · 30.3 KiB · d4cd221 Raw
1259 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * (c) Copyright 2002-2010, Ralink Technology, Inc.4 * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>5 * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>6 */7 8#include "mt7601u.h"9#include "mcu.h"10#include "eeprom.h"11#include "trace.h"12#include "initvals_phy.h"13 14#include <linux/etherdevice.h>15 16static void mt7601u_agc_reset(struct mt7601u_dev *dev);17 18static int19mt7601u_rf_wr(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 value)20{21	int ret = 0;22 23	if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) ||24	    WARN_ON(offset > 63))25		return -EINVAL;26	if (test_bit(MT7601U_STATE_REMOVED, &dev->state))27		return 0;28 29	mutex_lock(&dev->reg_atomic_mutex);30 31	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) {32		ret = -ETIMEDOUT;33		goto out;34	}35 36	mt7601u_wr(dev, MT_RF_CSR_CFG,37		   FIELD_PREP(MT_RF_CSR_CFG_DATA, value) |38		   FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |39		   FIELD_PREP(MT_RF_CSR_CFG_REG_ID, offset) |40		   MT_RF_CSR_CFG_WR |41		   MT_RF_CSR_CFG_KICK);42	trace_rf_write(dev, bank, offset, value);43out:44	mutex_unlock(&dev->reg_atomic_mutex);45 46	if (ret < 0)47		dev_err(dev->dev, "Error: RF write %02hhx:%02hhx failed:%d!!\n",48			bank, offset, ret);49 50	return ret;51}52 53static int54mt7601u_rf_rr(struct mt7601u_dev *dev, u8 bank, u8 offset)55{56	int ret = -ETIMEDOUT;57	u32 val;58 59	if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) ||60	    WARN_ON(offset > 63))61		return -EINVAL;62	if (test_bit(MT7601U_STATE_REMOVED, &dev->state))63		return 0xff;64 65	mutex_lock(&dev->reg_atomic_mutex);66 67	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))68		goto out;69 70	mt7601u_wr(dev, MT_RF_CSR_CFG,71		   FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |72		   FIELD_PREP(MT_RF_CSR_CFG_REG_ID, offset) |73		   MT_RF_CSR_CFG_KICK);74 75	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))76		goto out;77 78	val = mt7601u_rr(dev, MT_RF_CSR_CFG);79	if (FIELD_GET(MT_RF_CSR_CFG_REG_ID, val) == offset &&80	    FIELD_GET(MT_RF_CSR_CFG_REG_BANK, val) == bank) {81		ret = FIELD_GET(MT_RF_CSR_CFG_DATA, val);82		trace_rf_read(dev, bank, offset, ret);83	}84out:85	mutex_unlock(&dev->reg_atomic_mutex);86 87	if (ret < 0)88		dev_err(dev->dev, "Error: RF read %02hhx:%02hhx failed:%d!!\n",89			bank, offset, ret);90 91	return ret;92}93 94static int95mt7601u_rf_rmw(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 mask, u8 val)96{97	int ret;98 99	ret = mt7601u_rf_rr(dev, bank, offset);100	if (ret < 0)101		return ret;102	val |= ret & ~mask;103	ret = mt7601u_rf_wr(dev, bank, offset, val);104	if (ret)105		return ret;106 107	return val;108}109 110static int111mt7601u_rf_set(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 val)112{113	return mt7601u_rf_rmw(dev, bank, offset, 0, val);114}115 116static int117mt7601u_rf_clear(struct mt7601u_dev *dev, u8 bank, u8 offset, u8 mask)118{119	return mt7601u_rf_rmw(dev, bank, offset, mask, 0);120}121 122static void mt7601u_bbp_wr(struct mt7601u_dev *dev, u8 offset, u8 val)123{124	if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)) ||125	    test_bit(MT7601U_STATE_REMOVED, &dev->state))126		return;127 128	mutex_lock(&dev->reg_atomic_mutex);129 130	if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000)) {131		dev_err(dev->dev, "Error: BBP write %02hhx failed!!\n", offset);132		goto out;133	}134 135	mt7601u_wr(dev, MT_BBP_CSR_CFG,136		   FIELD_PREP(MT_BBP_CSR_CFG_VAL, val) |137		   FIELD_PREP(MT_BBP_CSR_CFG_REG_NUM, offset) |138		   MT_BBP_CSR_CFG_RW_MODE | MT_BBP_CSR_CFG_BUSY);139	trace_bbp_write(dev, offset, val);140out:141	mutex_unlock(&dev->reg_atomic_mutex);142}143 144static int mt7601u_bbp_rr(struct mt7601u_dev *dev, u8 offset)145{146	u32 val;147	int ret = -ETIMEDOUT;148 149	if (WARN_ON(!test_bit(MT7601U_STATE_WLAN_RUNNING, &dev->state)))150		return -EINVAL;151	if (test_bit(MT7601U_STATE_REMOVED, &dev->state))152		return 0xff;153 154	mutex_lock(&dev->reg_atomic_mutex);155 156	if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000))157		goto out;158 159	mt7601u_wr(dev, MT_BBP_CSR_CFG,160		   FIELD_PREP(MT_BBP_CSR_CFG_REG_NUM, offset) |161		   MT_BBP_CSR_CFG_RW_MODE | MT_BBP_CSR_CFG_BUSY |162		   MT_BBP_CSR_CFG_READ);163 164	if (!mt76_poll(dev, MT_BBP_CSR_CFG, MT_BBP_CSR_CFG_BUSY, 0, 1000))165		goto out;166 167	val = mt7601u_rr(dev, MT_BBP_CSR_CFG);168	if (FIELD_GET(MT_BBP_CSR_CFG_REG_NUM, val) == offset) {169		ret = FIELD_GET(MT_BBP_CSR_CFG_VAL, val);170		trace_bbp_read(dev, offset, ret);171	}172out:173	mutex_unlock(&dev->reg_atomic_mutex);174 175	if (ret < 0)176		dev_err(dev->dev, "Error: BBP read %02hhx failed:%d!!\n",177			offset, ret);178 179	return ret;180}181 182static int mt7601u_bbp_rmw(struct mt7601u_dev *dev, u8 offset, u8 mask, u8 val)183{184	int ret;185 186	ret = mt7601u_bbp_rr(dev, offset);187	if (ret < 0)188		return ret;189	val |= ret & ~mask;190	mt7601u_bbp_wr(dev, offset, val);191 192	return val;193}194 195static u8 mt7601u_bbp_rmc(struct mt7601u_dev *dev, u8 offset, u8 mask, u8 val)196{197	int ret;198 199	ret = mt7601u_bbp_rr(dev, offset);200	if (ret < 0)201		return ret;202	val |= ret & ~mask;203	if (ret != val)204		mt7601u_bbp_wr(dev, offset, val);205 206	return val;207}208 209int mt7601u_wait_bbp_ready(struct mt7601u_dev *dev)210{211	int i = 20;212	u8 val;213 214	do {215		val = mt7601u_bbp_rr(dev, MT_BBP_REG_VERSION);216		if (val && val != 0xff)217			break;218	} while (--i);219 220	if (!i) {221		dev_err(dev->dev, "Error: BBP is not ready\n");222		return -EIO;223	}224 225	return 0;226}227 228u32 mt7601u_bbp_set_ctrlch(struct mt7601u_dev *dev, bool below)229{230	return mt7601u_bbp_rmc(dev, 3, 0x20, below ? 0x20 : 0);231}232 233int mt7601u_phy_get_rssi(struct mt7601u_dev *dev,234			 struct mt7601u_rxwi *rxwi, u16 rate)235{236	static const s8 lna[2][2][3] = {237		/* main LNA */ {238			/* bw20 */ { -2, 15, 33 },239			/* bw40 */ {  0, 16, 34 }240		},241		/*  aux LNA */ {242			/* bw20 */ { -2, 15, 33 },243			/* bw40 */ { -2, 16, 34 }244		}245	};246	int bw = FIELD_GET(MT_RXWI_RATE_BW, rate);247	int aux_lna = FIELD_GET(MT_RXWI_ANT_AUX_LNA, rxwi->ant);248	int lna_id = FIELD_GET(MT_RXWI_GAIN_RSSI_LNA_ID, rxwi->gain);249	int val;250 251	if (lna_id) /* LNA id can be 0, 2, 3. */252		lna_id--;253 254	val = 8;255	val -= lna[aux_lna][bw][lna_id];256	val -= FIELD_GET(MT_RXWI_GAIN_RSSI_VAL, rxwi->gain);257	val -= dev->ee->lna_gain;258	val -= dev->ee->rssi_offset[0];259 260	return val;261}262 263static void mt7601u_vco_cal(struct mt7601u_dev *dev)264{265	mt7601u_rf_wr(dev, 0, 4, 0x0a);266	mt7601u_rf_wr(dev, 0, 5, 0x20);267	mt7601u_rf_set(dev, 0, 4, BIT(7));268	msleep(2);269}270 271static int mt7601u_set_bw_filter(struct mt7601u_dev *dev, bool cal)272{273	u32 filter = 0;274	int ret;275 276	if (!cal)277		filter |= 0x10000;278	if (dev->bw != MT_BW_20)279		filter |= 0x00100;280 281	/* TX */282	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_BW, filter | 1);283	if (ret)284		return ret;285	/* RX */286	return mt7601u_mcu_calibrate(dev, MCU_CAL_BW, filter);287}288 289static int mt7601u_load_bbp_temp_table_bw(struct mt7601u_dev *dev)290{291	const struct reg_table *t;292 293	if (WARN_ON(dev->temp_mode > MT_TEMP_MODE_LOW))294		return -EINVAL;295 296	t = &bbp_mode_table[dev->temp_mode][dev->bw];297 298	return mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP, t->regs, t->n);299}300 301static int mt7601u_bbp_temp(struct mt7601u_dev *dev, int mode, const char *name)302{303	const struct reg_table *t;304	int ret;305 306	if (dev->temp_mode == mode)307		return 0;308 309	dev->temp_mode = mode;310	trace_temp_mode(dev, mode);311 312	t = bbp_mode_table[dev->temp_mode];313	ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP,314				      t[2].regs, t[2].n);315	if (ret)316		return ret;317 318	return mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP,319				       t[dev->bw].regs, t[dev->bw].n);320}321 322static void mt7601u_apply_ch14_fixup(struct mt7601u_dev *dev, int hw_chan)323{324	struct mt7601u_rate_power *t = &dev->ee->power_rate_table;325 326	if (hw_chan != 14 || dev->bw != MT_BW_20) {327		mt7601u_bbp_rmw(dev, 4, 0x20, 0);328		mt7601u_bbp_wr(dev, 178, 0xff);329 330		t->cck[0].bw20 = dev->ee->real_cck_bw20[0];331		t->cck[1].bw20 = dev->ee->real_cck_bw20[1];332	} else { /* Apply CH14 OBW fixup */333		mt7601u_bbp_wr(dev, 4, 0x60);334		mt7601u_bbp_wr(dev, 178, 0);335 336		/* Note: vendor code is buggy here for negative values */337		t->cck[0].bw20 = dev->ee->real_cck_bw20[0] - 2;338		t->cck[1].bw20 = dev->ee->real_cck_bw20[1] - 2;339	}340}341 342static int __mt7601u_phy_set_channel(struct mt7601u_dev *dev,343				     struct cfg80211_chan_def *chandef)344{345#define FREQ_PLAN_REGS	4346	static const u8 freq_plan[14][FREQ_PLAN_REGS] = {347		{ 0x99,	0x99,	0x09,	0x50 },348		{ 0x46,	0x44,	0x0a,	0x50 },349		{ 0xec,	0xee,	0x0a,	0x50 },350		{ 0x99,	0x99,	0x0b,	0x50 },351		{ 0x46,	0x44,	0x08,	0x51 },352		{ 0xec,	0xee,	0x08,	0x51 },353		{ 0x99,	0x99,	0x09,	0x51 },354		{ 0x46,	0x44,	0x0a,	0x51 },355		{ 0xec,	0xee,	0x0a,	0x51 },356		{ 0x99,	0x99,	0x0b,	0x51 },357		{ 0x46,	0x44,	0x08,	0x52 },358		{ 0xec,	0xee,	0x08,	0x52 },359		{ 0x99,	0x99,	0x09,	0x52 },360		{ 0x33,	0x33,	0x0b,	0x52 },361	};362	struct mt76_reg_pair channel_freq_plan[FREQ_PLAN_REGS] = {363		{ 17, 0 }, { 18, 0 }, { 19, 0 }, { 20, 0 },364	};365	struct mt76_reg_pair bbp_settings[3] = {366		{ 62, 0x37 - dev->ee->lna_gain },367		{ 63, 0x37 - dev->ee->lna_gain },368		{ 64, 0x37 - dev->ee->lna_gain },369	};370 371	struct ieee80211_channel *chan = chandef->chan;372	enum nl80211_channel_type chan_type =373		cfg80211_get_chandef_type(chandef);374	struct mt7601u_rate_power *t = &dev->ee->power_rate_table;375	int chan_idx;376	bool chan_ext_below;377	u8 bw;378	int i, ret;379 380	bw = MT_BW_20;381	chan_ext_below = (chan_type == NL80211_CHAN_HT40MINUS);382	chan_idx = chan->hw_value - 1;383 384	if (chandef->width == NL80211_CHAN_WIDTH_40) {385		bw = MT_BW_40;386 387		if (chan_idx > 1 && chan_type == NL80211_CHAN_HT40MINUS)388			chan_idx -= 2;389		else if (chan_idx < 12 && chan_type == NL80211_CHAN_HT40PLUS)390			chan_idx += 2;391		else392			dev_err(dev->dev, "Error: invalid 40MHz channel!!\n");393	}394 395	if (bw != dev->bw || chan_ext_below != dev->chan_ext_below) {396		dev_dbg(dev->dev, "Info: switching HT mode bw:%d below:%d\n",397			bw, chan_ext_below);398 399		mt7601u_bbp_set_bw(dev, bw);400 401		mt7601u_bbp_set_ctrlch(dev, chan_ext_below);402		mt7601u_mac_set_ctrlch(dev, chan_ext_below);403		dev->chan_ext_below = chan_ext_below;404	}405 406	for (i = 0; i < FREQ_PLAN_REGS; i++)407		channel_freq_plan[i].value = freq_plan[chan_idx][i];408 409	ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_RF,410				      channel_freq_plan, FREQ_PLAN_REGS);411	if (ret)412		return ret;413 414	mt7601u_rmw(dev, MT_TX_ALC_CFG_0, 0x3f3f,415		    dev->ee->chan_pwr[chan_idx] & 0x3f);416 417	ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP,418				      bbp_settings, ARRAY_SIZE(bbp_settings));419	if (ret)420		return ret;421 422	mt7601u_vco_cal(dev);423	mt7601u_bbp_set_bw(dev, bw);424	ret = mt7601u_set_bw_filter(dev, false);425	if (ret)426		return ret;427 428	mt7601u_apply_ch14_fixup(dev, chan->hw_value);429	mt7601u_wr(dev, MT_TX_PWR_CFG_0, int_to_s6(t->ofdm[1].bw20) << 24 |430					 int_to_s6(t->ofdm[0].bw20) << 16 |431					 int_to_s6(t->cck[1].bw20) << 8 |432					 int_to_s6(t->cck[0].bw20));433 434	if (test_bit(MT7601U_STATE_SCANNING, &dev->state))435		mt7601u_agc_reset(dev);436 437	dev->chandef = *chandef;438 439	return 0;440}441 442int mt7601u_phy_set_channel(struct mt7601u_dev *dev,443			    struct cfg80211_chan_def *chandef)444{445	int ret;446 447	cancel_delayed_work_sync(&dev->cal_work);448	cancel_delayed_work_sync(&dev->freq_cal.work);449 450	mutex_lock(&dev->hw_atomic_mutex);451	ret = __mt7601u_phy_set_channel(dev, chandef);452	mutex_unlock(&dev->hw_atomic_mutex);453	if (ret)454		return ret;455 456	if (test_bit(MT7601U_STATE_SCANNING, &dev->state))457		return 0;458 459	ieee80211_queue_delayed_work(dev->hw, &dev->cal_work,460				     MT_CALIBRATE_INTERVAL);461	if (dev->freq_cal.enabled)462		ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work,463					     MT_FREQ_CAL_INIT_DELAY);464	return 0;465}466 467#define BBP_R47_FLAG		GENMASK(2, 0)468#define BBP_R47_F_TSSI		0469#define BBP_R47_F_PKT_T		1470#define BBP_R47_F_TX_RATE	2471#define BBP_R47_F_TEMP		4472/**473 * mt7601u_bbp_r47_get - read value through BBP R47/R49 pair474 * @dev:	pointer to adapter structure475 * @reg:	value of BBP R47 before the operation476 * @flag:	one of the BBP_R47_F_* flags477 *478 * Convenience helper for reading values through BBP R47/R49 pair.479 * Takes old value of BBP R47 as @reg, because callers usually have it480 * cached already.481 *482 * Return: value of BBP R49.483 */484static u8 mt7601u_bbp_r47_get(struct mt7601u_dev *dev, u8 reg, u8 flag)485{486	flag |= reg & ~BBP_R47_FLAG;487	mt7601u_bbp_wr(dev, 47, flag);488	usleep_range(500, 700);489	return mt7601u_bbp_rr(dev, 49);490}491 492static s8 mt7601u_read_bootup_temp(struct mt7601u_dev *dev)493{494	u8 bbp_val, temp;495	u32 rf_bp, rf_set;496	int i;497 498	rf_set = mt7601u_rr(dev, MT_RF_SETTING_0);499	rf_bp = mt7601u_rr(dev, MT_RF_BYPASS_0);500 501	mt7601u_wr(dev, MT_RF_BYPASS_0, 0);502	mt7601u_wr(dev, MT_RF_SETTING_0, 0x00000010);503	mt7601u_wr(dev, MT_RF_BYPASS_0, 0x00000010);504 505	bbp_val = mt7601u_bbp_rmw(dev, 47, 0, 0x10);506 507	mt7601u_bbp_wr(dev, 22, 0x40);508 509	for (i = 100; i && (bbp_val & 0x10); i--)510		bbp_val = mt7601u_bbp_rr(dev, 47);511 512	temp = mt7601u_bbp_r47_get(dev, bbp_val, BBP_R47_F_TEMP);513 514	mt7601u_bbp_wr(dev, 22, 0);515 516	bbp_val = mt7601u_bbp_rr(dev, 21);517	bbp_val |= 0x02;518	mt7601u_bbp_wr(dev, 21, bbp_val);519	bbp_val &= ~0x02;520	mt7601u_bbp_wr(dev, 21, bbp_val);521 522	mt7601u_wr(dev, MT_RF_BYPASS_0, 0);523	mt7601u_wr(dev, MT_RF_SETTING_0, rf_set);524	mt7601u_wr(dev, MT_RF_BYPASS_0, rf_bp);525 526	trace_read_temp(dev, temp);527	return temp;528}529 530static s8 mt7601u_read_temp(struct mt7601u_dev *dev)531{532	int i;533	u8 val;534	s8 temp;535 536	val = mt7601u_bbp_rmw(dev, 47, 0x7f, 0x10);537 538	/* Note: this rarely succeeds, temp can change even if it fails. */539	for (i = 100; i && (val & 0x10); i--)540		val = mt7601u_bbp_rr(dev, 47);541 542	temp = mt7601u_bbp_r47_get(dev, val, BBP_R47_F_TEMP);543 544	trace_read_temp(dev, temp);545	return temp;546}547 548static void mt7601u_rxdc_cal(struct mt7601u_dev *dev)549{550	static const struct mt76_reg_pair intro[] = {551		{ 158, 0x8d }, { 159, 0xfc },552		{ 158, 0x8c }, { 159, 0x4c },553	}, outro[] = {554		{ 158, 0x8d }, { 159, 0xe0 },555	};556	u32 mac_ctrl;557	int i, ret;558 559	mac_ctrl = mt7601u_rr(dev, MT_MAC_SYS_CTRL);560	mt7601u_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_RX);561 562	ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP,563				      intro, ARRAY_SIZE(intro));564	if (ret)565		dev_err(dev->dev, "%s intro failed:%d\n", __func__, ret);566 567	for (i = 20; i; i--) {568		usleep_range(300, 500);569 570		mt7601u_bbp_wr(dev, 158, 0x8c);571		if (mt7601u_bbp_rr(dev, 159) == 0x0c)572			break;573	}574	if (!i)575		dev_err(dev->dev, "%s timed out\n", __func__);576 577	mt7601u_wr(dev, MT_MAC_SYS_CTRL, 0);578 579	ret = mt7601u_write_reg_pairs(dev, MT_MCU_MEMMAP_BBP,580				      outro, ARRAY_SIZE(outro));581	if (ret)582		dev_err(dev->dev, "%s outro failed:%d\n", __func__, ret);583 584	mt7601u_wr(dev, MT_MAC_SYS_CTRL, mac_ctrl);585}586 587void mt7601u_phy_recalibrate_after_assoc(struct mt7601u_dev *dev)588{589	if (test_bit(MT7601U_STATE_REMOVED, &dev->state))590		return;591 592	mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->curr_temp);593 594	mt7601u_rxdc_cal(dev);595}596 597/* Note: function copied from vendor driver */598static s16 lin2dBd(u16 linear)599{600	short exp = 0;601	unsigned int mantisa;602	int app, dBd;603 604	if (WARN_ON(!linear))605		return -10000;606 607	mantisa = linear;608 609	exp = fls(mantisa) - 16;610	if (exp > 0)611		mantisa >>= exp;612	else613		mantisa <<= abs(exp);614 615	if (mantisa <= 0xb800)616		app = (mantisa + (mantisa >> 3) + (mantisa >> 4) - 0x9600);617	else618		app = (mantisa - (mantisa >> 3) - (mantisa >> 6) - 0x5a00);619	if (app < 0)620		app = 0;621 622	dBd = ((15 + exp) << 15) + app;623	dBd = (dBd << 2) + (dBd << 1) + (dBd >> 6) + (dBd >> 7);624	dBd = (dBd >> 10);625 626	return dBd;627}628 629static void630mt7601u_set_initial_tssi(struct mt7601u_dev *dev, s16 tssi_db, s16 tssi_hvga_db)631{632	struct tssi_data *d = &dev->ee->tssi_data;633	int init_offset;634 635	init_offset = -((tssi_db * d->slope + d->offset[1]) / 4096) + 10;636 637	mt76_rmw(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,638		 int_to_s6(init_offset) & MT_TX_ALC_CFG_1_TEMP_COMP);639}640 641static void mt7601u_tssi_dc_gain_cal(struct mt7601u_dev *dev)642{643	u8 rf_vga, rf_mixer, bbp_r47;644	int i, j;645	s8 res[4];646	s16 tssi_init_db, tssi_init_hvga_db;647 648	mt7601u_wr(dev, MT_RF_SETTING_0, 0x00000030);649	mt7601u_wr(dev, MT_RF_BYPASS_0, 0x000c0030);650	mt7601u_wr(dev, MT_MAC_SYS_CTRL, 0);651 652	mt7601u_bbp_wr(dev, 58, 0);653	mt7601u_bbp_wr(dev, 241, 0x2);654	mt7601u_bbp_wr(dev, 23, 0x8);655	bbp_r47 = mt7601u_bbp_rr(dev, 47);656 657	/* Set VGA gain */658	rf_vga = mt7601u_rf_rr(dev, 5, 3);659	mt7601u_rf_wr(dev, 5, 3, 8);660 661	/* Mixer disable */662	rf_mixer = mt7601u_rf_rr(dev, 4, 39);663	mt7601u_rf_wr(dev, 4, 39, 0);664 665	for (i = 0; i < 4; i++) {666		mt7601u_rf_wr(dev, 4, 39, (i & 1) ? rf_mixer : 0);667 668		mt7601u_bbp_wr(dev, 23, (i < 2) ? 0x08 : 0x02);669		mt7601u_rf_wr(dev, 5, 3, (i < 2) ? 0x08 : 0x11);670 671		/* BBP TSSI initial and soft reset */672		mt7601u_bbp_wr(dev, 22, 0);673		mt7601u_bbp_wr(dev, 244, 0);674 675		mt7601u_bbp_wr(dev, 21, 1);676		udelay(1);677		mt7601u_bbp_wr(dev, 21, 0);678 679		/* TSSI measurement */680		mt7601u_bbp_wr(dev, 47, 0x50);681		mt7601u_bbp_wr(dev, (i & 1) ? 244 : 22, (i & 1) ? 0x31 : 0x40);682 683		for (j = 20; j; j--)684			if (!(mt7601u_bbp_rr(dev, 47) & 0x10))685				break;686		if (!j)687			dev_err(dev->dev, "%s timed out\n", __func__);688 689		/* TSSI read */690		mt7601u_bbp_wr(dev, 47, 0x40);691		res[i] = mt7601u_bbp_rr(dev, 49);692	}693 694	tssi_init_db = lin2dBd((short)res[1] - res[0]);695	tssi_init_hvga_db = lin2dBd(((short)res[3] - res[2]) * 4);696	dev->tssi_init = res[0];697	dev->tssi_init_hvga = res[2];698	dev->tssi_init_hvga_offset_db = tssi_init_hvga_db - tssi_init_db;699 700	dev_dbg(dev->dev,701		"TSSI_init:%hhx db:%hx hvga:%hhx hvga_db:%hx off_db:%hx\n",702		dev->tssi_init, tssi_init_db, dev->tssi_init_hvga,703		tssi_init_hvga_db, dev->tssi_init_hvga_offset_db);704 705	mt7601u_bbp_wr(dev, 22, 0);706	mt7601u_bbp_wr(dev, 244, 0);707 708	mt7601u_bbp_wr(dev, 21, 1);709	udelay(1);710	mt7601u_bbp_wr(dev, 21, 0);711 712	mt7601u_wr(dev, MT_RF_BYPASS_0, 0);713	mt7601u_wr(dev, MT_RF_SETTING_0, 0);714 715	mt7601u_rf_wr(dev, 5, 3, rf_vga);716	mt7601u_rf_wr(dev, 4, 39, rf_mixer);717	mt7601u_bbp_wr(dev, 47, bbp_r47);718 719	mt7601u_set_initial_tssi(dev, tssi_init_db, tssi_init_hvga_db);720}721 722static int mt7601u_temp_comp(struct mt7601u_dev *dev, bool on)723{724	int ret, temp, hi_temp = 400, lo_temp = -200;725 726	temp = (dev->raw_temp - dev->ee->ref_temp) * MT_EE_TEMPERATURE_SLOPE;727	dev->curr_temp = temp;728 729	/* DPD Calibration */730	if (temp - dev->dpd_temp > 450 || temp - dev->dpd_temp < -450) {731		dev->dpd_temp = temp;732 733		ret = mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->dpd_temp);734		if (ret)735			return ret;736 737		mt7601u_vco_cal(dev);738 739		dev_dbg(dev->dev, "Recalibrate DPD\n");740	}741 742	/* PLL Lock Protect */743	if (temp < -50 && !dev->pll_lock_protect) { /* < 20C */744		dev->pll_lock_protect =  true;745 746		mt7601u_rf_wr(dev, 4, 4, 6);747		mt7601u_rf_clear(dev, 4, 10, 0x30);748 749		dev_dbg(dev->dev, "PLL lock protect on - too cold\n");750	} else if (temp > 50 && dev->pll_lock_protect) { /* > 30C */751		dev->pll_lock_protect = false;752 753		mt7601u_rf_wr(dev, 4, 4, 0);754		mt7601u_rf_rmw(dev, 4, 10, 0x30, 0x10);755 756		dev_dbg(dev->dev, "PLL lock protect off\n");757	}758 759	if (on) {760		hi_temp -= 50;761		lo_temp -= 50;762	}763 764	/* BBP CR for H, L, N temperature */765	if (temp > hi_temp)766		return mt7601u_bbp_temp(dev, MT_TEMP_MODE_HIGH, "high");767	else if (temp > lo_temp)768		return mt7601u_bbp_temp(dev, MT_TEMP_MODE_NORMAL, "normal");769	else770		return mt7601u_bbp_temp(dev, MT_TEMP_MODE_LOW, "low");771}772 773/* Note: this is used only with TSSI, we can just use trgt_pwr from eeprom. */774static int mt7601u_current_tx_power(struct mt7601u_dev *dev)775{776	return dev->ee->chan_pwr[dev->chandef.chan->hw_value - 1];777}778 779static bool mt7601u_use_hvga(struct mt7601u_dev *dev)780{781	return !(mt7601u_current_tx_power(dev) > 20);782}783 784static s16785mt7601u_phy_rf_pa_mode_val(struct mt7601u_dev *dev, int phy_mode, int tx_rate)786{787	static const s16 decode_tb[] = { 0, 8847, -5734, -5734 };788	u32 reg;789 790	switch (phy_mode) {791	case MT_PHY_TYPE_OFDM:792		tx_rate += 4;793		fallthrough;794	case MT_PHY_TYPE_CCK:795		reg = dev->rf_pa_mode[0];796		break;797	default:798		reg = dev->rf_pa_mode[1];799		break;800	}801 802	return decode_tb[(reg >> (tx_rate * 2)) & 0x3];803}804 805static struct mt7601u_tssi_params806mt7601u_tssi_params_get(struct mt7601u_dev *dev)807{808	static const u8 ofdm_pkt2rate[8] = { 6, 4, 2, 0, 7, 5, 3, 1 };809	static const int static_power[4] = { 0, -49152, -98304, 49152 };810	struct mt7601u_tssi_params p;811	u8 bbp_r47, pkt_type, tx_rate;812	struct power_per_rate *rate_table;813 814	bbp_r47 = mt7601u_bbp_rr(dev, 47);815 816	p.tssi0 = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TSSI);817	dev->raw_temp = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TEMP);818	pkt_type = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_PKT_T);819 820	p.trgt_power = mt7601u_current_tx_power(dev);821 822	switch (pkt_type & 0x03) {823	case MT_PHY_TYPE_CCK:824		tx_rate = (pkt_type >> 4) & 0x03;825		rate_table = dev->ee->power_rate_table.cck;826		break;827 828	case MT_PHY_TYPE_OFDM:829		tx_rate = ofdm_pkt2rate[(pkt_type >> 4) & 0x07];830		rate_table = dev->ee->power_rate_table.ofdm;831		break;832 833	default:834		tx_rate = mt7601u_bbp_r47_get(dev, bbp_r47, BBP_R47_F_TX_RATE);835		tx_rate &= 0x7f;836		rate_table = dev->ee->power_rate_table.ht;837		break;838	}839 840	if (dev->bw == MT_BW_20)841		p.trgt_power += rate_table[tx_rate / 2].bw20;842	else843		p.trgt_power += rate_table[tx_rate / 2].bw40;844 845	p.trgt_power <<= 12;846 847	dev_dbg(dev->dev, "tx_rate:%02hhx pwr:%08x\n", tx_rate, p.trgt_power);848 849	p.trgt_power += mt7601u_phy_rf_pa_mode_val(dev, pkt_type & 0x03,850						   tx_rate);851 852	/* Channel 14, cck, bw20 */853	if ((pkt_type & 0x03) == MT_PHY_TYPE_CCK) {854		if (mt7601u_bbp_rr(dev, 4) & 0x20)855			p.trgt_power += mt7601u_bbp_rr(dev, 178) ? 18022 : 9830;856		else857			p.trgt_power += mt7601u_bbp_rr(dev, 178) ? 819 : 24576;858	}859 860	p.trgt_power += static_power[mt7601u_bbp_rr(dev, 1) & 0x03];861 862	p.trgt_power += dev->ee->tssi_data.tx0_delta_offset;863 864	dev_dbg(dev->dev,865		"tssi:%02hhx t_power:%08x temp:%02hhx pkt_type:%02hhx\n",866		p.tssi0, p.trgt_power, dev->raw_temp, pkt_type);867 868	return p;869}870 871static bool mt7601u_tssi_read_ready(struct mt7601u_dev *dev)872{873	return !(mt7601u_bbp_rr(dev, 47) & 0x10);874}875 876static int mt7601u_tssi_cal(struct mt7601u_dev *dev)877{878	struct mt7601u_tssi_params params;879	int curr_pwr, diff_pwr;880	char tssi_offset;881	s8 tssi_init;882	s16 tssi_m_dc, tssi_db;883	bool hvga;884	u32 val;885 886	if (!dev->ee->tssi_enabled)887		return 0;888 889	hvga = mt7601u_use_hvga(dev);890	if (!dev->tssi_read_trig)891		return mt7601u_mcu_tssi_read_kick(dev, hvga);892 893	if (!mt7601u_tssi_read_ready(dev))894		return 0;895 896	params = mt7601u_tssi_params_get(dev);897 898	tssi_init = (hvga ? dev->tssi_init_hvga : dev->tssi_init);899	tssi_m_dc = params.tssi0 - tssi_init;900	tssi_db = lin2dBd(tssi_m_dc);901	dev_dbg(dev->dev, "tssi dc:%04hx db:%04hx hvga:%d\n",902		tssi_m_dc, tssi_db, hvga);903 904	if (dev->chandef.chan->hw_value < 5)905		tssi_offset = dev->ee->tssi_data.offset[0];906	else if (dev->chandef.chan->hw_value < 9)907		tssi_offset = dev->ee->tssi_data.offset[1];908	else909		tssi_offset = dev->ee->tssi_data.offset[2];910 911	if (hvga)912		tssi_db -= dev->tssi_init_hvga_offset_db;913 914	curr_pwr = tssi_db * dev->ee->tssi_data.slope + (tssi_offset << 9);915	diff_pwr = params.trgt_power - curr_pwr;916	dev_dbg(dev->dev, "Power curr:%08x diff:%08x\n", curr_pwr, diff_pwr);917 918	if (params.tssi0 > 126 && diff_pwr > 0) {919		dev_err(dev->dev, "Error: TSSI upper saturation\n");920		diff_pwr = 0;921	}922	if (params.tssi0 - tssi_init < 1 && diff_pwr < 0) {923		dev_err(dev->dev, "Error: TSSI lower saturation\n");924		diff_pwr = 0;925	}926 927	if ((dev->prev_pwr_diff ^ diff_pwr) < 0 && abs(diff_pwr) < 4096 &&928	    (abs(diff_pwr) > abs(dev->prev_pwr_diff) ||929	     (diff_pwr > 0 && diff_pwr == -dev->prev_pwr_diff)))930		diff_pwr = 0;931	else932		dev->prev_pwr_diff = diff_pwr;933 934	diff_pwr += (diff_pwr > 0) ? 2048 : -2048;935	diff_pwr /= 4096;936 937	dev_dbg(dev->dev, "final diff: %08x\n", diff_pwr);938 939	val = mt7601u_rr(dev, MT_TX_ALC_CFG_1);940	curr_pwr = s6_to_int(FIELD_GET(MT_TX_ALC_CFG_1_TEMP_COMP, val));941	diff_pwr += curr_pwr;942	val = (val & ~MT_TX_ALC_CFG_1_TEMP_COMP) | int_to_s6(diff_pwr);943	mt7601u_wr(dev, MT_TX_ALC_CFG_1, val);944 945	return mt7601u_mcu_tssi_read_kick(dev, hvga);946}947 948static u8 mt7601u_agc_default(struct mt7601u_dev *dev)949{950	return (dev->ee->lna_gain - 8) * 2 + 0x34;951}952 953static void mt7601u_agc_reset(struct mt7601u_dev *dev)954{955	u8 agc = mt7601u_agc_default(dev);956 957	mt7601u_bbp_wr(dev, 66,	agc);958}959 960void mt7601u_agc_save(struct mt7601u_dev *dev)961{962	dev->agc_save = mt7601u_bbp_rr(dev, 66);963}964 965void mt7601u_agc_restore(struct mt7601u_dev *dev)966{967	mt7601u_bbp_wr(dev, 66, dev->agc_save);968}969 970static void mt7601u_agc_tune(struct mt7601u_dev *dev)971{972	u8 val = mt7601u_agc_default(dev);973	long avg_rssi;974 975	if (test_bit(MT7601U_STATE_SCANNING, &dev->state))976		return;977 978	/* Note: only in STA mode and not dozing; perhaps do this only if979	 *	 there is enough rssi updates since last run?980	 *	 Rssi updates are only on beacons and U2M so should work...981	 */982	spin_lock_bh(&dev->con_mon_lock);983	avg_rssi = ewma_rssi_read(&dev->avg_rssi);984	spin_unlock_bh(&dev->con_mon_lock);985	if (avg_rssi == 0)986		return;987 988	avg_rssi = -avg_rssi;989	if (avg_rssi <= -70)990		val -= 0x20;991	else if (avg_rssi <= -60)992		val -= 0x10;993 994	if (val != mt7601u_bbp_rr(dev, 66))995		mt7601u_bbp_wr(dev, 66, val);996 997	/* TODO: also if lost a lot of beacons try resetting998	 *       (see RTMPSetAGCInitValue() call in mlme.c).999	 */1000}1001 1002static void mt7601u_phy_calibrate(struct work_struct *work)1003{1004	struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev,1005					    cal_work.work);1006 1007	mt7601u_agc_tune(dev);1008	mt7601u_tssi_cal(dev);1009	/* If TSSI calibration was run it already updated temperature. */1010	if (!dev->ee->tssi_enabled)1011		dev->raw_temp = mt7601u_read_temp(dev);1012	mt7601u_temp_comp(dev, true); /* TODO: find right value for @on */1013 1014	ieee80211_queue_delayed_work(dev->hw, &dev->cal_work,1015				     MT_CALIBRATE_INTERVAL);1016}1017 1018static unsigned long1019__mt7601u_phy_freq_cal(struct mt7601u_dev *dev, s8 last_offset, u8 phy_mode)1020{1021	u8 activate_threshold, deactivate_threshold;1022 1023	trace_freq_cal_offset(dev, phy_mode, last_offset);1024 1025	/* No beacons received - reschedule soon */1026	if (last_offset == MT_FREQ_OFFSET_INVALID)1027		return MT_FREQ_CAL_ADJ_INTERVAL;1028 1029	switch (phy_mode) {1030	case MT_PHY_TYPE_CCK:1031		activate_threshold = 19;1032		deactivate_threshold = 5;1033		break;1034	case MT_PHY_TYPE_OFDM:1035		activate_threshold = 102;1036		deactivate_threshold = 32;1037		break;1038	case MT_PHY_TYPE_HT:1039	case MT_PHY_TYPE_HT_GF:1040		activate_threshold = 82;1041		deactivate_threshold = 20;1042		break;1043	default:1044		WARN_ON(1);1045		return MT_FREQ_CAL_CHECK_INTERVAL;1046	}1047 1048	if (abs(last_offset) >= activate_threshold)1049		dev->freq_cal.adjusting = true;1050	else if (abs(last_offset) <= deactivate_threshold)1051		dev->freq_cal.adjusting = false;1052 1053	if (!dev->freq_cal.adjusting)1054		return MT_FREQ_CAL_CHECK_INTERVAL;1055 1056	if (last_offset > deactivate_threshold) {1057		if (dev->freq_cal.freq > 0)1058			dev->freq_cal.freq--;1059		else1060			dev->freq_cal.adjusting = false;1061	} else if (last_offset < -deactivate_threshold) {1062		if (dev->freq_cal.freq < 0xbf)1063			dev->freq_cal.freq++;1064		else1065			dev->freq_cal.adjusting = false;1066	}1067 1068	trace_freq_cal_adjust(dev, dev->freq_cal.freq);1069	mt7601u_rf_wr(dev, 0, 12, dev->freq_cal.freq);1070	mt7601u_vco_cal(dev);1071 1072	return dev->freq_cal.adjusting ? MT_FREQ_CAL_ADJ_INTERVAL :1073					 MT_FREQ_CAL_CHECK_INTERVAL;1074}1075 1076static void mt7601u_phy_freq_cal(struct work_struct *work)1077{1078	struct mt7601u_dev *dev = container_of(work, struct mt7601u_dev,1079					       freq_cal.work.work);1080	s8 last_offset;1081	u8 phy_mode;1082	unsigned long delay;1083 1084	spin_lock_bh(&dev->con_mon_lock);1085	last_offset = dev->bcn_freq_off;1086	phy_mode = dev->bcn_phy_mode;1087	spin_unlock_bh(&dev->con_mon_lock);1088 1089	delay = __mt7601u_phy_freq_cal(dev, last_offset, phy_mode);1090	ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work, delay);1091 1092	spin_lock_bh(&dev->con_mon_lock);1093	dev->bcn_freq_off = MT_FREQ_OFFSET_INVALID;1094	spin_unlock_bh(&dev->con_mon_lock);1095}1096 1097void mt7601u_phy_con_cal_onoff(struct mt7601u_dev *dev,1098			       struct ieee80211_bss_conf *info)1099{1100	struct ieee80211_vif *vif = container_of(info, struct ieee80211_vif,1101						 bss_conf);1102 1103	if (!vif->cfg.assoc)1104		cancel_delayed_work_sync(&dev->freq_cal.work);1105 1106	/* Start/stop collecting beacon data */1107	spin_lock_bh(&dev->con_mon_lock);1108	ether_addr_copy(dev->ap_bssid, info->bssid);1109	ewma_rssi_init(&dev->avg_rssi);1110	dev->bcn_freq_off = MT_FREQ_OFFSET_INVALID;1111	spin_unlock_bh(&dev->con_mon_lock);1112 1113	dev->freq_cal.freq = dev->ee->rf_freq_off;1114	dev->freq_cal.enabled = vif->cfg.assoc;1115	dev->freq_cal.adjusting = false;1116 1117	if (vif->cfg.assoc)1118		ieee80211_queue_delayed_work(dev->hw, &dev->freq_cal.work,1119					     MT_FREQ_CAL_INIT_DELAY);1120}1121 1122static int mt7601u_init_cal(struct mt7601u_dev *dev)1123{1124	u32 mac_ctrl;1125	int ret;1126 1127	dev->raw_temp = mt7601u_read_bootup_temp(dev);1128	dev->curr_temp = (dev->raw_temp - dev->ee->ref_temp) *1129		MT_EE_TEMPERATURE_SLOPE;1130	dev->dpd_temp = dev->curr_temp;1131 1132	mac_ctrl = mt7601u_rr(dev, MT_MAC_SYS_CTRL);1133 1134	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_R, 0);1135	if (ret)1136		return ret;1137 1138	ret = mt7601u_rf_rr(dev, 0, 4);1139	if (ret < 0)1140		return ret;1141	ret |= 0x80;1142	ret = mt7601u_rf_wr(dev, 0, 4, ret);1143	if (ret)1144		return ret;1145	msleep(2);1146 1147	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_TXDCOC, 0);1148	if (ret)1149		return ret;1150 1151	mt7601u_rxdc_cal(dev);1152 1153	ret = mt7601u_set_bw_filter(dev, true);1154	if (ret)1155		return ret;1156	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_LOFT, 0);1157	if (ret)1158		return ret;1159	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_TXIQ, 0);1160	if (ret)1161		return ret;1162	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_RXIQ, 0);1163	if (ret)1164		return ret;1165	ret = mt7601u_mcu_calibrate(dev, MCU_CAL_DPD, dev->dpd_temp);1166	if (ret)1167		return ret;1168 1169	mt7601u_rxdc_cal(dev);1170 1171	mt7601u_tssi_dc_gain_cal(dev);1172 1173	mt7601u_wr(dev, MT_MAC_SYS_CTRL, mac_ctrl);1174 1175	mt7601u_temp_comp(dev, true);1176 1177	return 0;1178}1179 1180int mt7601u_bbp_set_bw(struct mt7601u_dev *dev, int bw)1181{1182	u32 val, old;1183 1184	if (bw == dev->bw) {1185		/* Vendor driver does the rmc even when no change is needed. */1186		mt7601u_bbp_rmc(dev, 4, 0x18, bw == MT_BW_20 ? 0 : 0x10);1187 1188		return 0;1189	}1190	dev->bw = bw;1191 1192	/* Stop MAC for the time of bw change */1193	old = mt7601u_rr(dev, MT_MAC_SYS_CTRL);1194	val = old & ~(MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);1195	mt7601u_wr(dev, MT_MAC_SYS_CTRL, val);1196	mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_TX | MT_MAC_STATUS_RX,1197		  0, 500000);1198 1199	mt7601u_bbp_rmc(dev, 4, 0x18, bw == MT_BW_20 ? 0 : 0x10);1200 1201	mt7601u_wr(dev, MT_MAC_SYS_CTRL, old);1202 1203	return mt7601u_load_bbp_temp_table_bw(dev);1204}1205 1206/**1207 * mt7601u_set_rx_path - set rx path in BBP1208 * @dev:	pointer to adapter structure1209 * @path:	rx path to set values are 0-based1210 */1211void mt7601u_set_rx_path(struct mt7601u_dev *dev, u8 path)1212{1213	mt7601u_bbp_rmw(dev, 3, 0x18, path << 3);1214}1215 1216/**1217 * mt7601u_set_tx_dac - set which tx DAC to use1218 * @dev:	pointer to adapter structure1219 * @dac:	DAC index, values are 0-based1220 */1221void mt7601u_set_tx_dac(struct mt7601u_dev *dev, u8 dac)1222{1223	mt7601u_bbp_rmc(dev, 1, 0x18, dac << 3);1224}1225 1226int mt7601u_phy_init(struct mt7601u_dev *dev)1227{1228	int ret;1229 1230	dev->rf_pa_mode[0] = mt7601u_rr(dev, MT_RF_PA_MODE_CFG0);1231	dev->rf_pa_mode[1] = mt7601u_rr(dev, MT_RF_PA_MODE_CFG1);1232 1233	ret = mt7601u_rf_wr(dev, 0, 12, dev->ee->rf_freq_off);1234	if (ret)1235		return ret;1236	ret = mt7601u_write_reg_pairs(dev, 0, rf_central,1237				      ARRAY_SIZE(rf_central));1238	if (ret)1239		return ret;1240	ret = mt7601u_write_reg_pairs(dev, 0, rf_channel,1241				      ARRAY_SIZE(rf_channel));1242	if (ret)1243		return ret;1244	ret = mt7601u_write_reg_pairs(dev, 0, rf_vga, ARRAY_SIZE(rf_vga));1245	if (ret)1246		return ret;1247 1248	ret = mt7601u_init_cal(dev);1249	if (ret)1250		return ret;1251 1252	dev->prev_pwr_diff = 100;1253 1254	INIT_DELAYED_WORK(&dev->cal_work, mt7601u_phy_calibrate);1255	INIT_DELAYED_WORK(&dev->freq_cal.work, mt7601u_phy_freq_cal);1256 1257	return 0;1258}1259