Newer
Older
static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
enum ieee80211_band band, int power_level,
u8 txpower, int delta)
{
u32 reg;
u16 eeprom;
u8 criterion;
u8 eirp_txpower;
u8 eirp_txpower_criterion;
u8 reg_limit;
if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
return txpower;
if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
/*
* Check if eirp txpower exceed txpower_limit.
* We use OFDM 6M as criterion and its eirp txpower
* is stored at EEPROM_EIRP_MAX_TX_POWER.
* .11b data rate need add additional 4dbm
* when calculating eirp txpower.
*/
rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®);
criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS);
rt2x00_eeprom_read(rt2x00dev,
EEPROM_EIRP_MAX_TX_POWER, &eeprom);
if (band == IEEE80211_BAND_2GHZ)
eirp_txpower_criterion = rt2x00_get_field16(eeprom,
EEPROM_EIRP_MAX_TX_POWER_2GHZ);
else
eirp_txpower_criterion = rt2x00_get_field16(eeprom,
EEPROM_EIRP_MAX_TX_POWER_5GHZ);
eirp_txpower = eirp_txpower_criterion + (txpower - criterion) +
(is_rate_b ? 4 : 0) + delta;
reg_limit = (eirp_txpower > power_level) ?
(eirp_txpower - power_level) : 0;
} else
reg_limit = 0;
return txpower + delta - reg_limit;
static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
enum ieee80211_band band,
int power_level)
int delta;
/*
* Calculate HT40 compensation delta
*/
delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
/*
* calculate temperature compensation delta
*/
delta += rt2800_get_gain_calibration_delta(rt2x00dev);
* set to normal bbp tx power control mode: +/- 0dBm
rt2800_bbp_read(rt2x00dev, 1, &r1);
rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0);
rt2800_bbp_write(rt2x00dev, 1, r1);
offset = TX_PWR_CFG_0;
for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
/* just to be safe */
if (offset > TX_PWR_CFG_4)
break;
rt2800_register_read(rt2x00dev, offset, ®);
/* read the next four txpower values */
rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
&eeprom);
is_rate_b = i ? 0 : 1;
/*
* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
* TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower);
/*
* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
* TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE1);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower);
/*
* TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS,
* TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE2);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower);
/*
* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
* TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE3);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower);
/* read the next four txpower values */
rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
&eeprom);
is_rate_b = 0;
/*
* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0,
* TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE0);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower);
/*
* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1,
* TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE1);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower);
/*
* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2,
* TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE2);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower);
/*
* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3,
* TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown,
* TX_PWR_CFG_4: unknown
*/
txpower = rt2x00_get_field16(eeprom,
EEPROM_TXPOWER_BYRATE_RATE3);
txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
power_level, txpower, delta);
rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower);
rt2800_register_write(rt2x00dev, offset, reg);
/* next TX_PWR_CFG register */
offset += 4;
}
void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
{
rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band,
rt2x00dev->tx_power);
}
EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
u32 reg;
rt2800_register_read(rt2x00dev, TX_RTY_CFG, ®);
rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT,
libconf->conf->short_frame_max_tx_count);
rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT,
libconf->conf->long_frame_max_tx_count);
rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
}
static void rt2800_config_ps(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf)
{
enum dev_state state =
(libconf->conf->flags & IEEE80211_CONF_PS) ?
STATE_SLEEP : STATE_AWAKE;
u32 reg;
if (state == STATE_SLEEP) {
rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
libconf->conf->listen_interval - 1);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 1);
rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
} else {
rt2800_register_read(rt2x00dev, AUTOWAKEUP_CFG, ®);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
rt2x00_set_field32(®, AUTOWAKEUP_CFG_AUTOWAKE, 0);
rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
}
}
void rt2800_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
{
/* Always recalculate LNA gain before changing configuration */
rt2800_config_lna_gain(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
rt2800_config_channel(rt2x00dev, libconf->conf,
&libconf->rf, &libconf->channel);
rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_POWER)
rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
libconf->conf->power_level);
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
rt2800_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_PS)
rt2800_config_ps(rt2x00dev, libconf);
}
EXPORT_SYMBOL_GPL(rt2800_config);
/*
* Link tuning
*/
void rt2800_link_stats(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
{
u32 reg;
/*
* Update FCS error count from register.
*/
rt2800_register_read(rt2x00dev, RX_STA_CNT0, ®);
qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
}
EXPORT_SYMBOL_GPL(rt2800_link_stats);
static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
{
if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
rt2x00_rt(rt2x00dev, RT5390))
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
return 0x1c + (2 * rt2x00dev->lna_gain);
else
return 0x2e + rt2x00dev->lna_gain;
}
if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
else
return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
}
static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
struct link_qual *qual, u8 vgc_level)
{
if (qual->vgc_level != vgc_level) {
rt2800_bbp_write(rt2x00dev, 66, vgc_level);
qual->vgc_level = vgc_level;
qual->vgc_level_reg = vgc_level;
}
}
void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual)
{
rt2800_set_vgc(rt2x00dev, qual, rt2800_get_default_vgc(rt2x00dev));
}
EXPORT_SYMBOL_GPL(rt2800_reset_tuner);
void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
const u32 count)
{
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C))
return;
/*
* When RSSI is better then -80 increase VGC level with 0x10
*/
rt2800_set_vgc(rt2x00dev, qual,
rt2800_get_default_vgc(rt2x00dev) +
((qual->rssi > -80) * 0x10));
}
EXPORT_SYMBOL_GPL(rt2800_link_tuner);
/*
* Initialization functions.
*/
static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
u16 eeprom;
Gertjan van Wingerde
committed
int ret;
rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®);
rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
Gertjan van Wingerde
committed
ret = rt2800_drv_init_registers(rt2x00dev);
if (ret)
return ret;
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®);
rt2x00_set_field32(®, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
rt2x00_set_field32(®, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
rt2x00_set_field32(®, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
rt2x00_set_field32(®, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
rt2800_register_read(rt2x00dev, BCN_OFFSET1, ®);
rt2x00_set_field32(®, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
rt2x00_set_field32(®, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
rt2x00_set_field32(®, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
rt2x00_set_field32(®, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, 1600);
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0);
rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, 0);
rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0);
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
rt2x00_set_field32(®, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
rt2800_config_filter(rt2x00dev, FIF_ALLMULTI);
rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®);
rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, 9);
rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
if (rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x0000002c);
else
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x0000000f);
} else {
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
}
} else if (rt2x00_rt(rt2x00dev, RT3070)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000002c);
} else {
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
}
} else if (rt2800_is_305x_soc(rt2x00dev)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
} else {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
}
rt2800_register_read(rt2x00dev, TX_LINK_CFG, ®);
rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
rt2x00_set_field32(®, TX_LINK_CFG_MFB_ENABLE, 0);
rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
rt2x00_set_field32(®, TX_LINK_CFG_TX_MRQ_EN, 0);
rt2x00_set_field32(®, TX_LINK_CFG_TX_RDG_EN, 0);
rt2x00_set_field32(®, TX_LINK_CFG_TX_CF_ACK_EN, 1);
rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB, 0);
rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFS, 0);
rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, ®);
rt2x00_set_field32(®, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
rt2x00_set_field32(®, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 32);
rt2x00_set_field32(®, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®);
rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
Gertjan van Wingerde
committed
rt2x00_rt(rt2x00dev, RT2883) ||
rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2);
else
rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1);
rt2x00_set_field32(®, MAX_LEN_CFG_MIN_PSDU, 0);
rt2x00_set_field32(®, MAX_LEN_CFG_MIN_MPDU, 0);
rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
rt2800_register_read(rt2x00dev, LED_CFG, ®);
rt2x00_set_field32(®, LED_CFG_ON_PERIOD, 70);
rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, 30);
rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3);
rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3);
rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 3);
rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3);
rt2x00_set_field32(®, LED_CFG_LED_POLAR, 1);
rt2800_register_write(rt2x00dev, LED_CFG, reg);
rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
rt2800_register_read(rt2x00dev, TX_RTY_CFG, ®);
rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_THRE, 2000);
rt2x00_set_field32(®, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
rt2x00_set_field32(®, TX_RTY_CFG_AGG_RTY_MODE, 0);
rt2x00_set_field32(®, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®);
rt2x00_set_field32(®, AUTO_RSP_CFG_AUTORESPONDER, 1);
rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, 1);
rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MMODE, 0);
rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MREF, 0);
rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, 1);
rt2x00_set_field32(®, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
rt2x00_set_field32(®, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®);
rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3);
rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
rt2x00_set_field32(®, CCK_PROT_CFG_RTS_TH_EN, 1);
rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®);
rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3);
rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
rt2x00_set_field32(®, OFDM_PROT_CFG_RTS_TH_EN, 1);
rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®);
rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
rt2x00_set_field32(®, MM20_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®);
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
rt2x00_set_field32(®, MM40_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®);
rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
rt2x00_set_field32(®, GF20_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®);
rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0);
rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
rt2x00_set_field32(®, GF40_PROT_CFG_RTS_TH_EN, 0);
rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
if (rt2x00_is_usb(rt2x00dev)) {
rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®);
rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
rt2x00_set_field32(®, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
}
/*
* The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
* although it is reserved.
*/
rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, ®);
rt2x00_set_field32(®, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
rt2x00_set_field32(®, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0);
rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®);
rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES,
IEEE80211_MAX_RTS_THRESHOLD);
rt2x00_set_field32(®, TX_RTS_CFG_RTS_FBK_EN, 0);
rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
/*
* Usually the CCK SIFS time should be set to 10 and the OFDM SIFS
* time should be set to 16. However, the original Ralink driver uses
* 16 for both and indeed using a value of 10 for CCK SIFS results in
* connection problems with 11g + CTS protection. Hence, use the same
* defaults as the Ralink driver: 16 for both, CCK and OFDM SIFS.
*/
rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®);
rt2x00_set_field32(®, XIFS_TIME_CFG_CCKM_SIFS_TIME, 16);
rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_SIFS_TIME, 16);
rt2x00_set_field32(®, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, 314);
rt2x00_set_field32(®, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
/*
* ASIC will keep garbage value after boot, clear encryption keys.
*/
for (i = 0; i < 4; i++)
rt2800_register_write(rt2x00dev,
SHARED_KEY_MODE_ENTRY(i), 0);
for (i = 0; i < 256; i++) {
static const u32 wcid[2] = { 0xffffffff, 0x00ffffff };
rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
wcid, sizeof(wcid));
rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0);
rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
}
/*
* Clear all beacons
*/
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE0);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE1);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE2);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE3);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE4);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE5);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE6);
rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE7);
if (rt2x00_is_usb(rt2x00dev)) {
rt2800_register_read(rt2x00dev, US_CYC_CNT, ®);
rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30);
rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
} else if (rt2x00_is_pcie(rt2x00dev)) {
rt2800_register_read(rt2x00dev, US_CYC_CNT, ®);
rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125);
rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
}
rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS0FBK, 0);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS1FBK, 0);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS2FBK, 1);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS3FBK, 2);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS4FBK, 3);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS5FBK, 4);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS6FBK, 5);
rt2x00_set_field32(®, HT_FBK_CFG0_HTMCS7FBK, 6);
rt2800_register_write(rt2x00dev, HT_FBK_CFG0, reg);
rt2800_register_read(rt2x00dev, HT_FBK_CFG1, ®);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS8FBK, 8);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS9FBK, 8);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS10FBK, 9);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS11FBK, 10);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS12FBK, 11);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS13FBK, 12);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS14FBK, 13);
rt2x00_set_field32(®, HT_FBK_CFG1_HTMCS15FBK, 14);
rt2800_register_write(rt2x00dev, HT_FBK_CFG1, reg);
rt2800_register_read(rt2x00dev, LG_FBK_CFG0, ®);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS0FBK, 8);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS1FBK, 8);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS2FBK, 9);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS3FBK, 10);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS4FBK, 11);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS5FBK, 12);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS6FBK, 13);
rt2x00_set_field32(®, LG_FBK_CFG0_OFDMMCS7FBK, 14);
rt2800_register_write(rt2x00dev, LG_FBK_CFG0, reg);
rt2800_register_read(rt2x00dev, LG_FBK_CFG1, ®);
rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS0FBK, 0);
rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS1FBK, 0);
rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS2FBK, 1);
rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS3FBK, 2);
rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
/*
* Do not force the BA window size, we use the TXWI to set it
*/
rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, ®);
rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0);
rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0);
rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg);
/*
* We must clear the error counters.
* These registers are cleared on read,
* so we may pass a useless variable to store the value.
*/
rt2800_register_read(rt2x00dev, RX_STA_CNT0, ®);
rt2800_register_read(rt2x00dev, RX_STA_CNT1, ®);
rt2800_register_read(rt2x00dev, RX_STA_CNT2, ®);
rt2800_register_read(rt2x00dev, TX_STA_CNT0, ®);
rt2800_register_read(rt2x00dev, TX_STA_CNT1, ®);
rt2800_register_read(rt2x00dev, TX_STA_CNT2, ®);
/*
* Setup leadtime for pre tbtt interrupt to 6ms
*/
rt2800_register_read(rt2x00dev, INT_TIMER_CFG, ®);
rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
/*
* Set up channel statistics timer
*/
rt2800_register_read(rt2x00dev, CH_TIME_CFG, ®);
rt2x00_set_field32(®, CH_TIME_CFG_EIFS_BUSY, 1);
rt2x00_set_field32(®, CH_TIME_CFG_NAV_BUSY, 1);
rt2x00_set_field32(®, CH_TIME_CFG_RX_BUSY, 1);
rt2x00_set_field32(®, CH_TIME_CFG_TX_BUSY, 1);
rt2x00_set_field32(®, CH_TIME_CFG_TMR_EN, 1);
rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg);
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
return 0;
}
static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u32 reg;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, ®);
if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
return -EACCES;
}
static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u8 value;
/*
* BBP was enabled after firmware was loaded,
* but we need to reactivate it now.
*/
rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
msleep(1);
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2800_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
}
static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u16 eeprom;
u8 reg_id;
u8 value;
if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
rt2800_wait_bbp_ready(rt2x00dev)))
return -EACCES;
if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_read(rt2x00dev, 4, &value);
rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1);
rt2800_bbp_write(rt2x00dev, 4, value);
}
if (rt2800_is_305x_soc(rt2x00dev) ||
rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 31, 0x08);
rt2800_bbp_write(rt2x00dev, 65, 0x2c);
rt2800_bbp_write(rt2x00dev, 66, 0x38);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
rt2800_bbp_write(rt2x00dev, 69, 0x16);
rt2800_bbp_write(rt2x00dev, 73, 0x12);
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_write(rt2x00dev, 69, 0x12);
rt2800_bbp_write(rt2x00dev, 73, 0x13);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
rt2800_bbp_write(rt2x00dev, 76, 0x28);
rt2800_bbp_write(rt2x00dev, 77, 0x59);
} else {
rt2800_bbp_write(rt2x00dev, 69, 0x12);
rt2800_bbp_write(rt2x00dev, 73, 0x10);
}
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
if (rt2x00_rt(rt2x00dev, RT3070) ||
rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_write(rt2x00dev, 79, 0x13);
rt2800_bbp_write(rt2x00dev, 80, 0x05);
rt2800_bbp_write(rt2x00dev, 81, 0x33);
} else if (rt2800_is_305x_soc(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
rt2800_bbp_write(rt2x00dev, 80, 0x08);
} else {
rt2800_bbp_write(rt2x00dev, 81, 0x37);
}
rt2800_bbp_write(rt2x00dev, 82, 0x62);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 83, 0x7a);
else
rt2800_bbp_write(rt2x00dev, 83, 0x6a);
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
rt2800_bbp_write(rt2x00dev, 84, 0x19);
else if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 84, 0x9a);
else
rt2800_bbp_write(rt2x00dev, 84, 0x99);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 86, 0x38);
else
rt2800_bbp_write(rt2x00dev, 86, 0x00);
rt2800_bbp_write(rt2x00dev, 91, 0x04);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 92, 0x02);
else
rt2800_bbp_write(rt2x00dev, 92, 0x00);
if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2800_is_305x_soc(rt2x00dev))
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
else
rt2800_bbp_write(rt2x00dev, 103, 0x00);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 104, 0x92);
if (rt2800_is_305x_soc(rt2x00dev))
rt2800_bbp_write(rt2x00dev, 105, 0x01);
else if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 105, 0x3c);
else
rt2800_bbp_write(rt2x00dev, 105, 0x05);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 106, 0x03);
else
rt2800_bbp_write(rt2x00dev, 106, 0x35);
if (rt2x00_rt(rt2x00dev, RT5390))
rt2800_bbp_write(rt2x00dev, 128, 0x12);
if (rt2x00_rt(rt2x00dev, RT3071) ||
rt2x00_rt(rt2x00dev, RT3090) ||
rt2x00_rt(rt2x00dev, RT3390) ||
rt2x00_rt(rt2x00dev, RT5390)) {
rt2800_bbp_read(rt2x00dev, 138, &value);
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
value |= 0x20;
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
value &= ~0x02;
rt2800_bbp_write(rt2x00dev, 138, value);
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
if (rt2x00_rt(rt2x00dev, RT5390)) {
int ant, div_mode;
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
div_mode = rt2x00_get_field16(eeprom,
EEPROM_NIC_CONF1_ANT_DIVERSITY);
ant = (div_mode == 3) ? 1 : 0;
/* check if this is a Bluetooth combo card */
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
u32 reg;
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0);
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0);
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0);
if (ant == 0)
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1);
else if (ant == 1)
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1);
rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
}
rt2800_bbp_read(rt2x00dev, 152, &value);
if (ant == 0)
rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
else
rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
rt2800_bbp_write(rt2x00dev, 152, value);
/* Init frequency calibration */
rt2800_bbp_write(rt2x00dev, 142, 1);
rt2800_bbp_write(rt2x00dev, 143, 57);
}
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
if (eeprom != 0xffff && eeprom != 0x0000) {
reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
rt2800_bbp_write(rt2x00dev, reg_id, value);
}
}
return 0;
}
static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
bool bw40, u8 rfcsr24, u8 filter_target)
{
unsigned int i;
u8 bbp;
u8 rfcsr;
u8 passband;
u8 stopband;
u8 overtuned = 0;
rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
rt2800_bbp_read(rt2x00dev, 4, &bbp);
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
rt2800_bbp_write(rt2x00dev, 4, bbp);
rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR31_RX_H20M, bw40);
rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
/*
* Set power & frequency of passband test tone
*/
rt2800_bbp_write(rt2x00dev, 24, 0);
for (i = 0; i < 100; i++) {
rt2800_bbp_write(rt2x00dev, 25, 0x90);
msleep(1);
rt2800_bbp_read(rt2x00dev, 55, &passband);
if (passband)
break;
}
/*
* Set power & frequency of stopband test tone