All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] rt2x00 : RT3290 chip support v4
@ 2012-06-13 10:13 Xose Vazquez Perez
  2012-06-18  9:16 ` [rt2x00-users] " Matt Chen
  0 siblings, 1 reply; 7+ messages in thread
From: Xose Vazquez Perez @ 2012-06-13 10:13 UTC (permalink / raw)
  To: linux-wireless, users, Woody.Hung

Woody Hung wrote:

> --- a/drivers/net/wireless/rt2x00/rt2800pci.h
> +++ b/drivers/net/wireless/rt2x00/rt2800pci.h
> @@ -47,6 +47,7 @@
>   * 8051 firmware image.
>   */
>  #define FIRMWARE_RT2860			"rt2860.bin"
> +#define FIRMWARE_RT3290			"rt3290.bin"

There is no rt3290 fw in linux-firmware [1]
Please, send it ASAP.

[1] http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-13 10:13 [PATCH] rt2x00 : RT3290 chip support v4 Xose Vazquez Perez
@ 2012-06-18  9:16 ` Matt Chen
  2012-06-18 16:22   ` Woody Hung (洪秋竹)
  0 siblings, 1 reply; 7+ messages in thread
From: Matt Chen @ 2012-06-18  9:16 UTC (permalink / raw)
  To: Xose Vazquez Perez; +Cc: linux-wireless, users, Woody.Hung

2012/6/13 Xose Vazquez Perez <xose.vazquez@gmail.com>:
> Woody Hung wrote:
>
>> --- a/drivers/net/wireless/rt2x00/rt2800pci.h
>> +++ b/drivers/net/wireless/rt2x00/rt2800pci.h
>> @@ -47,6 +47,7 @@
>>  * 8051 firmware image.
>>  */
>>  #define FIRMWARE_RT2860                        "rt2860.bin"
>> +#define FIRMWARE_RT3290                        "rt3290.bin"
>
>
> There is no rt3290 fw in linux-firmware [1]
> Please, send it ASAP.
Indeed, I found the firmware is only in
http://www.ralink.com.tw/en/04_support/support.php?sn=501, RT3290 PCIe
driver tar ball.

Hi Woody,
Please send the firmware to the linux-firmware ASAP. :)

> [1] http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git
>
>
> _______________________________________________
> users mailing list
> users@rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
>



-- 
Thank you.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-18  9:16 ` [rt2x00-users] " Matt Chen
@ 2012-06-18 16:22   ` Woody Hung (洪秋竹)
  2012-06-19  3:28     ` Matt Chen
  0 siblings, 1 reply; 7+ messages in thread
From: Woody Hung (洪秋竹) @ 2012-06-18 16:22 UTC (permalink / raw)
  To: Matt Chen, Xose Vazquez Perez; +Cc: linux-wireless, users

RGVhciBBbGw6DQoNCglJIGhhdmUgc2VuZCBpdCB0byB0aGUgaHR0cDovL2dpdC5rZXJuZWwub3Jn
Lz9wPWxpbnV4L2tlcm5lbC9naXQvZmlybXdhcmUvbGludXgtZmlybXdhcmUuZ2l0Lg0KCUFuZCBp
dCBoYXZlIGJlZW4gYXBwbGllZCAzIGRheXMgYWdvLg0KCVBsZWFzZSBzZWUgdGhlIHNob3J0IGxv
ZyAicnQyODAwcGNpOkZpcm13YXJlIHVwZGF0ZSB2MSIuDQoJRG8gSSBtaXNzIHNvbWV0aGluZyBv
ciBzb21lIHJ1bGUgSSBuZWVkIHRvIGZvbGxvdz8/Pw0KDQpCUiwNCldvb2R5IEh1bmcNCi0tLS0t
T3JpZ2luYWwgTWVzc2FnZS0tLS0tDQpGcm9tOiBNYXR0IENoZW4gW21haWx0bzptYWNoZW5Ac3Vz
ZS5jb21dIA0KU2VudDogTW9uZGF5LCBKdW5lIDE4LCAyMDEyIDU6MTcgUE0NClRvOiBYb3NlIFZh
enF1ZXogUGVyZXoNCkNjOiBsaW51eC13aXJlbGVzc0B2Z2VyLmtlcm5lbC5vcmc7IHVzZXJzQHJ0
MngwMC5zZXJpYWxtb25rZXkuY29tOyBXb29keSBIdW5nICjmtKrnp4vnq7kpDQpTdWJqZWN0OiBS
ZTogW3J0MngwMC11c2Vyc10gW1BBVENIXSBydDJ4MDAgOiBSVDMyOTAgY2hpcCBzdXBwb3J0IHY0
DQoNCjIwMTIvNi8xMyBYb3NlIFZhenF1ZXogUGVyZXogPHhvc2UudmF6cXVlekBnbWFpbC5jb20+
Og0KPiBXb29keSBIdW5nIHdyb3RlOg0KPg0KPj4gLS0tIGEvZHJpdmVycy9uZXQvd2lyZWxlc3Mv
cnQyeDAwL3J0MjgwMHBjaS5oDQo+PiArKysgYi9kcml2ZXJzL25ldC93aXJlbGVzcy9ydDJ4MDAv
cnQyODAwcGNpLmgNCj4+IEBAIC00Nyw2ICs0Nyw3IEBADQo+PiDCoCogODA1MSBmaXJtd2FyZSBp
bWFnZS4NCj4+IMKgKi8NCj4+IMKgI2RlZmluZSBGSVJNV0FSRV9SVDI4NjAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAicnQyODYwLmJpbiINCj4+ICsjZGVmaW5lIEZJUk1XQVJF
X1JUMzI5MCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCJydDMyOTAuYmluIg0K
Pg0KPg0KPiBUaGVyZSBpcyBubyBydDMyOTAgZncgaW4gbGludXgtZmlybXdhcmUgWzFdIFBsZWFz
ZSwgc2VuZCBpdCBBU0FQLg0KSW5kZWVkLCBJIGZvdW5kIHRoZSBmaXJtd2FyZSBpcyBvbmx5IGlu
DQpodHRwOi8vd3d3LnJhbGluay5jb20udHcvZW4vMDRfc3VwcG9ydC9zdXBwb3J0LnBocD9zbj01
MDEsIFJUMzI5MCBQQ0llIGRyaXZlciB0YXIgYmFsbC4NCg0KSGkgV29vZHksDQpQbGVhc2Ugc2Vu
ZCB0aGUgZmlybXdhcmUgdG8gdGhlIGxpbnV4LWZpcm13YXJlIEFTQVAuIDopDQoNCj4gWzFdIA0K
PiBodHRwOi8vZ2l0Lmtlcm5lbC5vcmcvP3A9bGludXgva2VybmVsL2dpdC9maXJtd2FyZS9saW51
eC1maXJtd2FyZS5naXQNCj4NCj4NCj4gX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX18NCj4gdXNlcnMgbWFpbGluZyBsaXN0DQo+IHVzZXJzQHJ0MngwMC5zZXJp
YWxtb25rZXkuY29tDQo+IGh0dHA6Ly9ydDJ4MDAuc2VyaWFsbW9ua2V5LmNvbS9tYWlsbWFuL2xp
c3RpbmZvL3VzZXJzX3J0MngwMC5zZXJpYWxtb24NCj4ga2V5LmNvbQ0KPg0KDQoNCg0KLS0NClRo
YW5rIHlvdS4NCgoqKioqKioqKioqKioqIEVtYWlsIENvbmZpZGVudGlhbGl0eSBOb3RpY2UgKioq
KioqKioqKioqKioqKioqKioNClRoZSBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4gdGhpcyBlLW1h
aWwgbWVzc2FnZSAoaW5jbHVkaW5nIGFueSANCmF0dGFjaG1lbnRzKSBtYXkgYmUgY29uZmlkZW50
aWFsLCBwcm9wcmlldGFyeSwgcHJpdmlsZWdlZCwgb3Igb3RoZXJ3aXNlDQpleGVtcHQgZnJvbSBk
aXNjbG9zdXJlIHVuZGVyIGFwcGxpY2FibGUgbGF3cy4gSXQgaXMgaW50ZW5kZWQgdG8gYmUgDQpj
b252ZXllZCBvbmx5IHRvIHRoZSBkZXNpZ25hdGVkIHJlY2lwaWVudChzKS4gQW55IHVzZSwgZGlz
c2VtaW5hdGlvbiwgDQpkaXN0cmlidXRpb24sIHByaW50aW5nLCByZXRhaW5pbmcgb3IgY29weWlu
ZyBvZiB0aGlzIGUtbWFpbCAoaW5jbHVkaW5nIGl0cyANCmF0dGFjaG1lbnRzKSBieSB1bmludGVu
ZGVkIHJlY2lwaWVudChzKSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkIGFuZCBtYXkgDQpiZSB1bmxh
d2Z1bC4gSWYgeW91IGFyZSBub3QgYW4gaW50ZW5kZWQgcmVjaXBpZW50IG9mIHRoaXMgZS1tYWls
LCBvciBiZWxpZXZlIA0KdGhhdCB5b3UgaGF2ZSByZWNlaXZlZCB0aGlzIGUtbWFpbCBpbiBlcnJv
ciwgcGxlYXNlIG5vdGlmeSB0aGUgc2VuZGVyIA0KaW1tZWRpYXRlbHkgKGJ5IHJlcGx5aW5nIHRv
IHRoaXMgZS1tYWlsKSwgZGVsZXRlIGFueSBhbmQgYWxsIGNvcGllcyBvZiANCnRoaXMgZS1tYWls
IChpbmNsdWRpbmcgYW55IGF0dGFjaG1lbnRzKSBmcm9tIHlvdXIgc3lzdGVtLCBhbmQgZG8gbm90
DQpkaXNjbG9zZSB0aGUgY29udGVudCBvZiB0aGlzIGUtbWFpbCB0byBhbnkgb3RoZXIgcGVyc29u
LiBUaGFuayB5b3Uh


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-18 16:22   ` Woody Hung (洪秋竹)
@ 2012-06-19  3:28     ` Matt Chen
  0 siblings, 0 replies; 7+ messages in thread
From: Matt Chen @ 2012-06-19  3:28 UTC (permalink / raw)
  To: Woody Hung (洪秋竹)
  Cc: Xose Vazquez Perez, linux-wireless, users

Hi Woody,

2012/6/19 Woody Hung (洪秋竹) <woody.hung@mediatek.com>:
> Dear All:
>
>        I have send it to the http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git.
>        And it have been applied 3 days ago.
>        Please see the short log "rt2800pci:Firmware update v1".
>        Do I miss something or some rule I need to follow???
I see. I found it in the
http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git.
I tested this patch and firmware, it works fine to me here. :)
> BR,
> Woody Hung
> -----Original Message-----
> From: Matt Chen [mailto:machen@suse.com]
> Sent: Monday, June 18, 2012 5:17 PM
> To: Xose Vazquez Perez
> Cc: linux-wireless@vger.kernel.org; users@rt2x00.serialmonkey.com; Woody Hung (洪秋竹)
> Subject: Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
>
> 2012/6/13 Xose Vazquez Perez <xose.vazquez@gmail.com>:
>> Woody Hung wrote:
>>
>>> --- a/drivers/net/wireless/rt2x00/rt2800pci.h
>>> +++ b/drivers/net/wireless/rt2x00/rt2800pci.h
>>> @@ -47,6 +47,7 @@
>>>  * 8051 firmware image.
>>>  */
>>>  #define FIRMWARE_RT2860                        "rt2860.bin"
>>> +#define FIRMWARE_RT3290                        "rt3290.bin"
>>
>>
>> There is no rt3290 fw in linux-firmware [1] Please, send it ASAP.
> Indeed, I found the firmware is only in
> http://www.ralink.com.tw/en/04_support/support.php?sn=501, RT3290 PCIe driver tar ball.
>
> Hi Woody,
> Please send the firmware to the linux-firmware ASAP. :)
>
>> [1]
>> http://git.kernel.org/?p=linux/kernel/git/firmware/linux-firmware.git
>>
>>
>> _______________________________________________
>> users mailing list
>> users@rt2x00.serialmonkey.com
>> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmon
>> key.com
>>
>
>
>
> --
> Thank you.
>


-- 
Thank you.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-22  7:45 ` Helmut Schaa
@ 2012-07-09  9:14   ` Stanislaw Gruszka
  0 siblings, 0 replies; 7+ messages in thread
From: Stanislaw Gruszka @ 2012-07-09  9:14 UTC (permalink / raw)
  To: Helmut Schaa; +Cc: Woody Hung, linux-wireless, users

On Fri, Jun 22, 2012 at 09:45:49AM +0200, Helmut Schaa wrote:
> > +#define RT3290_POWER_BOUND     0x27
> > +#define RT3290_FREQ_OFFSET_BOUND       0x5f
> >  #define RT5390_POWER_BOUND     0x27
> >  #define RT5390_FREQ_OFFSET_BOUND       0x5f
> 
> Any reason why we cannot reuse the existing defines as they seem to be equal?
> Maybe we could just remove the prefix?

Because before that would conflict with some other patch, now we can merge
those two defines.

Stanislaw

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-21  2:46 ` [rt2x00-users] " Matt Chen
@ 2012-06-21  3:34   ` Matt Chen
  0 siblings, 0 replies; 7+ messages in thread
From: Matt Chen @ 2012-06-21  3:34 UTC (permalink / raw)
  To: Woody Hung
  Cc: linville, linux-wireless, users, Ivo Van Doorn, gwingerde, helmut.schaa

CC to maintainers.

