⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt61pci.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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, &reg);		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, &reg_mcu);	rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu);	rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);	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, &reg);	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, &reg);	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 + -