You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1630 lines
						
					
					
						
							54 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1630 lines
						
					
					
						
							54 KiB
						
					
					
				| Subject: [PATCH] rt2800usb: add support for rt55xx | |
| 
 | |
| --- | |
|  drivers/net/wireless/rt2x00/Kconfig       |    8 + | |
|  drivers/net/wireless/rt2x00/rt2800.h      |  103 +++- | |
|  drivers/net/wireless/rt2x00/rt2800lib.c   |  875 +++++++++++++++++++++++++++-- | |
|  drivers/net/wireless/rt2x00/rt2800pci.c   |    5 +- | |
|  drivers/net/wireless/rt2x00/rt2800usb.c   |   70 ++- | |
|  drivers/net/wireless/rt2x00/rt2x00.h      |   10 +- | |
|  drivers/net/wireless/rt2x00/rt2x00queue.c |    6 +- | |
|  drivers/net/wireless/rt2x00/rt2x00queue.h |    6 +- | |
|  8 files changed, 1019 insertions(+), 64 deletions(-) | |
| 
 | |
| diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig | |
| index 76cd47e..9614048 100644 | |
| --- a/drivers/net/wireless/rt2x00/Kconfig | |
| +++ b/drivers/net/wireless/rt2x00/Kconfig | |
| @@ -173,6 +173,14 @@ config RT2800USB_RT53XX | |
|           rt2800usb driver. | |
|           Supported chips: RT5370 | |
|   | |
| +config RT2800USB_RT55XX | |
| +	bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)" | |
| +	default y | |
| +	---help--- | |
| +	  This adds support for rt55xx wireless chipset family to the | |
| +	  rt2800usb driver. | |
| +	  Supported chips: RT5572 | |
| + | |
|  config RT2800USB_UNKNOWN | |
|  	bool "rt2800usb - Include support for unknown (USB) devices" | |
|  	default n | |
| diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h | |
| index 4db1088..b4a1821 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2800.h | |
| +++ b/drivers/net/wireless/rt2x00/rt2800.h | |
| @@ -51,6 +51,7 @@ | |
|   * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) | |
|   * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) | |
|   * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) | |
| + * RF5592 2.4G/5G 2T2R | |
|   * RF5360 2.4G 1T1R | |
|   * RF5370 2.4G 1T1R | |
|   * RF5390 2.4G 1T1R | |
| @@ -68,6 +69,7 @@ | |
|  #define RF3320				0x000b | |
|  #define RF3322				0x000c | |
|  #define RF3053				0x000d | |
| +#define RF5592				0x000f | |
|  #define RF3290				0x3290 | |
|  #define RF5360				0x5360 | |
|  #define RF5370				0x5370 | |
| @@ -88,6 +90,7 @@ | |
|  #define REV_RT3390E			0x0211 | |
|  #define REV_RT5390F			0x0502 | |
|  #define REV_RT5390R			0x1502 | |
| +#define REV_RT5592C			0x0221 | |
|   | |
|  /* | |
|   * Signal information. | |
| @@ -690,6 +693,12 @@ | |
|  #define GPIO_SWITCH_7			FIELD32(0x00000080) | |
|   | |
|  /* | |
| + * FIXME: where the DEBUG_INDEX name come from? | |
| + */ | |
| +#define MAC_DEBUG_INDEX			0x05e8 | |
| +#define MAC_DEBUG_INDEX_XTAL		FIELD32(0x80000000) | |
| + | |
| +/* | |
|   * MAC Control/Status Registers(CSR). | |
|   * Some values are set in TU, whereas 1 TU == 1024 us. | |
|   */ | |
| @@ -1934,9 +1943,13 @@ struct mac_iveiv_entry { | |
|  #define BBP4_BANDWIDTH			FIELD8(0x18) | |
|  #define BBP4_MAC_IF_CTRL		FIELD8(0x40) | |
|   | |
| +/* BBP27 */ | |
| +#define BBP27_RX_CHAIN_SEL		FIELD8(0x60) | |
| + | |
|  /* | |
|   * BBP 47: Bandwidth | |
|   */ | |
| + | |
|  #define BBP47_TSSI_REPORT_SEL		FIELD8(0x03) | |
|  #define BBP47_TSSI_UPDATE_REQ		FIELD8(0x04) | |
|  #define BBP47_TSSI_TSSI_MODE		FIELD8(0x18) | |
| @@ -1948,6 +1961,22 @@ struct mac_iveiv_entry { | |
|  #define BBP49_UPDATE_FLAG		FIELD8(0x01) | |
|   | |
|  /* | |
| + * BBP 105: | |
| + * - bit0: detect SIG on primary channel only (on 40MHz bandwidth) | |
| + * - bit1: FEQ (Feed Forward Compensation) for independend streams | |
| + * - bit2: MLD (Maximum Likehood Detection) for 2 streams (reserved on single | |
| + *	   stream) | |
| + * - bit4: channel estimation updates based on remodulation of | |
| + *	   L-SIG and HT-SIG symbols | |
| + */ | |
| +#define BBP105_DETECT_SIG_ON_PRIMARY	FIELD8(0x01) | |
| +#define BBP105_FEQ			FIELD8(0x02) | |
| +#define BBP105_MLD			FIELD8(0x04) | |
| +#define BBP105_SIG_REMODULATION		FIELD8(0x08) | |
| + | |
| +/* | |
| + | |
| +/* | |
|   * BBP 109 | |
|   */ | |
|  #define BBP109_TX0_POWER		FIELD8(0x0f) | |
| @@ -1967,6 +1996,11 @@ struct mac_iveiv_entry { | |
|  #define BBP152_RX_DEFAULT_ANT		FIELD8(0x80) | |
|   | |
|  /* | |
| + * BBP 254: unknown | |
| + */ | |
| +#define BBP254_BIT7			FIELD8(0x80) | |
| + | |
| +/* | |
|   * RFCSR registers | |
|   * The wordsize of the RFCSR is 8 bits. | |
|   */ | |
| @@ -2022,9 +2056,18 @@ struct mac_iveiv_entry { | |
|  #define RFCSR7_BITS67			FIELD8(0xc0) | |
|   | |
|  /* | |
| + * RFCSR 9: | |
| + */ | |
| +#define RFCSR9_K			FIELD8(0x0f) | |
| +#define RFCSR9_N			FIELD8(0x10) | |
| +#define RFCSR9_UNKNOWN			FIELD8(0x60) | |
| +#define RFCSR9_MOD			FIELD8(0x80) | |
| + | |
| +/* | |
|   * RFCSR 11: | |
|   */ | |
|  #define RFCSR11_R			FIELD8(0x03) | |
| +#define RFCSR11_MOD			FIELD8(0xc0) | |
|   | |
|  /* | |
|   * RFCSR 12: | |
| @@ -2130,11 +2173,13 @@ struct mac_iveiv_entry { | |
|   * RFCSR 49: | |
|   */ | |
|  #define RFCSR49_TX			FIELD8(0x3f) | |
| +#define RFCSR49_EP			FIELD8(0xc0) | |
|   | |
|  /* | |
|   * RFCSR 50: | |
|   */ | |
|  #define RFCSR50_TX			FIELD8(0x3f) | |
| +#define RFCSR50_EP			FIELD8(0xc0) | |
|   | |
|  /* | |
|   * RF registers | |
| @@ -2497,6 +2542,61 @@ struct mac_iveiv_entry { | |
|  #define EEPROM_BBP_REG_ID		FIELD16(0xff00) | |
|   | |
|  /* | |
| + * EEPROM IQ Calibration, unlike other entries those are byte addresses. | |
| + */ | |
| + | |
| +#define EEPROM_IQ_GAIN_CAL_TX0_2G			0x130 | |
| +#define EEPROM_IQ_PHASE_CAL_TX0_2G			0x131 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_2G			0x132 | |
| +#define EEPROM_IQ_GAIN_CAL_TX1_2G			0x133 | |
| +#define EEPROM_IQ_PHASE_CAL_TX1_2G			0x134 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_2G			0x135 | |
| +#define EEPROM_IQ_GAIN_CAL_RX0_2G			0x136 | |
| +#define EEPROM_IQ_PHASE_CAL_RX0_2G			0x137 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_2G			0x138 | |
| +#define EEPROM_IQ_GAIN_CAL_RX1_2G			0x139 | |
| +#define EEPROM_IQ_PHASE_CAL_RX1_2G			0x13A | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_2G			0x13B | |
| +#define EEPROM_RF_IQ_COMPENSATION_CONTROL		0x13C | |
| +#define EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL	0x13D | |
| +#define EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G		0x144 | |
| +#define EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G		0x145 | |
| +#define EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G	0X146 | |
| +#define EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G	0x147 | |
| +#define EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G	0x148 | |
| +#define EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G	0x149 | |
| +#define EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G		0x14A | |
| +#define EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G		0x14B | |
| +#define EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G	0X14C | |
| +#define EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G	0x14D | |
| +#define EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G	0x14E | |
| +#define EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G	0x14F | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH36_TO_CH64_5G	0x150 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH36_TO_CH64_5G	0x151 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH100_TO_CH138_5G	0x152 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH100_TO_CH138_5G	0x153 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX0_CH140_TO_CH165_5G	0x154 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_TX1_CH140_TO_CH165_5G	0x155 | |
| +#define EEPROM_IQ_GAIN_CAL_RX0_CH36_TO_CH64_5G		0x156 | |
| +#define EEPROM_IQ_PHASE_CAL_RX0_CH36_TO_CH64_5G		0x157 | |
| +#define EEPROM_IQ_GAIN_CAL_RX0_CH100_TO_CH138_5G	0X158 | |
| +#define EEPROM_IQ_PHASE_CAL_RX0_CH100_TO_CH138_5G	0x159 | |
| +#define EEPROM_IQ_GAIN_CAL_RX0_CH140_TO_CH165_5G	0x15A | |
| +#define EEPROM_IQ_PHASE_CAL_RX0_CH140_TO_CH165_5G	0x15B | |
| +#define EEPROM_IQ_GAIN_CAL_RX1_CH36_TO_CH64_5G		0x15C | |
| +#define EEPROM_IQ_PHASE_CAL_RX1_CH36_TO_CH64_5G		0x15D | |
| +#define EEPROM_IQ_GAIN_CAL_RX1_CH100_TO_CH138_5G	0X15E | |
| +#define EEPROM_IQ_PHASE_CAL_RX1_CH100_TO_CH138_5G	0x15F | |
| +#define EEPROM_IQ_GAIN_CAL_RX1_CH140_TO_CH165_5G	0x160 | |
| +#define EEPROM_IQ_PHASE_CAL_RX1_CH140_TO_CH165_5G	0x161 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH36_TO_CH64_5G	0x162 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH36_TO_CH64_5G	0x163 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH100_TO_CH138_5G	0x164 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH100_TO_CH138_5G	0x165 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX0_CH140_TO_CH165_5G	0x166 | |
| +#define EEPROM_IQ_GROUPDELAY_CAL_RX1_CH140_TO_CH165_5G	0x167 | |
| + | |
| +/* | |
|   * MCU mailbox commands. | |
|   * MCU_SLEEP - go to power-save mode. | |
|   *             arg1: 1: save as much power as possible, 0: save less power. | |
| @@ -2534,7 +2634,8 @@ struct mac_iveiv_entry { | |
|   */ | |
|  #define TXWI_DESC_SIZE			(4 * sizeof(__le32)) | |
|  #define RXWI_DESC_SIZE			(4 * sizeof(__le32)) | |
| - | |
| +#define TXWI_DESC_SIZE_5592		(5 * sizeof(__le32)) | |
| +#define RXWI_DESC_SIZE_5592		(6 * sizeof(__le32)) | |
|  /* | |
|   * TX WI structure | |
|   */ | |
| diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c | |
| index 92849e5..45dd96e 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2800lib.c | |
| +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |
| @@ -527,8 +527,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |
|  	 */ | |
|  	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | |
|  	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | |
| -	if (rt2x00_is_usb(rt2x00dev)) | |
| +	if (rt2x00_is_usb(rt2x00dev)) { | |
|  		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); | |
| +		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | |
| +	} | |
|  	msleep(1); | |
|   | |
|  	return 0; | |
| @@ -540,6 +542,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |
|  { | |
|  	__le32 *txwi = rt2800_drv_get_txwi(entry); | |
|  	u32 word; | |
| +	int i; | |
|   | |
|  	/* | |
|  	 * Initialize TX Info descriptor | |
| @@ -583,13 +586,16 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |
|   | |
|  	/* | |
|  	 * Always write 0 to IV/EIV fields, hardware will insert the IV | |
| -	 * from the IVEIV register when TXD_W3_WIV is set to 0. | |
| +	 * Always write 0 to IV/EIV fields (word 2 and 3), hardware will insert | |
| +	 * the IV from the IVEIV register when TXD_W3_WIV is set to 0. | |
|  	 * When TXD_W3_WIV is set to 1 it will use the IV data | |
|  	 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which | |
|  	 * crypto entry in the registers should be used to encrypt the frame. | |
| +	 *  | |
| +	 * Nulify all remaining words as well, we don't know how to program them. | |
|  	 */ | |
| -	_rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); | |
| -	_rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); | |
| +	for (i = 2; i < entry->queue->winfo_size / sizeof(__le32); i++) | |
| +		_rt2x00_desc_write(txwi, i, 0); | |
|  } | |
|  EXPORT_SYMBOL_GPL(rt2800_write_tx_data); | |
|   | |
| @@ -676,9 +682,9 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |
|  	rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); | |
|   | |
|  	/* | |
| -	 * Remove RXWI descriptor from start of buffer. | |
| +	 * Remove RXWI descriptor from start of the buffer. | |
|  	 */ | |
| -	skb_pull(entry->skb, RXWI_DESC_SIZE); | |
| +	skb_pull(entry->skb, entry->queue->winfo_size); | |
|  } | |
|  EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | |
|   | |
| @@ -769,6 +775,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |
|  	unsigned int beacon_base; | |
|  	unsigned int padding_len; | |
|  	u32 orig_reg, reg; | |
| +	const int txwi_desc_size = entry->queue->winfo_size; | |
|   | |
|  	/* | |
|  	 * Disable beaconing while we are reloading the beacon data, | |
| @@ -782,14 +789,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |
|  	/* | |
|  	 * Add space for the TXWI in front of the skb. | |
|  	 */ | |
| -	memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); | |
| +	memset(skb_push(entry->skb, txwi_desc_size), 0, txwi_desc_size); | |
|   | |
|  	/* | |
|  	 * Register descriptor details in skb frame descriptor. | |
|  	 */ | |
|  	skbdesc->flags |= SKBDESC_DESC_IN_SKB; | |
|  	skbdesc->desc = entry->skb->data; | |
| -	skbdesc->desc_len = TXWI_DESC_SIZE; | |
| +	skbdesc->desc_len = txwi_desc_size; | |
|   | |
|  	/* | |
|  	 * Add the TXWI for the beacon to the skb. | |
| @@ -835,13 +842,14 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev, | |
|  						unsigned int beacon_base) | |
|  { | |
|  	int i; | |
| +	const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size; | |
|   | |
|  	/* | |
|  	 * For the Beacon base registers we only need to clear | |
|  	 * the whole TXWI which (when set to 0) will invalidate | |
|  	 * the entire beacon. | |
|  	 */ | |
| -	for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32)) | |
| +	for (i = 0; i < txwi_desc_size; i += sizeof(__le32)) | |
|  		rt2800_register_write(rt2x00dev, beacon_base + i, 0); | |
|  } | |
|   | |
| @@ -1988,8 +1996,21 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, | |
|  } | |
|   | |
|  #define POWER_BOUND		0x27 | |
| +#define POWER_BOUND_5G		0x2b | |
|  #define FREQ_OFFSET_BOUND	0x5f | |
|   | |
| +static void rt2800_adjust_freq_offset(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	u8 rfcsr; | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | |
| +	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) | |
| +		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); | |
| +	else | |
| +		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | |
| +	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
| +} | |
| + | |
|  static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, | |
|  					 struct ieee80211_conf *conf, | |
|  					 struct rf_channel *rf, | |
| @@ -2010,12 +2031,7 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, | |
|  		rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | |
|  	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | |
|   | |
| -	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | |
| -	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); | |
| -	else | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | |
| -	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
| +	rt2800_adjust_freq_offset(rt2x00dev); | |
|   | |
|  	if (rf->channel <= 14) { | |
|  		if (rf->channel == 6) | |
| @@ -2056,13 +2072,7 @@ static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev, | |
|  	else | |
|  		rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2); | |
|   | |
| -	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | |
| -	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); | |
| -	else | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | |
| - | |
| -	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
| +	rt2800_adjust_freq_offset(rt2x00dev); | |
|   | |
|  	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | |
|  	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | |
| @@ -2127,12 +2137,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | |
|  	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); | |
|  	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | |
|   | |
| -	rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | |
| -	if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); | |
| -	else | |
| -		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | |
| -	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
| +	rt2800_adjust_freq_offset(rt2x00dev); | |
|   | |
|  	if (rf->channel <= 14) { | |
|  		int idx = rf->channel-1; | |
| @@ -2183,6 +2188,379 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | |
|  		} | |
|  	} | |
|  } | |
| +static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev, | |
| +					 struct ieee80211_conf *conf, | |
| +					 struct rf_channel *rf, | |
| +					 struct channel_info *info) | |
| +{ | |
| +	u8 rfcsr, ep_reg; | |
| +	u32 reg; | |
| +	int power_bound; | |
| + | |
| +	/* TODO */ | |
| +	const bool is_11b = false; | |
| +	const bool is_type_ep = false; | |
| + | |
| +	rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | |
| +	rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, | |
| +			   (rf->channel > 14 || conf_is_ht40(conf)) ? 5 : 0); | |
| +	rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | |
| + | |
| +	/* Order of values on rf_channel entry: N, K, mod, R */ | |
| +	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1 & 0xff); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev,  9, &rfcsr); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR9_K, rf->rf2 & 0xf); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR9_N, (rf->rf1 & 0x100) >> 8); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR9_MOD, ((rf->rf3 - 8) & 0x4) >> 2); | |
| +	rt2800_rfcsr_write(rt2x00dev, 9, rfcsr); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf4 - 1); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR11_MOD, (rf->rf3 - 8) & 0x3); | |
| +	rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); | |
| + | |
| +	if (rf->channel <= 14) { | |
| +		rt2800_rfcsr_write(rt2x00dev, 10, 0x90); | |
| +		/* FIXME: RF11 owerwrite ? */ | |
| +		rt2800_rfcsr_write(rt2x00dev, 11, 0x4A); | |
| +		rt2800_rfcsr_write(rt2x00dev, 12, 0x52); | |
| +		rt2800_rfcsr_write(rt2x00dev, 13, 0x42); | |
| +		rt2800_rfcsr_write(rt2x00dev, 22, 0x40); | |
| +		rt2800_rfcsr_write(rt2x00dev, 24, 0x4A); | |
| +		rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | |
| +		rt2800_rfcsr_write(rt2x00dev, 27, 0x42); | |
| +		rt2800_rfcsr_write(rt2x00dev, 36, 0x80); | |
| +		rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | |
| +		rt2800_rfcsr_write(rt2x00dev, 38, 0x89); | |
| +		rt2800_rfcsr_write(rt2x00dev, 39, 0x1B); | |
| +		rt2800_rfcsr_write(rt2x00dev, 40, 0x0D); | |
| +		rt2800_rfcsr_write(rt2x00dev, 41, 0x9B); | |
| +		rt2800_rfcsr_write(rt2x00dev, 42, 0xD5); | |
| +		rt2800_rfcsr_write(rt2x00dev, 43, 0x72); | |
| +		rt2800_rfcsr_write(rt2x00dev, 44, 0x0E); | |
| +		rt2800_rfcsr_write(rt2x00dev, 45, 0xA2); | |
| +		rt2800_rfcsr_write(rt2x00dev, 46, 0x6B); | |
| +		rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | |
| +		rt2800_rfcsr_write(rt2x00dev, 51, 0x3E); | |
| +		rt2800_rfcsr_write(rt2x00dev, 52, 0x48); | |
| +		rt2800_rfcsr_write(rt2x00dev, 54, 0x38); | |
| +		rt2800_rfcsr_write(rt2x00dev, 56, 0xA1); | |
| +		rt2800_rfcsr_write(rt2x00dev, 57, 0x00); | |
| +		rt2800_rfcsr_write(rt2x00dev, 58, 0x39); | |
| +		rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | |
| +		rt2800_rfcsr_write(rt2x00dev, 61, 0x91); | |
| +		rt2800_rfcsr_write(rt2x00dev, 62, 0x39); | |
| + | |
| +		/* TODO RF27 <- tssi */ | |
| + | |
| +		rfcsr = rf->channel <= 10 ? 0x07 : 0x06; | |
| +		rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | |
| +		rt2800_rfcsr_write(rt2x00dev, 59, rfcsr); | |
| + | |
| +		if (is_11b) { | |
| +			/* CCK */ | |
| +			rt2800_rfcsr_write(rt2x00dev, 31, 0xF8); | |
| +			rt2800_rfcsr_write(rt2x00dev, 32, 0xC0); | |
| +			if (is_type_ep) | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x06); | |
| +			else | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x47); | |
| +		} else { | |
| +			/* OFDM */ | |
| +			if (is_type_ep) | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x03); | |
| +			else | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x43); | |
| +		} | |
| + | |
| +		power_bound = POWER_BOUND; | |
| +		ep_reg = 0x2; | |
| +	} else { | |
| +		rt2800_rfcsr_write(rt2x00dev, 10, 0x97); | |
| +		/* FIMXE: RF11 overwrite */ | |
| +		rt2800_rfcsr_write(rt2x00dev, 11, 0x40); | |
| +		rt2800_rfcsr_write(rt2x00dev, 25, 0xBF); | |
| +		rt2800_rfcsr_write(rt2x00dev, 27, 0x42); | |
| +		rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | |
| +		rt2800_rfcsr_write(rt2x00dev, 37, 0x04); | |
| +		rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | |
| +		rt2800_rfcsr_write(rt2x00dev, 40, 0x42); | |
| +		rt2800_rfcsr_write(rt2x00dev, 41, 0xBB); | |
| +		rt2800_rfcsr_write(rt2x00dev, 42, 0xD7); | |
| +		rt2800_rfcsr_write(rt2x00dev, 45, 0x41); | |
| +		rt2800_rfcsr_write(rt2x00dev, 48, 0x00); | |
| +		rt2800_rfcsr_write(rt2x00dev, 57, 0x77); | |
| +		rt2800_rfcsr_write(rt2x00dev, 60, 0x05); | |
| +		rt2800_rfcsr_write(rt2x00dev, 61, 0x01); | |
| + | |
| +		/* TODO RF27 <- tssi */ | |
| + | |
| +		if (rf->channel >= 36 && rf->channel <= 64) { | |
| + | |
| +			rt2800_rfcsr_write(rt2x00dev, 12, 0x2E); | |
| +			rt2800_rfcsr_write(rt2x00dev, 13, 0x22); | |
| +			rt2800_rfcsr_write(rt2x00dev, 22, 0x60); | |
| +			rt2800_rfcsr_write(rt2x00dev, 23, 0x7F); | |
| +			if (rf->channel <= 50) | |
| +				rt2800_rfcsr_write(rt2x00dev, 24, 0x09); | |
| +			else if (rf->channel >= 52) | |
| +				rt2800_rfcsr_write(rt2x00dev, 24, 0x07); | |
| +			rt2800_rfcsr_write(rt2x00dev, 39, 0x1C); | |
| +			rt2800_rfcsr_write(rt2x00dev, 43, 0x5B); | |
| +			rt2800_rfcsr_write(rt2x00dev, 44, 0X40); | |
| +			rt2800_rfcsr_write(rt2x00dev, 46, 0X00); | |
| +			rt2800_rfcsr_write(rt2x00dev, 51, 0xFE); | |
| +			rt2800_rfcsr_write(rt2x00dev, 52, 0x0C); | |
| +			rt2800_rfcsr_write(rt2x00dev, 54, 0xF8); | |
| +			if (rf->channel <= 50) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x06), | |
| +				rt2800_rfcsr_write(rt2x00dev, 56, 0xD3); | |
| +			} else if (rf->channel >= 52) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x04); | |
| +				rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); | |
| +			} | |
| + | |
| +			rt2800_rfcsr_write(rt2x00dev, 58, 0x15); | |
| +			rt2800_rfcsr_write(rt2x00dev, 59, 0x7F); | |
| +			rt2800_rfcsr_write(rt2x00dev, 62, 0x15); | |
| + | |
| +		} else if (rf->channel >= 100 && rf->channel <= 165) { | |
| + | |
| +			rt2800_rfcsr_write(rt2x00dev, 12, 0x0E); | |
| +			rt2800_rfcsr_write(rt2x00dev, 13, 0x42); | |
| +			rt2800_rfcsr_write(rt2x00dev, 22, 0x40); | |
| +			if (rf->channel <= 153) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 23, 0x3C); | |
| +				rt2800_rfcsr_write(rt2x00dev, 24, 0x06); | |
| +			} else if (rf->channel >= 155) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 23, 0x38); | |
| +				rt2800_rfcsr_write(rt2x00dev, 24, 0x05); | |
| +			} | |
| +			if (rf->channel <= 138) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 39, 0x1A); | |
| +				rt2800_rfcsr_write(rt2x00dev, 43, 0x3B); | |
| +				rt2800_rfcsr_write(rt2x00dev, 44, 0x20); | |
| +				rt2800_rfcsr_write(rt2x00dev, 46, 0x18); | |
| +			} else if (rf->channel >= 140) { | |
| +				rt2800_rfcsr_write(rt2x00dev, 39, 0x18); | |
| +				rt2800_rfcsr_write(rt2x00dev, 43, 0x1B); | |
| +				rt2800_rfcsr_write(rt2x00dev, 44, 0x10); | |
| +				rt2800_rfcsr_write(rt2x00dev, 46, 0X08); | |
| +			} | |
| +			if (rf->channel <= 124) | |
| +				rt2800_rfcsr_write(rt2x00dev, 51, 0xFC); | |
| +			else if (rf->channel >= 126) | |
| +				rt2800_rfcsr_write(rt2x00dev, 51, 0xEC); | |
| +			if (rf->channel <= 138) | |
| +				rt2800_rfcsr_write(rt2x00dev, 52, 0x06); | |
| +			else if (rf->channel >= 140) | |
| +				rt2800_rfcsr_write(rt2x00dev, 52, 0x06); | |
| +			rt2800_rfcsr_write(rt2x00dev, 54, 0xEB); | |
| +			if (rf->channel <= 138) | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x01); | |
| +			else if (rf->channel >= 140) | |
| +				rt2800_rfcsr_write(rt2x00dev, 55, 0x00); | |
| +			if (rf->channel <= 128) | |
| +				rt2800_rfcsr_write(rt2x00dev, 56, 0xBB); | |
| +			else if (rf->channel >= 130) | |
| +				rt2800_rfcsr_write(rt2x00dev, 56, 0xAB); | |
| +			if (rf->channel <= 116) | |
| +				rt2800_rfcsr_write(rt2x00dev, 58, 0x1D); | |
| +			else if (rf->channel >= 118) | |
| +				rt2800_rfcsr_write(rt2x00dev, 58, 0x15); | |
| +			if (rf->channel <= 138) | |
| +				rt2800_rfcsr_write(rt2x00dev, 59, 0x3F); | |
| +			else if (rf->channel >= 140) | |
| +				rt2800_rfcsr_write(rt2x00dev, 59, 0x7C); | |
| +			if (rf->channel <= 116) | |
| +				rt2800_rfcsr_write(rt2x00dev, 62, 0x1D); | |
| +			else if (rf->channel >= 118) | |
| +				rt2800_rfcsr_write(rt2x00dev, 62, 0x15); | |
| +		} | |
| + | |
| +		power_bound = POWER_BOUND_5G; | |
| +		ep_reg = 0x3; | |
| +	} | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); | |
| +	if (info->default_power1 > power_bound) | |
| +		rt2x00_set_field8(&rfcsr, RFCSR49_TX, power_bound); | |
| +	else | |
| +		rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | |
| +	if (is_type_ep) | |
| +		rt2x00_set_field8(&rfcsr, RFCSR49_EP, ep_reg); | |
| +	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); | |
| +	if (info->default_power1 > power_bound) | |
| +		rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); | |
| +	else | |
| +		rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); | |
| +	if (is_type_ep) | |
| +		rt2x00_set_field8(&rfcsr, RFCSR50_EP, ep_reg); | |
| +	rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); | |
| +	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); | |
| + | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, | |
| +			  rt2x00dev->default_ant.tx_chain_num >= 1); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, | |
| +			  rt2x00dev->default_ant.tx_chain_num == 2); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); | |
| + | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, | |
| +			  rt2x00dev->default_ant.rx_chain_num >= 1); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, | |
| +			  rt2x00dev->default_ant.rx_chain_num == 2); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); | |
| + | |
| +	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | |
| +	rt2800_rfcsr_write(rt2x00dev, 6, 0xe4); | |
| + | |
| +	if (conf_is_ht40(conf)) | |
| +		rt2800_rfcsr_write(rt2x00dev, 30, 0x16); | |
| +	else | |
| +		rt2800_rfcsr_write(rt2x00dev, 30, 0x10); | |
| +	if (!is_11b) { | |
| +		rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | |
| +		rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | |
| +	} | |
| + | |
| +	/* TODO proper frequency adjustment */ | |
| +	rt2800_adjust_freq_offset(rt2x00dev); | |
| + | |
| +	/* TODO merge with others */ | |
| +	rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | |
| +	rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); | |
| +	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | |
| + | |
| +	/* BBP settings */ | |
| +	rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); | |
| +	rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); | |
| +	rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); | |
| + | |
| +	rt2800_bbp_write(rt2x00dev, 79, (rf->channel <= 14) ? 0x1C : 0x18); | |
| +	rt2800_bbp_write(rt2x00dev, 80, (rf->channel <= 14) ? 0x0E : 0x08); | |
| +	rt2800_bbp_write(rt2x00dev, 81, (rf->channel <= 14) ? 0x3A : 0x38); | |
| +	rt2800_bbp_write(rt2x00dev, 82, (rf->channel <= 14) ? 0x62 : 0x92); | |
| + | |
| +	/* GLRT band configuration */ | |
| +	rt2800_bbp_write(rt2x00dev, 195, 128); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0xE0 : 0xF0); | |
| +	rt2800_bbp_write(rt2x00dev, 195, 129); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x1F : 0x1E); | |
| +	rt2800_bbp_write(rt2x00dev, 195, 130); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x38 : 0x28); | |
| +	rt2800_bbp_write(rt2x00dev, 195, 131); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x32 : 0x20); | |
| +	rt2800_bbp_write(rt2x00dev, 195, 133); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x28 : 0x7F); | |
| +	rt2800_bbp_write(rt2x00dev, 195, 124); | |
| +	rt2800_bbp_write(rt2x00dev, 196, (rf->channel <= 14) ? 0x19 : 0x7F); | |
| +} | |
| + | |
| +static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev, | |
| +					   const unsigned int word, | |
| +					   const u8 value) | |
| +{ | |
| +	u8 chain, reg; | |
| + | |
| +	for (chain = 0; chain < rt2x00dev->default_ant.rx_chain_num; chain++) { | |
| +		rt2800_bbp_read(rt2x00dev, 27, ®); | |
| +		rt2x00_set_field8(®,  BBP27_RX_CHAIN_SEL, chain); | |
| +		rt2800_bbp_write(rt2x00dev, 27, reg); | |
| + | |
| +		rt2800_bbp_write(rt2x00dev, word, value); | |
| +	} | |
| +} | |
| + | |
| +static void rt2800_iq_calibrate(struct rt2x00_dev *rt2x00dev, int channel) | |
| +{ | |
| +	u8 cal; | |
| + | |
| +	/* TX0 IQ Gain */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x2c); | |
| +	if (channel <= 14) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX0_2G); | |
| +	else if (channel >= 36 && channel <= 64) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX0_CH36_TO_CH64_5G); | |
| +	else if (channel >= 100 && channel <= 138) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX0_CH100_TO_CH138_5G); | |
| +	else if (channel >= 140 && channel <= 165) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX0_CH140_TO_CH165_5G); | |
| +	else | |
| +		cal = 0; | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal); | |
| + | |
| +	/* TX0 IQ Phase */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x2d); | |
| +	if (channel <= 14) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX0_2G); | |
| +	else if (channel >= 36 && channel <= 64) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX0_CH36_TO_CH64_5G); | |
| +	else if (channel >= 100 && channel <= 138) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX0_CH100_TO_CH138_5G); | |
| +	else if (channel >= 140 && channel <= 165) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX0_CH140_TO_CH165_5G); | |
| +	else | |
| +		cal = 0; | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal); | |
| + | |
| +	/* TX1 IQ Gain */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x4a); | |
| +	if (channel <= 14) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_GAIN_CAL_TX1_2G); | |
| +	else if (channel >= 36 && channel <= 64) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX1_CH36_TO_CH64_5G); | |
| +	else if (channel >= 100 && channel <= 138) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX1_CH100_TO_CH138_5G); | |
| +	else if (channel >= 140 && channel <= 165) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_GAIN_CAL_TX1_CH140_TO_CH165_5G); | |
| +	else | |
| +		cal = 0; | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal); | |
| + | |
| +	/* TX1 IQ Phase */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x4b); | |
| +	if (channel <= 14) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_IQ_PHASE_CAL_TX1_2G); | |
| +	else if (channel >= 36 && channel <= 64) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX1_CH36_TO_CH64_5G); | |
| +	else if (channel >= 100 && channel <= 138) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX1_CH100_TO_CH138_5G); | |
| +	else if (channel >= 140 && channel <= 165) | |
| +		cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +					 EEPROM_IQ_PHASE_CAL_TX1_CH140_TO_CH165_5G); | |
| +	else | |
| +		cal = 0; | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal); | |
| + | |
| +	/* FIXME: possible RX0, RX1 callibration ? */ | |
| + | |
| +	/* RF IQ compensation control */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x04); | |
| +	cal = rt2x00_eeprom_byte(rt2x00dev, EEPROM_RF_IQ_COMPENSATION_CONTROL); | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); | |
| + | |
| +	/* RF IQ imbalance compensation control */ | |
| +	rt2800_bbp_write(rt2x00dev, 158, 0x03); | |
| +	cal = rt2x00_eeprom_byte(rt2x00dev, | |
| +				 EEPROM_RF_IQ_IMBALANCE_COMPENSATION_CONTROL); | |
| +	rt2800_bbp_write(rt2x00dev, 159, cal != 0xff ? cal : 0); | |
| +} | |
|   | |
|  static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |
|  				  struct ieee80211_conf *conf, | |
| @@ -2225,6 +2603,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |
|  	case RF5392: | |
|  		rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | |
|  		break; | |
| +	case RF5592: | |
| +		rt2800_config_channel_rf55xx(rt2x00dev, conf, rf, info); | |
| +		break; | |
|  	default: | |
|  		rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | |
|  	} | |
| @@ -2294,6 +2675,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |
|  	if (rt2x00_rt(rt2x00dev, RT3572)) | |
|  		rt2800_rfcsr_write(rt2x00dev, 8, 0); | |
|   | |
| +	if (rt2x00_rt(rt2x00dev, RT5592)) { | |
| +		rt2800_bbp_write(rt2x00dev, 195, 141); | |
| +		rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a); | |
| + | |
| +		/* AGC init */ | |
| +		reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain; | |
| +		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); | |
| + | |
| +		rt2800_iq_calibrate(rt2x00dev, rf->channel); | |
| +	} | |
| + | |
|  	tx_pin = 0; | |
|   | |
|  	/* Turn on unused PA or LNA when not using 1T or 1R */ | |
| @@ -2938,13 +3330,16 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) | |
|  		    rt2x00_rt(rt2x00dev, RT3390) || | |
|  		    rt2x00_rt(rt2x00dev, RT3572) || | |
|  		    rt2x00_rt(rt2x00dev, RT5390) || | |
| -		    rt2x00_rt(rt2x00dev, RT5392)) | |
| +		    rt2x00_rt(rt2x00dev, RT5392) || | |
| +		    rt2x00_rt(rt2x00dev, RT5592)) | |
|  			vgc = 0x1c + (2 * rt2x00dev->lna_gain); | |
|  		else | |
|  			vgc = 0x2e + rt2x00dev->lna_gain; | |
|  	} else { /* 5GHZ band */ | |
|  		if (rt2x00_rt(rt2x00dev, RT3572)) | |
|  			vgc = 0x22 + (rt2x00dev->lna_gain * 5) / 3; | |
| +		else if (rt2x00_rt(rt2x00dev, RT5592)) | |
| +			vgc = 0x24 + (2 * rt2x00dev->lna_gain); | |
|  		else { | |
|  			if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) | |
|  				vgc = 0x32 + (rt2x00dev->lna_gain * 5) / 3; | |
| @@ -2960,7 +3355,11 @@ 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); | |
| +		if (rt2x00_rt(rt2x00dev, RT5592)) { | |
| +			rt2800_bbp_write(rt2x00dev, 83, qual->rssi > -65 ? 0x4a : 0x7a); | |
| +			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); | |
| +		} else | |
| +			rt2800_bbp_write(rt2x00dev, 66, vgc_level); | |
|  		qual->vgc_level = vgc_level; | |
|  		qual->vgc_level_reg = vgc_level; | |
|  	} | |
| @@ -2975,15 +3374,24 @@ EXPORT_SYMBOL_GPL(rt2800_reset_tuner); | |
|  void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, | |
|  		       const u32 count) | |
|  { | |
| +	u8 vgc; | |
| + | |
|  	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) | |
|  		return; | |
|   | |
|  	/* | |
| -	 * When RSSI is better then -80 increase VGC level with 0x10 | |
| +	 * When RSSI is better then -80 increase VGC level with 0x10, except | |
| +	 * for rt5592 chip. | |
|  	 */ | |
| -	rt2800_set_vgc(rt2x00dev, qual, | |
| -		       rt2800_get_default_vgc(rt2x00dev) + | |
| -		       ((qual->rssi > -80) * 0x10)); | |
| + | |
| +	vgc = rt2800_get_default_vgc(rt2x00dev); | |
| + | |
| +	if (rt2x00_rt(rt2x00dev, RT5592) && qual->rssi > -65) | |
| +		vgc += 0x20; | |
| +	else if (qual->rssi > -80) | |
| +		vgc += 0x10; | |
| + | |
| +	rt2800_set_vgc(rt2x00dev, qual, vgc); | |
|  } | |
|  EXPORT_SYMBOL_GPL(rt2800_link_tuner); | |
|   | |
| @@ -3122,7 +3530,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |
|  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | |
|  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | |
|  	} else if (rt2x00_rt(rt2x00dev, RT5390) || | |
| -		   rt2x00_rt(rt2x00dev, RT5392)) { | |
| +		   rt2x00_rt(rt2x00dev, RT5392) || | |
| +		   rt2x00_rt(rt2x00dev, RT5592)) { | |
|  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | |
|  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | |
|  		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | |
| @@ -3302,7 +3711,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |
|  	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); | |
| +	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; | |
| +	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); | |
|   | |
|  	rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); | |
|  	rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); | |
| @@ -3462,6 +3872,135 @@ static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) | |
|  	ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n"); | |
|  	return -EACCES; | |
|  } | |
| +static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	u8 value; | |
| + | |
| +	rt2800_bbp_read(rt2x00dev, 4, &value); | |
| +	rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); | |
| +	rt2800_bbp_write(rt2x00dev, 4, value); | |
| +} | |
| + | |
| +static void rt2800_init_freq_calibration(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	rt2800_bbp_write(rt2x00dev, 142, 1); | |
| +	rt2800_bbp_write(rt2x00dev, 143, 57); | |
| +} | |
| + | |
| +static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	const u8 glrt_table[] = { | |
| +		0xE0, 0x1F, 0X38, 0x32, 0x08, 0x28, 0x19, 0x0A, 0xFF, 0x00, /* 128 ~ 137 */ | |
| +		0x16, 0x10, 0x10, 0x0B, 0x36, 0x2C, 0x26, 0x24, 0x42, 0x36, /* 138 ~ 147 */ | |
| +		0x30, 0x2D, 0x4C, 0x46, 0x3D, 0x40, 0x3E, 0x42, 0x3D, 0x40, /* 148 ~ 157 */ | |
| +		0X3C, 0x34, 0x2C, 0x2F, 0x3C, 0x35, 0x2E, 0x2A, 0x49, 0x41, /* 158 ~ 167 */ | |
| +		0x36, 0x31, 0x30, 0x30, 0x0E, 0x0D, 0x28, 0x21, 0x1C, 0x16, /* 168 ~ 177 */ | |
| +		0x50, 0x4A, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, /* 178 ~ 187 */ | |
| +		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 ~ 197 */ | |
| +		0x00, 0x00, 0x7D, 0x14, 0x32, 0x2C, 0x36, 0x4C, 0x43, 0x2C, /* 198 ~ 207 */ | |
| +		0x2E, 0x36, 0x30, 0x6E,					    /* 208 ~ 211 */ | |
| +	}; | |
| +	int i; | |
| + | |
| +	for (i = 0; i < ARRAY_SIZE(glrt_table); i++) { | |
| +		rt2800_bbp_write(rt2x00dev, 195, 128 + i); | |
| +		rt2800_bbp_write(rt2x00dev, 196, glrt_table[i]); | |
| +	} | |
| +}; | |
| + | |
| +static void rt2800_init_bbb_early(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	rt2800_bbp_write(rt2x00dev, 65, 0x2C); | |
| +	rt2800_bbp_write(rt2x00dev, 66, 0x38); | |
| +	rt2800_bbp_write(rt2x00dev, 68, 0x0B); | |
| +	rt2800_bbp_write(rt2x00dev, 69, 0x12); | |
| +	rt2800_bbp_write(rt2x00dev, 70, 0x0a); | |
| +	rt2800_bbp_write(rt2x00dev, 73, 0x10); | |
| +	rt2800_bbp_write(rt2x00dev, 81, 0x37); | |
| +	rt2800_bbp_write(rt2x00dev, 82, 0x62); | |
| +	rt2800_bbp_write(rt2x00dev, 83, 0x6A); | |
| +	rt2800_bbp_write(rt2x00dev, 84, 0x99); | |
| +	rt2800_bbp_write(rt2x00dev, 86, 0x00); | |
| +	rt2800_bbp_write(rt2x00dev, 91, 0x04); | |
| +	rt2800_bbp_write(rt2x00dev, 92, 0x00); | |
| +	rt2800_bbp_write(rt2x00dev, 103, 0x00); | |
| +	rt2800_bbp_write(rt2x00dev, 105, 0x05); | |
| +	rt2800_bbp_write(rt2x00dev, 106, 0x35); | |
| +} | |
| + | |
| +static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	int ant, div_mode; | |
| +	u16 eeprom; | |
| +	u8 value; | |
| + | |
| +	rt2800_init_bbb_early(rt2x00dev); | |
| + | |
| +	rt2800_bbp_read(rt2x00dev, 105, &value); | |
| +	rt2x00_set_field8(&value, BBP105_MLD, | |
| +			  rt2x00dev->default_ant.rx_chain_num == 2); | |
| +	rt2800_bbp_write(rt2x00dev, 105, value); | |
| + | |
| +	rt2800_bbp4_mac_if_ctrl(rt2x00dev); | |
| + | |
| +	rt2800_bbp_write(rt2x00dev, 20, 0x06); | |
| +	rt2800_bbp_write(rt2x00dev, 31, 0x08); | |
| +	rt2800_bbp_write(rt2x00dev, 65, 0x2C); | |
| +	rt2800_bbp_write(rt2x00dev, 68, 0xDD); | |
| +	rt2800_bbp_write(rt2x00dev, 69, 0x1A); | |
| +	rt2800_bbp_write(rt2x00dev, 70, 0x05); | |
| +	rt2800_bbp_write(rt2x00dev, 73, 0x13); | |
| +	rt2800_bbp_write(rt2x00dev, 74, 0x0F); | |
| +	rt2800_bbp_write(rt2x00dev, 75, 0x4F); | |
| +	rt2800_bbp_write(rt2x00dev, 76, 0x28); | |
| +	rt2800_bbp_write(rt2x00dev, 77, 0x59); | |
| +	rt2800_bbp_write(rt2x00dev, 84, 0x9A); | |
| +	rt2800_bbp_write(rt2x00dev, 86, 0x38); | |
| +	rt2800_bbp_write(rt2x00dev, 88, 0x90); | |
| +	rt2800_bbp_write(rt2x00dev, 91, 0x04); | |
| +	rt2800_bbp_write(rt2x00dev, 92, 0x02); | |
| +	rt2800_bbp_write(rt2x00dev, 95, 0x9a); | |
| +	rt2800_bbp_write(rt2x00dev, 98, 0x12); | |
| +	rt2800_bbp_write(rt2x00dev, 103, 0xC0); | |
| +	rt2800_bbp_write(rt2x00dev, 104, 0x92); | |
| +	/* FIXME BBP105 owerwrite */ | |
| +	rt2800_bbp_write(rt2x00dev, 105, 0x3C); | |
| +	rt2800_bbp_write(rt2x00dev, 106, 0x35); | |
| +	rt2800_bbp_write(rt2x00dev, 128, 0x12); | |
| +	rt2800_bbp_write(rt2x00dev, 134, 0xD0); | |
| +	rt2800_bbp_write(rt2x00dev, 135, 0xF6); | |
| +	rt2800_bbp_write(rt2x00dev, 137, 0x0F); | |
| + | |
| +	/* Initialize GLRT (Generalized Likehood Radio Test) */ | |
| +	rt2800_init_bbp_5592_glrt(rt2x00dev); | |
| + | |
| +	rt2800_bbp4_mac_if_ctrl(rt2x00dev); | |
| + | |
| +	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; | |
| +	rt2800_bbp_read(rt2x00dev, 152, &value); | |
| +	if (ant == 0) { | |
| +		/* Main antenna */ | |
| +		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); | |
| +	} else { | |
| +		/* Auxiliary antenna */ | |
| +		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); | |
| +	} | |
| +	rt2800_bbp_write(rt2x00dev, 152, value); | |
| + | |
| +	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) { | |
| +		rt2800_bbp_read(rt2x00dev, 254, &value); | |
| +		rt2x00_set_field8(&value, BBP254_BIT7, 1); | |
| +		rt2800_bbp_write(rt2x00dev, 254, value); | |
| +	} | |
| + | |
| +	rt2800_init_freq_calibration(rt2x00dev); | |
| + | |
| +	rt2800_bbp_write(rt2x00dev, 84, 0x19); | |
| +	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) | |
| +		rt2800_bbp_write(rt2x00dev, 103, 0xc0); | |
| +} | |
|   | |
|  static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) | |
|  { | |
| @@ -3498,6 +4037,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |
|  		     rt2800_wait_bbp_ready(rt2x00dev))) | |
|  		return -EACCES; | |
|   | |
| +	if (rt2x00_rt(rt2x00dev, RT5592)) { | |
| +		rt2800_init_bbp_5592(rt2x00dev); | |
| +		return 0; | |
| +	} | |
| + | |
|  	if (rt2x00_rt(rt2x00dev, RT3352)) { | |
|  		rt2800_bbp_write(rt2x00dev, 3, 0x00); | |
|  		rt2800_bbp_write(rt2x00dev, 4, 0x50); | |
| @@ -3505,11 +4049,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |
|   | |
|  	if (rt2x00_rt(rt2x00dev, RT3290) || | |
|  	    rt2x00_rt(rt2x00dev, RT5390) || | |
| -	    rt2x00_rt(rt2x00dev, RT5392)) { | |
| -		rt2800_bbp_read(rt2x00dev, 4, &value); | |
| -		rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); | |
| -		rt2800_bbp_write(rt2x00dev, 4, value); | |
| -	} | |
| +	    rt2x00_rt(rt2x00dev, RT5392)) | |
| +		rt2800_bbp4_mac_if_ctrl(rt2x00dev); | |
|   | |
|  	if (rt2800_is_305x_soc(rt2x00dev) || | |
|  	    rt2x00_rt(rt2x00dev, RT3290) || | |
| @@ -3783,9 +4324,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |
|  			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); | |
| +		rt2800_init_freq_calibration(rt2x00dev); | |
|  	} | |
|   | |
|  	for (i = 0; i < EEPROM_BBP_SIZE; i++) { | |
| @@ -3865,6 +4404,73 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, | |
|  	return rfcsr24; | |
|  } | |
|   | |
| +/* | |
| + * Post 3.8, rt2800_init_rfcsr was split into several functions: | |
| + *   rt2800_init_rfcsr_xxxx | |
| + */ | |
| +static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev) | |
| +{ | |
| +	u8 reg; | |
| +	u16 eeprom; | |
| + | |
| +	rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); | |
| +	rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | |
| +	rt2800_rfcsr_write(rt2x00dev, 3, 0x08); | |
| +	rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | |
| +	rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); | |
| +	rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | |
| +	rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | |
| +	rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | |
| +	rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | |
| +	rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | |
| +	rt2800_rfcsr_write(rt2x00dev, 19, 0x4D); | |
| +	rt2800_rfcsr_write(rt2x00dev, 20, 0x10); | |
| +	rt2800_rfcsr_write(rt2x00dev, 21, 0x8D); | |
| +	rt2800_rfcsr_write(rt2x00dev, 26, 0x82); | |
| +	rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | |
| +	rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | |
| +	rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); | |
| +	rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | |
| +	rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | |
| +	rt2800_rfcsr_write(rt2x00dev, 47, 0x0C); | |
| +	rt2800_rfcsr_write(rt2x00dev, 53, 0x22); | |
| +	rt2800_rfcsr_write(rt2x00dev, 63, 0x07); | |
| + | |
| +	rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | |
| +	msleep(1); | |
| + | |
| +	rt2800_adjust_freq_offset(rt2x00dev); | |
| + | |
| +	rt2800_bbp_read(rt2x00dev, 138, ®); | |
| + | |
| +	/*  Turn off unused DAC1 and ADC1 to reduce power consumption */ | |
| +	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | |
| +	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) | |
| +		rt2x00_set_field8(®, BBP138_RX_ADC1, 0); | |
| +	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) | |
| +		rt2x00_set_field8(®, BBP138_TX_DAC1, 1); | |
| + | |
| +	rt2800_bbp_write(rt2x00dev, 138, reg); | |
| + | |
| +	/* Enable DC filter */ | |
| +	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) | |
| +		rt2800_bbp_write(rt2x00dev, 103, 0xc0); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 38, ®); | |
| +	rt2x00_set_field8(®, RFCSR38_RX_LO1_EN, 0); | |
| +	rt2800_rfcsr_write(rt2x00dev, 38, reg); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 39, ®); | |
| +	rt2x00_set_field8(®, RFCSR39_RX_LO2_EN, 0); | |
| +	rt2800_rfcsr_write(rt2x00dev, 39, reg); | |
| + | |
| +	rt2800_bbp4_mac_if_ctrl(rt2x00dev); | |
| + | |
| +	rt2800_rfcsr_read(rt2x00dev, 30, ®); | |
| +	rt2x00_set_field8(®, RFCSR30_RX_VCM, 2); | |
| +	rt2800_rfcsr_write(rt2x00dev, 30, reg); | |
| +} | |
| + | |
|  static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) | |
|  { | |
|  	rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | |
| @@ -4276,6 +4882,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |
|  	    !rt2x00_rt(rt2x00dev, RT3572) && | |
|  	    !rt2x00_rt(rt2x00dev, RT5390) && | |
|  	    !rt2x00_rt(rt2x00dev, RT5392) && | |
| +	    !rt2x00_rt(rt2x00dev, RT5592) && | |
|  	    !rt2800_is_305x_soc(rt2x00dev)) | |
|  		return 0; | |
|   | |
| @@ -4330,6 +4937,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |
|  	case RT5392: | |
|  		rt2800_init_rfcsr_5392(rt2x00dev); | |
|  		break; | |
| +	case RT5592: | |
| +		rt2800_init_rfcsr_5592(rt2x00dev); | |
| +		return 0;	// why return 0 just for RT5592? | |
|  	} | |
|   | |
|  	if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | |
| @@ -4427,7 +5037,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |
|  	if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | |
|  	    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_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E) || | |
| +	    rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT5592C)) | |
|  		rt2800_rfcsr_write(rt2x00dev, 27, 0x03); | |
|   | |
|  	rt2800_register_read(rt2x00dev, OPT_14_CSR, ®); | |
| @@ -4455,7 +5066,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |
|  		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | |
|  	} | |
|   | |
| -	if (rt2x00_rt(rt2x00dev, RT3090)) { | |
| +	if (rt2x00_rt(rt2x00dev, RT3090) || | |
| +	   (rt2x00_rt(rt2x00dev, RT5592))) { | |
|  		rt2800_bbp_read(rt2x00dev, 138, &bbp); | |
|   | |
|  		/*  Turn off unused DAC1 and ADC1 to reduce power consumption */ | |
| @@ -4511,7 +5123,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |
|  	} | |
|   | |
|  	if (rt2x00_rt(rt2x00dev, RT5390) || | |
| -	    rt2x00_rt(rt2x00dev, RT5392)) { | |
| +	    rt2x00_rt(rt2x00dev, RT5392) || | |
| +	    rt2x00_rt(rt2x00dev, RT5592)) { | |
|  		rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); | |
|  		rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); | |
|  		rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); | |
| @@ -4537,15 +5150,23 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | |
|  	 * Initialize all registers. | |
|  	 */ | |
|  	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || | |
| -		     rt2800_init_registers(rt2x00dev) || | |
| -		     rt2800_init_bbp(rt2x00dev) || | |
| -		     rt2800_init_rfcsr(rt2x00dev))) | |
| +		     rt2800_init_registers(rt2x00dev))) | |
|  		return -EIO; | |
|   | |
|  	/* | |
|  	 * Send signal to firmware during boot time. | |
|  	 */ | |
| -	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | |
| +	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | |
| +	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | |
| +	if (rt2x00_is_usb(rt2x00dev)) { | |
| +		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); | |
| +		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | |
| +	} | |
| +	msleep(1); | |
| + | |
| +	if (unlikely(rt2800_init_bbp(rt2x00dev) || | |
| +		     rt2800_init_rfcsr(rt2x00dev))) | |
| +		return -EIO; | |
|   | |
|  	if (rt2x00_is_usb(rt2x00dev) && | |
|  	    (rt2x00_rt(rt2x00dev, RT3070) || | |
| @@ -4867,6 +5488,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |
|  	case RT3572: | |
|  	case RT5390: | |
|  	case RT5392: | |
| +	case RT5592: | |
|  		break; | |
|  	default: | |
|  		ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt); | |
| @@ -4891,6 +5513,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |
|  	case RF5372: | |
|  	case RF5390: | |
|  	case RF5392: | |
| +	case RF5592: | |
|  		break; | |
|  	default: | |
|  		ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", | |
| @@ -5126,6 +5749,138 @@ static const struct rf_channel rf_vals_3x[] = { | |
|  	{173, 0x61, 0, 9}, | |
|  }; | |
|   | |
| +static const struct rf_channel rf_vals_5592_xtal20[] = { | |
| +	/* Channel, N, K, mod, R */ | |
| +	{1, 482, 4, 10, 3}, | |
| +	{2, 483, 4, 10, 3}, | |
| +	{3, 484, 4, 10, 3}, | |
| +	{4, 485, 4, 10, 3}, | |
| +	{5, 486, 4, 10, 3}, | |
| +	{6, 487, 4, 10, 3}, | |
| +	{7, 488, 4, 10, 3}, | |
| +	{8, 489, 4, 10, 3}, | |
| +	{9, 490, 4, 10, 3}, | |
| +	{10, 491, 4, 10, 3}, | |
| +	{11, 492, 4, 10, 3}, | |
| +	{12, 493, 4, 10, 3}, | |
| +	{13, 494, 4, 10, 3}, | |
| +	{14, 496, 8, 10, 3}, | |
| +	{36, 172, 8, 12, 1}, | |
| +	{38, 173, 0, 12, 1}, | |
| +	{40, 173, 4, 12, 1}, | |
| +	{42, 173, 8, 12, 1}, | |
| +	{44, 174, 0, 12, 1}, | |
| +	{46, 174, 4, 12, 1}, | |
| +	{48, 174, 8, 12, 1}, | |
| +	{50, 175, 0, 12, 1}, | |
| +	{52, 175, 4, 12, 1}, | |
| +	{54, 175, 8, 12, 1}, | |
| +	{56, 176, 0, 12, 1}, | |
| +	{58, 176, 4, 12, 1}, | |
| +	{60, 176, 8, 12, 1}, | |
| +	{62, 177, 0, 12, 1}, | |
| +	{64, 177, 4, 12, 1}, | |
| +	{100, 183, 4, 12, 1}, | |
| +	{102, 183, 8, 12, 1}, | |
| +	{104, 184, 0, 12, 1}, | |
| +	{106, 184, 4, 12, 1}, | |
| +	{108, 184, 8, 12, 1}, | |
| +	{110, 185, 0, 12, 1}, | |
| +	{112, 185, 4, 12, 1}, | |
| +	{114, 185, 8, 12, 1}, | |
| +	{116, 186, 0, 12, 1}, | |
| +	{118, 186, 4, 12, 1}, | |
| +	{120, 186, 8, 12, 1}, | |
| +	{122, 187, 0, 12, 1}, | |
| +	{124, 187, 4, 12, 1}, | |
| +	{126, 187, 8, 12, 1}, | |
| +	{128, 188, 0, 12, 1}, | |
| +	{130, 188, 4, 12, 1}, | |
| +	{132, 188, 8, 12, 1}, | |
| +	{134, 189, 0, 12, 1}, | |
| +	{136, 189, 4, 12, 1}, | |
| +	{138, 189, 8, 12, 1}, | |
| +	{140, 190, 0, 12, 1}, | |
| +	{149, 191, 6, 12, 1}, | |
| +	{151, 191, 10, 12, 1}, | |
| +	{153, 192, 2, 12, 1}, | |
| +	{155, 192, 6, 12, 1}, | |
| +	{157, 192, 10, 12, 1}, | |
| +	{159, 193, 2, 12, 1}, | |
| +	{161, 193, 6, 12, 1}, | |
| +	{165, 194, 2, 12, 1}, | |
| +	{184, 164, 0, 12, 1}, | |
| +	{188, 164, 4, 12, 1}, | |
| +	{192, 165, 8, 12, 1}, | |
| +	{196, 166, 0, 12, 1}, | |
| +}; | |
| + | |
| +static const struct rf_channel rf_vals_5592_xtal40[] = { | |
| +	/* Channel, N, K, mod, R */ | |
| +	{1, 241, 2, 10, 3}, | |
| +	{2, 241, 7, 10, 3}, | |
| +	{3, 242, 2, 10, 3}, | |
| +	{4, 242, 7, 10, 3}, | |
| +	{5, 243, 2, 10, 3}, | |
| +	{6, 243, 7, 10, 3}, | |
| +	{7, 244, 2, 10, 3}, | |
| +	{8, 244, 7, 10, 3}, | |
| +	{9, 245, 2, 10, 3}, | |
| +	{10, 245, 7, 10, 3}, | |
| +	{11, 246, 2, 10, 3}, | |
| +	{12, 246, 7, 10, 3}, | |
| +	{13, 247, 2, 10, 3}, | |
| +	{14, 248, 4, 10, 3}, | |
| +	{36, 86, 4, 12, 1}, | |
| +	{38, 86, 6, 12, 1}, | |
| +	{40, 86, 8, 12, 1}, | |
| +	{42, 86, 10, 12, 1}, | |
| +	{44, 87, 0, 12, 1}, | |
| +	{46, 87, 2, 12, 1}, | |
| +	{48, 87, 4, 12, 1}, | |
| +	{50, 87, 6, 12, 1}, | |
| +	{52, 87, 8, 12, 1}, | |
| +	{54, 87, 10, 12, 1}, | |
| +	{56, 88, 0, 12, 1}, | |
| +	{58, 88, 2, 12, 1}, | |
| +	{60, 88, 4, 12, 1}, | |
| +	{62, 88, 6, 12, 1}, | |
| +	{64, 88, 8, 12, 1}, | |
| +	{100, 91, 8, 12, 1}, | |
| +	{102, 91, 10, 12, 1}, | |
| +	{104, 92, 0, 12, 1}, | |
| +	{106, 92, 2, 12, 1}, | |
| +	{108, 92, 4, 12, 1}, | |
| +	{110, 92, 6, 12, 1}, | |
| +	{112, 92, 8, 12, 1}, | |
| +	{114, 92, 10, 12, 1}, | |
| +	{116, 93, 0, 12, 1}, | |
| +	{118, 93, 2, 12, 1}, | |
| +	{120, 93, 4, 12, 1}, | |
| +	{122, 93, 6, 12, 1}, | |
| +	{124, 93, 8, 12, 1}, | |
| +	{126, 93, 10, 12, 1}, | |
| +	{128, 94, 0, 12, 1}, | |
| +	{130, 94, 2, 12, 1}, | |
| +	{132, 94, 4, 12, 1}, | |
| +	{134, 94, 6, 12, 1}, | |
| +	{136, 94, 8, 12, 1}, | |
| +	{138, 94, 10, 12, 1}, | |
| +	{140, 95, 0, 12, 1}, | |
| +	{149, 95, 9, 12, 1}, | |
| +	{151, 95, 11, 12, 1}, | |
| +	{153, 96, 1, 12, 1}, | |
| +	{155, 96, 3, 12, 1}, | |
| +	{157, 96, 5, 12, 1}, | |
| +	{159, 96, 7, 12, 1}, | |
| +	{161, 96, 9, 12, 1}, | |
| +	{165, 97, 1, 12, 1}, | |
| +	{184, 82, 0, 12, 1}, | |
| +	{188, 82, 4, 12, 1}, | |
| +	{192, 82, 8, 12, 1}, | |
| +	{196, 83, 0, 12, 1}, | |
| +}; | |
| + | |
|  static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |
|  { | |
|  	struct hw_mode_spec *spec = &rt2x00dev->spec; | |
| @@ -5134,6 +5889,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |
|  	char *default_power2; | |
|  	unsigned int i; | |
|  	u16 eeprom; | |
| +	u32 reg; | |
|   | |
|  	/* | |
|  	 * Disable powersaving as default on PCI devices. | |
| @@ -5215,7 +5971,22 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |
|  		spec->supported_bands |= SUPPORT_BAND_5GHZ; | |
|  		spec->num_channels = ARRAY_SIZE(rf_vals_3x); | |
|  		spec->channels = rf_vals_3x; | |
| -	} | |
| + | |
| +	} else if (rt2x00_rf(rt2x00dev, RF5592)) { | |
| +		spec->supported_bands |= SUPPORT_BAND_5GHZ; | |
| + | |
| +		rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); | |
| +		if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { | |
| +			spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40); | |
| +			spec->channels = rf_vals_5592_xtal40; | |
| +		} else { | |
| +			spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20); | |
| +			spec->channels = rf_vals_5592_xtal20; | |
| +		} | |
| + 	} | |
| +  | |
| +	if (WARN_ON_ONCE(!spec->channels)) | |
| +		return -ENODEV; | |
|   | |
|  	/* | |
|  	 * Initialize HT information. | |
| diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c | |
| index ba5a056..2cb6f64 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2800pci.c | |
| +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |
| @@ -1082,6 +1082,7 @@ static const struct data_queue_desc rt2800pci_queue_rx = { | |
|  	.entry_num		= 128, | |
|  	.data_size		= AGGREGATION_SIZE, | |
|  	.desc_size		= RXD_DESC_SIZE, | |
| +	.winfo_size		= RXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_pci), | |
|  }; | |
|   | |
| @@ -1089,13 +1090,15 @@ static const struct data_queue_desc rt2800pci_queue_tx = { | |
|  	.entry_num		= 64, | |
|  	.data_size		= AGGREGATION_SIZE, | |
|  	.desc_size		= TXD_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_pci), | |
|  }; | |
|   | |
|  static const struct data_queue_desc rt2800pci_queue_bcn = { | |
|  	.entry_num		= 8, | |
|  	.data_size		= 0, /* No DMA required for beacons */ | |
| -	.desc_size		= TXWI_DESC_SIZE, | |
| +	.desc_size		= TXD_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_pci), | |
|  }; | |
|   | |
| diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c | |
| index 098613e..0cb6bbe 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2800usb.c | |
| +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |
| @@ -485,7 +485,7 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, | |
|  	 */ | |
|  	skbdesc->flags |= SKBDESC_DESC_IN_SKB; | |
|  	skbdesc->desc = txi; | |
| -	skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | |
| +	skbdesc->desc_len = TXINFO_DESC_SIZE + entry->queue->winfo_size; | |
|  } | |
|   | |
|  /* | |
| @@ -853,21 +853,24 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |
|  static const struct data_queue_desc rt2800usb_queue_rx = { | |
|  	.entry_num		= 128, | |
|  	.data_size		= AGGREGATION_SIZE, | |
| -	.desc_size		= RXINFO_DESC_SIZE + RXWI_DESC_SIZE, | |
| +	.desc_size		= RXINFO_DESC_SIZE, | |
| +	.winfo_size		= RXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
|  }; | |
|   | |
|  static const struct data_queue_desc rt2800usb_queue_tx = { | |
|  	.entry_num		= 16, | |
|  	.data_size		= AGGREGATION_SIZE, | |
| -	.desc_size		= TXINFO_DESC_SIZE + TXWI_DESC_SIZE, | |
| +	.desc_size		= TXINFO_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
|  }; | |
|   | |
|  static const struct data_queue_desc rt2800usb_queue_bcn = { | |
|  	.entry_num		= 8, | |
|  	.data_size		= MGMT_FRAME_SIZE, | |
| -	.desc_size		= TXINFO_DESC_SIZE + TXWI_DESC_SIZE, | |
| +	.desc_size		= TXINFO_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE, | |
|  	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
|  }; | |
|   | |
| @@ -890,6 +893,50 @@ static const struct rt2x00_ops rt2800usb_ops = { | |
|  #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | |
|  }; | |
|   | |
| +static const struct data_queue_desc rt2800usb_queue_rx_5592 = { | |
| +	.entry_num		= 128, | |
| +	.data_size		= AGGREGATION_SIZE, | |
| +	.desc_size		= RXINFO_DESC_SIZE, | |
| +	.winfo_size		= RXWI_DESC_SIZE_5592, | |
| +	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
| +}; | |
| + | |
| +static const struct data_queue_desc rt2800usb_queue_tx_5592 = { | |
| +	.entry_num		= 16, | |
| +	.data_size		= AGGREGATION_SIZE, | |
| +	.desc_size		= TXINFO_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE_5592, | |
| +	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
| +}; | |
| + | |
| +static const struct data_queue_desc rt2800usb_queue_bcn_5592 = { | |
| +	.entry_num		= 8, | |
| +	.data_size		= MGMT_FRAME_SIZE, | |
| +	.desc_size		= TXINFO_DESC_SIZE, | |
| +	.winfo_size		= TXWI_DESC_SIZE_5592, | |
| +	.priv_size		= sizeof(struct queue_entry_priv_usb), | |
| +}; | |
| + | |
| + | |
| +static const struct rt2x00_ops rt2800usb_ops_5592 = { | |
| +	.name			= KBUILD_MODNAME, | |
| +	.drv_data_size		= sizeof(struct rt2800_drv_data), | |
| +	.max_ap_intf		= 8, | |
| +	.eeprom_size		= EEPROM_SIZE, | |
| +	.rf_size		= RF_SIZE, | |
| +	.tx_queues		= NUM_TX_QUEUES, | |
| +	.extra_tx_headroom	= TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592, | |
| +	.rx			= &rt2800usb_queue_rx_5592, | |
| +	.tx			= &rt2800usb_queue_tx_5592, | |
| +	.bcn			= &rt2800usb_queue_bcn_5592, | |
| +	.lib			= &rt2800usb_rt2x00_ops, | |
| +	.drv			= &rt2800usb_rt2800_ops, | |
| +	.hw			= &rt2800usb_mac80211_ops, | |
| +#ifdef CONFIG_RT2X00_LIB_DEBUGFS | |
| +	.debugfs		= &rt2800_rt2x00debug, | |
| +#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | |
| +}; | |
| + | |
|  /* | |
|   * rt2800usb module information. | |
|   */ | |
| @@ -1200,6 +1247,18 @@ static struct usb_device_id rt2800usb_device_table[] = { | |
|  	{ USB_DEVICE(0x148f, 0x5370) }, | |
|  	{ USB_DEVICE(0x148f, 0x5372) }, | |
|  #endif | |
| +#ifdef CONFIG_RT2800USB_RT55XX | |
| +	/* Arcadyan */ | |
| +	{ USB_DEVICE(0x043e, 0x7a32), .driver_info = 5592 }, | |
| +	/* AVM GmbH */ | |
| +	{ USB_DEVICE(0x057c, 0x8501), .driver_info = 5592 }, | |
| +	/* D-Link DWA-160-B2 */ | |
| +	{ USB_DEVICE(0x2001, 0x3c1a), .driver_info = 5592 }, | |
| +	/* Proware */ | |
| +	{ USB_DEVICE(0x043e, 0x7a13), .driver_info = 5592 }, | |
| +	/* Ralink */ | |
| +	{ USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 }, | |
| +#endif | |
|  #ifdef CONFIG_RT2800USB_UNKNOWN | |
|  	/* | |
|  	 * Unclear what kind of devices these are (they aren't supported by the | |
| @@ -1303,6 +1362,9 @@ MODULE_LICENSE("GPL"); | |
|  static int rt2800usb_probe(struct usb_interface *usb_intf, | |
|  			   const struct usb_device_id *id) | |
|  { | |
| +	if (id->driver_info == 5592) | |
| +		return rt2x00usb_probe(usb_intf, &rt2800usb_ops_5592); | |
| + | |
|  	return rt2x00usb_probe(usb_intf, &rt2800usb_ops); | |
|  } | |
|   | |
| diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h | |
| index 086abb4..ae50c43 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2x00.h | |
| +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |
| @@ -193,6 +193,7 @@ struct rt2x00_chip { | |
|  #define RT3883		0x3883	/* WSOC */ | |
|  #define RT5390		0x5390  /* 2.4GHz */ | |
|  #define RT5392		0x5392  /* 2.4GHz */ | |
| +#define RT5592		0x5592 | |
|   | |
|  	u16 rf; | |
|  	u16 rev; | |
| @@ -1064,8 +1065,7 @@ static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, | |
|  } | |
|   | |
|  /* | |
| - *  Generic EEPROM access. | |
| - * The EEPROM is being accessed by word index. | |
| + * Generic EEPROM access. The EEPROM is being accessed by word or byte index. | |
|   */ | |
|  static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, | |
|  				       const unsigned int word) | |
| @@ -1085,6 +1085,12 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, | |
|  	rt2x00dev->eeprom[word] = cpu_to_le16(data); | |
|  } | |
|   | |
| +static inline u8 rt2x00_eeprom_byte(struct rt2x00_dev *rt2x00dev, | |
| +				    const unsigned int byte) | |
| +{ | |
| +	return *(((u8 *)rt2x00dev->eeprom) + byte); | |
| +}	 | |
| + | |
|  /* | |
|   * Chipset handlers | |
|   */ | |
| diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c | |
| index 4d91795..57f0bbb 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2x00queue.c | |
| +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |
| @@ -35,7 +35,8 @@ | |
|   | |
|  struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) | |
|  { | |
| -	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | |
| +	struct data_queue *queue = entry->queue; | |
| +	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | |
|  	struct sk_buff *skb; | |
|  	struct skb_frame_desc *skbdesc; | |
|  	unsigned int frame_size; | |
| @@ -46,7 +47,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) | |
|  	 * The frame size includes descriptor size, because the | |
|  	 * hardware directly receive the frame into the skbuffer. | |
|  	 */ | |
| -	frame_size = entry->queue->data_size + entry->queue->desc_size; | |
| +	frame_size = queue->data_size + queue->desc_size + queue->winfo_size; | |
|   | |
|  	/* | |
|  	 * The payload should be aligned to a 4-byte boundary, | |
| @@ -1170,6 +1171,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |
|  	queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); | |
|  	queue->data_size = qdesc->data_size; | |
|  	queue->desc_size = qdesc->desc_size; | |
| +	queue->winfo_size = qdesc->winfo_size; | |
|   | |
|  	/* | |
|  	 * Allocate all queue entries. | |
| diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h | |
| index 9b8c10a..6e77227 100644 | |
| --- a/drivers/net/wireless/rt2x00/rt2x00queue.h | |
| +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |
| @@ -475,7 +475,8 @@ struct data_queue { | |
|  	unsigned short cw_max; | |
|   | |
|  	unsigned short data_size; | |
| -	unsigned short desc_size; | |
| +	unsigned char  desc_size; | |
| +	unsigned char  winfo_size; | |
|   | |
|  	unsigned short usb_endpoint; | |
|  	unsigned short usb_maxpacket; | |
| @@ -495,7 +496,8 @@ struct data_queue { | |
|  struct data_queue_desc { | |
|  	unsigned short entry_num; | |
|  	unsigned short data_size; | |
| -	unsigned short desc_size; | |
| +	unsigned char  desc_size; | |
| +	unsigned char  winfo_size; | |
|  	unsigned short priv_size; | |
|  }; | |
|   | |
| --  | |
| 1.7.9.5 | |
| 
 | |
| 
 |