2012/6/21 Matt Chen <machen@suse.com>:
> Tested-by: Matt Chen <machen@suse.de>
>
> 2012/6/13 Woody Hung <Woody.Hung@mediatek.com>:
>> This patch support the new chipset rt3290 wifi implementation in rt2x00.
>> It initailize the related mac, bbp and rf register in startup phase.
>> And this patch modify the efuse read/write method for the different efuse data offset of rt3290.
>>
>> Signed-off-by: Woody Hung <Woody.Hung@mediatek.com>
>> ---
>>  drivers/net/wireless/rt2x00/Kconfig     |    8 +
>>  drivers/net/wireless/rt2x00/rt2800.h    |  173 +++++++++++++++-
>>  drivers/net/wireless/rt2x00/rt2800lib.c |  350 ++++++++++++++++++++++++++-----
>>  drivers/net/wireless/rt2x00/rt2800pci.c |   82 +++++++-
>>  drivers/net/wireless/rt2x00/rt2800pci.h |    1 +
>>  drivers/net/wireless/rt2x00/rt2x00.h    |    1 +
>>  drivers/net/wireless/rt2x00/rt2x00pci.c |    9 +
>>  7 files changed, 567 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
>> index 299c387..c7548da 100644
>> --- a/drivers/net/wireless/rt2x00/Kconfig
>> +++ b/drivers/net/wireless/rt2x00/Kconfig
>> @@ -99,6 +99,14 @@ config RT2800PCI_RT53XX
>>          rt2800pci driver.
>>          Supported chips: RT5390
>>
>> +config RT2800PCI_RT3290
>> +       bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)"
>> +       depends on EXPERIMENTAL
>> +       default y
>> +       ---help---
>> +         This adds support for rt3290 wireless chipset family to the
>> +         rt2800pci driver.
>> +         Supported chips: RT3290
>>  endif
>>
>>  config RT2500USB
>> diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
>> index 1ca88cd..e252e9b 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800.h
>> +++ b/drivers/net/wireless/rt2x00/rt2800.h
>> @@ -68,6 +68,7 @@
>>  #define RF3320                         0x000b
>>  #define RF3322                         0x000c
>>  #define RF3053                         0x000d
>> +#define RF3290                         0x3290
>>  #define RF5360                         0x5360
>>  #define RF5370                         0x5370
>>  #define RF5372                         0x5372
>> @@ -117,6 +118,12 @@
>>  * Registers.
>>  */
>>
>> +
>> +/*
>> + * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number.
>> + */
>> +#define MAC_CSR0_3290                          0x0000
>> +
>>  /*
>>  * E2PROM_CSR: PCI EEPROM control register.
>>  * RELOAD: Write 1 to reload eeprom content.
>> @@ -133,6 +140,150 @@
>>  #define E2PROM_CSR_RELOAD              FIELD32(0x00000080)
>>
>>  /*
>> + * CMB_CTRL_CFG
>> + */
>> +#define CMB_CTRL               0x0020
>> +#define AUX_OPT_BIT0           FIELD32(0x00000001)
>> +#define AUX_OPT_BIT1           FIELD32(0x00000002)
>> +#define AUX_OPT_BIT2           FIELD32(0x00000004)
>> +#define AUX_OPT_BIT3           FIELD32(0x00000008)
>> +#define AUX_OPT_BIT4           FIELD32(0x00000010)
>> +#define AUX_OPT_BIT5           FIELD32(0x00000020)
>> +#define AUX_OPT_BIT6           FIELD32(0x00000040)
>> +#define AUX_OPT_BIT7           FIELD32(0x00000080)
>> +#define AUX_OPT_BIT8           FIELD32(0x00000100)
>> +#define AUX_OPT_BIT9           FIELD32(0x00000200)
>> +#define AUX_OPT_BIT10          FIELD32(0x00000400)
>> +#define AUX_OPT_BIT11          FIELD32(0x00000800)
>> +#define AUX_OPT_BIT12          FIELD32(0x00001000)
>> +#define AUX_OPT_BIT13          FIELD32(0x00002000)
>> +#define AUX_OPT_BIT14          FIELD32(0x00004000)
>> +#define AUX_OPT_BIT15          FIELD32(0x00008000)
>> +#define LDO25_LEVEL            FIELD32(0x00030000)
>> +#define LDO25_LARGEA           FIELD32(0x00040000)
>> +#define LDO25_FRC_ON           FIELD32(0x00080000)
>> +#define CMB_RSV                        FIELD32(0x00300000)
>> +#define XTAL_RDY               FIELD32(0x00400000)
>> +#define PLL_LD                 FIELD32(0x00800000)
>> +#define LDO_CORE_LEVEL         FIELD32(0x0F000000)
>> +#define LDO_BGSEL              FIELD32(0x30000000)
>> +#define LDO3_EN                        FIELD32(0x40000000)
>> +#define LDO0_EN                        FIELD32(0x80000000)
>> +
>> +/*
>> + * EFUSE_CSR_3290: RT3290 EEPROM
>> + */
>> +#define EFUSE_CTRL_3290                        0x0024
>> +
>> +/*
>> + * EFUSE_DATA3 of 3290
>> + */
>> +#define EFUSE_DATA3_3290               0x0028
>> +
>> +/*
>> + * EFUSE_DATA2 of 3290
>> + */
>> +#define EFUSE_DATA2_3290               0x002c
>> +
>> +/*
>> + * EFUSE_DATA1 of 3290
>> + */
>> +#define EFUSE_DATA1_3290               0x0030
>> +
>> +/*
>> + * EFUSE_DATA0 of 3290
>> + */
>> +#define EFUSE_DATA0_3290               0x0034
>> +
>> +/*
>> + * OSC_CTRL_CFG
>> + * Ring oscillator configuration
>> + */
>> +#define OSC_CTRL               0x0038
>> +#define OSC_REF_CYCLE          FIELD32(0x00001fff)
>> +#define OSC_RSV                        FIELD32(0x0000e000)
>> +#define OSC_CAL_CNT            FIELD32(0x0fff0000)
>> +#define OSC_CAL_ACK            FIELD32(0x10000000)
>> +#define OSC_CLK_32K_VLD                FIELD32(0x20000000)
>> +#define OSC_CAL_REQ            FIELD32(0x40000000)
>> +#define OSC_ROSC_EN            FIELD32(0x80000000)
>> +
>> +/*
>> + * COEX_CFG_0
>> + */
>> +#define COEX_CFG0                      0x0040
>> +#define COEX_CFG_ANT           FIELD32(0xff000000)
>> +/*
>> + * COEX_CFG_1
>> + */
>> +#define COEX_CFG1                      0x0044
>> +
>> +/*
>> + * COEX_CFG_2
>> + */
>> +#define COEX_CFG2                      0x0048
>> +#define BT_COEX_CFG1           FIELD32(0xff000000)
>> +#define BT_COEX_CFG0           FIELD32(0x00ff0000)
>> +#define WL_COEX_CFG1           FIELD32(0x0000ff00)
>> +#define WL_COEX_CFG0           FIELD32(0x000000ff)
>> +/*
>> + * PLL_CTRL_CFG
>> + * PLL configuration register
>> + */
>> +#define PLL_CTRL               0x0050
>> +#define PLL_RESERVED_INPUT1    FIELD32(0x000000ff)
>> +#define PLL_RESERVED_INPUT2    FIELD32(0x0000ff00)
>> +#define PLL_CONTROL            FIELD32(0x00070000)
>> +#define PLL_LPF_R1             FIELD32(0x00080000)
>> +#define PLL_LPF_C1_CTRL        FIELD32(0x00300000)
>> +#define PLL_LPF_C2_CTRL        FIELD32(0x00c00000)
>> +#define PLL_CP_CURRENT_CTRL    FIELD32(0x03000000)
>> +#define PLL_PFD_DELAY_CTRL     FIELD32(0x0c000000)
>> +#define PLL_LOCK_CTRL          FIELD32(0x70000000)
>> +#define PLL_VBGBK_EN           FIELD32(0x80000000)
>> +
>> +
>> +/*
>> + * WLAN_CTRL_CFG
>> + * RT3290 wlan configuration
>> + */
>> +#define WLAN_FUN_CTRL                  0x0080
>> +#define WLAN_EN                                FIELD32(0x00000001)
>> +#define WLAN_CLK_EN                    FIELD32(0x00000002)
>> +#define WLAN_RSV1                      FIELD32(0x00000004)
>> +#define WLAN_RESET                     FIELD32(0x00000008)
>> +#define PCIE_APP0_CLK_REQ              FIELD32(0x00000010)
>> +#define FRC_WL_ANT_SET                 FIELD32(0x00000020)
>> +#define INV_TR_SW0                     FIELD32(0x00000040)
>> +#define WLAN_GPIO_IN_BIT0              FIELD32(0x00000100)
>> +#define WLAN_GPIO_IN_BIT1              FIELD32(0x00000200)
>> +#define WLAN_GPIO_IN_BIT2              FIELD32(0x00000400)
>> +#define WLAN_GPIO_IN_BIT3              FIELD32(0x00000800)
>> +#define WLAN_GPIO_IN_BIT4              FIELD32(0x00001000)
>> +#define WLAN_GPIO_IN_BIT5              FIELD32(0x00002000)
>> +#define WLAN_GPIO_IN_BIT6              FIELD32(0x00004000)
>> +#define WLAN_GPIO_IN_BIT7              FIELD32(0x00008000)
>> +#define WLAN_GPIO_IN_BIT_ALL           FIELD32(0x0000ff00)
>> +#define WLAN_GPIO_OUT_BIT0             FIELD32(0x00010000)
>> +#define WLAN_GPIO_OUT_BIT1             FIELD32(0x00020000)
>> +#define WLAN_GPIO_OUT_BIT2             FIELD32(0x00040000)
>> +#define WLAN_GPIO_OUT_BIT3             FIELD32(0x00050000)
>> +#define WLAN_GPIO_OUT_BIT4             FIELD32(0x00100000)
>> +#define WLAN_GPIO_OUT_BIT5             FIELD32(0x00200000)
>> +#define WLAN_GPIO_OUT_BIT6             FIELD32(0x00400000)
>> +#define WLAN_GPIO_OUT_BIT7             FIELD32(0x00800000)
>> +#define WLAN_GPIO_OUT_BIT_ALL          FIELD32(0x00ff0000)
>> +#define WLAN_GPIO_OUT_OE_BIT0          FIELD32(0x01000000)
>> +#define WLAN_GPIO_OUT_OE_BIT1          FIELD32(0x02000000)
>> +#define WLAN_GPIO_OUT_OE_BIT2          FIELD32(0x04000000)
>> +#define WLAN_GPIO_OUT_OE_BIT3          FIELD32(0x08000000)
>> +#define WLAN_GPIO_OUT_OE_BIT4          FIELD32(0x10000000)
>> +#define WLAN_GPIO_OUT_OE_BIT5          FIELD32(0x20000000)
>> +#define WLAN_GPIO_OUT_OE_BIT6          FIELD32(0x40000000)
>> +#define WLAN_GPIO_OUT_OE_BIT7          FIELD32(0x80000000)
>> +#define WLAN_GPIO_OUT_OE_BIT_ALL       FIELD32(0xff000000)
>> +
>> +/*
>>  * AUX_CTRL: Aux/PCI-E related configuration
>>  */
>>  #define AUX_CTRL                       0x10c
>> @@ -1763,9 +1914,11 @@ struct mac_iveiv_entry {
>>  /*
>>  * BBP 3: RX Antenna
>>  */
>> -#define BBP3_RX_ADC                            FIELD8(0x03)
>> +#define BBP3_RX_ADC                    FIELD8(0x03)
>>  #define BBP3_RX_ANTENNA                        FIELD8(0x18)
>>  #define BBP3_HT40_MINUS                        FIELD8(0x20)
>> +#define BBP3_ADC_MODE_SWITCH           FIELD8(0x40)
>> +#define BBP3_ADC_INIT_MODE             FIELD8(0x80)
>>
>>  /*
>>  * BBP 4: Bandwidth
>> @@ -1775,6 +1928,14 @@ struct mac_iveiv_entry {
>>  #define BBP4_MAC_IF_CTRL               FIELD8(0x40)
>>
>>  /*
>> + * BBP 47: Bandwidth
>> + */
>> +#define BBP47_TSSI_REPORT_SEL          FIELD8(0x03)
>> +#define BBP47_TSSI_UPDATE_REQ          FIELD8(0x04)
>> +#define BBP47_TSSI_TSSI_MODE           FIELD8(0x18)
>> +#define BBP47_TSSI_ADC6                        FIELD8(0x80)
>> +
>> +/*
>>  * BBP 109
>>  */
>>  #define BBP109_TX0_POWER               FIELD8(0x0f)
>> @@ -1917,6 +2078,16 @@ struct mac_iveiv_entry {
>>  #define RFCSR27_R4                     FIELD8(0x40)
>>
>>  /*
>> + * RFCSR 29:
>> + */
>> +#define RFCSR29_ADC6_TEST              FIELD8(0x01)
>> +#define RFCSR29_ADC6_INT_TEST          FIELD8(0x02)
>> +#define RFCSR29_RSSI_RESET             FIELD8(0x04)
>> +#define RFCSR29_RSSI_ON                        FIELD8(0x08)
>> +#define RFCSR29_RSSI_RIP_CTRL          FIELD8(0x30)
>> +#define RFCSR29_RSSI_GAIN              FIELD8(0xc0)
>> +
>> +/*
>>  * RFCSR 30:
>>  */
>>  #define RFCSR30_TX_H20M                        FIELD8(0x02)
>> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
>> index 4d3747c..068276e 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
>> @@ -354,16 +354,15 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev,
>>         * of 4kb. Certain USB chipsets however require different firmware,
>>         * which Ralink only provides attached to the original firmware
>>         * file. Thus for USB devices, firmware files have a length
>> -        * which is a multiple of 4kb.
>> +        * which is a multiple of 4kb. The firmware for rt3290 chip also
>> +        * have a length which is a multiple of 4kb.
>>         */
>> -       if (rt2x00_is_usb(rt2x00dev)) {
>> +       if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290))
>>                fw_len = 4096;
>> -               multiple = true;
>> -       } else {
>> +       else
>>                fw_len = 8192;
>> -               multiple = true;
>> -       }
>>
>> +       multiple = true;
>>        /*
>>         * Validate the firmware length
>>         */
>> @@ -415,7 +414,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
>>                return -EBUSY;
>>
>>        if (rt2x00_is_pci(rt2x00dev)) {
>> -               if (rt2x00_rt(rt2x00dev, RT3572) ||
>> +               if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +                   rt2x00_rt(rt2x00dev, RT3572) ||
>>                    rt2x00_rt(rt2x00dev, RT5390) ||
>>                    rt2x00_rt(rt2x00dev, RT5392)) {
>>                        rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
>> @@ -851,8 +851,13 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
>>  {
>>        u32 reg;
>>
>> -       rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
>> -       return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
>> +               return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0);
>> +       } else {
>> +               rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
>> +               return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
>> +       }
>>  }
>>  EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
>>
>> @@ -1935,9 +1940,54 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
>>        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
>>  }
>>
>> +#define RT3290_POWER_BOUND     0x27
>> +#define RT3290_FREQ_OFFSET_BOUND       0x5f
>>  #define RT5390_POWER_BOUND     0x27
>>  #define RT5390_FREQ_OFFSET_BOUND       0x5f
>>
>> +static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
>> +                                        struct ieee80211_conf *conf,
>> +                                        struct rf_channel *rf,
>> +                                        struct channel_info *info)
>> +{
>> +       u8 rfcsr;
>> +
>> +       rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
>> +       rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
>> +       rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
>> +       rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2);
>> +       rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
>> +
>> +       rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
>> +       if (info->default_power1 > RT3290_POWER_BOUND)
>> +               rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT3290_POWER_BOUND);
>> +       else
>> +               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 > RT3290_FREQ_OFFSET_BOUND)
>> +               rt2x00_set_field8(&rfcsr, RFCSR17_CODE,
>> +                                 RT3290_FREQ_OFFSET_BOUND);
>> +       else
>> +               rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
>> +       rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
>> +
>> +       if (rf->channel <= 14) {
>> +               if (rf->channel == 6)
>> +                       rt2800_bbp_write(rt2x00dev, 68, 0x0c);
>> +               else
>> +                       rt2800_bbp_write(rt2x00dev, 68, 0x0b);
>> +
>> +               if (rf->channel >= 1 && rf->channel <= 6)
>> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0f);
>> +               else if (rf->channel >= 7 && rf->channel <= 11)
>> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0e);
>> +               else if (rf->channel >= 12 && rf->channel <= 14)
>> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0d);
>> +       }
>> +}
>> +
>>  static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
>>                                         struct ieee80211_conf *conf,
>>                                         struct rf_channel *rf,
>> @@ -2036,15 +2086,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
>>                        }
>>                }
>>        }
>> -
>> -       rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
>> -       rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
>> -       rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
>> -       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
>> -
>> -       rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
>> -       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
>> -       rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
>>  }
>>
>>  static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>> @@ -2054,7 +2095,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>>  {
>>        u32 reg;
>>        unsigned int tx_pin;
>> -       u8 bbp;
>> +       u8 bbp, rfcsr;
>>
>>        if (rf->channel <= 14) {
>>                info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
>> @@ -2075,6 +2116,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>>        case RF3052:
>>                rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
>>                break;
>> +       case RF3290:
>> +               rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
>> +               break;
>>        case RF5360:
>>        case RF5370:
>>        case RF5372:
>> @@ -2086,6 +2130,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>>                rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
>>        }
>>
>> +       if (rt2x00_rf(rt2x00dev, RF3290) ||
>> +           rt2x00_rf(rt2x00dev, RF5360) ||
>> +           rt2x00_rf(rt2x00dev, RF5370) ||
>> +           rt2x00_rf(rt2x00dev, RF5372) ||
>> +           rt2x00_rf(rt2x00dev, RF5390) ||
>> +           rt2x00_rf(rt2x00dev, RF5392)) {
>> +               rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
>> +               rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
>> +               rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
>> +               rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
>> +
>> +               rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
>> +               rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
>> +               rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
>> +       }
>> +
>>        /*
>>         * Change BBP settings
>>         */
>> @@ -2566,6 +2626,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
>>                rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
>>                rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
>>                break;
>> +       case RF3290:
>>        case RF5360:
>>        case RF5370:
>>        case RF5372:
>> @@ -2701,6 +2762,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
>>                if (rt2x00_rt(rt2x00dev, RT3070) ||
>>                    rt2x00_rt(rt2x00dev, RT3071) ||
>>                    rt2x00_rt(rt2x00dev, RT3090) ||
>> +                   rt2x00_rt(rt2x00dev, RT3290) ||
>>                    rt2x00_rt(rt2x00dev, RT3390) ||
>>                    rt2x00_rt(rt2x00dev, RT5390) ||
>>                    rt2x00_rt(rt2x00dev, RT5392))
>> @@ -2797,10 +2859,54 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>>        rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
>>        rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
>>
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
>> +               if (rt2x00_get_field32(reg, WLAN_EN) == 1) {
>> +                       rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 1);
>> +                       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
>> +               }
>> +
>> +               rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
>> +               if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) {
>> +                       rt2x00_set_field32(&reg, LDO0_EN, 1);
>> +                       rt2x00_set_field32(&reg, LDO_BGSEL, 3);
>> +                       rt2800_register_write(rt2x00dev, CMB_CTRL, reg);
>> +               }
>> +
>> +               rt2800_register_read(rt2x00dev, OSC_CTRL, &reg);
>> +               rt2x00_set_field32(&reg, OSC_ROSC_EN, 1);
>> +               rt2x00_set_field32(&reg, OSC_CAL_REQ, 1);
>> +               rt2x00_set_field32(&reg, OSC_REF_CYCLE, 0x27);
>> +               rt2800_register_write(rt2x00dev, OSC_CTRL, reg);
>> +
>> +               rt2800_register_read(rt2x00dev, COEX_CFG0, &reg);
>> +               rt2x00_set_field32(&reg, COEX_CFG_ANT, 0x5e);
>> +               rt2800_register_write(rt2x00dev, COEX_CFG0, reg);
>> +
>> +               rt2800_register_read(rt2x00dev, COEX_CFG2, &reg);
>> +               rt2x00_set_field32(&reg, BT_COEX_CFG1, 0x00);
>> +               rt2x00_set_field32(&reg, BT_COEX_CFG0, 0x17);
>> +               rt2x00_set_field32(&reg, WL_COEX_CFG1, 0x93);
>> +               rt2x00_set_field32(&reg, WL_COEX_CFG0, 0x7f);
>> +               rt2800_register_write(rt2x00dev, COEX_CFG2, reg);
>> +
>> +               rt2800_register_read(rt2x00dev, PLL_CTRL, &reg);
>> +               rt2x00_set_field32(&reg, PLL_CONTROL, 1);
>> +               rt2800_register_write(rt2x00dev, PLL_CTRL, reg);
>> +       }
>> +
>>        if (rt2x00_rt(rt2x00dev, RT3071) ||
>>            rt2x00_rt(rt2x00dev, RT3090) ||
>> +           rt2x00_rt(rt2x00dev, RT3290) ||
>>            rt2x00_rt(rt2x00dev, RT3390)) {
>> -               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
>> +
>> +               if (rt2x00_rt(rt2x00dev, RT3290))
>> +                       rt2800_register_write(rt2x00dev, TX_SW_CFG0,
>> +                                             0x00000404);
>> +               else
>> +                       rt2800_register_write(rt2x00dev, TX_SW_CFG0,
>> +                                             0x00000400);
>> +
>>                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
>>                if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
>>                    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
>> @@ -3209,14 +3315,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>                     rt2800_wait_bbp_ready(rt2x00dev)))
>>                return -EACCES;
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392)) {
>> +       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);
>>        }
>>
>>        if (rt2800_is_305x_soc(rt2x00dev) ||
>> +           rt2x00_rt(rt2x00dev, RT3290) ||
>>            rt2x00_rt(rt2x00dev, RT3572) ||
>>            rt2x00_rt(rt2x00dev, RT5390) ||
>>            rt2x00_rt(rt2x00dev, RT5392))
>> @@ -3225,20 +3333,26 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>        rt2800_bbp_write(rt2x00dev, 65, 0x2c);
>>        rt2800_bbp_write(rt2x00dev, 66, 0x38);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 68, 0x0b);
>>
>>        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
>>                rt2800_bbp_write(rt2x00dev, 69, 0x16);
>>                rt2800_bbp_write(rt2x00dev, 73, 0x12);
>> -       } else if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -                          rt2x00_rt(rt2x00dev, RT5392)) {
>> +       } else if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +                  rt2x00_rt(rt2x00dev, RT5390) ||
>> +                  rt2x00_rt(rt2x00dev, RT5392)) {
>>                rt2800_bbp_write(rt2x00dev, 69, 0x12);
>>                rt2800_bbp_write(rt2x00dev, 73, 0x13);
>>                rt2800_bbp_write(rt2x00dev, 75, 0x46);
>>                rt2800_bbp_write(rt2x00dev, 76, 0x28);
>> -               rt2800_bbp_write(rt2x00dev, 77, 0x59);
>> +
>> +               if (rt2x00_rt(rt2x00dev, RT3290))
>> +                       rt2800_bbp_write(rt2x00dev, 77, 0x58);
>> +               else
>> +                       rt2800_bbp_write(rt2x00dev, 77, 0x59);
>>        } else {
>>                rt2800_bbp_write(rt2x00dev, 69, 0x12);
>>                rt2800_bbp_write(rt2x00dev, 73, 0x10);
>> @@ -3263,23 +3377,33 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>                rt2800_bbp_write(rt2x00dev, 81, 0x37);
>>        }
>>
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_bbp_write(rt2x00dev, 74, 0x0b);
>> +               rt2800_bbp_write(rt2x00dev, 79, 0x18);
>> +               rt2800_bbp_write(rt2x00dev, 80, 0x09);
>> +               rt2800_bbp_write(rt2x00dev, 81, 0x33);
>> +       }
>> +
>>        rt2800_bbp_write(rt2x00dev, 82, 0x62);
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 83, 0x7a);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 83, 0x6a);
>>
>>        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
>>                rt2800_bbp_write(rt2x00dev, 84, 0x19);
>> -       else if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -                        rt2x00_rt(rt2x00dev, RT5392))
>> +       else if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +                    rt2x00_rt(rt2x00dev, RT5390) ||
>> +                    rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 84, 0x9a);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 84, 0x99);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 86, 0x38);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 86, 0x00);
>> @@ -3289,8 +3413,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>
>>        rt2800_bbp_write(rt2x00dev, 91, 0x04);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 92, 0x02);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 92, 0x00);
>> @@ -3304,6 +3429,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>            rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
>>            rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
>>            rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
>> +           rt2x00_rt(rt2x00dev, RT3290) ||
>>            rt2x00_rt(rt2x00dev, RT3572) ||
>>            rt2x00_rt(rt2x00dev, RT5390) ||
>>            rt2x00_rt(rt2x00dev, RT5392) ||
>> @@ -3312,27 +3438,32 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>        else
>>                rt2800_bbp_write(rt2x00dev, 103, 0x00);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 104, 0x92);
>>
>>        if (rt2800_is_305x_soc(rt2x00dev))
>>                rt2800_bbp_write(rt2x00dev, 105, 0x01);
>> +       else if (rt2x00_rt(rt2x00dev, RT3290))
>> +               rt2800_bbp_write(rt2x00dev, 105, 0x1c);
>>        else if (rt2x00_rt(rt2x00dev, RT5390) ||
>>                         rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 105, 0x3c);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 105, 0x05);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390))
>>                rt2800_bbp_write(rt2x00dev, 106, 0x03);
>>        else if (rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 106, 0x12);
>>        else
>>                rt2800_bbp_write(rt2x00dev, 106, 0x35);
>>
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392))
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392))
>>                rt2800_bbp_write(rt2x00dev, 128, 0x12);
>>
>>        if (rt2x00_rt(rt2x00dev, RT5392)) {
>> @@ -3357,6 +3488,29 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>>                rt2800_bbp_write(rt2x00dev, 138, value);
>>        }
>>
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_bbp_write(rt2x00dev, 67, 0x24);
>> +               rt2800_bbp_write(rt2x00dev, 143, 0x04);
>> +               rt2800_bbp_write(rt2x00dev, 142, 0x99);
>> +               rt2800_bbp_write(rt2x00dev, 150, 0x30);
>> +               rt2800_bbp_write(rt2x00dev, 151, 0x2e);
>> +               rt2800_bbp_write(rt2x00dev, 152, 0x20);
>> +               rt2800_bbp_write(rt2x00dev, 153, 0x34);
>> +               rt2800_bbp_write(rt2x00dev, 154, 0x40);
>> +               rt2800_bbp_write(rt2x00dev, 155, 0x3b);
>> +               rt2800_bbp_write(rt2x00dev, 253, 0x04);
>> +
>> +               rt2800_bbp_read(rt2x00dev, 47, &value);
>> +               rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
>> +               rt2800_bbp_write(rt2x00dev, 47, value);
>> +
>> +               /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
>> +               rt2800_bbp_read(rt2x00dev, 3, &value);
>> +               rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
>> +               rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
>> +               rt2800_bbp_write(rt2x00dev, 3, value);
>> +       }
>> +
>>        if (rt2x00_rt(rt2x00dev, RT5390) ||
>>                rt2x00_rt(rt2x00dev, RT5392)) {
>>                int ant, div_mode;
>> @@ -3489,6 +3643,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>>        if (!rt2x00_rt(rt2x00dev, RT3070) &&
>>            !rt2x00_rt(rt2x00dev, RT3071) &&
>>            !rt2x00_rt(rt2x00dev, RT3090) &&
>> +           !rt2x00_rt(rt2x00dev, RT3290) &&
>>            !rt2x00_rt(rt2x00dev, RT3390) &&
>>            !rt2x00_rt(rt2x00dev, RT3572) &&
>>            !rt2x00_rt(rt2x00dev, RT5390) &&
>> @@ -3499,8 +3654,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>>        /*
>>         * Init RF calibration.
>>         */
>> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
>> -               rt2x00_rt(rt2x00dev, RT5392)) {
>> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
>> +           rt2x00_rt(rt2x00dev, RT5390) ||
>> +           rt2x00_rt(rt2x00dev, RT5392)) {
>>                rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
>>                rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
>>                rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
>> @@ -3538,6 +3694,53 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>>                rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
>>                rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
>>                rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
>> +       } else if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
>> +               rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
>> +               rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
>> +               rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
>> +               rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
>> +               rt2800_rfcsr_write(rt2x00dev, 8, 0xf3);
>> +               rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
>> +               rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
>> +               rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
>> +               rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
>> +               rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
>> +               rt2800_rfcsr_write(rt2x00dev, 18, 0x02);
>> +               rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
>> +               rt2800_rfcsr_write(rt2x00dev, 25, 0x83);
>> +               rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
>> +               rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
>> +               rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
>> +               rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
>> +               rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
>> +               rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
>> +               rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
>> +               rt2800_rfcsr_write(rt2x00dev, 34, 0x05);
>> +               rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
>> +               rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
>> +               rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
>> +               rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
>> +               rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
>> +               rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
>> +               rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
>> +               rt2800_rfcsr_write(rt2x00dev, 43, 0x7b);
>> +               rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
>> +               rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
>> +               rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
>> +               rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
>> +               rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
>> +               rt2800_rfcsr_write(rt2x00dev, 49, 0x98);
>> +               rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
>> +               rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
>> +               rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
>> +               rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
>> +               rt2800_rfcsr_write(rt2x00dev, 56, 0x02);
>> +               rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
>> +               rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
>> +               rt2800_rfcsr_write(rt2x00dev, 59, 0x09);
>> +               rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
>> +               rt2800_rfcsr_write(rt2x00dev, 61, 0xc1);
>>        } else if (rt2x00_rt(rt2x00dev, RT3390)) {
>>                rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
>>                rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
>> @@ -3946,6 +4149,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>>                rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
>>        }
>>
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr);
>> +               rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3);
>> +               rt2800_rfcsr_write(rt2x00dev, 29, rfcsr);
>> +       }
>> +
>>        if (rt2x00_rt(rt2x00dev, RT5390) ||
>>                rt2x00_rt(rt2x00dev, RT5392)) {
>>                rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
>> @@ -4052,9 +4261,14 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio);
>>  int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
>>  {
>>        u32 reg;
>> +       u16 efuse_ctrl_reg;
>>
>> -       rt2800_register_read(rt2x00dev, EFUSE_CTRL, &reg);
>> +       if (rt2x00_rt(rt2x00dev, RT3290))
>> +               efuse_ctrl_reg = EFUSE_CTRL_3290;
>> +       else
>> +               efuse_ctrl_reg = EFUSE_CTRL;
>>
>> +       rt2800_register_read(rt2x00dev, efuse_ctrl_reg, &reg);
>>        return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT);
>>  }
>>  EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
>> @@ -4062,27 +4276,44 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
>>  static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
>>  {
>>        u32 reg;
>> -
>> +       u16 efuse_ctrl_reg;
>> +       u16 efuse_data0_reg;
>> +       u16 efuse_data1_reg;
>> +       u16 efuse_data2_reg;
>> +       u16 efuse_data3_reg;
>> +
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               efuse_ctrl_reg = EFUSE_CTRL_3290;
>> +               efuse_data0_reg = EFUSE_DATA0_3290;
>> +               efuse_data1_reg = EFUSE_DATA1_3290;
>> +               efuse_data2_reg = EFUSE_DATA2_3290;
>> +               efuse_data3_reg = EFUSE_DATA3_3290;
>> +       } else {
>> +               efuse_ctrl_reg = EFUSE_CTRL;
>> +               efuse_data0_reg = EFUSE_DATA0;
>> +               efuse_data1_reg = EFUSE_DATA1;
>> +               efuse_data2_reg = EFUSE_DATA2;
>> +               efuse_data3_reg = EFUSE_DATA3;
>> +       }
>>        mutex_lock(&rt2x00dev->csr_mutex);
>>
>> -       rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, &reg);
>> +       rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, &reg);
>>        rt2x00_set_field32(&reg, EFUSE_CTRL_ADDRESS_IN, i);
>>        rt2x00_set_field32(&reg, EFUSE_CTRL_MODE, 0);
>>        rt2x00_set_field32(&reg, EFUSE_CTRL_KICK, 1);
>> -       rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg);
>> +       rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg);
>>
>>        /* Wait until the EEPROM has been loaded */
>> -       rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, &reg);
>> -
>> +       rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, &reg);
>>        /* Apparently the data is read from end to start */
>> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
>> +       rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, &reg);
>>        /* The returned value is in CPU order, but eeprom is le */
>>        *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
>> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
>> +       rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, &reg);
>>        *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
>> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
>> +       rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, &reg);
>>        *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg);
>> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, &reg);
>> +       rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, &reg);
>>        *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg);
>>
>>        mutex_unlock(&rt2x00dev->csr_mutex);
>> @@ -4244,9 +4475,14 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>>         * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field
>>         * RT53xx: defined in "EEPROM_CHIP_ID" field
>>         */
>> -       rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
>> -       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
>> -               rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
>> +       if (rt2x00_rt(rt2x00dev, RT3290))
>> +               rt2800_register_read(rt2x00dev, MAC_CSR0_3290, &reg);
>> +       else
>> +               rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
>> +
>> +       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 ||
>> +           rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
>> +           rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
>>                rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
>>        else
>>                value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
>> @@ -4261,6 +4497,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>>        case RT3070:
>>        case RT3071:
>>        case RT3090:
>> +       case RT3290:
>>        case RT3390:
>>        case RT3572:
>>        case RT5390:
>> @@ -4281,6 +4518,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>>        case RF3021:
>>        case RF3022:
>>        case RF3052:
>> +       case RF3290:
>>        case RF3320:
>>        case RF5360:
>>        case RF5370:
>> @@ -4597,6 +4835,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>>                   rt2x00_rf(rt2x00dev, RF2020) ||
>>                   rt2x00_rf(rt2x00dev, RF3021) ||
>>                   rt2x00_rf(rt2x00dev, RF3022) ||
>> +                  rt2x00_rf(rt2x00dev, RF3290) ||
>>                   rt2x00_rf(rt2x00dev, RF3320) ||
>>                   rt2x00_rf(rt2x00dev, RF5360) ||
>>                   rt2x00_rf(rt2x00dev, RF5370) ||
>> @@ -4685,6 +4924,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>>        case RF3022:
>>        case RF3320:
>>        case RF3052:
>> +       case RF3290:
>>        case RF5360:
>>        case RF5370:
>>        case RF5372:
>> diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
>> index 206158b..dd43612 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800pci.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
>> @@ -280,7 +280,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
>>  */
>>  static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
>>  {
>> -       return FIRMWARE_RT2860;
>> +       /*
>> +        * Chip rt3290 use specific 4KB firmware named rt3290.bin.
>> +        */
>> +       if (rt2x00_rt(rt2x00dev, RT3290))
>> +               return FIRMWARE_RT3290;
>> +       else
>> +               return FIRMWARE_RT2860;
>>  }
>>
>>  static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
>> @@ -974,6 +980,66 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
>>        return rt2800_validate_eeprom(rt2x00dev);
>>  }
>>
>> +static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
>> +{
>> +       u32 reg;
>> +       int i, count;
>> +
>> +       rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
>> +       if ((rt2x00_get_field32(reg, WLAN_EN) == 1))
>> +               return 0;
>> +
>> +       rt2x00_set_field32(&reg, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
>> +       rt2x00_set_field32(&reg, FRC_WL_ANT_SET, 1);
>> +       rt2x00_set_field32(&reg, WLAN_CLK_EN, 0);
>> +       rt2x00_set_field32(&reg, WLAN_EN, 1);
>> +       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
>> +
>> +       udelay(REGISTER_BUSY_DELAY);
>> +
>> +       count = 0;
>> +       do {
>> +               /*
>> +                * Check PLL_LD & XTAL_RDY.
>> +                */
>> +               for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
>> +                       rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
>> +                       if ((rt2x00_get_field32(reg, PLL_LD) == 1) &&
>> +                               (rt2x00_get_field32(reg, XTAL_RDY) == 1))
>> +                                       break;
>> +                       udelay(REGISTER_BUSY_DELAY);
>> +               }
>> +
>> +               if (i >= REGISTER_BUSY_COUNT) {
>> +
>> +                       if (count >= 10)
>> +                               return -EIO;
>> +
>> +                       rt2800_register_write(rt2x00dev, 0x58, 0x018);
>> +                       udelay(REGISTER_BUSY_DELAY);
>> +                       rt2800_register_write(rt2x00dev, 0x58, 0x418);
>> +                       udelay(REGISTER_BUSY_DELAY);
>> +                       rt2800_register_write(rt2x00dev, 0x58, 0x618);
>> +                       udelay(REGISTER_BUSY_DELAY);
>> +                       count++;
>> +               } else {
>> +                       count = 0;
>> +               }
>> +
>> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
>> +               rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 0);
>> +               rt2x00_set_field32(&reg, WLAN_CLK_EN, 1);
>> +               rt2x00_set_field32(&reg, WLAN_RESET, 1);
>> +               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
>> +               udelay(10);
>> +               rt2x00_set_field32(&reg, WLAN_RESET, 0);
>> +               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
>> +               udelay(10);
>> +               rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
>> +       } while (count != 0);
>> +
>> +       return 0;
>> +}
>>  static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
>>  {
>>        int retval;
>> @@ -997,6 +1063,17 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
>>                return retval;
>>
>>        /*
>> +        * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan
>> +        * clk for rt3290. That avoid the MCU fail in start phase.
>> +        */
>> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
>> +               retval = rt2800_enable_wlan_rt3290(rt2x00dev);
>> +
>> +               if (retval)
>> +                       return retval;
>> +       }
>> +
>> +       /*
>>         * This device has multiple filters for control frames
>>         * and has a separate filter for PS Poll frames.
>>         */
>> @@ -1175,6 +1252,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
>>        { PCI_DEVICE(0x1432, 0x7768) },
>>        { PCI_DEVICE(0x1462, 0x891a) },
>>        { PCI_DEVICE(0x1a3b, 0x1059) },
>> +#ifdef CONFIG_RT2800PCI_RT3290
>> +       { PCI_DEVICE(0x1814, 0x3290) },
>> +#endif
>>  #ifdef CONFIG_RT2800PCI_RT33XX
>>        { PCI_DEVICE(0x1814, 0x3390) },
>>  #endif
>> diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
>> index 70e050d..ab22a08 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800pci.h
>> +++ b/drivers/net/wireless/rt2x00/rt2800pci.h
>> @@ -47,6 +47,7 @@
>>  * 8051 firmware image.
>>  */
>>  #define FIRMWARE_RT2860                        "rt2860.bin"
>> +#define FIRMWARE_RT3290                        "rt3290.bin"
>>  #define FIRMWARE_IMAGE_BASE            0x2000
>>
>>  /*
>> diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
>> index 8f75402..8afb546 100644
>> --- a/drivers/net/wireless/rt2x00/rt2x00.h
>> +++ b/drivers/net/wireless/rt2x00/rt2x00.h
>> @@ -187,6 +187,7 @@ struct rt2x00_chip {
>>  #define RT3070         0x3070
>>  #define RT3071         0x3071
>>  #define RT3090         0x3090  /* 2.4GHz PCIe */
>> +#define RT3290         0x3290
>>  #define RT3390         0x3390
>>  #define RT3572         0x3572
>>  #define RT3593         0x3593
>> diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
>> index 0a4653a..a0c8cae 100644
>> --- a/drivers/net/wireless/rt2x00/rt2x00pci.c
>> +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
>> @@ -256,6 +256,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
>>        struct ieee80211_hw *hw;
>>        struct rt2x00_dev *rt2x00dev;
>>        int retval;
>> +       u16 chip;
>>
>>        retval = pci_enable_device(pci_dev);
>>        if (retval) {
>> @@ -305,6 +306,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
>>        if (retval)
>>                goto exit_free_device;
>>
>> +       /*
>> +        * Because rt3290 chip use different efuse offset to read efuse data.
>> +        * So before read efuse it need to indicate it is the
>> +        * rt3290 or not.
>> +        */
>> +       pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
>> +       rt2x00dev->chip.rt = chip;
>> +
>>        retval = rt2x00lib_probe_dev(rt2x00dev);
>>        if (retval)
>>                goto exit_free_reg;
>> --
>> 1.7.5.4
>>
>>
>> _______________________________________________
>> users mailing list
>> users@rt2x00.serialmonkey.com
>> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
>>
>
>
>
> --
> Thank you.



-- 
Thank you.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [rt2x00-users] [PATCH] rt2x00 : RT3290 chip support v4
  2012-06-13  7:01 Woody Hung
@ 2012-06-21  2:46 ` Matt Chen
  2012-06-21  3:34   ` Matt Chen
  2012-06-22  7:45 ` Helmut Schaa
  1 sibling, 1 reply; 7+ messages in thread
From: Matt Chen @ 2012-06-21  2:46 UTC (permalink / raw)
  To: Woody Hung; +Cc: linville, linux-wireless, users

Tested-by: Matt Chen <machen@suse.de>

2012/6/13 Woody Hung <Woody.Hung@mediatek.com>:
> This patch support the new chipset rt3290 wifi implementation in rt2x00.
> It initailize the related mac, bbp and rf register in startup phase.
> And this patch modify the efuse read/write method for the different efuse data offset of rt3290.
>
> Signed-off-by: Woody Hung <Woody.Hung@mediatek.com>
> ---
>  drivers/net/wireless/rt2x00/Kconfig     |    8 +
>  drivers/net/wireless/rt2x00/rt2800.h    |  173 +++++++++++++++-
>  drivers/net/wireless/rt2x00/rt2800lib.c |  350 ++++++++++++++++++++++++++-----
>  drivers/net/wireless/rt2x00/rt2800pci.c |   82 +++++++-
>  drivers/net/wireless/rt2x00/rt2800pci.h |    1 +
>  drivers/net/wireless/rt2x00/rt2x00.h    |    1 +
>  drivers/net/wireless/rt2x00/rt2x00pci.c |    9 +
>  7 files changed, 567 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
> index 299c387..c7548da 100644
> --- a/drivers/net/wireless/rt2x00/Kconfig
> +++ b/drivers/net/wireless/rt2x00/Kconfig
> @@ -99,6 +99,14 @@ config RT2800PCI_RT53XX
>          rt2800pci driver.
>          Supported chips: RT5390
>
> +config RT2800PCI_RT3290
> +       bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)"
> +       depends on EXPERIMENTAL
> +       default y
> +       ---help---
> +         This adds support for rt3290 wireless chipset family to the
> +         rt2800pci driver.
> +         Supported chips: RT3290
>  endif
>
>  config RT2500USB
> diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
> index 1ca88cd..e252e9b 100644
> --- a/drivers/net/wireless/rt2x00/rt2800.h
> +++ b/drivers/net/wireless/rt2x00/rt2800.h
> @@ -68,6 +68,7 @@
>  #define RF3320                         0x000b
>  #define RF3322                         0x000c
>  #define RF3053                         0x000d
> +#define RF3290                         0x3290
>  #define RF5360                         0x5360
>  #define RF5370                         0x5370
>  #define RF5372                         0x5372
> @@ -117,6 +118,12 @@
>  * Registers.
>  */
>
> +
> +/*
> + * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number.
> + */
> +#define MAC_CSR0_3290                          0x0000
> +
>  /*
>  * E2PROM_CSR: PCI EEPROM control register.
>  * RELOAD: Write 1 to reload eeprom content.
> @@ -133,6 +140,150 @@
>  #define E2PROM_CSR_RELOAD              FIELD32(0x00000080)
>
>  /*
> + * CMB_CTRL_CFG
> + */
> +#define CMB_CTRL               0x0020
> +#define AUX_OPT_BIT0           FIELD32(0x00000001)
> +#define AUX_OPT_BIT1           FIELD32(0x00000002)
> +#define AUX_OPT_BIT2           FIELD32(0x00000004)
> +#define AUX_OPT_BIT3           FIELD32(0x00000008)
> +#define AUX_OPT_BIT4           FIELD32(0x00000010)
> +#define AUX_OPT_BIT5           FIELD32(0x00000020)
> +#define AUX_OPT_BIT6           FIELD32(0x00000040)
> +#define AUX_OPT_BIT7           FIELD32(0x00000080)
> +#define AUX_OPT_BIT8           FIELD32(0x00000100)
> +#define AUX_OPT_BIT9           FIELD32(0x00000200)
> +#define AUX_OPT_BIT10          FIELD32(0x00000400)
> +#define AUX_OPT_BIT11          FIELD32(0x00000800)
> +#define AUX_OPT_BIT12          FIELD32(0x00001000)
> +#define AUX_OPT_BIT13          FIELD32(0x00002000)
> +#define AUX_OPT_BIT14          FIELD32(0x00004000)
> +#define AUX_OPT_BIT15          FIELD32(0x00008000)
> +#define LDO25_LEVEL            FIELD32(0x00030000)
> +#define LDO25_LARGEA           FIELD32(0x00040000)
> +#define LDO25_FRC_ON           FIELD32(0x00080000)
> +#define CMB_RSV                        FIELD32(0x00300000)
> +#define XTAL_RDY               FIELD32(0x00400000)
> +#define PLL_LD                 FIELD32(0x00800000)
> +#define LDO_CORE_LEVEL         FIELD32(0x0F000000)
> +#define LDO_BGSEL              FIELD32(0x30000000)
> +#define LDO3_EN                        FIELD32(0x40000000)
> +#define LDO0_EN                        FIELD32(0x80000000)
> +
> +/*
> + * EFUSE_CSR_3290: RT3290 EEPROM
> + */
> +#define EFUSE_CTRL_3290                        0x0024
> +
> +/*
> + * EFUSE_DATA3 of 3290
> + */
> +#define EFUSE_DATA3_3290               0x0028
> +
> +/*
> + * EFUSE_DATA2 of 3290
> + */
> +#define EFUSE_DATA2_3290               0x002c
> +
> +/*
> + * EFUSE_DATA1 of 3290
> + */
> +#define EFUSE_DATA1_3290               0x0030
> +
> +/*
> + * EFUSE_DATA0 of 3290
> + */
> +#define EFUSE_DATA0_3290               0x0034
> +
> +/*
> + * OSC_CTRL_CFG
> + * Ring oscillator configuration
> + */
> +#define OSC_CTRL               0x0038
> +#define OSC_REF_CYCLE          FIELD32(0x00001fff)
> +#define OSC_RSV                        FIELD32(0x0000e000)
> +#define OSC_CAL_CNT            FIELD32(0x0fff0000)
> +#define OSC_CAL_ACK            FIELD32(0x10000000)
> +#define OSC_CLK_32K_VLD                FIELD32(0x20000000)
> +#define OSC_CAL_REQ            FIELD32(0x40000000)
> +#define OSC_ROSC_EN            FIELD32(0x80000000)
> +
> +/*
> + * COEX_CFG_0
> + */
> +#define COEX_CFG0                      0x0040
> +#define COEX_CFG_ANT           FIELD32(0xff000000)
> +/*
> + * COEX_CFG_1
> + */
> +#define COEX_CFG1                      0x0044
> +
> +/*
> + * COEX_CFG_2
> + */
> +#define COEX_CFG2                      0x0048
> +#define BT_COEX_CFG1           FIELD32(0xff000000)
> +#define BT_COEX_CFG0           FIELD32(0x00ff0000)
> +#define WL_COEX_CFG1           FIELD32(0x0000ff00)
> +#define WL_COEX_CFG0           FIELD32(0x000000ff)
> +/*
> + * PLL_CTRL_CFG
> + * PLL configuration register
> + */
> +#define PLL_CTRL               0x0050
> +#define PLL_RESERVED_INPUT1    FIELD32(0x000000ff)
> +#define PLL_RESERVED_INPUT2    FIELD32(0x0000ff00)
> +#define PLL_CONTROL            FIELD32(0x00070000)
> +#define PLL_LPF_R1             FIELD32(0x00080000)
> +#define PLL_LPF_C1_CTRL        FIELD32(0x00300000)
> +#define PLL_LPF_C2_CTRL        FIELD32(0x00c00000)
> +#define PLL_CP_CURRENT_CTRL    FIELD32(0x03000000)
> +#define PLL_PFD_DELAY_CTRL     FIELD32(0x0c000000)
> +#define PLL_LOCK_CTRL          FIELD32(0x70000000)
> +#define PLL_VBGBK_EN           FIELD32(0x80000000)
> +
> +
> +/*
> + * WLAN_CTRL_CFG
> + * RT3290 wlan configuration
> + */
> +#define WLAN_FUN_CTRL                  0x0080
> +#define WLAN_EN                                FIELD32(0x00000001)
> +#define WLAN_CLK_EN                    FIELD32(0x00000002)
> +#define WLAN_RSV1                      FIELD32(0x00000004)
> +#define WLAN_RESET                     FIELD32(0x00000008)
> +#define PCIE_APP0_CLK_REQ              FIELD32(0x00000010)
> +#define FRC_WL_ANT_SET                 FIELD32(0x00000020)
> +#define INV_TR_SW0                     FIELD32(0x00000040)
> +#define WLAN_GPIO_IN_BIT0              FIELD32(0x00000100)
> +#define WLAN_GPIO_IN_BIT1              FIELD32(0x00000200)
> +#define WLAN_GPIO_IN_BIT2              FIELD32(0x00000400)
> +#define WLAN_GPIO_IN_BIT3              FIELD32(0x00000800)
> +#define WLAN_GPIO_IN_BIT4              FIELD32(0x00001000)
> +#define WLAN_GPIO_IN_BIT5              FIELD32(0x00002000)
> +#define WLAN_GPIO_IN_BIT6              FIELD32(0x00004000)
> +#define WLAN_GPIO_IN_BIT7              FIELD32(0x00008000)
> +#define WLAN_GPIO_IN_BIT_ALL           FIELD32(0x0000ff00)
> +#define WLAN_GPIO_OUT_BIT0             FIELD32(0x00010000)
> +#define WLAN_GPIO_OUT_BIT1             FIELD32(0x00020000)
> +#define WLAN_GPIO_OUT_BIT2             FIELD32(0x00040000)
> +#define WLAN_GPIO_OUT_BIT3             FIELD32(0x00050000)
> +#define WLAN_GPIO_OUT_BIT4             FIELD32(0x00100000)
> +#define WLAN_GPIO_OUT_BIT5             FIELD32(0x00200000)
> +#define WLAN_GPIO_OUT_BIT6             FIELD32(0x00400000)
> +#define WLAN_GPIO_OUT_BIT7             FIELD32(0x00800000)
> +#define WLAN_GPIO_OUT_BIT_ALL          FIELD32(0x00ff0000)
> +#define WLAN_GPIO_OUT_OE_BIT0          FIELD32(0x01000000)
> +#define WLAN_GPIO_OUT_OE_BIT1          FIELD32(0x02000000)
> +#define WLAN_GPIO_OUT_OE_BIT2          FIELD32(0x04000000)
> +#define WLAN_GPIO_OUT_OE_BIT3          FIELD32(0x08000000)
> +#define WLAN_GPIO_OUT_OE_BIT4          FIELD32(0x10000000)
> +#define WLAN_GPIO_OUT_OE_BIT5          FIELD32(0x20000000)
> +#define WLAN_GPIO_OUT_OE_BIT6          FIELD32(0x40000000)
> +#define WLAN_GPIO_OUT_OE_BIT7          FIELD32(0x80000000)
> +#define WLAN_GPIO_OUT_OE_BIT_ALL       FIELD32(0xff000000)
> +
> +/*
>  * AUX_CTRL: Aux/PCI-E related configuration
>  */
>  #define AUX_CTRL                       0x10c
> @@ -1763,9 +1914,11 @@ struct mac_iveiv_entry {
>  /*
>  * BBP 3: RX Antenna
>  */
> -#define BBP3_RX_ADC                            FIELD8(0x03)
> +#define BBP3_RX_ADC                    FIELD8(0x03)
>  #define BBP3_RX_ANTENNA                        FIELD8(0x18)
>  #define BBP3_HT40_MINUS                        FIELD8(0x20)
> +#define BBP3_ADC_MODE_SWITCH           FIELD8(0x40)
> +#define BBP3_ADC_INIT_MODE             FIELD8(0x80)
>
>  /*
>  * BBP 4: Bandwidth
> @@ -1775,6 +1928,14 @@ struct mac_iveiv_entry {
>  #define BBP4_MAC_IF_CTRL               FIELD8(0x40)
>
>  /*
> + * BBP 47: Bandwidth
> + */
> +#define BBP47_TSSI_REPORT_SEL          FIELD8(0x03)
> +#define BBP47_TSSI_UPDATE_REQ          FIELD8(0x04)
> +#define BBP47_TSSI_TSSI_MODE           FIELD8(0x18)
> +#define BBP47_TSSI_ADC6                        FIELD8(0x80)
> +
> +/*
>  * BBP 109
>  */
>  #define BBP109_TX0_POWER               FIELD8(0x0f)
> @@ -1917,6 +2078,16 @@ struct mac_iveiv_entry {
>  #define RFCSR27_R4                     FIELD8(0x40)
>
>  /*
> + * RFCSR 29:
> + */
> +#define RFCSR29_ADC6_TEST              FIELD8(0x01)
> +#define RFCSR29_ADC6_INT_TEST          FIELD8(0x02)
> +#define RFCSR29_RSSI_RESET             FIELD8(0x04)
> +#define RFCSR29_RSSI_ON                        FIELD8(0x08)
> +#define RFCSR29_RSSI_RIP_CTRL          FIELD8(0x30)
> +#define RFCSR29_RSSI_GAIN              FIELD8(0xc0)
> +
> +/*
>  * RFCSR 30:
>  */
>  #define RFCSR30_TX_H20M                        FIELD8(0x02)
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 4d3747c..068276e 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -354,16 +354,15 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev,
>         * of 4kb. Certain USB chipsets however require different firmware,
>         * which Ralink only provides attached to the original firmware
>         * file. Thus for USB devices, firmware files have a length
> -        * which is a multiple of 4kb.
> +        * which is a multiple of 4kb. The firmware for rt3290 chip also
> +        * have a length which is a multiple of 4kb.
>         */
> -       if (rt2x00_is_usb(rt2x00dev)) {
> +       if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290))
>                fw_len = 4096;
> -               multiple = true;
> -       } else {
> +       else
>                fw_len = 8192;
> -               multiple = true;
> -       }
>
> +       multiple = true;
>        /*
>         * Validate the firmware length
>         */
> @@ -415,7 +414,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
>                return -EBUSY;
>
>        if (rt2x00_is_pci(rt2x00dev)) {
> -               if (rt2x00_rt(rt2x00dev, RT3572) ||
> +               if (rt2x00_rt(rt2x00dev, RT3290) ||
> +                   rt2x00_rt(rt2x00dev, RT3572) ||
>                    rt2x00_rt(rt2x00dev, RT5390) ||
>                    rt2x00_rt(rt2x00dev, RT5392)) {
>                        rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
> @@ -851,8 +851,13 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
>  {
>        u32 reg;
>
> -       rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
> -       return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
> +               return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0);
> +       } else {
> +               rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
> +               return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
> +       }
>  }
>  EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
>
> @@ -1935,9 +1940,54 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
>        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
>  }
>
> +#define RT3290_POWER_BOUND     0x27
> +#define RT3290_FREQ_OFFSET_BOUND       0x5f
>  #define RT5390_POWER_BOUND     0x27
>  #define RT5390_FREQ_OFFSET_BOUND       0x5f
>
> +static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
> +                                        struct ieee80211_conf *conf,
> +                                        struct rf_channel *rf,
> +                                        struct channel_info *info)
> +{
> +       u8 rfcsr;
> +
> +       rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
> +       rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
> +       rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
> +       rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2);
> +       rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
> +
> +       rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
> +       if (info->default_power1 > RT3290_POWER_BOUND)
> +               rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT3290_POWER_BOUND);
> +       else
> +               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 > RT3290_FREQ_OFFSET_BOUND)
> +               rt2x00_set_field8(&rfcsr, RFCSR17_CODE,
> +                                 RT3290_FREQ_OFFSET_BOUND);
> +       else
> +               rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
> +       rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
> +
> +       if (rf->channel <= 14) {
> +               if (rf->channel == 6)
> +                       rt2800_bbp_write(rt2x00dev, 68, 0x0c);
> +               else
> +                       rt2800_bbp_write(rt2x00dev, 68, 0x0b);
> +
> +               if (rf->channel >= 1 && rf->channel <= 6)
> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0f);
> +               else if (rf->channel >= 7 && rf->channel <= 11)
> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0e);
> +               else if (rf->channel >= 12 && rf->channel <= 14)
> +                       rt2800_bbp_write(rt2x00dev, 59, 0x0d);
> +       }
> +}
> +
>  static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
>                                         struct ieee80211_conf *conf,
>                                         struct rf_channel *rf,
> @@ -2036,15 +2086,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
>                        }
>                }
>        }
> -
> -       rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
> -       rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
> -       rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
> -       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> -
> -       rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
> -       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
> -       rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
>  }
>
>  static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
> @@ -2054,7 +2095,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>  {
>        u32 reg;
>        unsigned int tx_pin;
> -       u8 bbp;
> +       u8 bbp, rfcsr;
>
>        if (rf->channel <= 14) {
>                info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
> @@ -2075,6 +2116,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>        case RF3052:
>                rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
>                break;
> +       case RF3290:
> +               rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
> +               break;
>        case RF5360:
>        case RF5370:
>        case RF5372:
> @@ -2086,6 +2130,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
>                rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
>        }
>
> +       if (rt2x00_rf(rt2x00dev, RF3290) ||
> +           rt2x00_rf(rt2x00dev, RF5360) ||
> +           rt2x00_rf(rt2x00dev, RF5370) ||
> +           rt2x00_rf(rt2x00dev, RF5372) ||
> +           rt2x00_rf(rt2x00dev, RF5390) ||
> +           rt2x00_rf(rt2x00dev, RF5392)) {
> +               rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
> +               rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
> +               rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
> +               rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
> +
> +               rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
> +               rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
> +               rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
> +       }
> +
>        /*
>         * Change BBP settings
>         */
> @@ -2566,6 +2626,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
>                rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
>                rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
>                break;
> +       case RF3290:
>        case RF5360:
>        case RF5370:
>        case RF5372:
> @@ -2701,6 +2762,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
>                if (rt2x00_rt(rt2x00dev, RT3070) ||
>                    rt2x00_rt(rt2x00dev, RT3071) ||
>                    rt2x00_rt(rt2x00dev, RT3090) ||
> +                   rt2x00_rt(rt2x00dev, RT3290) ||
>                    rt2x00_rt(rt2x00dev, RT3390) ||
>                    rt2x00_rt(rt2x00dev, RT5390) ||
>                    rt2x00_rt(rt2x00dev, RT5392))
> @@ -2797,10 +2859,54 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
>        rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
>        rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
>
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
> +               if (rt2x00_get_field32(reg, WLAN_EN) == 1) {
> +                       rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 1);
> +                       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
> +               }
> +
> +               rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
> +               if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) {
> +                       rt2x00_set_field32(&reg, LDO0_EN, 1);
> +                       rt2x00_set_field32(&reg, LDO_BGSEL, 3);
> +                       rt2800_register_write(rt2x00dev, CMB_CTRL, reg);
> +               }
> +
> +               rt2800_register_read(rt2x00dev, OSC_CTRL, &reg);
> +               rt2x00_set_field32(&reg, OSC_ROSC_EN, 1);
> +               rt2x00_set_field32(&reg, OSC_CAL_REQ, 1);
> +               rt2x00_set_field32(&reg, OSC_REF_CYCLE, 0x27);
> +               rt2800_register_write(rt2x00dev, OSC_CTRL, reg);
> +
> +               rt2800_register_read(rt2x00dev, COEX_CFG0, &reg);
> +               rt2x00_set_field32(&reg, COEX_CFG_ANT, 0x5e);
> +               rt2800_register_write(rt2x00dev, COEX_CFG0, reg);
> +
> +               rt2800_register_read(rt2x00dev, COEX_CFG2, &reg);
> +               rt2x00_set_field32(&reg, BT_COEX_CFG1, 0x00);
> +               rt2x00_set_field32(&reg, BT_COEX_CFG0, 0x17);
> +               rt2x00_set_field32(&reg, WL_COEX_CFG1, 0x93);
> +               rt2x00_set_field32(&reg, WL_COEX_CFG0, 0x7f);
> +               rt2800_register_write(rt2x00dev, COEX_CFG2, reg);
> +
> +               rt2800_register_read(rt2x00dev, PLL_CTRL, &reg);
> +               rt2x00_set_field32(&reg, PLL_CONTROL, 1);
> +               rt2800_register_write(rt2x00dev, PLL_CTRL, reg);
> +       }
> +
>        if (rt2x00_rt(rt2x00dev, RT3071) ||
>            rt2x00_rt(rt2x00dev, RT3090) ||
> +           rt2x00_rt(rt2x00dev, RT3290) ||
>            rt2x00_rt(rt2x00dev, RT3390)) {
> -               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
> +
> +               if (rt2x00_rt(rt2x00dev, RT3290))
> +                       rt2800_register_write(rt2x00dev, TX_SW_CFG0,
> +                                             0x00000404);
> +               else
> +                       rt2800_register_write(rt2x00dev, TX_SW_CFG0,
> +                                             0x00000400);
> +
>                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
>                if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
>                    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
> @@ -3209,14 +3315,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>                     rt2800_wait_bbp_ready(rt2x00dev)))
>                return -EACCES;
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392)) {
> +       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);
>        }
>
>        if (rt2800_is_305x_soc(rt2x00dev) ||
> +           rt2x00_rt(rt2x00dev, RT3290) ||
>            rt2x00_rt(rt2x00dev, RT3572) ||
>            rt2x00_rt(rt2x00dev, RT5390) ||
>            rt2x00_rt(rt2x00dev, RT5392))
> @@ -3225,20 +3333,26 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>        rt2800_bbp_write(rt2x00dev, 65, 0x2c);
>        rt2800_bbp_write(rt2x00dev, 66, 0x38);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 68, 0x0b);
>
>        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
>                rt2800_bbp_write(rt2x00dev, 69, 0x16);
>                rt2800_bbp_write(rt2x00dev, 73, 0x12);
> -       } else if (rt2x00_rt(rt2x00dev, RT5390) ||
> -                          rt2x00_rt(rt2x00dev, RT5392)) {
> +       } else if (rt2x00_rt(rt2x00dev, RT3290) ||
> +                  rt2x00_rt(rt2x00dev, RT5390) ||
> +                  rt2x00_rt(rt2x00dev, RT5392)) {
>                rt2800_bbp_write(rt2x00dev, 69, 0x12);
>                rt2800_bbp_write(rt2x00dev, 73, 0x13);
>                rt2800_bbp_write(rt2x00dev, 75, 0x46);
>                rt2800_bbp_write(rt2x00dev, 76, 0x28);
> -               rt2800_bbp_write(rt2x00dev, 77, 0x59);
> +
> +               if (rt2x00_rt(rt2x00dev, RT3290))
> +                       rt2800_bbp_write(rt2x00dev, 77, 0x58);
> +               else
> +                       rt2800_bbp_write(rt2x00dev, 77, 0x59);
>        } else {
>                rt2800_bbp_write(rt2x00dev, 69, 0x12);
>                rt2800_bbp_write(rt2x00dev, 73, 0x10);
> @@ -3263,23 +3377,33 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>                rt2800_bbp_write(rt2x00dev, 81, 0x37);
>        }
>
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_bbp_write(rt2x00dev, 74, 0x0b);
> +               rt2800_bbp_write(rt2x00dev, 79, 0x18);
> +               rt2800_bbp_write(rt2x00dev, 80, 0x09);
> +               rt2800_bbp_write(rt2x00dev, 81, 0x33);
> +       }
> +
>        rt2800_bbp_write(rt2x00dev, 82, 0x62);
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 83, 0x7a);
>        else
>                rt2800_bbp_write(rt2x00dev, 83, 0x6a);
>
>        if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
>                rt2800_bbp_write(rt2x00dev, 84, 0x19);
> -       else if (rt2x00_rt(rt2x00dev, RT5390) ||
> -                        rt2x00_rt(rt2x00dev, RT5392))
> +       else if (rt2x00_rt(rt2x00dev, RT3290) ||
> +                    rt2x00_rt(rt2x00dev, RT5390) ||
> +                    rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 84, 0x9a);
>        else
>                rt2800_bbp_write(rt2x00dev, 84, 0x99);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 86, 0x38);
>        else
>                rt2800_bbp_write(rt2x00dev, 86, 0x00);
> @@ -3289,8 +3413,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>
>        rt2800_bbp_write(rt2x00dev, 91, 0x04);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 92, 0x02);
>        else
>                rt2800_bbp_write(rt2x00dev, 92, 0x00);
> @@ -3304,6 +3429,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>            rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
>            rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
>            rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
> +           rt2x00_rt(rt2x00dev, RT3290) ||
>            rt2x00_rt(rt2x00dev, RT3572) ||
>            rt2x00_rt(rt2x00dev, RT5390) ||
>            rt2x00_rt(rt2x00dev, RT5392) ||
> @@ -3312,27 +3438,32 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>        else
>                rt2800_bbp_write(rt2x00dev, 103, 0x00);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 104, 0x92);
>
>        if (rt2800_is_305x_soc(rt2x00dev))
>                rt2800_bbp_write(rt2x00dev, 105, 0x01);
> +       else if (rt2x00_rt(rt2x00dev, RT3290))
> +               rt2800_bbp_write(rt2x00dev, 105, 0x1c);
>        else if (rt2x00_rt(rt2x00dev, RT5390) ||
>                         rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 105, 0x3c);
>        else
>                rt2800_bbp_write(rt2x00dev, 105, 0x05);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390))
>                rt2800_bbp_write(rt2x00dev, 106, 0x03);
>        else if (rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 106, 0x12);
>        else
>                rt2800_bbp_write(rt2x00dev, 106, 0x35);
>
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392))
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392))
>                rt2800_bbp_write(rt2x00dev, 128, 0x12);
>
>        if (rt2x00_rt(rt2x00dev, RT5392)) {
> @@ -3357,6 +3488,29 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
>                rt2800_bbp_write(rt2x00dev, 138, value);
>        }
>
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_bbp_write(rt2x00dev, 67, 0x24);
> +               rt2800_bbp_write(rt2x00dev, 143, 0x04);
> +               rt2800_bbp_write(rt2x00dev, 142, 0x99);
> +               rt2800_bbp_write(rt2x00dev, 150, 0x30);
> +               rt2800_bbp_write(rt2x00dev, 151, 0x2e);
> +               rt2800_bbp_write(rt2x00dev, 152, 0x20);
> +               rt2800_bbp_write(rt2x00dev, 153, 0x34);
> +               rt2800_bbp_write(rt2x00dev, 154, 0x40);
> +               rt2800_bbp_write(rt2x00dev, 155, 0x3b);
> +               rt2800_bbp_write(rt2x00dev, 253, 0x04);
> +
> +               rt2800_bbp_read(rt2x00dev, 47, &value);
> +               rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
> +               rt2800_bbp_write(rt2x00dev, 47, value);
> +
> +               /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
> +               rt2800_bbp_read(rt2x00dev, 3, &value);
> +               rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
> +               rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
> +               rt2800_bbp_write(rt2x00dev, 3, value);
> +       }
> +
>        if (rt2x00_rt(rt2x00dev, RT5390) ||
>                rt2x00_rt(rt2x00dev, RT5392)) {
>                int ant, div_mode;
> @@ -3489,6 +3643,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>        if (!rt2x00_rt(rt2x00dev, RT3070) &&
>            !rt2x00_rt(rt2x00dev, RT3071) &&
>            !rt2x00_rt(rt2x00dev, RT3090) &&
> +           !rt2x00_rt(rt2x00dev, RT3290) &&
>            !rt2x00_rt(rt2x00dev, RT3390) &&
>            !rt2x00_rt(rt2x00dev, RT3572) &&
>            !rt2x00_rt(rt2x00dev, RT5390) &&
> @@ -3499,8 +3654,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>        /*
>         * Init RF calibration.
>         */
> -       if (rt2x00_rt(rt2x00dev, RT5390) ||
> -               rt2x00_rt(rt2x00dev, RT5392)) {
> +       if (rt2x00_rt(rt2x00dev, RT3290) ||
> +           rt2x00_rt(rt2x00dev, RT5390) ||
> +           rt2x00_rt(rt2x00dev, RT5392)) {
>                rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
>                rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
>                rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
> @@ -3538,6 +3694,53 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>                rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
>                rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
>                rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
> +       } else if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
> +               rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
> +               rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
> +               rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
> +               rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
> +               rt2800_rfcsr_write(rt2x00dev, 8, 0xf3);
> +               rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
> +               rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
> +               rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
> +               rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
> +               rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
> +               rt2800_rfcsr_write(rt2x00dev, 18, 0x02);
> +               rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
> +               rt2800_rfcsr_write(rt2x00dev, 25, 0x83);
> +               rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
> +               rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
> +               rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
> +               rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
> +               rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
> +               rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
> +               rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
> +               rt2800_rfcsr_write(rt2x00dev, 34, 0x05);
> +               rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
> +               rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
> +               rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
> +               rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
> +               rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
> +               rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
> +               rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
> +               rt2800_rfcsr_write(rt2x00dev, 43, 0x7b);
> +               rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
> +               rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
> +               rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
> +               rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
> +               rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
> +               rt2800_rfcsr_write(rt2x00dev, 49, 0x98);
> +               rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
> +               rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
> +               rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
> +               rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
> +               rt2800_rfcsr_write(rt2x00dev, 56, 0x02);
> +               rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
> +               rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
> +               rt2800_rfcsr_write(rt2x00dev, 59, 0x09);
> +               rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
> +               rt2800_rfcsr_write(rt2x00dev, 61, 0xc1);
>        } else if (rt2x00_rt(rt2x00dev, RT3390)) {
>                rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
>                rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
> @@ -3946,6 +4149,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
>                rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
>        }
>
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr);
> +               rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3);
> +               rt2800_rfcsr_write(rt2x00dev, 29, rfcsr);
> +       }
> +
>        if (rt2x00_rt(rt2x00dev, RT5390) ||
>                rt2x00_rt(rt2x00dev, RT5392)) {
>                rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
> @@ -4052,9 +4261,14 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio);
>  int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
>  {
>        u32 reg;
> +       u16 efuse_ctrl_reg;
>
> -       rt2800_register_read(rt2x00dev, EFUSE_CTRL, &reg);
> +       if (rt2x00_rt(rt2x00dev, RT3290))
> +               efuse_ctrl_reg = EFUSE_CTRL_3290;
> +       else
> +               efuse_ctrl_reg = EFUSE_CTRL;
>
> +       rt2800_register_read(rt2x00dev, efuse_ctrl_reg, &reg);
>        return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT);
>  }
>  EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
> @@ -4062,27 +4276,44 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
>  static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
>  {
>        u32 reg;
> -
> +       u16 efuse_ctrl_reg;
> +       u16 efuse_data0_reg;
> +       u16 efuse_data1_reg;
> +       u16 efuse_data2_reg;
> +       u16 efuse_data3_reg;
> +
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               efuse_ctrl_reg = EFUSE_CTRL_3290;
> +               efuse_data0_reg = EFUSE_DATA0_3290;
> +               efuse_data1_reg = EFUSE_DATA1_3290;
> +               efuse_data2_reg = EFUSE_DATA2_3290;
> +               efuse_data3_reg = EFUSE_DATA3_3290;
> +       } else {
> +               efuse_ctrl_reg = EFUSE_CTRL;
> +               efuse_data0_reg = EFUSE_DATA0;
> +               efuse_data1_reg = EFUSE_DATA1;
> +               efuse_data2_reg = EFUSE_DATA2;
> +               efuse_data3_reg = EFUSE_DATA3;
> +       }
>        mutex_lock(&rt2x00dev->csr_mutex);
>
> -       rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, &reg);
> +       rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, &reg);
>        rt2x00_set_field32(&reg, EFUSE_CTRL_ADDRESS_IN, i);
>        rt2x00_set_field32(&reg, EFUSE_CTRL_MODE, 0);
>        rt2x00_set_field32(&reg, EFUSE_CTRL_KICK, 1);
> -       rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg);
> +       rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg);
>
>        /* Wait until the EEPROM has been loaded */
> -       rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, &reg);
> -
> +       rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, &reg);
>        /* Apparently the data is read from end to start */
> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
> +       rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, &reg);
>        /* The returned value is in CPU order, but eeprom is le */
>        *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
> +       rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, &reg);
>        *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
> +       rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, &reg);
>        *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg);
> -       rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, &reg);
> +       rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, &reg);
>        *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg);
>
>        mutex_unlock(&rt2x00dev->csr_mutex);
> @@ -4244,9 +4475,14 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>         * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field
>         * RT53xx: defined in "EEPROM_CHIP_ID" field
>         */
> -       rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
> -       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
> -               rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
> +       if (rt2x00_rt(rt2x00dev, RT3290))
> +               rt2800_register_read(rt2x00dev, MAC_CSR0_3290, &reg);
> +       else
> +               rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
> +
> +       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 ||
> +           rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
> +           rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
>                rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
>        else
>                value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
> @@ -4261,6 +4497,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>        case RT3070:
>        case RT3071:
>        case RT3090:
> +       case RT3290:
>        case RT3390:
>        case RT3572:
>        case RT5390:
> @@ -4281,6 +4518,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
>        case RF3021:
>        case RF3022:
>        case RF3052:
> +       case RF3290:
>        case RF3320:
>        case RF5360:
>        case RF5370:
> @@ -4597,6 +4835,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>                   rt2x00_rf(rt2x00dev, RF2020) ||
>                   rt2x00_rf(rt2x00dev, RF3021) ||
>                   rt2x00_rf(rt2x00dev, RF3022) ||
> +                  rt2x00_rf(rt2x00dev, RF3290) ||
>                   rt2x00_rf(rt2x00dev, RF3320) ||
>                   rt2x00_rf(rt2x00dev, RF5360) ||
>                   rt2x00_rf(rt2x00dev, RF5370) ||
> @@ -4685,6 +4924,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>        case RF3022:
>        case RF3320:
>        case RF3052:
> +       case RF3290:
>        case RF5360:
>        case RF5370:
>        case RF5372:
> diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
> index 206158b..dd43612 100644
> --- a/drivers/net/wireless/rt2x00/rt2800pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2800pci.c
> @@ -280,7 +280,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
>  */
>  static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
>  {
> -       return FIRMWARE_RT2860;
> +       /*
> +        * Chip rt3290 use specific 4KB firmware named rt3290.bin.
> +        */
> +       if (rt2x00_rt(rt2x00dev, RT3290))
> +               return FIRMWARE_RT3290;
> +       else
> +               return FIRMWARE_RT2860;
>  }
>
>  static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
> @@ -974,6 +980,66 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
>        return rt2800_validate_eeprom(rt2x00dev);
>  }
>
> +static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
> +{
> +       u32 reg;
> +       int i, count;
> +
> +       rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
> +       if ((rt2x00_get_field32(reg, WLAN_EN) == 1))
> +               return 0;
> +
> +       rt2x00_set_field32(&reg, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
> +       rt2x00_set_field32(&reg, FRC_WL_ANT_SET, 1);
> +       rt2x00_set_field32(&reg, WLAN_CLK_EN, 0);
> +       rt2x00_set_field32(&reg, WLAN_EN, 1);
> +       rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
> +
> +       udelay(REGISTER_BUSY_DELAY);
> +
> +       count = 0;
> +       do {
> +               /*
> +                * Check PLL_LD & XTAL_RDY.
> +                */
> +               for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
> +                       rt2800_register_read(rt2x00dev, CMB_CTRL, &reg);
> +                       if ((rt2x00_get_field32(reg, PLL_LD) == 1) &&
> +                               (rt2x00_get_field32(reg, XTAL_RDY) == 1))
> +                                       break;
> +                       udelay(REGISTER_BUSY_DELAY);
> +               }
> +
> +               if (i >= REGISTER_BUSY_COUNT) {
> +
> +                       if (count >= 10)
> +                               return -EIO;
> +
> +                       rt2800_register_write(rt2x00dev, 0x58, 0x018);
> +                       udelay(REGISTER_BUSY_DELAY);
> +                       rt2800_register_write(rt2x00dev, 0x58, 0x418);
> +                       udelay(REGISTER_BUSY_DELAY);
> +                       rt2800_register_write(rt2x00dev, 0x58, 0x618);
> +                       udelay(REGISTER_BUSY_DELAY);
> +                       count++;
> +               } else {
> +                       count = 0;
> +               }
> +
> +               rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
> +               rt2x00_set_field32(&reg, PCIE_APP0_CLK_REQ, 0);
> +               rt2x00_set_field32(&reg, WLAN_CLK_EN, 1);
> +               rt2x00_set_field32(&reg, WLAN_RESET, 1);
> +               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
> +               udelay(10);
> +               rt2x00_set_field32(&reg, WLAN_RESET, 0);
> +               rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
> +               udelay(10);
> +               rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
> +       } while (count != 0);
> +
> +       return 0;
> +}
>  static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
>  {
>        int retval;
> @@ -997,6 +1063,17 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
>                return retval;
>
>        /*
> +        * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan
> +        * clk for rt3290. That avoid the MCU fail in start phase.
> +        */
> +       if (rt2x00_rt(rt2x00dev, RT3290)) {
> +               retval = rt2800_enable_wlan_rt3290(rt2x00dev);
> +
> +               if (retval)
> +                       return retval;
> +       }
> +
> +       /*
>         * This device has multiple filters for control frames
>         * and has a separate filter for PS Poll frames.
>         */
> @@ -1175,6 +1252,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
>        { PCI_DEVICE(0x1432, 0x7768) },
>        { PCI_DEVICE(0x1462, 0x891a) },
>        { PCI_DEVICE(0x1a3b, 0x1059) },
> +#ifdef CONFIG_RT2800PCI_RT3290
> +       { PCI_DEVICE(0x1814, 0x3290) },
> +#endif
>  #ifdef CONFIG_RT2800PCI_RT33XX
>        { PCI_DEVICE(0x1814, 0x3390) },
>  #endif
> diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
> index 70e050d..ab22a08 100644
> --- a/drivers/net/wireless/rt2x00/rt2800pci.h
> +++ b/drivers/net/wireless/rt2x00/rt2800pci.h
> @@ -47,6 +47,7 @@
>  * 8051 firmware image.
>  */
>  #define FIRMWARE_RT2860                        "rt2860.bin"
> +#define FIRMWARE_RT3290                        "rt3290.bin"
>  #define FIRMWARE_IMAGE_BASE            0x2000
>
>  /*
> diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
> index 8f75402..8afb546 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00.h
> @@ -187,6 +187,7 @@ struct rt2x00_chip {
>  #define RT3070         0x3070
>  #define RT3071         0x3071
>  #define RT3090         0x3090  /* 2.4GHz PCIe */
> +#define RT3290         0x3290
>  #define RT3390         0x3390
>  #define RT3572         0x3572
>  #define RT3593         0x3593
> diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
> index 0a4653a..a0c8cae 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
> @@ -256,6 +256,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
>        struct ieee80211_hw *hw;
>        struct rt2x00_dev *rt2x00dev;
>        int retval;
> +       u16 chip;
>
>        retval = pci_enable_device(pci_dev);
>        if (retval) {
> @@ -305,6 +306,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
>        if (retval)
>                goto exit_free_device;
>
> +       /*
> +        * Because rt3290 chip use different efuse offset to read efuse data.
> +        * So before read efuse it need to indicate it is the
> +        * rt3290 or not.
> +        */
> +       pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
> +       rt2x00dev->chip.rt = chip;
> +
>        retval = rt2x00lib_probe_dev(rt2x00dev);
>        if (retval)
>                goto exit_free_reg;
> --
> 1.7.5.4
>
>
> _______________________________________________
> users mailing list
> users@rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
>



-- 
Thank you.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-07-09  9:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-13 10:13 [PATCH] rt2x00 : RT3290 chip support v4 Xose Vazquez Perez
2012-06-18  9:16 ` [rt2x00-users] " Matt Chen
2012-06-18 16:22   ` Woody Hung (洪秋竹)
2012-06-19  3:28     ` Matt Chen
  -- strict thread matches above, loose matches on Subject: below --
2012-06-13  7:01 Woody Hung
2012-06-21  2:46 ` [rt2x00-users] " Matt Chen
2012-06-21  3:34   ` Matt Chen
2012-06-22  7:45 ` Helmut Schaa
2012-07-09  9:14   ` [rt2x00-users] " Stanislaw Gruszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.