📄 rt61pci.c
字号:
int retry; /* * During each loop we will compare the freshly read * STA_CSR4 register value with the value read from * the previous loop. If the 2 values are equal then * we should stop processing because the chance it * quite big that the device has been unplugged and * we risk going into an endless loop. */ old_reg = 0; while (1) { rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) break; if (old_reg == reg) break; old_reg = reg; /* * Skip this entry when it contains an invalid * ring identication number. */ type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); ring = rt2x00lib_get_ring(rt2x00dev, type); if (unlikely(!ring)) continue; /* * Skip this entry when it contains an invalid * index number. */ index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); if (unlikely(index >= ring->stats.limit)) continue; entry = &ring->entry[index]; txd = entry->priv; rt2x00_desc_read(txd, 0, &word); if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || !rt2x00_get_field32(word, TXD_W0_VALID)) return; entry_done = rt2x00_get_data_entry_done(ring); while (entry != entry_done) { /* Catch up. Just report any entries we missed as * failed. */ WARNING(rt2x00dev, "TX status report missed for entry %p\n", entry_done); rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0); entry_done = rt2x00_get_data_entry_done(ring); } /* * Obtain the status about this packet. */ tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); rt2x00lib_txdone(entry, tx_status, retry); /* * Make this entry available for reuse. */ entry->flags = 0; rt2x00_set_field32(&word, TXD_W0_VALID, 0); rt2x00_desc_write(txd, 0, word); rt2x00_ring_index_done_inc(entry->ring); /* * If the data ring was full before the txdone handler * we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ if (!rt2x00_ring_full(ring)) ieee80211_wake_queue(rt2x00dev->hw, entry->tx_status.control.queue); }}static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance){ struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg_mcu; u32 reg; /* * Get the interrupt sources & saved to local variable. * Write register value back to clear pending interrupts. */ rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); if (!reg && !reg_mcu) return IRQ_NONE; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; /* * Handle interrupts, walk through all bits * and run the tasks, the bits are checked in order of * priority. */ /* * 1 - Rx ring done interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE)) rt2x00pci_rxdone(rt2x00dev); /* * 2 - Tx ring done interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE)) rt61pci_txdone(rt2x00dev); /* * 3 - Handle MCU command done. */ if (reg_mcu) rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); return IRQ_HANDLED;}/* * Device probe functions. */static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev){ struct eeprom_93cx6 eeprom; u32 reg; u16 word; u8 *mac; s8 value; rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); eeprom.data = rt2x00dev; eeprom.register_read = rt61pci_eepromregister_read; eeprom.register_write = rt61pci_eepromregister_write; eeprom.width = rt2x00_get_field32(reg, E2PROM_CSR_TYPE_93C46) ? PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; eeprom.reg_data_in = 0; eeprom.reg_data_out = 0; eeprom.reg_data_clock = 0; eeprom.reg_chip_select = 0; eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, EEPROM_SIZE / sizeof(u16)); /* * Start validation of the data that has been read. */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { DECLARE_MAC_BUF(macbuf); random_ether_addr(mac); EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0); rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0); rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0); rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, LED_MODE_DEFAULT); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); EEPROM(rt2x00dev, "Led: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); if (value < -10 || value > 10) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_2); if (value < -10 || value > 10) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); } rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); } else { value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); if (value < -10 || value > 10) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_2); if (value < -10 || value > 10) rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); } return 0;}static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev){ u32 reg; u16 value; u16 eeprom; u16 device; /* * Read EEPROM word for configuration. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); /* * Identify RF chipset. * To determine the RT chip we have to read the * PCI header of the device. */ pci_read_config_word(rt2x00dev_pci(rt2x00dev), PCI_CONFIG_HEADER_DEVICE, &device); value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); rt2x00_set_chip(rt2x00dev, device, value, reg); if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && !rt2x00_rf(&rt2x00dev->chip, RF5325) && !rt2x00_rf(&rt2x00dev->chip, RF2527) && !rt2x00_rf(&rt2x00dev->chip, RF2529)) { ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } /* * Identify default antenna configuration. */ rt2x00dev->hw->conf.antenna_sel_tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); rt2x00dev->hw->conf.antenna_sel_rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* * Read the Frame type. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); /* * Determine number of antenna's. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); /* * Detect if this device has an hardware controlled radio. */#ifdef CONFIG_RT61PCI_RFKILL if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);#endif /* CONFIG_RT61PCI_RFKILL */ /* * Read frequency offset and RF programming sequence. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags); rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); /* * Read external LNA informations. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); /* * Store led settings, for correct led behaviour. * If the eeprom value is invalid, * switch to default led mode. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, rt2x00dev->led_mode); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_0)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_1)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_2)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_3)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_4)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_RDY_G)); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_RDY_A)); return 0;}/* * RF value list for RF5225 & RF5325 * Supports: 2.4 GHz & 5.2 GHz, rf_sequence disabled */static const struct rf_channel rf_vals_noseq[] = { { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, /* 802.11 UNI / HyperLan 2 */ { 36, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa23 }, { 40, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa03 }, { 44, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa0b }, { 48, 0x00002ccc, 0x000049aa, 0x0009be55, 0x000ffa13 }, { 52, 0x00002ccc, 0x000049ae, 0x0009ae55, 0x000ffa1b }, { 56, 0x00002ccc, 0x000049b2, 0x0009ae55, 0x000ffa23 }, { 60, 0x00002ccc, 0x000049ba, 0x0009ae55, 0x000ffa03 }, { 64, 0x00002ccc, 0x000049be, 0x0009ae55, 0x000ffa0b }, /* 802.11 HyperLan 2 */ { 100, 0x00002ccc, 0x00004a2a, 0x000bae55, 0x000ffa03 }, { 104, 0x00002ccc, 0x00004a2e, 0x000bae55, 0x000ffa0b }, { 108, 0x00002ccc, 0x00004a32, 0x000bae55, 0x000ffa13 }, { 112, 0x00002ccc, 0x00004a36, 0x000bae55, 0x000ffa1b }, { 116, 0x00002ccc, 0x00004a3a, 0x000bbe55, 0x000ffa23 }, { 120, 0x00002ccc, 0x00004a82, 0x000bbe55, 0x000ffa03 }, { 124, 0x00002ccc, 0x00004a86, 0x000bbe55, 0x000ffa0b }, { 128, 0x00002ccc, 0x00004a8a, 0x000bbe55, 0x000ffa13 }, { 132, 0x00002ccc, 0x00004a8e, 0x000bbe55, 0x000ffa1b }, { 136, 0x00002ccc, 0x00004a92, 0x000bbe55, 0x000ffa23 }, /* 802.11 UNII */ { 140, 0x00002ccc, 0x00004a9a, 0x000bbe55, 0x000ffa03 }, { 149, 0x00002ccc, 0x00004aa2, 0x000bbe55, 0x000ffa1f }, { 153, 0x00002ccc, 0x00004aa6, 0x000bbe55, 0x000ffa27 }, { 157, 0x00002ccc, 0x00004aae, 0x000bbe55, 0x000ffa07 }, { 161, 0x00002ccc, 0x00004ab2, 0x000bbe55, 0x000ffa0f }, { 165, 0x00002ccc, 0x00004ab6, 0x000bbe55, 0x000ffa17 }, /* MMAC(Japan)J52 ch 34,38,42,46 */ { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa0b }, { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000ffa13 }, { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa1b }, { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa23 },};/* * RF value list for RF5225 & RF5325 * Supports: 2.4 GHz & 5.2 GHz, rf_sequence enabled */static const struct rf_channel rf_vals_seq[] = { { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, { 10,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -