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

📄 rt61pci.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg);	return 0;}static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev){	unsigned int i;	u16 eeprom;	u8 reg_id;	u8 value;	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {		rt61pci_bbp_read(rt2x00dev, 0, &value);		if ((value != 0xff) && (value != 0x00))			goto continue_csr_init;		NOTICE(rt2x00dev, "Waiting for BBP register.\n");		udelay(REGISTER_BUSY_DELAY);	}	ERROR(rt2x00dev, "BBP register access failed, aborting.\n");	return -EACCES;continue_csr_init:	rt61pci_bbp_write(rt2x00dev, 3, 0x00);	rt61pci_bbp_write(rt2x00dev, 15, 0x30);	rt61pci_bbp_write(rt2x00dev, 21, 0xc8);	rt61pci_bbp_write(rt2x00dev, 22, 0x38);	rt61pci_bbp_write(rt2x00dev, 23, 0x06);	rt61pci_bbp_write(rt2x00dev, 24, 0xfe);	rt61pci_bbp_write(rt2x00dev, 25, 0x0a);	rt61pci_bbp_write(rt2x00dev, 26, 0x0d);	rt61pci_bbp_write(rt2x00dev, 34, 0x12);	rt61pci_bbp_write(rt2x00dev, 37, 0x07);	rt61pci_bbp_write(rt2x00dev, 39, 0xf8);	rt61pci_bbp_write(rt2x00dev, 41, 0x60);	rt61pci_bbp_write(rt2x00dev, 53, 0x10);	rt61pci_bbp_write(rt2x00dev, 54, 0x18);	rt61pci_bbp_write(rt2x00dev, 60, 0x10);	rt61pci_bbp_write(rt2x00dev, 61, 0x04);	rt61pci_bbp_write(rt2x00dev, 62, 0x04);	rt61pci_bbp_write(rt2x00dev, 75, 0xfe);	rt61pci_bbp_write(rt2x00dev, 86, 0xfe);	rt61pci_bbp_write(rt2x00dev, 88, 0xfe);	rt61pci_bbp_write(rt2x00dev, 90, 0x0f);	rt61pci_bbp_write(rt2x00dev, 99, 0x00);	rt61pci_bbp_write(rt2x00dev, 102, 0x16);	rt61pci_bbp_write(rt2x00dev, 107, 0x04);	DEBUG(rt2x00dev, "Start initialization from EEPROM...\n");	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);			DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n",			      reg_id, value);			rt61pci_bbp_write(rt2x00dev, reg_id, value);		}	}	DEBUG(rt2x00dev, "...End initialization from EEPROM.\n");	return 0;}/* * Device state switch handlers. */static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,			      enum dev_state state){	u32 reg;	rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);	rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,			   state == STATE_RADIO_RX_OFF);	rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);}static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,			       enum dev_state state){	int mask = (state == STATE_RADIO_IRQ_OFF);	u32 reg;	/*	 * When interrupts are being enabled, the interrupt registers	 * should clear the register to assure a clean state.	 */	if (state == STATE_RADIO_IRQ_ON) {		rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);		rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);		rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, &reg);		rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg);	}	/*	 * Only toggle the interrupts bits we are going to use.	 * Non-checked interrupt bits are disabled by default.	 */	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);	rt2x00_set_field32(&reg, INT_MASK_CSR_TXDONE, mask);	rt2x00_set_field32(&reg, INT_MASK_CSR_RXDONE, mask);	rt2x00_set_field32(&reg, INT_MASK_CSR_ENABLE_MITIGATION, mask);	rt2x00_set_field32(&reg, INT_MASK_CSR_MITIGATION_PERIOD, 0xff);	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);	rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, &reg);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_0, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_1, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_2, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_3, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_4, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_5, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_6, mask);	rt2x00_set_field32(&reg, MCU_INT_MASK_CSR_7, mask);	rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg);}static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev){	u32 reg;	/*	 * Initialize all registers.	 */	if (rt61pci_init_rings(rt2x00dev) ||	    rt61pci_init_registers(rt2x00dev) ||	    rt61pci_init_bbp(rt2x00dev)) {		ERROR(rt2x00dev, "Register initialization failed.\n");		return -EIO;	}	/*	 * Enable interrupts.	 */	rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);	/*	 * Enable RX.	 */	rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, &reg);	rt2x00_set_field32(&reg, RX_CNTL_CSR_ENABLE_RX_DMA, 1);	rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg);	/*	 * Enable LED	 */	rt61pci_enable_led(rt2x00dev);	return 0;}static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev){	u32 reg;	/*	 * Disable LED	 */	rt61pci_disable_led(rt2x00dev);	rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);	/*	 * Disable synchronisation.	 */	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);	/*	 * Cancel RX and TX.	 */	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);	rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_MGMT, 1);	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);	/*	 * Disable interrupts.	 */	rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);}static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state){	u32 reg;	unsigned int i;	char put_to_sleep;	char current_state;	put_to_sleep = (state != STATE_AWAKE);	rt2x00pci_register_read(rt2x00dev, MAC_CSR12, &reg);	rt2x00_set_field32(&reg, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep);	rt2x00_set_field32(&reg, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep);	rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg);	/*	 * Device is not guaranteed to be in the requested state yet.	 * We must wait until the register indicates that the	 * device has entered the correct state.	 */	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {		rt2x00pci_register_read(rt2x00dev, MAC_CSR12, &reg);		current_state =		    rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);		if (current_state == !put_to_sleep)			return 0;		msleep(10);	}	NOTICE(rt2x00dev, "Device failed to enter state %d, "	       "current device state %d.\n", !put_to_sleep, current_state);	return -EBUSY;}static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,				    enum dev_state state){	int retval = 0;	switch (state) {	case STATE_RADIO_ON:		retval = rt61pci_enable_radio(rt2x00dev);		break;	case STATE_RADIO_OFF:		rt61pci_disable_radio(rt2x00dev);		break;	case STATE_RADIO_RX_ON:	case STATE_RADIO_RX_OFF:		rt61pci_toggle_rx(rt2x00dev, state);		break;	case STATE_DEEP_SLEEP:	case STATE_SLEEP:	case STATE_STANDBY:	case STATE_AWAKE:		retval = rt61pci_set_state(rt2x00dev, state);		break;	default:		retval = -ENOTSUPP;		break;	}	return retval;}/* * TX descriptor initialization */static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,				  struct data_desc *txd,				  struct txdata_entry_desc *desc,				  struct ieee80211_hdr *ieee80211hdr,				  unsigned int length,				  struct ieee80211_tx_control *control){	u32 word;	/*	 * Start writing the descriptor words.	 */	rt2x00_desc_read(txd, 1, &word);	rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue);	rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs);	rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);	rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);	rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);	rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);	rt2x00_desc_write(txd, 1, word);	rt2x00_desc_read(txd, 2, &word);	rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal);	rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service);	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low);	rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high);	rt2x00_desc_write(txd, 2, word);	rt2x00_desc_read(txd, 5, &word);	rt2x00_set_field32(&word, TXD_W5_TX_POWER,			   TXPOWER_TO_DEV(control->power_level));	rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);	rt2x00_desc_write(txd, 5, word);	rt2x00_desc_read(txd, 11, &word);	rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length);	rt2x00_desc_write(txd, 11, word);	rt2x00_desc_read(txd, 0, &word);	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);	rt2x00_set_field32(&word, TXD_W0_VALID, 1);	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_ACK,			   !(control->flags & IEEE80211_TXCTL_NO_ACK));	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_OFDM,			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,			   !!(control->flags &			      IEEE80211_TXCTL_LONG_RETRY_LIMIT));	rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);	rt2x00_set_field32(&word, TXD_W0_BURST,			   test_bit(ENTRY_TXD_BURST, &desc->flags));	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);	rt2x00_desc_write(txd, 0, word);}/* * TX data initialization */static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,				  unsigned int queue){	u32 reg;	if (queue == IEEE80211_TX_QUEUE_BEACON) {		/*		 * For Wi-Fi faily generated beacons between participating		 * stations. Set TBTT phase adaptive adjustment step to 8us.		 */		rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);		rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);		if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {			rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);			rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);		}		return;	}	rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);	if (queue == IEEE80211_TX_QUEUE_DATA0)		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);	else if (queue == IEEE80211_TX_QUEUE_DATA1)		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);	else if (queue == IEEE80211_TX_QUEUE_DATA2)		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);	else if (queue == IEEE80211_TX_QUEUE_DATA3)		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);	else if (queue == IEEE80211_TX_QUEUE_DATA4)		rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_MGMT, 1);	rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);}/* * RX control handlers */static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1){	u16 eeprom;	u8 offset;	u8 lna;	lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA);	switch (lna) {	case 3:		offset = 90;		break;	case 2:		offset = 74;		break;	case 1:		offset = 64;		break;	default:		return 0;	}	if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) {		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))			offset += 14;		if (lna == 3 || lna == 2)			offset += 10;		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);		offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);	} else {		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))			offset += 14;		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);		offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);	}	return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;}static void rt61pci_fill_rxdone(struct data_entry *entry,			        struct rxdata_entry_desc *desc){	struct data_desc *rxd = entry->priv;	u32 word0;	u32 word1;	rt2x00_desc_read(rxd, 0, &word0);	rt2x00_desc_read(rxd, 1, &word1);	desc->flags = 0;	if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))		desc->flags |= RX_FLAG_FAILED_FCS_CRC;	/*	 * Obtain the status about this packet.	 */	desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);	desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);	desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);	desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);	return;}/* * Interrupt functions. */static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev){	struct data_ring *ring;	struct data_entry *entry;	struct data_entry *entry_done;	struct data_desc *txd;	u32 word;	u32 reg;	u32 old_reg;	int type;	int index;	int tx_status;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -