📄 rt61pci.c
字号:
if (rt2x00dev->curr_hwmode == HWMODE_A) rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); else rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); break; case ANTENNA_B: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); if (rt2x00dev->curr_hwmode == HWMODE_A) rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); else rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); break; } rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_bbp_write(rt2x00dev, 3, r3); rt61pci_bbp_write(rt2x00dev, 4, r4);}static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, const int antenna_tx, const int antenna_rx){ u8 r3; u8 r4; u8 r77; rt61pci_bbp_read(rt2x00dev, 3, &r3); rt61pci_bbp_read(rt2x00dev, 4, &r4); rt61pci_bbp_read(rt2x00dev, 77, &r77); rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, !rt2x00_rf(&rt2x00dev->chip, RF2527)); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); switch (antenna_rx) { case ANTENNA_SW_DIVERSITY: case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); break; case ANTENNA_A: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); break; case ANTENNA_B: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); break; } rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_bbp_write(rt2x00dev, 3, r3); rt61pci_bbp_write(rt2x00dev, 4, r4);}static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, const int p1, const int p2){ u32 reg; rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); if (p1 != 0xff) { rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1); rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); } if (p2 != 0xff) { rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); }}static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, const int antenna_tx, const int antenna_rx){ u16 eeprom; u8 r3; u8 r4; u8 r77; rt61pci_bbp_read(rt2x00dev, 3, &r3); rt61pci_bbp_read(rt2x00dev, 4, &r4); rt61pci_bbp_read(rt2x00dev, 77, &r77); rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1); rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) { if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) { rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); rt61pci_bbp_write(rt2x00dev, 77, r77); } rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { case 0: rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); break; case 1: rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); break; case 2: rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); break; case 3: rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); break; } } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { case 0: rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); break; case 1: rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); break; case 2: rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); break; case 3: rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); break; } } rt61pci_bbp_write(rt2x00dev, 3, r3); rt61pci_bbp_write(rt2x00dev, 4, r4);}struct antenna_sel { u8 word; /* * value[0] -> non-LNA * value[1] -> LNA */ u8 value[2];};static const struct antenna_sel antenna_sel_a[] = { { 96, { 0x58, 0x78 } }, { 104, { 0x38, 0x48 } }, { 75, { 0xfe, 0x80 } }, { 86, { 0xfe, 0x80 } }, { 88, { 0xfe, 0x80 } }, { 35, { 0x60, 0x60 } }, { 97, { 0x58, 0x58 } }, { 98, { 0x58, 0x58 } },};static const struct antenna_sel antenna_sel_bg[] = { { 96, { 0x48, 0x68 } }, { 104, { 0x2c, 0x3c } }, { 75, { 0xfe, 0x80 } }, { 86, { 0xfe, 0x80 } }, { 88, { 0xfe, 0x80 } }, { 35, { 0x50, 0x50 } }, { 97, { 0x48, 0x48 } }, { 98, { 0x48, 0x48 } },};static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, const int antenna_tx, const int antenna_rx){ const struct antenna_sel *sel; unsigned int lna; unsigned int i; u32 reg; rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); if (rt2x00dev->curr_hwmode == HWMODE_A) { sel = antenna_sel_a; lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); } else { sel = antenna_sel_bg; lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); if (rt2x00_rf(&rt2x00dev->chip, RF5225) || rt2x00_rf(&rt2x00dev->chip, RF5325)) rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) { if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); else rt61pci_config_antenna_2529(rt2x00dev, antenna_tx, antenna_rx); }}static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf){ u32 reg; rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, libconf->slot_time); rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); rt2x00_set_field32(®, MAC_CSR8_SIFS, libconf->sifs); rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); rt2x00_set_field32(®, MAC_CSR8_EIFS, libconf->eifs); rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, libconf->conf->beacon_int * 16); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);}static void rt61pci_config(struct rt2x00_dev *rt2x00dev, const unsigned int flags, struct rt2x00lib_conf *libconf){ if (flags & CONFIG_UPDATE_PHYMODE) rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); if (flags & CONFIG_UPDATE_CHANNEL) rt61pci_config_channel(rt2x00dev, &libconf->rf, libconf->conf->power_level); if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) rt61pci_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx, libconf->conf->antenna_sel_rx); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt61pci_config_duration(rt2x00dev, libconf);}/* * LED functions. */static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev){ u32 reg; u16 led_reg; u8 arg0; u8 arg1; rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); led_reg = rt2x00dev->led_reg; rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1); if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1); else rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1); arg0 = led_reg & 0xff; arg1 = (led_reg >> 8) & 0xff; rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);}static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev){ u16 led_reg; u8 arg0; u8 arg1; led_reg = rt2x00dev->led_reg; rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); arg0 = led_reg & 0xff; arg1 = (led_reg >> 8) & 0xff; rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);}static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi){ u8 led; if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) return; /* * Led handling requires a positive value for the rssi, * to do that correctly we need to add the correction. */ rssi += rt2x00dev->rssi_offset; if (rssi <= 30) led = 0; else if (rssi <= 39) led = 1; else if (rssi <= 49) led = 2; else if (rssi <= 53) led = 3; else if (rssi <= 63) led = 4; else led = 5; rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0);}/* * Link tuning */static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev){ u32 reg; /* * Update FCS error count from register. */ rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); /* * Update False CCA count from register. */ rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); rt2x00dev->link.false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);}static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev){ rt61pci_bbp_write(rt2x00dev, 17, 0x20); rt2x00dev->link.vgc_level = 0x20;}static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev){ int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); u8 r17; u8 up_bound; u8 low_bound; /* * Update Led strength */ rt61pci_activity_led(rt2x00dev, rssi); rt61pci_bbp_read(rt2x00dev, 17, &r17); /* * Determine r17 bounds. */ if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { low_bound = 0x28; up_bound = 0x48; if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { low_bound += 0x10; up_bound += 0x10; } } else { low_bound = 0x20; up_bound = 0x40; if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { low_bound += 0x10; up_bound += 0x10; } } /* * Special big-R17 for very short distance */ if (rssi >= -35) { if (r17 != 0x60) rt61pci_bbp_write(rt2x00dev, 17, 0x60); return; } /* * Special big-R17 for short distance */ if (rssi >= -58) { if (r17 != up_bound) rt61pci_bbp_write(rt2x00dev, 17, up_bound); return; } /* * Special big-R17 for middle-short distance */ if (rssi >= -66) { low_bound += 0x10;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -