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
|
|
|
|
|