Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
John W. Linville [Tue, 22 Feb 2011 20:10:22 +0000 (15:10 -0500)]
153 files changed:
Documentation/feature-removal-schedule.txt
MAINTAINERS
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ldisc.c
drivers/net/wireless/ath/ar9170/Kconfig
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9485_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/eeprom.h
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/lmac.h
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54spi_eeprom.h
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2800.h
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00ht.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/debug.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
drivers/net/wireless/rtlwifi/rtl8192ce/def.h
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/led.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
drivers/net/wireless/rtlwifi/rtl8192cu/Makefile [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/def.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/dm.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/dm.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/fw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/fw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/led.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/led.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/mac.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/phy.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/reg.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/rf.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/table.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/table.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192cu/trx.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/usb.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/usb.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.h
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_def.h
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/wireless/zd1211rw/zd_usb.h
drivers/ssb/main.c
drivers/ssb/pci.c
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
include/linux/ssb/ssb_regs.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/bluetooth/mgmt.h
include/net/bluetooth/smp.h [new file with mode: 0644]
net/bluetooth/Kconfig
net/bluetooth/Makefile
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/core.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap_core.c [moved from net/bluetooth/l2cap.c with 76% similarity]
net/bluetooth/l2cap_sock.c [new file with mode: 0644]
net/bluetooth/mgmt.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/tty.c
net/bluetooth/sco.c
net/mac80211/Kconfig
net/mac80211/cfg.c
net/mac80211/debugfs.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/work.c

index 057602d..d6f5255 100644 (file)
@@ -35,6 +35,17 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com>
 
 ---------------------------
 
+What:  AR9170USB
+When:  2.6.40
+
+Why:   This driver is deprecated and the firmware is no longer
+       maintained. The replacement driver "carl9170" has been
+       around for a while, so the devices are still supported.
+
+Who:   Christian Lamparter <chunkeey@googlemail.com>
+
+---------------------------
+
 What:  IRQF_SAMPLE_RANDOM
 Check: IRQF_SAMPLE_RANDOM
 When:  July 2009
index 1eacf29..0d83e58 100644 (file)
@@ -1205,7 +1205,7 @@ ATHEROS AR9170 WIRELESS DRIVER
 M:     Christian Lamparter <chunkeey@web.de>
 L:     linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org/en/users/Drivers/ar9170
-S:     Maintained
+S:     Obsolete
 F:     drivers/net/wireless/ath/ar9170/
 
 CARL9170 LINUX COMMUNITY WIRELESS DRIVER
index 333c212..5577ed6 100644 (file)
 
 #define VERSION "1.0"
 
+#define ATH3K_DNLOAD                           0x01
+#define ATH3K_GETSTATE                         0x05
+#define ATH3K_SET_NORMAL_MODE                  0x07
+#define ATH3K_GETVERSION                       0x09
+#define USB_REG_SWITCH_VID_PID                 0x0a
+
+#define ATH3K_MODE_MASK                                0x3F
+#define ATH3K_NORMAL_MODE                      0x0E
+
+#define ATH3K_PATCH_UPDATE                     0x80
+#define ATH3K_SYSCFG_UPDATE                    0x40
+
+#define ATH3K_XTAL_FREQ_26M                    0x00
+#define ATH3K_XTAL_FREQ_40M                    0x01
+#define ATH3K_XTAL_FREQ_19P2                   0x02
+#define ATH3K_NAME_LEN                         0xFF
+
+struct ath3k_version {
+       unsigned int    rom_version;
+       unsigned int    build_version;
+       unsigned int    ram_version;
+       unsigned char   ref_clock;
+       unsigned char   reserved[0x07];
+};
 
 static struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 */
@@ -41,13 +65,32 @@ static struct usb_device_id ath3k_table[] = {
 
        /* Atheros AR9285 Malbec with sflash firmware */
        { USB_DEVICE(0x03F0, 0x311D) },
+
+       /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x3004) },
+
+       /* Atheros AR5BBU12 with sflash firmware */
+       { USB_DEVICE(0x0489, 0xE02C) },
+
        { }     /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, ath3k_table);
 
+#define BTUSB_ATH3012          0x80
+/* This table is to load patch and sysconfig files
+ * for AR3012 */
+static struct usb_device_id ath3k_blist_tbl[] = {
+
+       /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+
+       { }     /* Terminating entry */
+};
+
 #define USB_REQ_DFU_DNLOAD     1
 #define BULK_SIZE              4096
+#define FW_HDR_SIZE            20
 
 static int ath3k_load_firmware(struct usb_device *udev,
                                const struct firmware *firmware)
@@ -103,28 +146,265 @@ error:
        return err;
 }
 
+static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
+{
+       int pipe = 0;
+
+       pipe = usb_rcvctrlpipe(udev, 0);
+       return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
+                       USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                       state, 0x01, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_get_version(struct usb_device *udev,
+                       struct ath3k_version *version)
+{
+       int pipe = 0;
+
+       pipe = usb_rcvctrlpipe(udev, 0);
+       return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
+                       USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
+                       sizeof(struct ath3k_version),
+                       USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_load_fwfile(struct usb_device *udev,
+               const struct firmware *firmware)
+{
+       u8 *send_buf;
+       int err, pipe, len, size, count, sent = 0;
+       int ret;
+
+       count = firmware->size;
+
+       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       if (!send_buf) {
+               BT_ERR("Can't allocate memory chunk for firmware");
+               return -ENOMEM;
+       }
+
+       size = min_t(uint, count, FW_HDR_SIZE);
+       memcpy(send_buf, firmware->data, size);
+
+       pipe = usb_sndctrlpipe(udev, 0);
+       ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD,
+                       USB_TYPE_VENDOR, 0, 0, send_buf,
+                       size, USB_CTRL_SET_TIMEOUT);
+       if (ret < 0) {
+               BT_ERR("Can't change to loading configuration err");
+               kfree(send_buf);
+               return ret;
+       }
+
+       sent += size;
+       count -= size;
+
+       while (count) {
+               size = min_t(uint, count, BULK_SIZE);
+               pipe = usb_sndbulkpipe(udev, 0x02);
+
+               memcpy(send_buf, firmware->data + sent, size);
+
+               err = usb_bulk_msg(udev, pipe, send_buf, size,
+                                       &len, 3000);
+               if (err || (len != size)) {
+                       BT_ERR("Error in firmware loading err = %d,"
+                               "len = %d, size = %d", err, len, size);
+                       kfree(send_buf);
+                       return err;
+               }
+               sent  += size;
+               count -= size;
+       }
+
+       kfree(send_buf);
+       return 0;
+}
+
+static int ath3k_switch_pid(struct usb_device *udev)
+{
+       int pipe = 0;
+
+       pipe = usb_sndctrlpipe(udev, 0);
+       return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID,
+                       USB_TYPE_VENDOR, 0, 0,
+                       NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_set_normal_mode(struct usb_device *udev)
+{
+       unsigned char fw_state;
+       int pipe = 0, ret;
+
+       ret = ath3k_get_state(udev, &fw_state);
+       if (ret < 0) {
+               BT_ERR("Can't get state to change to normal mode err");
+               return ret;
+       }
+
+       if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) {
+               BT_DBG("firmware was already in normal mode");
+               return 0;
+       }
+
+       pipe = usb_sndctrlpipe(udev, 0);
+       return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE,
+                       USB_TYPE_VENDOR, 0, 0,
+                       NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static int ath3k_load_patch(struct usb_device *udev)
+{
+       unsigned char fw_state;
+       char filename[ATH3K_NAME_LEN] = {0};
+       const struct firmware *firmware;
+       struct ath3k_version fw_version, pt_version;
+       int ret;
+
+       ret = ath3k_get_state(udev, &fw_state);
+       if (ret < 0) {
+               BT_ERR("Can't get state to change to load ram patch err");
+               return ret;
+       }
+
+       if (fw_state & ATH3K_PATCH_UPDATE) {
+               BT_DBG("Patch was already downloaded");
+               return 0;
+       }
+
+       ret = ath3k_get_version(udev, &fw_version);
+       if (ret < 0) {
+               BT_ERR("Can't get version to change to load ram patch err");
+               return ret;
+       }
+
+       snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
+               fw_version.rom_version);
+
+       ret = request_firmware(&firmware, filename, &udev->dev);
+       if (ret < 0) {
+               BT_ERR("Patch file not found %s", filename);
+               return ret;
+       }
+
+       pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
+       pt_version.build_version = *(int *)
+               (firmware->data + firmware->size - 4);
+
+       if ((pt_version.rom_version != fw_version.rom_version) ||
+               (pt_version.build_version <= fw_version.build_version)) {
+               BT_ERR("Patch file version did not match with firmware");
+               release_firmware(firmware);
+               return -EINVAL;
+       }
+
+       ret = ath3k_load_fwfile(udev, firmware);
+       release_firmware(firmware);
+
+       return ret;
+}
+
+static int ath3k_load_syscfg(struct usb_device *udev)
+{
+       unsigned char fw_state;
+       char filename[ATH3K_NAME_LEN] = {0};
+       const struct firmware *firmware;
+       struct ath3k_version fw_version;
+       int clk_value, ret;
+
+       ret = ath3k_get_state(udev, &fw_state);
+       if (ret < 0) {
+               BT_ERR("Can't get state to change to load configration err");
+               return -EBUSY;
+       }
+
+       ret = ath3k_get_version(udev, &fw_version);
+       if (ret < 0) {
+               BT_ERR("Can't get version to change to load ram patch err");
+               return ret;
+       }
+
+       switch (fw_version.ref_clock) {
+
+       case ATH3K_XTAL_FREQ_26M:
+               clk_value = 26;
+               break;
+       case ATH3K_XTAL_FREQ_40M:
+               clk_value = 40;
+               break;
+       case ATH3K_XTAL_FREQ_19P2:
+               clk_value = 19;
+               break;
+       default:
+               clk_value = 0;
+               break;
+       }
+
+       snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
+               fw_version.rom_version, clk_value, ".dfu");
+
+       ret = request_firmware(&firmware, filename, &udev->dev);
+       if (ret < 0) {
+               BT_ERR("Configuration file not found %s", filename);
+               return ret;
+       }
+
+       ret = ath3k_load_fwfile(udev, firmware);
+       release_firmware(firmware);
+
+       return ret;
+}
+
 static int ath3k_probe(struct usb_interface *intf,
                        const struct usb_device_id *id)
 {
        const struct firmware *firmware;
        struct usb_device *udev = interface_to_usbdev(intf);
+       int ret;
 
        BT_DBG("intf %p id %p", intf, id);
 
        if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
                return -ENODEV;
 
-       if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
-               return -EIO;
+       /* match device ID in ath3k blacklist table */
+       if (!id->driver_info) {
+               const struct usb_device_id *match;
+               match = usb_match_id(intf, ath3k_blist_tbl);
+               if (match)
+                       id = match;
        }
 
-       if (ath3k_load_firmware(udev, firmware)) {
-               release_firmware(firmware);
+       /* load patch and sysconfig files for AR3012 */
+       if (id->driver_info & BTUSB_ATH3012) {
+               ret = ath3k_load_patch(udev);
+               if (ret < 0) {
+                       BT_ERR("Loading patch file failed");
+                       return ret;
+               }
+               ret = ath3k_load_syscfg(udev);
+               if (ret < 0) {
+                       BT_ERR("Loading sysconfig file failed");
+                       return ret;
+               }
+               ret = ath3k_set_normal_mode(udev);
+               if (ret < 0) {
+                       BT_ERR("Set normal mode failed");
+                       return ret;
+               }
+               ath3k_switch_pid(udev);
+               return 0;
+       }
+
+       if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
+               BT_ERR("Error loading firmware");
                return -EIO;
        }
+
+       ret = ath3k_load_firmware(udev, firmware);
        release_firmware(firmware);
 
-       return 0;
+       return ret;
 }
 
 static void ath3k_disconnect(struct usb_interface *intf)
index 4cefa91..411ae9c 100644 (file)
@@ -105,6 +105,12 @@ static struct usb_device_id blacklist_table[] = {
        /* Atheros AR9285 Malbec with sflash firmware */
        { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
+       /* Atheros 3012 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE },
+
+       /* Atheros AR5BBU12 with sflash firmware */
+       { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
+
        /* Broadcom BCM2035 */
        { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -711,15 +717,11 @@ static int btusb_send_frame(struct sk_buff *skb)
                pipe = usb_sndisocpipe(data->udev,
                                        data->isoc_tx_ep->bEndpointAddress);
 
-               urb->dev      = data->udev;
-               urb->pipe     = pipe;
-               urb->context  = skb;
-               urb->complete = btusb_isoc_tx_complete;
-               urb->interval = data->isoc_tx_ep->bInterval;
+               usb_fill_int_urb(urb, data->udev, pipe,
+                               skb->data, skb->len, btusb_isoc_tx_complete,
+                               skb, data->isoc_tx_ep->bInterval);
 
                urb->transfer_flags  = URB_ISO_ASAP;
-               urb->transfer_buffer = skb->data;
-               urb->transfer_buffer_length = skb->len;
 
                __fill_isoc_descriptor(urb, skb->len,
                                le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
@@ -829,7 +831,7 @@ static void btusb_work(struct work_struct *work)
 
        if (hdev->conn_hash.sco_num > 0) {
                if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
-                       err = usb_autopm_get_interface(data->isoc);
+                       err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
                        if (err < 0) {
                                clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                                usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -858,7 +860,7 @@ static void btusb_work(struct work_struct *work)
 
                __set_isoc_interface(hdev, 0);
                if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
-                       usb_autopm_put_interface(data->isoc);
+                       usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
        }
 }
 
index 3c6cabc..48ad2a7 100644 (file)
@@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
        hdev->flush = hci_uart_flush;
        hdev->send  = hci_uart_send_frame;
        hdev->destruct = hci_uart_destruct;
+       hdev->parent = hu->tty->dev;
 
        hdev->owner = THIS_MODULE;
 
index d7a4799..7b9672b 100644 (file)
@@ -1,8 +1,10 @@
 config AR9170_USB
-       tristate "Atheros AR9170 802.11n USB support"
+       tristate "Atheros AR9170 802.11n USB support (OBSOLETE)"
        depends on USB && MAC80211
        select FW_LOADER
        help
+         This driver is going to get replaced by carl9170.
+
          This is a driver for the Atheros "otus" 802.11n USB devices.
 
          These devices require additional firmware (2 files).
index e43175a..70abb61 100644 (file)
@@ -1158,6 +1158,26 @@ void ath5k_hw_deinit(struct ath5k_hw *ah);
 int ath5k_sysfs_register(struct ath5k_softc *sc);
 void ath5k_sysfs_unregister(struct ath5k_softc *sc);
 
+/* base.c */
+struct ath5k_buf;
+struct ath5k_txq;
+
+void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
+bool ath_any_vif_assoc(struct ath5k_softc *sc);
+int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+                  struct ath5k_txq *txq);
+int ath5k_init_hw(struct ath5k_softc *sc);
+int ath5k_stop_hw(struct ath5k_softc *sc);
+void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+                                       struct ieee80211_vif *vif);
+int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
+void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void ath5k_beacon_config(struct ath5k_softc *sc);
+void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
+void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
+
 /*Chip id helper functions */
 const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 int ath5k_hw_read_srev(struct ath5k_hw *ah);
index c71fdbb..bc82405 100644 (file)
@@ -220,7 +220,8 @@ int ath5k_hw_init(struct ath5k_softc *sc)
                        ah->ah_radio = AR5K_RF5112;
                        ah->ah_single_chip = false;
                        ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) ||
+                       ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) {
                        ah->ah_radio = AR5K_RF2316;
                        ah->ah_single_chip = true;
                        ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
index 36a5199..a60a726 100644 (file)
 
 extern int ath5k_modparam_nohwcrypt;
 
-/* functions used from base.c */
-void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
-bool ath_any_vif_assoc(struct ath5k_softc *sc);
-int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-                  struct ath5k_txq *txq);
-int ath5k_init_hw(struct ath5k_softc *sc);
-int ath5k_stop_hw(struct ath5k_softc *sc);
-void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
-void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
-                                       struct ieee80211_vif *vif);
-int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void ath5k_beacon_config(struct ath5k_softc *sc);
-void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
-void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
-
 /********************\
 * Mac80211 functions *
 \********************/
index d673ab2..62ce2f4 100644 (file)
@@ -1281,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
        case AR5K_RF5111:
                ret = ath5k_hw_rf5111_channel(ah, channel);
                break;
+       case AR5K_RF2317:
        case AR5K_RF2425:
                ret = ath5k_hw_rf2425_channel(ah, channel);
                break;
index 06fb2c8..6fa3c24 100644 (file)
  */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
-       if (AR_SREV_9485(ah)) {
+       if (AR_SREV_9485_11(ah)) {
+               /* mac */
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                               ar9485_1_1_mac_core,
+                               ARRAY_SIZE(ar9485_1_1_mac_core), 2);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                               ar9485_1_1_mac_postamble,
+                               ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
+
+               /* bb */
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
+                               ARRAY_SIZE(ar9485_1_1), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                               ar9485_1_1_baseband_core,
+                               ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                               ar9485_1_1_baseband_postamble,
+                               ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
+
+               /* radio */
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                               ar9485_1_1_radio_core,
+                               ARRAY_SIZE(ar9485_1_1_radio_core), 2);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                               ar9485_1_1_radio_postamble,
+                               ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
+
+               /* soc */
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                               ar9485_1_1_soc_preamble,
+                               ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+
+               /* rx/tx gain */
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                               ar9485_common_rx_gain_1_1,
+                               ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9485_modes_lowest_ob_db_tx_gain_1_1,
+                               ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+                               5);
+
+               /* Load PCIE SERDES settings from INI */
+
+               /* Awake Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                               ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
+                               2);
+
+               /* Sleep Setting */
+
+               INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+                               ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1),
+                               2);
+       } else if (AR_SREV_9485(ah)) {
                /* mac */
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -85,8 +145,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                /* Sleep Setting */
 
                INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-                               ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1,
-                               ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1),
+                               ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
+                               ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
                                2);
        } else {
                /* mac */
@@ -163,7 +223,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
        switch (ar9003_hw_get_tx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485_modes_lowest_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+                                      5);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_lowest_ob_db_tx_gain_1_0,
                                       ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
@@ -175,10 +240,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 1:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_high_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
+                                      5);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_high_ob_db_tx_gain_1_0,
-                                      ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+                                      ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0),
                                       5);
                else
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -187,10 +257,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 2:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_low_ob_db_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
+                                      5);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_low_ob_db_tx_gain_1_0,
-                                      ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+                                      ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0),
                                       5);
                else
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -199,7 +274,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 3:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                      ar9485Modes_high_power_tx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
+                                      5);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_high_power_tx_gain_1_0,
                                       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
@@ -218,7 +298,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
        switch (ar9003_hw_get_rx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9485_common_rx_gain_1_1,
+                                      ARRAY_SIZE(ar9485_common_rx_gain_1_1),
+                                      2);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesRxGain,
                                       ar9485Common_rx_gain_1_0,
                                       ARRAY_SIZE(ar9485Common_rx_gain_1_0),
@@ -230,7 +315,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
                                       2);
                break;
        case 1:
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485_11(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9485Common_wo_xlna_rx_gain_1_1,
+                                      ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+                                      2);
+               else if (AR_SREV_9485(ah))
                        INIT_INI_ARRAY(&ah->iniModesRxGain,
                                       ar9485Common_wo_xlna_rx_gain_1_0,
                                       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
index 70de3d8..eac4d85 100644 (file)
@@ -940,4 +940,1145 @@ static const u32 ar9485_1_0_mac_core[][2] = {
        {0x000083cc, 0x00000200},
        {0x000083d0, 0x000301ff},
 };
+
+static const u32 ar9485_1_1_mac_core[][2] = {
+       /*  Addr       allmodes */
+       {0x00000008, 0x00000000},
+       {0x00000030, 0x00020085},
+       {0x00000034, 0x00000005},
+       {0x00000040, 0x00000000},
+       {0x00000044, 0x00000000},
+       {0x00000048, 0x00000008},
+       {0x0000004c, 0x00000010},
+       {0x00000050, 0x00000000},
+       {0x00001040, 0x002ffc0f},
+       {0x00001044, 0x002ffc0f},
+       {0x00001048, 0x002ffc0f},
+       {0x0000104c, 0x002ffc0f},
+       {0x00001050, 0x002ffc0f},
+       {0x00001054, 0x002ffc0f},
+       {0x00001058, 0x002ffc0f},
+       {0x0000105c, 0x002ffc0f},
+       {0x00001060, 0x002ffc0f},
+       {0x00001064, 0x002ffc0f},
+       {0x000010f0, 0x00000100},
+       {0x00001270, 0x00000000},
+       {0x000012b0, 0x00000000},
+       {0x000012f0, 0x00000000},
+       {0x0000143c, 0x00000000},
+       {0x0000147c, 0x00000000},
+       {0x00008000, 0x00000000},
+       {0x00008004, 0x00000000},
+       {0x00008008, 0x00000000},
+       {0x0000800c, 0x00000000},
+       {0x00008018, 0x00000000},
+       {0x00008020, 0x00000000},
+       {0x00008038, 0x00000000},
+       {0x0000803c, 0x00000000},
+       {0x00008040, 0x00000000},
+       {0x00008044, 0x00000000},
+       {0x00008048, 0x00000000},
+       {0x0000804c, 0xffffffff},
+       {0x00008054, 0x00000000},
+       {0x00008058, 0x00000000},
+       {0x0000805c, 0x000fc78f},
+       {0x00008060, 0x0000000f},
+       {0x00008064, 0x00000000},
+       {0x00008070, 0x00000310},
+       {0x00008074, 0x00000020},
+       {0x00008078, 0x00000000},
+       {0x0000809c, 0x0000000f},
+       {0x000080a0, 0x00000000},
+       {0x000080a4, 0x02ff0000},
+       {0x000080a8, 0x0e070605},
+       {0x000080ac, 0x0000000d},
+       {0x000080b0, 0x00000000},
+       {0x000080b4, 0x00000000},
+       {0x000080b8, 0x00000000},
+       {0x000080bc, 0x00000000},
+       {0x000080c0, 0x2a800000},
+       {0x000080c4, 0x06900168},
+       {0x000080c8, 0x13881c22},
+       {0x000080cc, 0x01f40000},
+       {0x000080d0, 0x00252500},
+       {0x000080d4, 0x00a00000},
+       {0x000080d8, 0x00400000},
+       {0x000080dc, 0x00000000},
+       {0x000080e0, 0xffffffff},
+       {0x000080e4, 0x0000ffff},
+       {0x000080e8, 0x3f3f3f3f},
+       {0x000080ec, 0x00000000},
+       {0x000080f0, 0x00000000},
+       {0x000080f4, 0x00000000},
+       {0x000080fc, 0x00020000},
+       {0x00008100, 0x00000000},
+       {0x00008108, 0x00000052},
+       {0x0000810c, 0x00000000},
+       {0x00008110, 0x00000000},
+       {0x00008114, 0x000007ff},
+       {0x00008118, 0x000000aa},
+       {0x0000811c, 0x00003210},
+       {0x00008124, 0x00000000},
+       {0x00008128, 0x00000000},
+       {0x0000812c, 0x00000000},
+       {0x00008130, 0x00000000},
+       {0x00008134, 0x00000000},
+       {0x00008138, 0x00000000},
+       {0x0000813c, 0x0000ffff},
+       {0x00008144, 0xffffffff},
+       {0x00008168, 0x00000000},
+       {0x0000816c, 0x00000000},
+       {0x00008170, 0x18486200},
+       {0x00008174, 0x33332210},
+       {0x00008178, 0x00000000},
+       {0x0000817c, 0x00020000},
+       {0x000081c0, 0x00000000},
+       {0x000081c4, 0x33332210},
+       {0x000081d4, 0x00000000},
+       {0x000081ec, 0x00000000},
+       {0x000081f0, 0x00000000},
+       {0x000081f4, 0x00000000},
+       {0x000081f8, 0x00000000},
+       {0x000081fc, 0x00000000},
+       {0x00008240, 0x00100000},
+       {0x00008244, 0x0010f400},
+       {0x00008248, 0x00000800},
+       {0x0000824c, 0x0001e800},
+       {0x00008250, 0x00000000},
+       {0x00008254, 0x00000000},
+       {0x00008258, 0x00000000},
+       {0x0000825c, 0x40000000},
+       {0x00008260, 0x00080922},
+       {0x00008264, 0x9ca00010},
+       {0x00008268, 0xffffffff},
+       {0x0000826c, 0x0000ffff},
+       {0x00008270, 0x00000000},
+       {0x00008274, 0x40000000},
+       {0x00008278, 0x003e4180},
+       {0x0000827c, 0x00000004},
+       {0x00008284, 0x0000002c},
+       {0x00008288, 0x0000002c},
+       {0x0000828c, 0x000000ff},
+       {0x00008294, 0x00000000},
+       {0x00008298, 0x00000000},
+       {0x0000829c, 0x00000000},
+       {0x00008300, 0x00000140},
+       {0x00008314, 0x00000000},
+       {0x0000831c, 0x0000010d},
+       {0x00008328, 0x00000000},
+       {0x0000832c, 0x00000007},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000700},
+       {0x00008338, 0x00ff0000},
+       {0x0000833c, 0x02400000},
+       {0x00008340, 0x000107ff},
+       {0x00008344, 0xa248105b},
+       {0x00008348, 0x008f0000},
+       {0x0000835c, 0x00000000},
+       {0x00008360, 0xffffffff},
+       {0x00008364, 0xffffffff},
+       {0x00008368, 0x00000000},
+       {0x00008370, 0x00000000},
+       {0x00008374, 0x000000ff},
+       {0x00008378, 0x00000000},
+       {0x0000837c, 0x00000000},
+       {0x00008380, 0xffffffff},
+       {0x00008384, 0xffffffff},
+       {0x00008390, 0xffffffff},
+       {0x00008394, 0xffffffff},
+       {0x00008398, 0x00000000},
+       {0x0000839c, 0x00000000},
+       {0x000083a0, 0x00000000},
+       {0x000083a4, 0x0000fa14},
+       {0x000083a8, 0x000f0c00},
+       {0x000083ac, 0x33332210},
+       {0x000083b0, 0x33332210},
+       {0x000083b4, 0x33332210},
+       {0x000083b8, 0x33332210},
+       {0x000083bc, 0x00000000},
+       {0x000083c0, 0x00000000},
+       {0x000083c4, 0x00000000},
+       {0x000083c8, 0x00000000},
+       {0x000083cc, 0x00000200},
+       {0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9485_1_1_baseband_core[][2] = {
+       /* Addr       allmodes */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a8f6b},
+       {0x0000980c, 0x04800000},
+       {0x00009814, 0x9280c00a},
+       {0x00009818, 0x00000000},
+       {0x0000981c, 0x00020028},
+       {0x00009834, 0x5f3ca3de},
+       {0x00009838, 0x0108ecff},
+       {0x0000983c, 0x14750600},
+       {0x00009880, 0x201fff00},
+       {0x00009884, 0x00001042},
+       {0x000098a4, 0x00200400},
+       {0x000098b0, 0x52440bbe},
+       {0x000098d0, 0x004b6a8e},
+       {0x000098d4, 0x00000820},
+       {0x000098dc, 0x00000000},
+       {0x000098f0, 0x00000000},
+       {0x000098f4, 0x00000000},
+       {0x00009c04, 0x00000000},
+       {0x00009c08, 0x03200000},
+       {0x00009c0c, 0x00000000},
+       {0x00009c10, 0x00000000},
+       {0x00009c14, 0x00046384},
+       {0x00009c18, 0x05b6b440},
+       {0x00009c1c, 0x00b6b440},
+       {0x00009d00, 0xc080a333},
+       {0x00009d04, 0x40206c10},
+       {0x00009d08, 0x009c4060},
+       {0x00009d0c, 0x1883800a},
+       {0x00009d10, 0x01834061},
+       {0x00009d14, 0x00c00400},
+       {0x00009d18, 0x00000000},
+       {0x00009d1c, 0x00000000},
+       {0x00009e08, 0x0038233c},
+       {0x00009e24, 0x9927b515},
+       {0x00009e28, 0x12ef0200},
+       {0x00009e30, 0x06336f77},
+       {0x00009e34, 0x6af6532f},
+       {0x00009e38, 0x0cc80c00},
+       {0x00009e40, 0x0d261820},
+       {0x00009e4c, 0x00001004},
+       {0x00009e50, 0x00ff03f1},
+       {0x00009fc0, 0x80be4788},
+       {0x00009fc4, 0x0001efb5},
+       {0x00009fcc, 0x40000014},
+       {0x0000a20c, 0x00000000},
+       {0x0000a210, 0x00000000},
+       {0x0000a220, 0x00000000},
+       {0x0000a224, 0x00000000},
+       {0x0000a228, 0x10002310},
+       {0x0000a23c, 0x00000000},
+       {0x0000a244, 0x0c000000},
+       {0x0000a2a0, 0x00000001},
+       {0x0000a2c0, 0x00000001},
+       {0x0000a2c8, 0x00000000},
+       {0x0000a2cc, 0x18c43433},
+       {0x0000a2d4, 0x00000000},
+       {0x0000a2dc, 0x00000000},
+       {0x0000a2e0, 0x00000000},
+       {0x0000a2e4, 0x00000000},
+       {0x0000a2e8, 0x00000000},
+       {0x0000a2ec, 0x00000000},
+       {0x0000a2f0, 0x00000000},
+       {0x0000a2f4, 0x00000000},
+       {0x0000a2f8, 0x00000000},
+       {0x0000a344, 0x00000000},
+       {0x0000a34c, 0x00000000},
+       {0x0000a350, 0x0000a000},
+       {0x0000a364, 0x00000000},
+       {0x0000a370, 0x00000000},
+       {0x0000a390, 0x00000001},
+       {0x0000a394, 0x00000444},
+       {0x0000a398, 0x001f0e0f},
+       {0x0000a39c, 0x0075393f},
+       {0x0000a3a0, 0xb79f6427},
+       {0x0000a3a4, 0x000000ff},
+       {0x0000a3a8, 0x3b3b3b3b},
+       {0x0000a3ac, 0x2f2f2f2f},
+       {0x0000a3c0, 0x20202020},
+       {0x0000a3c4, 0x22222220},
+       {0x0000a3c8, 0x20200020},
+       {0x0000a3cc, 0x20202020},
+       {0x0000a3d0, 0x20202020},
+       {0x0000a3d4, 0x20202020},
+       {0x0000a3d8, 0x20202020},
+       {0x0000a3dc, 0x20202020},
+       {0x0000a3e0, 0x20202020},
+       {0x0000a3e4, 0x20202020},
+       {0x0000a3e8, 0x20202020},
+       {0x0000a3ec, 0x20202020},
+       {0x0000a3f0, 0x00000000},
+       {0x0000a3f4, 0x00000006},
+       {0x0000a3f8, 0x0cdbd380},
+       {0x0000a3fc, 0x000f0f01},
+       {0x0000a400, 0x8fa91f01},
+       {0x0000a404, 0x00000000},
+       {0x0000a408, 0x0e79e5c6},
+       {0x0000a40c, 0x00820820},
+       {0x0000a414, 0x1ce739cf},
+       {0x0000a418, 0x2d0019ce},
+       {0x0000a41c, 0x1ce739ce},
+       {0x0000a420, 0x000001ce},
+       {0x0000a424, 0x1ce739ce},
+       {0x0000a428, 0x000001ce},
+       {0x0000a42c, 0x1ce739ce},
+       {0x0000a430, 0x1ce739ce},
+       {0x0000a434, 0x00000000},
+       {0x0000a438, 0x00001801},
+       {0x0000a43c, 0x00000000},
+       {0x0000a440, 0x00000000},
+       {0x0000a444, 0x00000000},
+       {0x0000a448, 0x04000000},
+       {0x0000a44c, 0x00000001},
+       {0x0000a450, 0x00010000},
+       {0x0000a5c4, 0xbfad9d74},
+       {0x0000a5c8, 0x0048060a},
+       {0x0000a5cc, 0x00000637},
+       {0x0000a760, 0x03020100},
+       {0x0000a764, 0x09080504},
+       {0x0000a768, 0x0d0c0b0a},
+       {0x0000a76c, 0x13121110},
+       {0x0000a770, 0x31301514},
+       {0x0000a774, 0x35343332},
+       {0x0000a778, 0x00000036},
+       {0x0000a780, 0x00000838},
+       {0x0000a7c0, 0x00000000},
+       {0x0000a7c4, 0xfffffffc},
+       {0x0000a7c8, 0x00000000},
+       {0x0000a7cc, 0x00000000},
+       {0x0000a7d0, 0x00000000},
+       {0x0000a7d4, 0x00000004},
+       {0x0000a7dc, 0x00000000},
+};
+
+static const u32 ar9485Common_1_1[][2] = {
+       /*  Addr      allmodes */
+       {0x00007010, 0x00000022},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+};
+
+static const u32 ar9485_1_1_baseband_postamble[][5] = {
+       /* Addr       5G_HT20        5G_HT40       2G_HT40       2G_HT20 */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
+       {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
+       {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
+       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
+       {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+       {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
+       {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
+       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+       {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
+       {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
+       {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+       {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+       {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+       {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
+       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+       {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
+       {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
+       {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+};
+
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1_radio_postamble[][2] = {
+       /* Addr        allmodes */
+       {0x0001609c, 0x0b283f31},
+       {0x000160ac, 0x24611800},
+       {0x000160b0, 0x03284f3e},
+       {0x0001610c, 0x00170000},
+       {0x00016140, 0x10804008},
+};
+
+static const u32 ar9485_1_1_mac_postamble[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+       {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+       {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+       {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+       {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+       {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+       {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+       {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9485_1_1_radio_core[][2] = {
+       /* Addr        allmodes */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73800000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x0001604c, 0x000f0278},
+       {0x00016050, 0x4db6db8c},
+       {0x00016054, 0x6db60000},
+       {0x00016080, 0x00080000},
+       {0x00016084, 0x0e48048c},
+       {0x00016088, 0x14214514},
+       {0x0001608c, 0x119f081e},
+       {0x00016090, 0x24926490},
+       {0x00016098, 0xd28b3330},
+       {0x000160a0, 0xc2108ffe},
+       {0x000160a4, 0x812fc370},
+       {0x000160a8, 0x423c8000},
+       {0x000160b4, 0x92480040},
+       {0x000160c0, 0x006db6db},
+       {0x000160c4, 0x0186db60},
+       {0x000160c8, 0x6db6db6c},
+       {0x000160cc, 0x6de6fbe0},
+       {0x000160d0, 0xf7dfcf3c},
+       {0x00016100, 0x04cb0001},
+       {0x00016104, 0xfff80015},
+       {0x00016108, 0x00080010},
+       {0x00016144, 0x01884080},
+       {0x00016148, 0x00008040},
+       {0x00016240, 0x08400000},
+       {0x00016244, 0x1bf90f00},
+       {0x00016248, 0x00000000},
+       {0x0001624c, 0x00000000},
+       {0x00016280, 0x01000015},
+       {0x00016284, 0x00d30000},
+       {0x00016288, 0x00318000},
+       {0x0001628c, 0x50000000},
+       {0x00016290, 0x4b96210f},
+       {0x00016380, 0x00000000},
+       {0x00016384, 0x00000000},
+       {0x00016388, 0x00800700},
+       {0x0001638c, 0x00800700},
+       {0x00016390, 0x00800700},
+       {0x00016394, 0x00000000},
+       {0x00016398, 0x00000000},
+       {0x0001639c, 0x00000000},
+       {0x000163a0, 0x00000001},
+       {0x000163a4, 0x00000001},
+       {0x000163a8, 0x00000000},
+       {0x000163ac, 0x00000000},
+       {0x000163b0, 0x00000000},
+       {0x000163b4, 0x00000000},
+       {0x000163b8, 0x00000000},
+       {0x000163bc, 0x00000000},
+       {0x000163c0, 0x000000a0},
+       {0x000163c4, 0x000c0000},
+       {0x000163c8, 0x14021402},
+       {0x000163cc, 0x00001402},
+       {0x000163d0, 0x00000000},
+       {0x000163d4, 0x00000000},
+       {0x00016c40, 0x13188278},
+       {0x00016c44, 0x12000000},
+};
+
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10052e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1[][2] = {
+       /* Addr        allmodes */
+       {0x0000a580, 0x00000000},
+       {0x0000a584, 0x00000000},
+       {0x0000a588, 0x00000000},
+       {0x0000a58c, 0x00000000},
+       {0x0000a590, 0x00000000},
+       {0x0000a594, 0x00000000},
+       {0x0000a598, 0x00000000},
+       {0x0000a59c, 0x00000000},
+       {0x0000a5a0, 0x00000000},
+       {0x0000a5a4, 0x00000000},
+       {0x0000a5a8, 0x00000000},
+       {0x0000a5ac, 0x00000000},
+       {0x0000a5b0, 0x00000000},
+       {0x0000a5b4, 0x00000000},
+       {0x0000a5b8, 0x00000000},
+       {0x0000a5bc, 0x00000000},
+};
+
+static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20 */
+       {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
+       {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
+       {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
+       {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
+       {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10013e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485_1_1_soc_preamble[][2] = {
+       /* Addr        allmodes */
+       {0x00004014, 0xba280400},
+       {0x000040a4, 0x00a0c9c9},
+       {0x00007010, 0x00000022},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+       {0x00007048, 0x00000002},
+};
+
+static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = {
+       /* Addr        allmodes */
+       {0x0000a398, 0x00000000},
+       {0x0000a39c, 0x6f7f0301},
+       {0x0000a3a0, 0xca9228ee},
+};
+
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
+       /* Addr        5G_HT20       5G_HT40       2G_HT40       2G_HT20  */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
+static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
+       /* Addr        5G_HT2        5G_HT40  */
+       {0x00009e00, 0x03721821, 0x03721821},
+       {0x0000a230, 0x0000400b, 0x00004016},
+       {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
+       /* Addr        allmodes  */
+       {0x00018c00, 0x10012e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485_common_rx_gain_1_1[][2] = {
+       /* Addr        allmodes */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x01800082},
+       {0x0000a014, 0x01820181},
+       {0x0000a018, 0x01840183},
+       {0x0000a01c, 0x01880185},
+       {0x0000a020, 0x018a0189},
+       {0x0000a024, 0x02850284},
+       {0x0000a028, 0x02890288},
+       {0x0000a02c, 0x03850384},
+       {0x0000a030, 0x03890388},
+       {0x0000a034, 0x038b038a},
+       {0x0000a038, 0x038d038c},
+       {0x0000a03c, 0x03910390},
+       {0x0000a040, 0x03930392},
+       {0x0000a044, 0x03950394},
+       {0x0000a048, 0x00000396},
+       {0x0000a04c, 0x00000000},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x28282828},
+       {0x0000a084, 0x28282828},
+       {0x0000a088, 0x28282828},
+       {0x0000a08c, 0x28282828},
+       {0x0000a090, 0x28282828},
+       {0x0000a094, 0x21212128},
+       {0x0000a098, 0x171c1c1c},
+       {0x0000a09c, 0x02020212},
+       {0x0000a0a0, 0x00000202},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x111f1100},
+       {0x0000a0c8, 0x111d111e},
+       {0x0000a0cc, 0x111b111c},
+       {0x0000a0d0, 0x22032204},
+       {0x0000a0d4, 0x22012202},
+       {0x0000a0d8, 0x221f2200},
+       {0x0000a0dc, 0x221d221e},
+       {0x0000a0e0, 0x33013302},
+       {0x0000a0e4, 0x331f3300},
+       {0x0000a0e8, 0x4402331e},
+       {0x0000a0ec, 0x44004401},
+       {0x0000a0f0, 0x441e441f},
+       {0x0000a0f4, 0x55015502},
+       {0x0000a0f8, 0x551f5500},
+       {0x0000a0fc, 0x6602551e},
+       {0x0000a100, 0x66006601},
+       {0x0000a104, 0x661e661f},
+       {0x0000a108, 0x7703661d},
+       {0x0000a10c, 0x77017702},
+       {0x0000a110, 0x00007700},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x111f1100},
+       {0x0000a148, 0x111d111e},
+       {0x0000a14c, 0x111b111c},
+       {0x0000a150, 0x22032204},
+       {0x0000a154, 0x22012202},
+       {0x0000a158, 0x221f2200},
+       {0x0000a15c, 0x221d221e},
+       {0x0000a160, 0x33013302},
+       {0x0000a164, 0x331f3300},
+       {0x0000a168, 0x4402331e},
+       {0x0000a16c, 0x44004401},
+       {0x0000a170, 0x441e441f},
+       {0x0000a174, 0x55015502},
+       {0x0000a178, 0x551f5500},
+       {0x0000a17c, 0x6602551e},
+       {0x0000a180, 0x66006601},
+       {0x0000a184, 0x661e661f},
+       {0x0000a188, 0x7703661d},
+       {0x0000a18c, 0x77017702},
+       {0x0000a190, 0x00007700},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000296},
+};
+
+static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
+       /* Addr        allmodes */
+       {0x00018c00, 0x10053e5e},
+       {0x00018c04, 0x000801d8},
+       {0x00018c08, 0x0000080c},
+};
+
+static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
+       /* Addr        allmodes */
+       {0x0000a000, 0x00060005},
+       {0x0000a004, 0x00810080},
+       {0x0000a008, 0x00830082},
+       {0x0000a00c, 0x00850084},
+       {0x0000a010, 0x01820181},
+       {0x0000a014, 0x01840183},
+       {0x0000a018, 0x01880185},
+       {0x0000a01c, 0x018a0189},
+       {0x0000a020, 0x02850284},
+       {0x0000a024, 0x02890288},
+       {0x0000a028, 0x028b028a},
+       {0x0000a02c, 0x03850384},
+       {0x0000a030, 0x03890388},
+       {0x0000a034, 0x038b038a},
+       {0x0000a038, 0x038d038c},
+       {0x0000a03c, 0x03910390},
+       {0x0000a040, 0x03930392},
+       {0x0000a044, 0x03950394},
+       {0x0000a048, 0x00000396},
+       {0x0000a04c, 0x00000000},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x28282828},
+       {0x0000a084, 0x28282828},
+       {0x0000a088, 0x28282828},
+       {0x0000a08c, 0x28282828},
+       {0x0000a090, 0x28282828},
+       {0x0000a094, 0x24242428},
+       {0x0000a098, 0x171e1e1e},
+       {0x0000a09c, 0x02020b0b},
+       {0x0000a0a0, 0x02020202},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x22072208},
+       {0x0000a0c4, 0x22052206},
+       {0x0000a0c8, 0x22032204},
+       {0x0000a0cc, 0x22012202},
+       {0x0000a0d0, 0x221f2200},
+       {0x0000a0d4, 0x221d221e},
+       {0x0000a0d8, 0x33023303},
+       {0x0000a0dc, 0x33003301},
+       {0x0000a0e0, 0x331e331f},
+       {0x0000a0e4, 0x4402331d},
+       {0x0000a0e8, 0x44004401},
+       {0x0000a0ec, 0x441e441f},
+       {0x0000a0f0, 0x55025503},
+       {0x0000a0f4, 0x55005501},
+       {0x0000a0f8, 0x551e551f},
+       {0x0000a0fc, 0x6602551d},
+       {0x0000a100, 0x66006601},
+       {0x0000a104, 0x661e661f},
+       {0x0000a108, 0x7703661d},
+       {0x0000a10c, 0x77017702},
+       {0x0000a110, 0x00007700},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x111f1100},
+       {0x0000a148, 0x111d111e},
+       {0x0000a14c, 0x111b111c},
+       {0x0000a150, 0x22032204},
+       {0x0000a154, 0x22012202},
+       {0x0000a158, 0x221f2200},
+       {0x0000a15c, 0x221d221e},
+       {0x0000a160, 0x33013302},
+       {0x0000a164, 0x331f3300},
+       {0x0000a168, 0x4402331e},
+       {0x0000a16c, 0x44004401},
+       {0x0000a170, 0x441e441f},
+       {0x0000a174, 0x55015502},
+       {0x0000a178, 0x551f5500},
+       {0x0000a17c, 0x6602551e},
+       {0x0000a180, 0x66006601},
+       {0x0000a184, 0x661e661f},
+       {0x0000a188, 0x7703661d},
+       {0x0000a18c, 0x77017702},
+       {0x0000a190, 0x00007700},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000296},
+};
+
 #endif
index 9272278..f9f0389 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/completion.h>
-#include <linux/pm_qos_params.h>
 
 #include "debug.h"
 #include "common.h"
@@ -57,8 +56,6 @@ struct ath_node;
 
 #define A_MAX(a, b) ((a) > (b) ? (a) : (b))
 
-#define ATH9K_PM_QOS_DEFAULT_VALUE     55
-
 #define TSF_TO_TU(_h,_l) \
        ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
@@ -192,6 +189,7 @@ struct ath_txq {
        u32 axq_ampdu_depth;
        bool stopped;
        bool axq_tx_inprogress;
+       bool txq_flush_inprogress;
        struct list_head axq_acq;
        struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
        struct list_head txq_fifo_pending;
@@ -349,6 +347,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
 
 struct ath_vif {
        int av_bslot;
+       bool is_bslot_active;
        __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
        enum nl80211_iftype av_opmode;
        struct ath_buf *av_bcbuf;
@@ -371,7 +370,7 @@ struct ath_vif {
 #define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
 
 struct ath_beacon_config {
-       u16 beacon_interval;
+       int beacon_interval;
        u16 listen_interval;
        u16 dtim_period;
        u16 bmiss_timeout;
@@ -403,6 +402,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
 int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
 int ath_beaconq_config(struct ath_softc *sc);
+void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
 
 /*******/
 /* ANI */
@@ -633,8 +633,6 @@ struct ath_softc {
        struct ath9k_hw_cal_data caldata;
        int last_rssi;
 
-       int beacon_interval;
-
 #ifdef CONFIG_ATH9K_DEBUGFS
        struct ath9k_debug debug;
        spinlock_t nodes_lock;
@@ -649,8 +647,6 @@ struct ath_softc {
        struct ath_descdma txsdma;
 
        struct ath_ant_comb ant_comb;
-
-       struct pm_qos_request_list pm_qos_req;
 };
 
 void ath9k_tasklet(unsigned long data);
@@ -665,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 extern struct ieee80211_ops ath9k_ops;
 extern int ath9k_modparam_nohwcrypt;
 extern int led_blink;
-extern int ath9k_pm_qos_value;
 extern bool is_ath9k_unloaded;
 
 irqreturn_t ath_isr(int irq, void *dev);
index fcb36ab..a4bdfdb 100644 (file)
@@ -143,7 +143,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
        avp = (void *)vif->drv_priv;
        cabq = sc->beacon.cabq;
 
-       if (avp->av_bcbuf == NULL)
+       if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active)
                return NULL;
 
        /* Release the old beacon first */
@@ -226,6 +226,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
        struct ath_vif *avp;
        struct ath_buf *bf;
        struct sk_buff *skb;
+       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
        __le64 tstamp;
 
        avp = (void *)vif->drv_priv;
@@ -248,6 +249,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
                        for (slot = 0; slot < ATH_BCBUF; slot++)
                                if (sc->beacon.bslot[slot] == NULL) {
                                        avp->av_bslot = slot;
+                                       avp->is_bslot_active = false;
 
                                        /* NB: keep looking for a double slot */
                                        if (slot == 0 || !sc->beacon.bslot[slot-1])
@@ -282,7 +284,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
                u64 tsfadjust;
                int intval;
 
-               intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+               intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
 
                /*
                 * Calculate the TSF offset for this beacon slot, i.e., the
@@ -314,6 +316,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
                ath_err(common, "dma_mapping_error on beacon alloc\n");
                return -ENOMEM;
        }
+       avp->is_bslot_active = true;
 
        return 0;
 }
@@ -346,6 +349,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
 void ath_beacon_tasklet(unsigned long data)
 {
        struct ath_softc *sc = (struct ath_softc *)data;
+       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_buf *bf = NULL;
@@ -393,7 +397,7 @@ void ath_beacon_tasklet(unsigned long data)
         * on the tsf to safeguard against missing an swba.
         */
 
-       intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+       intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
 
        tsf = ath9k_hw_gettsf64(ah);
        tsftu = TSF_TO_TU(tsf>>32, tsf);
@@ -747,3 +751,36 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
 
        sc->sc_flags |= SC_OP_BEACONS;
 }
+
+void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_vif *avp;
+       int slot;
+       bool found = false;
+
+       ath9k_ps_wakeup(sc);
+       if (status) {
+               for (slot = 0; slot < ATH_BCBUF; slot++) {
+                       if (sc->beacon.bslot[slot]) {
+                               avp = (void *)sc->beacon.bslot[slot]->drv_priv;
+                               if (avp->is_bslot_active) {
+                                       found = true;
+                                       break;
+                               }
+                       }
+               }
+               if (found) {
+                       /* Re-enable beaconing */
+                       ah->imask |= ATH9K_INT_SWBA;
+                       ath9k_hw_set_interrupts(ah, ah->imask);
+               }
+       } else {
+               /* Disable SWBA interrupt */
+               ah->imask &= ~ATH9K_INT_SWBA;
+               ath9k_hw_set_interrupts(ah, ah->imask);
+               tasklet_kill(&sc->bcon_tasklet);
+               ath9k_hw_stoptxdma(ah, sc->beacon.beaconq);
+       }
+       ath9k_ps_restore(sc);
+}
index 953036a..50fde0e 100644 (file)
@@ -169,7 +169,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
        struct ieee80211_conf *conf = &common->hw->conf;
        bool fastcc;
        struct ieee80211_channel *channel = hw->conf.channel;
-       struct ath9k_hw_cal_data *caldata;
+       struct ath9k_hw_cal_data *caldata = NULL;
        enum htc_phymode mode;
        __be16 htc_mode;
        u8 cmd_rsp;
index f9cf815..9a34381 100644 (file)
@@ -1100,7 +1100,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
                REG_WRITE(ah, AR_RC, AR_RC_AHB);
 
        REG_WRITE(ah, AR_RTC_RESET, 0);
-       udelay(2);
 
        REGWRITE_BUFFER_FLUSH(ah);
 
index e5c1eea..f66c882 100644 (file)
@@ -41,10 +41,6 @@ static int ath9k_btcoex_enable;
 module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
 MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
 
-int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
-module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
-
 bool is_ath9k_unloaded;
 /* We use the hw_value as an index into our private channel structure */
 
@@ -760,9 +756,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
 
-       pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-                          PM_QOS_DEFAULT_VALUE);
-
        return 0;
 
 error_world:
@@ -819,7 +812,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
        ath9k_ps_restore(sc);
 
        ieee80211_unregister_hw(hw);
-       pm_qos_remove_request(&sc->pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index 4ed43b2..a715500 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/nl80211.h>
+#include <linux/delay.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -53,6 +54,21 @@ static u8 parse_mpdudensity(u8 mpdudensity)
        }
 }
 
+static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
+{
+       bool pending = false;
+
+       spin_lock_bh(&txq->axq_lock);
+
+       if (txq->axq_depth || !list_empty(&txq->axq_acq))
+               pending = true;
+       else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               pending = !list_empty(&txq->txq_fifo_pending);
+
+       spin_unlock_bh(&txq->axq_lock);
+       return pending;
+}
+
 bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 {
        unsigned long flags;
@@ -1117,12 +1133,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
-       /* User has the option to provide pm-qos value as a module
-        * parameter rather than using the default value of
-        * 'ATH9K_PM_QOS_DEFAULT_VALUE'.
-        */
-       pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
-
        if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
                common->bus_ops->extn_synch_en(common);
 
@@ -1267,8 +1277,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
-       pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
-
        mutex_unlock(&sc->mutex);
 
        ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
@@ -1291,24 +1299,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc,
 {
        struct ath_vif *avp = (void *)vif->drv_priv;
 
-       /* Disable SWBA interrupt */
-       sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
-       ath9k_ps_wakeup(sc);
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-       tasklet_kill(&sc->bcon_tasklet);
-       ath9k_ps_restore(sc);
-
+       ath9k_set_beaconing_status(sc, false);
        ath_beacon_return(sc, avp);
+       ath9k_set_beaconing_status(sc, true);
        sc->sc_flags &= ~SC_OP_BEACONS;
-
-       if (sc->nbcnvifs > 0) {
-               /* Re-enable beaconing */
-               sc->sc_ah->imask |= ATH9K_INT_SWBA;
-               ath9k_ps_wakeup(sc);
-               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
-               ath9k_ps_restore(sc);
-       }
 }
 
 static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -1436,16 +1430,17 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
 
        if (ath9k_uses_beacons(vif->type)) {
                int error;
-               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
                /* This may fail because upper levels do not have beacons
                 * properly configured yet.  That's OK, we assume it
                 * will be properly configured and then we will be notified
                 * in the info_changed method and set up beacons properly
                 * there.
                 */
+               ath9k_set_beaconing_status(sc, false);
                error = ath_beacon_alloc(sc, vif);
                if (!error)
                        ath_beacon_config(sc, vif);
+               ath9k_set_beaconing_status(sc, true);
        }
 }
 
@@ -1676,8 +1671,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                else
                        sc->sc_flags &= ~SC_OP_OFFCHANNEL;
 
-               ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
-                       curchan->center_freq);
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Set channel: %d MHz type: %d\n",
+                       curchan->center_freq, conf->channel_type);
 
                ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
                                          curchan, conf->channel_type);
@@ -1723,6 +1719,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Set power: %d\n", conf->power_level);
                sc->config.txpowlimit = 2 * conf->power_level;
                ath9k_ps_wakeup(sc);
                ath9k_cmn_update_txpow(ah, sc->curtxpow,
@@ -1886,6 +1884,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                                   u32 changed)
 {
        struct ath_softc *sc = hw->priv;
+       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_vif *avp = (void *)vif->drv_priv;
@@ -1914,10 +1913,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
        /* Enable transmission of beacons (AP, IBSS, MESH) */
        if ((changed & BSS_CHANGED_BEACON) ||
            ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) {
-               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+               ath9k_set_beaconing_status(sc, false);
                error = ath_beacon_alloc(sc, vif);
                if (!error)
                        ath_beacon_config(sc, vif);
+               ath9k_set_beaconing_status(sc, true);
        }
 
        if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1940,21 +1940,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        /* Disable transmission of beacons */
-       if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
-               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+       if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
+           !bss_conf->enable_beacon) {
+               ath9k_set_beaconing_status(sc, false);
+               avp->is_bslot_active = false;
+               ath9k_set_beaconing_status(sc, true);
+       }
 
        if (changed & BSS_CHANGED_BEACON_INT) {
-               sc->beacon_interval = bss_conf->beacon_int;
+               cur_conf->beacon_interval = bss_conf->beacon_int;
                /*
                 * In case of AP mode, the HW TSF has to be reset
                 * when the beacon interval changes.
                 */
                if (vif->type == NL80211_IFTYPE_AP) {
                        sc->sc_flags |= SC_OP_TSF_RESET;
-                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+                       ath9k_set_beaconing_status(sc, false);
                        error = ath_beacon_alloc(sc, vif);
                        if (!error)
                                ath_beacon_config(sc, vif);
+                       ath9k_set_beaconing_status(sc, true);
                } else {
                        ath_beacon_config(sc, vif);
                }
@@ -2122,6 +2127,60 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
        mutex_unlock(&sc->mutex);
 }
 
+static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
+{
+#define ATH_FLUSH_TIMEOUT      60 /* ms */
+       struct ath_softc *sc = hw->priv;
+       struct ath_txq *txq;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       int i, j, npend = 0;
+
+       mutex_lock(&sc->mutex);
+
+       cancel_delayed_work_sync(&sc->tx_complete_work);
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (!ATH_TXQ_SETUP(sc, i))
+                       continue;
+               txq = &sc->tx.txq[i];
+
+               if (!drop) {
+                       for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) {
+                               if (!ath9k_has_pending_frames(sc, txq))
+                                       break;
+                               usleep_range(1000, 2000);
+                       }
+               }
+
+               if (drop || ath9k_has_pending_frames(sc, txq)) {
+                       ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n",
+                               txq->axq_qnum);
+                       spin_lock_bh(&txq->axq_lock);
+                       txq->txq_flush_inprogress = true;
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       ath9k_ps_wakeup(sc);
+                       ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+                       npend = ath9k_hw_numtxpending(ah, txq->axq_qnum);
+                       ath9k_ps_restore(sc);
+                       if (npend)
+                               break;
+
+                       ath_draintxq(sc, txq, false);
+                       txq->txq_flush_inprogress = false;
+               }
+       }
+
+       if (npend) {
+               ath_reset(sc, false);
+               txq->txq_flush_inprogress = false;
+       }
+
+       ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
+       mutex_unlock(&sc->mutex);
+}
+
 struct ieee80211_ops ath9k_ops = {
        .tx                 = ath9k_tx,
        .start              = ath9k_start,
@@ -2143,4 +2202,5 @@ struct ieee80211_ops ath9k_ops = {
        .get_survey         = ath9k_get_survey,
        .rfkill_poll        = ath9k_rfkill_poll_state,
        .set_coverage_class = ath9k_set_coverage_class,
+       .flush              = ath9k_flush,
 };
index b262e98..64b226a 100644 (file)
 #define AR_SREV_REVISION_9300_20       2 /* 2.0 and 2.1 */
 #define AR_SREV_VERSION_9485           0x240
 #define AR_SREV_REVISION_9485_10       0
+#define AR_SREV_REVISION_9485_11        1
 
 #define AR_SREV_5416(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
 #define AR_SREV_9485_10(_ah) \
        (AR_SREV_9485(_ah) && \
         ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10))
+#define AR_SREV_9485_11(_ah) \
+       (AR_SREV_9485(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
 
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
index 9f4e755..e16136d 100644 (file)
@@ -1055,6 +1055,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
 int ath_cabq_update(struct ath_softc *sc)
 {
        struct ath9k_tx_queue_info qi;
+       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
        int qnum = sc->beacon.cabq->axq_qnum;
 
        ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
@@ -1066,7 +1067,7 @@ int ath_cabq_update(struct ath_softc *sc)
        else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
                sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
 
-       qi.tqi_readyTime = (sc->beacon_interval *
+       qi.tqi_readyTime = (cur_conf->beacon_interval *
                            sc->config.cabqReadytime) / 100;
        ath_txq_update(sc, qnum, &qi);
 
@@ -2013,7 +2014,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                spin_lock_bh(&txq->axq_lock);
                if (list_empty(&txq->axq_q)) {
                        txq->axq_link = NULL;
-                       if (sc->sc_flags & SC_OP_TXAGGR)
+                       if (sc->sc_flags & SC_OP_TXAGGR &&
+                           !txq->txq_flush_inprogress)
                                ath_txq_schedule(sc, txq);
                        spin_unlock_bh(&txq->axq_lock);
                        break;
@@ -2070,6 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 
                if (bf_is_ampdu_not_probing(bf))
                        txq->axq_ampdu_depth--;
+
                spin_unlock_bh(&txq->axq_lock);
 
                if (bf_held)
@@ -2093,7 +2096,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 
                spin_lock_bh(&txq->axq_lock);
 
-               if (sc->sc_flags & SC_OP_TXAGGR)
+               if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress)
                        ath_txq_schedule(sc, txq);
                spin_unlock_bh(&txq->axq_lock);
        }
@@ -2264,15 +2267,18 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
 
                spin_lock_bh(&txq->axq_lock);
 
-               if (!list_empty(&txq->txq_fifo_pending)) {
-                       INIT_LIST_HEAD(&bf_head);
-                       bf = list_first_entry(&txq->txq_fifo_pending,
-                               struct ath_buf, list);
-                       list_cut_position(&bf_head, &txq->txq_fifo_pending,
-                               &bf->bf_lastbf->list);
-                       ath_tx_txqaddbuf(sc, txq, &bf_head);
-               } else if (sc->sc_flags & SC_OP_TXAGGR)
-                       ath_txq_schedule(sc, txq);
+               if (!txq->txq_flush_inprogress) {
+                       if (!list_empty(&txq->txq_fifo_pending)) {
+                               INIT_LIST_HEAD(&bf_head);
+                               bf = list_first_entry(&txq->txq_fifo_pending,
+                                                     struct ath_buf, list);
+                               list_cut_position(&bf_head,
+                                                 &txq->txq_fifo_pending,
+                                                 &bf->bf_lastbf->list);
+                               ath_tx_txqaddbuf(sc, txq, &bf_head);
+                       } else if (sc->sc_flags & SC_OP_TXAGGR)
+                               ath_txq_schedule(sc, txq);
+               }
                spin_unlock_bh(&txq->axq_lock);
        }
 }
index 3c5dd36..30483e2 100644 (file)
@@ -265,7 +265,8 @@ static struct iwl_lib_ops iwl2000_lib = {
        .txq_free_tfd = iwl_hw_txq_free_tfd,
        .txq_init = iwl_hw_tx_queue_init,
        .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
+       .setup_deferred_work = iwlagn_bt_setup_deferred_work,
+       .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .load_ucode = iwlagn_load_ucode,
        .dump_nic_event_log = iwl_dump_nic_event_log,
index 3aa4864..325ff5c 100644 (file)
@@ -1832,7 +1832,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
         * IBSS mode (no proper uCode support for coex then).
         */
        if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) {
-               bt_cmd.flags = 0;
+               bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED;
        } else {
                bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
                                        IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
@@ -1869,6 +1869,11 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
        struct iwl_rxon_context *ctx;
        int smps_request = -1;
 
+       if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
+               /* bt coex disabled */
+               return;
+       }
+
        /*
         * Note: bt_traffic_load can be overridden by scan complete and
         * coex profile notifications. Ignore that since only bad consequence
@@ -2022,6 +2027,11 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
        struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
        struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
 
+       if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
+               /* bt coex disabled */
+               return;
+       }
+
        IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n");
        IWL_DEBUG_NOTIF(priv, "    status: %d\n", coex->bt_status);
        IWL_DEBUG_NOTIF(priv, "    traffic load: %d\n", coex->bt_traffic_load);
index 8ee810f..abd0461 100644 (file)
@@ -1413,34 +1413,42 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 /**
  * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
  *
- * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
+ * When the ACK count ratio is low and aggregated BA timeout retries exceeding
  * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
  * operation state.
  */
-bool iwl_good_ack_health(struct iwl_priv *priv,
-                               struct iwl_rx_packet *pkt)
+bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
 {
-       bool rc = true;
-       int actual_ack_cnt_delta, expected_ack_cnt_delta;
-       int ba_timeout_delta;
-
-       actual_ack_cnt_delta =
-               le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
-               le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt);
-       expected_ack_cnt_delta =
-               le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
-               le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt);
-       ba_timeout_delta =
-               le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
-               le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout);
-       if ((priv->_agn.agg_tids_count > 0) &&
-           (expected_ack_cnt_delta > 0) &&
-           (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
-               < ACK_CNT_RATIO) &&
-           (ba_timeout_delta > BA_TIMEOUT_CNT)) {
-               IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d,"
-                               " expected_ack_cnt = %d\n",
-                               actual_ack_cnt_delta, expected_ack_cnt_delta);
+       int actual_delta, expected_delta, ba_timeout_delta;
+       struct statistics_tx *cur, *old;
+
+       if (priv->_agn.agg_tids_count)
+               return true;
+
+       if (iwl_bt_statistics(priv)) {
+               cur = &pkt->u.stats_bt.tx;
+               old = &priv->_agn.statistics_bt.tx;
+       } else {
+               cur = &pkt->u.stats.tx;
+               old = &priv->_agn.statistics.tx;
+       }
+
+       actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
+                      le32_to_cpu(old->actual_ack_cnt);
+       expected_delta = le32_to_cpu(cur->expected_ack_cnt) -
+                        le32_to_cpu(old->expected_ack_cnt);
+
+       /* Values should not be negative, but we do not trust the firmware */
+       if (actual_delta <= 0 || expected_delta <= 0)
+               return true;
+
+       ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) -
+                          le32_to_cpu(old->agg.ba_timeout);
+
+       if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO &&
+           ba_timeout_delta > BA_TIMEOUT_CNT) {
+               IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n",
+                               actual_delta, expected_delta, ba_timeout_delta);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                /*
@@ -1448,20 +1456,18 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
                 * statistics aren't available. If DEBUGFS is set but
                 * DEBUG is not, these will just compile out.
                 */
-               IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
+               IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
                                priv->_agn.delta_statistics.tx.rx_detected_cnt);
                IWL_DEBUG_RADIO(priv,
-                               "ack_or_ba_timeout_collision delta = %d\n",
-                               priv->_agn.delta_statistics.tx.
-                               ack_or_ba_timeout_collision);
+                               "ack_or_ba_timeout_collision delta %d\n",
+                               priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
 #endif
-               IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
-                               ba_timeout_delta);
-               if (!actual_ack_cnt_delta &&
-                   (ba_timeout_delta >= BA_TIMEOUT_MAX))
-                       rc = false;
+
+               if (ba_timeout_delta >= BA_TIMEOUT_MAX)
+                       return false;
        }
-       return rc;
+
+       return true;
 }
 
 
index 87a6fd8..bc89393 100644 (file)
@@ -234,33 +234,20 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
 void iwl_recover_from_statistics(struct iwl_priv *priv,
                                struct iwl_rx_packet *pkt)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+           !iwl_is_any_associated(priv))
                return;
-       if (iwl_is_any_associated(priv)) {
-               if (priv->cfg->ops->lib->check_ack_health) {
-                       if (!priv->cfg->ops->lib->check_ack_health(
-                           priv, pkt)) {
-                               /*
-                                * low ack count detected
-                                * restart Firmware
-                                */
-                               IWL_ERR(priv, "low ack count detected, "
-                                       "restart firmware\n");
-                               if (!iwl_force_reset(priv, IWL_FW_RESET, false))
-                                       return;
-                       }
-               }
-               if (priv->cfg->ops->lib->check_plcp_health) {
-                       if (!priv->cfg->ops->lib->check_plcp_health(
-                           priv, pkt)) {
-                               /*
-                                * high plcp error detected
-                                * reset Radio
-                                */
-                               iwl_force_reset(priv, IWL_RF_RESET, false);
-                       }
-               }
+
+       if (priv->cfg->ops->lib->check_ack_health &&
+           !priv->cfg->ops->lib->check_ack_health(priv, pkt)) {
+               IWL_ERR(priv, "low ack count detected, restart firmware\n");
+               if (!iwl_force_reset(priv, IWL_FW_RESET, false))
+                       return;
        }
+
+       if (priv->cfg->ops->lib->check_plcp_health &&
+           !priv->cfg->ops->lib->check_plcp_health(priv, pkt))
+               iwl_force_reset(priv, IWL_RF_RESET, false);
 }
 EXPORT_SYMBOL(iwl_recover_from_statistics);
 
index 35b09aa..f54e15f 100644 (file)
@@ -55,6 +55,17 @@ static struct ieee80211_rate p54_arates[] = {
        { .bitrate = 540, .hw_value = 11, },
 };
 
+static struct p54_rssi_db_entry p54_rssi_default = {
+       /*
+        * The defaults are taken from usb-logs of the
+        * vendor driver. So, they should be safe to
+        * use in case we can't get a match from the
+        * rssi <-> dBm conversion database.
+        */
+       .mul = 130,
+       .add = -398,
+};
+
 #define CHAN_HAS_CAL           BIT(0)
 #define CHAN_HAS_LIMIT         BIT(1)
 #define CHAN_HAS_CURVE         BIT(2)
@@ -87,13 +98,27 @@ static int p54_get_band_from_freq(u16 freq)
        return -1;
 }
 
+static int same_band(u16 freq, u16 freq2)
+{
+       return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
+}
+
 static int p54_compare_channels(const void *_a,
                                const void *_b)
 {
        const struct p54_channel_entry *a = _a;
        const struct p54_channel_entry *b = _b;
 
-       return a->index - b->index;
+       return a->freq - b->freq;
+}
+
+static int p54_compare_rssichan(const void *_a,
+                               const void *_b)
+{
+       const struct p54_rssi_db_entry *a = _a;
+       const struct p54_rssi_db_entry *b = _b;
+
+       return a->freq - b->freq;
 }
 
 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
@@ -145,25 +170,26 @@ static int p54_generate_band(struct ieee80211_hw *dev,
 
        for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
                           (i < list->entries); i++) {
+               struct p54_channel_entry *chan = &list->channels[i];
 
-               if (list->channels[i].band != band)
+               if (chan->band != band)
                        continue;
 
-               if (list->channels[i].data != CHAN_HAS_ALL) {
-                       wiphy_err(dev->wiphy,
-                                 "%s%s%s is/are missing for channel:%d [%d MHz].\n",
-                                 (list->channels[i].data & CHAN_HAS_CAL ? "" :
+               if (chan->data != CHAN_HAS_ALL) {
+                       wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
+                                 "channel:%d [%d MHz].\n",
+                                 (chan->data & CHAN_HAS_CAL ? "" :
                                   " [iqauto calibration data]"),
-                                 (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
+                                 (chan->data & CHAN_HAS_LIMIT ? "" :
                                   " [output power limits]"),
-                                 (list->channels[i].data & CHAN_HAS_CURVE ? "" :
+                                 (chan->data & CHAN_HAS_CURVE ? "" :
                                   " [curve data]"),
-                                 list->channels[i].index, list->channels[i].freq);
+                                 chan->index, chan->freq);
                        continue;
                }
 
-               tmp->channels[j].band = list->channels[i].band;
-               tmp->channels[j].center_freq = list->channels[i].freq;
+               tmp->channels[j].band = chan->band;
+               tmp->channels[j].center_freq = chan->freq;
                j++;
        }
 
@@ -291,7 +317,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
                }
        }
 
-       /* sort the list by the channel index */
+       /* sort the channel list by frequency */
        sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
             p54_compare_channels, NULL);
 
@@ -410,33 +436,118 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
        "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
 
-static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
-                            u16 type)
+static int p54_parse_rssical(struct ieee80211_hw *dev,
+                            u8 *data, int len, u16 type)
 {
        struct p54_common *priv = dev->priv;
-       int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
-       int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
-       int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
-       int i;
+       struct p54_rssi_db_entry *entry;
+       size_t db_len, entries;
+       int offset = 0, i;
+
+       if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
+               entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
+               if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
+                       wiphy_err(dev->wiphy, "rssical size mismatch.\n");
+                       goto err_data;
+               }
+       } else {
+               /*
+                * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
+                * have an empty two byte header.
+                */
+               if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
+                       offset += 2;
 
-       if (len != (entry_size * num_entries)) {
-               wiphy_err(dev->wiphy,
-                         "unknown rssi calibration data packing type:(%x) len:%d.\n",
-                         type, len);
+               entries = (len - offset) /
+                       sizeof(struct pda_rssi_cal_ext_entry);
 
-               print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
-                                    data, len);
+               if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
+                   entries <= 0) {
+                       wiphy_err(dev->wiphy, "invalid rssi database.\n");
+                       goto err_data;
+               }
+       }
 
-               wiphy_err(dev->wiphy, "please report this issue.\n");
-               return;
+       db_len = sizeof(*entry) * entries;
+       priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
+       if (!priv->rssi_db)
+               return -ENOMEM;
+
+       priv->rssi_db->offset = 0;
+       priv->rssi_db->entries = entries;
+       priv->rssi_db->entry_size = sizeof(*entry);
+       priv->rssi_db->len = db_len;
+
+       entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
+       if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
+               struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
+
+               for (i = 0; i < entries; i++) {
+                       entry[i].freq = le16_to_cpu(cal[i].freq);
+                       entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
+                       entry[i].add = (s16) le16_to_cpu(cal[i].add);
+               }
+       } else {
+               struct pda_rssi_cal_entry *cal = (void *) &data[offset];
+
+               for (i = 0; i < entries; i++) {
+                       u16 freq;
+                       switch (i) {
+                       case IEEE80211_BAND_2GHZ:
+                               freq = 2437;
+                               break;
+                       case IEEE80211_BAND_5GHZ:
+                               freq = 5240;
+                               break;
+                       }
+
+                       entry[i].freq = freq;
+                       entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
+                       entry[i].add = (s16) le16_to_cpu(cal[i].add);
+               }
        }
 
-       for (i = 0; i < num_entries; i++) {
-               struct pda_rssi_cal_entry *cal = data +
-                                                (offset + i * entry_size);
-               priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
-               priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
+       /* sort the list by channel frequency */
+       sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
+       return 0;
+
+err_data:
+       wiphy_err(dev->wiphy,
+                 "rssi calibration data packing type:(%x) len:%d.\n",
+                 type, len);
+
+       print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
+
+       wiphy_err(dev->wiphy, "please report this issue.\n");
+       return -EINVAL;
+}
+
+struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
+{
+       struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data +
+                                                  priv->rssi_db->offset);
+       int i, found = -1;
+
+       for (i = 0; i < priv->rssi_db->entries; i++) {
+               if (!same_band(freq, entry[i].freq))
+                       continue;
+
+               if (found == -1) {
+                       found = i;
+                       continue;
+               }
+
+               /* nearest match */
+               if (abs(freq - entry[i].freq) <
+                   abs(freq - entry[found].freq)) {
+                       found = i;
+                       continue;
+               } else {
+                       break;
+               }
        }
+
+       return found < 0 ? &p54_rssi_default : &entry[found];
 }
 
 static void p54_parse_default_country(struct ieee80211_hw *dev,
@@ -627,21 +738,30 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                case PDR_RSSI_LINEAR_APPROXIMATION:
                case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
                case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
-                       p54_parse_rssical(dev, entry->data, data_len,
-                                         le16_to_cpu(entry->code));
+                       err = p54_parse_rssical(dev, entry->data, data_len,
+                                               le16_to_cpu(entry->code));
+                       if (err)
+                               goto err;
                        break;
-               case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
-                       __le16 *src = (void *) entry->data;
-                       s16 *dst = (void *) &priv->rssical_db;
+               case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
+                       struct pda_custom_wrapper *pda = (void *) entry->data;
+                       __le16 *src;
+                       u16 *dst;
                        int i;
 
-                       if (data_len != sizeof(priv->rssical_db)) {
-                               err = -EINVAL;
-                               goto err;
-                       }
-                       for (i = 0; i < sizeof(priv->rssical_db) /
-                                       sizeof(*src); i++)
+                       if (priv->rssi_db || data_len < sizeof(*pda))
+                               break;
+
+                       priv->rssi_db = p54_convert_db(pda, data_len);
+                       if (!priv->rssi_db)
+                               break;
+
+                       src = (void *) priv->rssi_db->data;
+                       dst = (void *) priv->rssi_db->data;
+
+                       for (i = 0; i < priv->rssi_db->entries; i++)
                                *(dst++) = (s16) le16_to_cpu(*(src++));
+
                        }
                        break;
                case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
@@ -717,6 +837,8 @@ good_eeprom:
                SET_IEEE80211_PERM_ADDR(dev, perm_addr);
        }
 
+       priv->cur_rssi = &p54_rssi_default;
+
        wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
                   dev->wiphy->perm_addr, priv->version,
                   p54_rf_chips[priv->rxhw]);
@@ -727,9 +849,11 @@ err:
        kfree(priv->iq_autocal);
        kfree(priv->output_limit);
        kfree(priv->curve_data);
+       kfree(priv->rssi_db);
        priv->iq_autocal = NULL;
        priv->output_limit = NULL;
        priv->curve_data = NULL;
+       priv->rssi_db = NULL;
 
        wiphy_err(dev->wiphy, "eeprom parse failed!\n");
        return err;
index 9051aef..afde72b 100644 (file)
@@ -81,6 +81,12 @@ struct pda_pa_curve_data {
        u8 data[0];
 } __packed;
 
+struct pda_rssi_cal_ext_entry {
+       __le16 freq;
+       __le16 mul;
+       __le16 add;
+} __packed;
+
 struct pda_rssi_cal_entry {
        __le16 mul;
        __le16 add;
@@ -179,6 +185,7 @@ struct pda_custom_wrapper {
 
 /* used by our modificated eeprom image */
 #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM           0xDEAD
+#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2         0xCAFF
 #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM    0xBEEF
 #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM             0xB05D
 
index 92b9b1f..0d3d108 100644 (file)
@@ -397,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
        union p54_scan_body_union *body;
        struct p54_scan_tail_rate *rate;
        struct pda_rssi_cal_entry *rssi;
+       struct p54_rssi_db_entry *rssi_data;
        unsigned int i;
        void *entry;
-       int band = priv->hw->conf.channel->band;
        __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
 
        skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
@@ -503,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
        }
 
        rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
-       rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
-       rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+       rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
+       rssi->mul = cpu_to_le16(rssi_data->mul);
+       rssi->add = cpu_to_le16(rssi_data->add);
        if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
                /* Longbow frontend needs ever more */
                rssi = (void *) skb_put(skb, sizeof(*rssi));
-               rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
-               rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+               rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
+               rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
        }
 
        if (priv->fw_var >= 0x509) {
@@ -523,6 +524,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
        hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
 
        p54_tx(priv, skb);
+       priv->cur_rssi = rssi_data;
        return 0;
 
 err:
index 04b63ec..5ca117e 100644 (file)
@@ -551,6 +551,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot,
 /* eeprom */
 int p54_download_eeprom(struct p54_common *priv, void *buf,
                        u16 offset, u16 len);
+struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq);
 
 /* utility */
 u8 *p54_find_ie(struct sk_buff *skb, u8 ie);
index 622d27b..e14a05b 100644 (file)
@@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
        return 0;
 }
 
+static unsigned int p54_flush_count(struct p54_common *priv)
+{
+       unsigned int total = 0, i;
+
+       BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats));
+
+       /*
+        * Because the firmware has the sole control over any frames
+        * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they
+        * don't really count as pending or active.
+        */
+       for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++)
+               total += priv->tx_stats[i].len;
+       return total;
+}
+
+static void p54_flush(struct ieee80211_hw *dev, bool drop)
+{
+       struct p54_common *priv = dev->priv;
+       unsigned int total, i;
+
+       /*
+        * Currently, it wouldn't really matter if we wait for one second
+        * or 15 minutes. But once someone gets around and completes the
+        * TODOs [ancel stuck frames / reset device] in p54_work, it will
+        * suddenly make sense to wait that long.
+        */
+       i = P54_STATISTICS_UPDATE * 2 / 20;
+
+       /*
+        * In this case no locking is required because as we speak the
+        * queues have already been stopped and no new frames can sneak
+        * up from behind.
+        */
+       while ((total = p54_flush_count(priv) && i--)) {
+               /* waste time */
+               msleep(20);
+       }
+
+       WARN(total, "tx flush timeout, unresponsive firmware");
+}
+
 static const struct ieee80211_ops p54_ops = {
        .tx                     = p54_tx_80211,
        .start                  = p54_start,
@@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = {
        .sta_remove             = p54_sta_add_remove,
        .set_key                = p54_set_key,
        .config                 = p54_config,
+       .flush                  = p54_flush,
        .bss_info_changed       = p54_bss_info_changed,
        .configure_filter       = p54_configure_filter,
        .conf_tx                = p54_conf_tx,
@@ -611,7 +654,7 @@ EXPORT_SYMBOL_GPL(p54_init_common);
 
 int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
 {
-       struct p54_common *priv = dev->priv;
+       struct p54_common __maybe_unused *priv = dev->priv;
        int err;
 
        err = ieee80211_register_hw(dev);
@@ -642,10 +685,12 @@ void p54_free_common(struct ieee80211_hw *dev)
        kfree(priv->iq_autocal);
        kfree(priv->output_limit);
        kfree(priv->curve_data);
+       kfree(priv->rssi_db);
        kfree(priv->used_rxkeys);
        priv->iq_autocal = NULL;
        priv->output_limit = NULL;
        priv->curve_data = NULL;
+       priv->rssi_db = NULL;
        priv->used_rxkeys = NULL;
        ieee80211_free_hw(dev);
 }
index 43a3b2e..f951c8f 100644 (file)
@@ -116,7 +116,8 @@ struct p54_edcf_queue_param {
        __le16 txop;
 } __packed;
 
-struct p54_rssi_linear_approximation {
+struct p54_rssi_db_entry {
+       u16 freq;
        s16 mul;
        s16 add;
        s16 longbow_unkn;
@@ -197,13 +198,14 @@ struct p54_common {
        u8 rx_diversity_mask;
        u8 tx_diversity_mask;
        unsigned int output_power;
+       struct p54_rssi_db_entry *cur_rssi;
        int noise;
        /* calibration, output power limit and rssi<->dBm conversation data */
        struct pda_iq_autocal_entry *iq_autocal;
        unsigned int iq_autocal_len;
        struct p54_cal_database *curve_data;
        struct p54_cal_database *output_limit;
-       struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+       struct p54_cal_database *rssi_db;
        struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
 
        /* BBP/MAC state */
index d592cbd..0b7bfb0 100644 (file)
@@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = {
 0x03, 0x00, 0x00, 0x11,                /* PDR_ANTENNA_GAIN */
        0x08, 0x08, 0x08, 0x08,
 
-0x09, 0x00, 0xad, 0xde,                /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */
-       0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x0a, 0x00, 0xff, 0xca,                /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */
+       0x01, 0x00, 0x0a, 0x00,
+       0x00, 0x00, 0x0a, 0x00,
+               0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
 
 /* struct pda_custom_wrapper */
 0x10, 0x06, 0x5d, 0xb0,                /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
@@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = {
        0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
 
 0x02, 0x00, 0x00, 0x00,                /* PDR_END */
-       0x67, 0x99,
+       0xb6, 0x04,
 };
 
 #endif /* P54SPI_EEPROM_H */
index f618b96..917d5d9 100644 (file)
@@ -273,11 +273,9 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb)
 
 static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
 {
-       int band = priv->hw->conf.channel->band;
-
        if (priv->rxhw != 5) {
-               return ((rssi * priv->rssical_db[band].mul) / 64 +
-                        priv->rssical_db[band].add) / 4;
+               return ((rssi * priv->cur_rssi->mul) / 64 +
+                        priv->cur_rssi->add) / 4;
        } else {
                /*
                 * TODO: find the correct formula
index 6f383cd..f630552 100644 (file)
@@ -97,6 +97,18 @@ config RT2800PCI_RT35XX
          Support for these devices is non-functional at the moment and is
          intended for testers and developers.
 
+config RT2800PCI_RT53XX
+       bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       default n
+       ---help---
+         This adds support for rt53xx wireless chipset family to the
+         rt2800pci driver.
+         Supported chips: RT5390
+
+         Support for these devices is non-functional at the moment and is
+         intended for testers and developers.
+
 endif
 
 config RT2500USB
index ec8159c..6f4a243 100644 (file)
@@ -51,6 +51,7 @@
  * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
  * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
  * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+ * RF5390 2.4G 1T1R
  */
 #define RF2820                         0x0001
 #define RF2850                         0x0002
@@ -65,6 +66,7 @@
 #define RF3320                         0x000b
 #define RF3322                         0x000c
 #define RF3853                         0x000d
+#define RF5390                         0x5390
 
 /*
  * Chipset revisions.
@@ -77,6 +79,7 @@
 #define REV_RT3071E                    0x0211
 #define REV_RT3090E                    0x0211
 #define REV_RT3390E                    0x0211
+#define REV_RT5390F                    0x0502
 
 /*
  * Signal information.
 #define E2PROM_CSR_RELOAD              FIELD32(0x00000080)
 
 /*
+ * AUX_CTRL: Aux/PCI-E related configuration
+ */
+#define AUX_CTRL               0x10c
+#define AUX_CTRL_WAKE_PCIE_EN          FIELD32(0x00000002)
+#define AUX_CTRL_FORCE_PCIE_CLK        FIELD32(0x00000400)
+
+/*
  * OPT_14: Unknown register used by rt3xxx devices.
  */
 #define OPT_14_CSR                     0x0114
 
 /*
  * GPIO_CTRL_CFG:
+ * GPIOD: GPIO direction, 0: Output, 1: Input
  */
 #define GPIO_CTRL_CFG                  0x0228
 #define GPIO_CTRL_CFG_BIT0             FIELD32(0x00000001)
 #define GPIO_CTRL_CFG_BIT5             FIELD32(0x00000020)
 #define GPIO_CTRL_CFG_BIT6             FIELD32(0x00000040)
 #define GPIO_CTRL_CFG_BIT7             FIELD32(0x00000080)
-#define GPIO_CTRL_CFG_BIT8             FIELD32(0x00000100)
+#define GPIO_CTRL_CFG_GPIOD_BIT0       FIELD32(0x00000100)
+#define GPIO_CTRL_CFG_GPIOD_BIT1       FIELD32(0x00000200)
+#define GPIO_CTRL_CFG_GPIOD_BIT2       FIELD32(0x00000400)
+#define GPIO_CTRL_CFG_GPIOD_BIT3       FIELD32(0x00000800)
+#define GPIO_CTRL_CFG_GPIOD_BIT4       FIELD32(0x00001000)
+#define GPIO_CTRL_CFG_GPIOD_BIT5       FIELD32(0x00002000)
+#define GPIO_CTRL_CFG_GPIOD_BIT6       FIELD32(0x00004000)
+#define GPIO_CTRL_CFG_GPIOD_BIT7       FIELD32(0x00008000)
 
 /*
  * MCU_CMD_CFG
  */
 #define        RF_CSR_CFG                      0x0500
 #define RF_CSR_CFG_DATA                        FIELD32(0x000000ff)
-#define RF_CSR_CFG_REGNUM              FIELD32(0x00001f00)
+#define RF_CSR_CFG_REGNUM              FIELD32(0x00003f00)
 #define RF_CSR_CFG_WRITE               FIELD32(0x00010000)
 #define RF_CSR_CFG_BUSY                        FIELD32(0x00020000)
 
  * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
  * PROTECT_CTRL: Protection control frame type for CCK TX
  *               0:none, 1:RTS/CTS, 2:CTS-to-self
- * PROTECT_NAV: TXOP protection type for CCK TX
- *              0:none, 1:ShortNAVprotect, 2:LongNAVProtect
+ * PROTECT_NAV_SHORT: TXOP protection type for CCK TX with short NAV
+ * PROTECT_NAV_LONG: TXOP protection type for CCK TX with long NAV
  * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
  * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
  * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
 #define CCK_PROT_CFG                   0x1364
 #define CCK_PROT_CFG_PROTECT_RATE      FIELD32(0x0000ffff)
 #define CCK_PROT_CFG_PROTECT_CTRL      FIELD32(0x00030000)
-#define CCK_PROT_CFG_PROTECT_NAV       FIELD32(0x000c0000)
+#define CCK_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000)
+#define CCK_PROT_CFG_PROTECT_NAV_LONG  FIELD32(0x00080000)
 #define CCK_PROT_CFG_TX_OP_ALLOW_CCK   FIELD32(0x00100000)
 #define CCK_PROT_CFG_TX_OP_ALLOW_OFDM  FIELD32(0x00200000)
 #define CCK_PROT_CFG_TX_OP_ALLOW_MM20  FIELD32(0x00400000)
 #define OFDM_PROT_CFG                  0x1368
 #define OFDM_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
 #define OFDM_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
-#define OFDM_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define OFDM_PROT_CFG_PROTECT_NAV_SHORT        FIELD32(0x00040000)
+#define OFDM_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
 #define OFDM_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
 #define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
 #define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
 #define MM20_PROT_CFG                  0x136c
 #define MM20_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
 #define MM20_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
-#define MM20_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define MM20_PROT_CFG_PROTECT_NAV_SHORT        FIELD32(0x00040000)
+#define MM20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
 #define MM20_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
 #define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
 #define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
 #define MM40_PROT_CFG                  0x1370
 #define MM40_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
 #define MM40_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
-#define MM40_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define MM40_PROT_CFG_PROTECT_NAV_SHORT        FIELD32(0x00040000)
+#define MM40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
 #define MM40_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
 #define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
 #define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
 #define GF20_PROT_CFG                  0x1374
 #define GF20_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
 #define GF20_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
-#define GF20_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define GF20_PROT_CFG_PROTECT_NAV_SHORT        FIELD32(0x00040000)
+#define GF20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
 #define GF20_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
 #define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
 #define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
 #define GF40_PROT_CFG                  0x1378
 #define GF40_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
 #define GF40_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
-#define GF40_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define GF40_PROT_CFG_PROTECT_NAV_SHORT        FIELD32(0x00040000)
+#define GF40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000)
 #define GF40_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
 #define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
 #define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
@@ -1701,11 +1725,14 @@ struct mac_iveiv_entry {
  */
 
 /*
- * BBP 1: TX Antenna & Power
- * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm,
- *     3 - increase tx power by 6dBm
+ * BBP 1: TX Antenna & Power Control
+ * POWER_CTRL:
+ * 0 - normal,
+ * 1 - drop tx power by 6dBm,
+ * 2 - drop tx power by 12dBm,
+ * 3 - increase tx power by 6dBm
  */
-#define BBP1_TX_POWER                  FIELD8(0x07)
+#define BBP1_TX_POWER_CTRL             FIELD8(0x07)
 #define BBP1_TX_ANTENNA                        FIELD8(0x18)
 
 /*
@@ -1719,6 +1746,13 @@ struct mac_iveiv_entry {
  */
 #define BBP4_TX_BF                     FIELD8(0x01)
 #define BBP4_BANDWIDTH                 FIELD8(0x18)
+#define BBP4_MAC_IF_CTRL               FIELD8(0x40)
+
+/*
+ * BBP 109
+ */
+#define BBP109_TX0_POWER       FIELD8(0x0f)
+#define BBP109_TX1_POWER       FIELD8(0xf0)
 
 /*
  * BBP 138: Unknown
@@ -1729,6 +1763,11 @@ struct mac_iveiv_entry {
 #define BBP138_TX_DAC2                 FIELD8(0x40)
 
 /*
+ * BBP 152: Rx Ant
+ */
+#define BBP152_RX_DEFAULT_ANT  FIELD8(0x80)
+
+/*
  * RFCSR registers
  * The wordsize of the RFCSR is 8 bits.
  */
@@ -1737,12 +1776,18 @@ struct mac_iveiv_entry {
  * RFCSR 1:
  */
 #define RFCSR1_RF_BLOCK_EN             FIELD8(0x01)
+#define RFCSR1_PLL_PD                  FIELD8(0x02)
 #define RFCSR1_RX0_PD                  FIELD8(0x04)
 #define RFCSR1_TX0_PD                  FIELD8(0x08)
 #define RFCSR1_RX1_PD                  FIELD8(0x10)
 #define RFCSR1_TX1_PD                  FIELD8(0x20)
 
 /*
+ * RFCSR 2:
+ */
+#define RFCSR2_RESCAL_EN               FIELD8(0x80)
+
+/*
  * RFCSR 6:
  */
 #define RFCSR6_R1                      FIELD8(0x03)
@@ -1754,6 +1799,11 @@ struct mac_iveiv_entry {
 #define RFCSR7_RF_TUNING               FIELD8(0x01)
 
 /*
+ * RFCSR 11:
+ */
+#define RFCSR11_R                      FIELD8(0x03)
+
+/*
  * RFCSR 12:
  */
 #define RFCSR12_TX_POWER               FIELD8(0x1f)
@@ -1774,6 +1824,7 @@ struct mac_iveiv_entry {
 #define RFCSR17_TXMIXER_GAIN           FIELD8(0x07)
 #define RFCSR17_TX_LO1_EN              FIELD8(0x08)
 #define RFCSR17_R                      FIELD8(0x20)
+#define RFCSR17_CODE                   FIELD8(0x7f)
 
 /*
  * RFCSR 20:
@@ -1806,6 +1857,9 @@ struct mac_iveiv_entry {
 /*
  * RFCSR 30:
  */
+#define RFCSR30_TX_H20M                FIELD8(0x02)
+#define RFCSR30_RX_H20M                FIELD8(0x04)
+#define RFCSR30_RX_VCM         FIELD8(0x18)
 #define RFCSR30_RF_CALIBRATION         FIELD8(0x80)
 
 /*
@@ -1815,6 +1869,21 @@ struct mac_iveiv_entry {
 #define RFCSR31_RX_H20M                        FIELD8(0x20)
 
 /*
+ * RFCSR 38:
+ */
+#define RFCSR38_RX_LO1_EN      FIELD8(0x20)
+
+/*
+ * RFCSR 39:
+ */
+#define RFCSR39_RX_LO2_EN      FIELD8(0x80)
+
+/*
+ * RFCSR 49:
+ */
+#define RFCSR49_TX                     FIELD8(0x3f)
+
+/*
  * RF registers
  */
 
@@ -1847,6 +1916,11 @@ struct mac_iveiv_entry {
  */
 
 /*
+ * Chip ID
+ */
+#define EEPROM_CHIP_ID         0x0000
+
+/*
  * EEPROM Version
  */
 #define EEPROM_VERSION                 0x0001
@@ -1999,23 +2073,26 @@ struct mac_iveiv_entry {
 #define EEPROM_RSSI_A2_LNA_A2          FIELD16(0xff00)
 
 /*
- * EEPROM Maximum TX power values
+ * EEPROM EIRP Maximum TX power values(unit: dbm)
  */
-#define EEPROM_MAX_TX_POWER            0x0027
-#define EEPROM_MAX_TX_POWER_24GHZ      FIELD16(0x00ff)
-#define EEPROM_MAX_TX_POWER_5GHZ       FIELD16(0xff00)
+#define EEPROM_EIRP_MAX_TX_POWER       0x0027
+#define EEPROM_EIRP_MAX_TX_POWER_2GHZ  FIELD16(0x00ff)
+#define EEPROM_EIRP_MAX_TX_POWER_5GHZ  FIELD16(0xff00)
 
 /*
  * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
  * This is delta in 40MHZ.
- * VALUE: Tx Power dalta value (MAX=4)
+ * VALUE: Tx Power dalta value, MAX=4(unit: dbm)
  * TYPE: 1: Plus the delta value, 0: minus the delta value
- * TXPOWER: Enable:
+ * ENABLE: enable tx power compensation for 40BW
  */
 #define EEPROM_TXPOWER_DELTA           0x0028
-#define EEPROM_TXPOWER_DELTA_VALUE     FIELD16(0x003f)
-#define EEPROM_TXPOWER_DELTA_TYPE      FIELD16(0x0040)
-#define EEPROM_TXPOWER_DELTA_TXPOWER   FIELD16(0x0080)
+#define EEPROM_TXPOWER_DELTA_VALUE_2G  FIELD16(0x003f)
+#define EEPROM_TXPOWER_DELTA_TYPE_2G   FIELD16(0x0040)
+#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080)
+#define EEPROM_TXPOWER_DELTA_VALUE_5G  FIELD16(0x3f00)
+#define EEPROM_TXPOWER_DELTA_TYPE_5G   FIELD16(0x4000)
+#define EEPROM_TXPOWER_DELTA_ENABLE_5G FIELD16(0x8000)
 
 /*
  * EEPROM TXPOWER 802.11BG
@@ -2068,6 +2145,7 @@ struct mac_iveiv_entry {
 #define MCU_LED_LED_POLARITY           0x54
 #define MCU_RADAR                      0x60
 #define MCU_BOOT_SIGNAL                        0x72
+#define MCU_ANT_SELECT                 0X73
 #define MCU_BBP_SIGNAL                 0x80
 #define MCU_POWER_SAVE                 0x83
 
@@ -2212,4 +2290,9 @@ struct mac_iveiv_entry {
 #define TXPOWER_A_TO_DEV(__txpower) \
        clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
 
+/*
+ *  Board's maximun TX power limitation
+ */
+#define EIRP_MAX_TX_POWER_LIMIT        0x50
+
 #endif /* RT2800_H */
index c9bf074..3da78bf 100644 (file)
@@ -400,8 +400,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
        if (rt2800_wait_csr_ready(rt2x00dev))
                return -EBUSY;
 
-       if (rt2x00_is_pci(rt2x00dev))
+       if (rt2x00_is_pci(rt2x00dev)) {
+               if (rt2x00_rt(rt2x00dev, RT5390)) {
+                       rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
+                       rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
+                       rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
+                       rt2800_register_write(rt2x00dev, AUX_CTRL, reg);
+               }
                rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
+       }
 
        /*
         * Disable DMA, will be reenabled later when enabling
@@ -773,13 +780,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        unsigned int beacon_base;
        unsigned int padding_len;
-       u32 reg;
+       u32 orig_reg, reg;
 
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
        rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
@@ -810,7 +818,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
         * Write entire beacon with TXWI and padding to register.
         */
        padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
-       skb_pad(entry->skb, padding_len);
+       if (padding_len && skb_pad(entry->skb, padding_len)) {
+               ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
+               /* skb freed by skb_pad() on failure */
+               entry->skb = NULL;
+               rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
+               return;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
                                   entry->skb->len + padding_len);
@@ -1368,10 +1383,32 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp,
 }
 EXPORT_SYMBOL_GPL(rt2800_config_erp);
 
+static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
+                                    enum antenna ant)
+{
+       u32 reg;
+       u8 eesk_pin = (ant == ANTENNA_A) ? 1 : 0;
+       u8 gpio_bit3 = (ant == ANTENNA_A) ? 0 : 1;
+
+       if (rt2x00_is_pci(rt2x00dev)) {
+               rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+               rt2x00_set_field32(&reg, E2PROM_CSR_DATA_CLOCK, eesk_pin);
+               rt2800_register_write(rt2x00dev, E2PROM_CSR, reg);
+       } else if (rt2x00_is_usb(rt2x00dev))
+               rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff,
+                                  eesk_pin, 0);
+
+       rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
+       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, gpio_bit3);
+       rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+}
+
 void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
 {
        u8 r1;
        u8 r3;
+       u16 eeprom;
 
        rt2800_bbp_read(rt2x00dev, 1, &r1);
        rt2800_bbp_read(rt2x00dev, 3, &r3);
@@ -1379,7 +1416,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
        /*
         * Configure the TX antenna.
         */
-       switch ((int)ant->tx) {
+       switch (ant->tx_chain_num) {
        case 1:
                rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
                break;
@@ -1394,8 +1431,18 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
        /*
         * Configure the RX antenna.
         */
-       switch ((int)ant->rx) {
+       switch (ant->rx_chain_num) {
        case 1:
+               if (rt2x00_rt(rt2x00dev, RT3070) ||
+                   rt2x00_rt(rt2x00dev, RT3090) ||
+                   rt2x00_rt(rt2x00dev, RT3390)) {
+                       rt2x00_eeprom_read(rt2x00dev,
+                                          EEPROM_NIC_CONF1, &eeprom);
+                       if (rt2x00_get_field16(eeprom,
+                                               EEPROM_NIC_CONF1_ANT_DIVERSITY))
+                               rt2800_set_ant_diversity(rt2x00dev,
+                                               rt2x00dev->default_ant.rx);
+               }
                rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
                break;
        case 2:
@@ -1441,13 +1488,13 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev,
 {
        rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
 
-       if (rt2x00dev->default_ant.tx == 1)
+       if (rt2x00dev->default_ant.tx_chain_num == 1)
                rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
 
-       if (rt2x00dev->default_ant.rx == 1) {
+       if (rt2x00dev->default_ant.rx_chain_num == 1) {
                rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
                rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
-       } else if (rt2x00dev->default_ant.rx == 2)
+       } else if (rt2x00dev->default_ant.rx_chain_num == 2)
                rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
 
        if (rf->channel > 14) {
@@ -1533,6 +1580,99 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 }
 
+
+#define RT5390_POWER_BOUND     0x27
+#define RT5390_FREQ_OFFSET_BOUND       0x5f
+
+static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
+                                        struct ieee80211_conf *conf,
+                                        struct rf_channel *rf,
+                                        struct channel_info *info)
+{
+       u8 rfcsr;
+       u16 eeprom;
+
+       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 > RT5390_POWER_BOUND)
+               rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND);
+       else
+               rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1);
+       rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+       rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
+       rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+       rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+       rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+       rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+       if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND)
+               rt2x00_set_field8(&rfcsr, RFCSR17_CODE, RT5390_FREQ_OFFSET_BOUND);
+       else
+               rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
+       rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+       if (rf->channel <= 14) {
+               int idx = rf->channel-1;
+
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+                       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+                               /* r55/r59 value array of channel 1~14 */
+                               static const char r55_bt_rev[] = {0x83, 0x83,
+                                       0x83, 0x73, 0x73, 0x63, 0x53, 0x53,
+                                       0x53, 0x43, 0x43, 0x43, 0x43, 0x43};
+                               static const char r59_bt_rev[] = {0x0e, 0x0e,
+                                       0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09,
+                                       0x07, 0x07, 0x07, 0x07, 0x07, 0x07};
+
+                               rt2800_rfcsr_write(rt2x00dev, 55, r55_bt_rev[idx]);
+                               rt2800_rfcsr_write(rt2x00dev, 59, r59_bt_rev[idx]);
+                       } else {
+                               static const char r59_bt[] = {0x8b, 0x8b, 0x8b,
+                                       0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89,
+                                       0x88, 0x88, 0x86, 0x85, 0x84};
+
+                               rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]);
+                       }
+               } else {
+                       if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
+                               static const char r55_nonbt_rev[] = {0x23, 0x23,
+                                       0x23, 0x23, 0x13, 0x13, 0x03, 0x03,
+                                       0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
+                               static const char r59_nonbt_rev[] = {0x07, 0x07,
+                                       0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+                                       0x07, 0x07, 0x06, 0x05, 0x04, 0x04};
+
+                               rt2800_rfcsr_write(rt2x00dev, 55, r55_nonbt_rev[idx]);
+                               rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]);
+                       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+                               static const char r59_non_bt[] = {0x8f, 0x8f,
+                                       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
+                                       0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
+
+                               rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]);
+                       }
+               }
+       }
+
+       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,
                                  struct ieee80211_conf *conf,
                                  struct rf_channel *rf,
@@ -1557,6 +1697,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
            rt2x00_rf(rt2x00dev, RF3052) ||
            rt2x00_rf(rt2x00dev, RF3320))
                rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
+       else if (rt2x00_rf(rt2x00dev, RF5390))
+               rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
        else
                rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
 
@@ -1569,12 +1711,14 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2800_bbp_write(rt2x00dev, 86, 0);
 
        if (rf->channel <= 14) {
-               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
-                       rt2800_bbp_write(rt2x00dev, 82, 0x62);
-                       rt2800_bbp_write(rt2x00dev, 75, 0x46);
-               } else {
-                       rt2800_bbp_write(rt2x00dev, 82, 0x84);
-                       rt2800_bbp_write(rt2x00dev, 75, 0x50);
+               if (!rt2x00_rt(rt2x00dev, RT5390)) {
+                       if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+                               rt2800_bbp_write(rt2x00dev, 82, 0x62);
+                               rt2800_bbp_write(rt2x00dev, 75, 0x46);
+                       } else {
+                               rt2800_bbp_write(rt2x00dev, 82, 0x84);
+                               rt2800_bbp_write(rt2x00dev, 75, 0x50);
+                       }
                }
        } else {
                rt2800_bbp_write(rt2x00dev, 82, 0xf2);
@@ -1594,13 +1738,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        tx_pin = 0;
 
        /* Turn on unused PA or LNA when not using 1T or 1R */
-       if (rt2x00dev->default_ant.tx != 1) {
+       if (rt2x00dev->default_ant.tx_chain_num == 2) {
                rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
                rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
        }
 
        /* Turn on unused PA or LNA when not using 1T or 1R */
-       if (rt2x00dev->default_ant.rx != 1) {
+       if (rt2x00dev->default_ant.rx_chain_num == 2) {
                rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
                rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
        }
@@ -1644,30 +1788,116 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
 }
 
+static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
+                                     enum ieee80211_band band)
+{
+       u16 eeprom;
+       u8 comp_en;
+       u8 comp_type;
+       int comp_value;
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
+
+       if (eeprom == 0xffff)
+               return 0;
+
+       if (band == IEEE80211_BAND_2GHZ) {
+               comp_en = rt2x00_get_field16(eeprom,
+                                EEPROM_TXPOWER_DELTA_ENABLE_2G);
+               if (comp_en) {
+                       comp_type = rt2x00_get_field16(eeprom,
+                                          EEPROM_TXPOWER_DELTA_TYPE_2G);
+                       comp_value = rt2x00_get_field16(eeprom,
+                                           EEPROM_TXPOWER_DELTA_VALUE_2G);
+                       if (!comp_type)
+                               comp_value = -comp_value;
+               }
+       } else {
+               comp_en = rt2x00_get_field16(eeprom,
+                                EEPROM_TXPOWER_DELTA_ENABLE_5G);
+               if (comp_en) {
+                       comp_type = rt2x00_get_field16(eeprom,
+                                          EEPROM_TXPOWER_DELTA_TYPE_5G);
+                       comp_value = rt2x00_get_field16(eeprom,
+                                           EEPROM_TXPOWER_DELTA_VALUE_5G);
+                       if (!comp_type)
+                               comp_value = -comp_value;
+               }
+       }
+
+       return comp_value;
+}
+
+static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
+                                    int is_rate_b,
+                                    enum ieee80211_band band,
+                                    int power_level,
+                                    u8 txpower)
+{
+       u32 reg;
+       u16 eeprom;
+       u8 criterion;
+       u8 eirp_txpower;
+       u8 eirp_txpower_criterion;
+       u8 reg_limit;
+       int bw_comp = 0;
+
+       if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
+               return txpower;
+
+       if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+               bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band);
+
+       if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) {
+               /*
+                * Check if eirp txpower exceed txpower_limit.
+                * We use OFDM 6M as criterion and its eirp txpower
+                * is stored at EEPROM_EIRP_MAX_TX_POWER.
+                * .11b data rate need add additional 4dbm
+                * when calculating eirp txpower.
+                */
+               rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
+               criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS);
+
+               rt2x00_eeprom_read(rt2x00dev,
+                                  EEPROM_EIRP_MAX_TX_POWER, &eeprom);
+
+               if (band == IEEE80211_BAND_2GHZ)
+                       eirp_txpower_criterion = rt2x00_get_field16(eeprom,
+                                                EEPROM_EIRP_MAX_TX_POWER_2GHZ);
+               else
+                       eirp_txpower_criterion = rt2x00_get_field16(eeprom,
+                                                EEPROM_EIRP_MAX_TX_POWER_5GHZ);
+
+               eirp_txpower = eirp_txpower_criterion + (txpower - criterion) +
+                                      (is_rate_b ? 4 : 0) + bw_comp;
+
+               reg_limit = (eirp_txpower > power_level) ?
+                                       (eirp_txpower - power_level) : 0;
+       } else
+               reg_limit = 0;
+
+       return txpower + bw_comp - reg_limit;
+}
+
 static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
-                                 const int max_txpower)
+                                 struct ieee80211_conf *conf)
 {
        u8 txpower;
-       u8 max_value = (u8)max_txpower;
        u16 eeprom;
-       int i;
+       int i, is_rate_b;
        u32 reg;
        u8 r1;
        u32 offset;
+       enum ieee80211_band band = conf->channel->band;
+       int power_level = conf->power_level;
 
        /*
-        * set to normal tx power mode: +/- 0dBm
+        * set to normal bbp tx power control mode: +/- 0dBm
         */
        rt2800_bbp_read(rt2x00dev, 1, &r1);
-       rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
+       rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0);
        rt2800_bbp_write(rt2x00dev, 1, r1);
-
-       /*
-        * The eeprom contains the tx power values for each rate. These
-        * values map to 100% tx power. Each 16bit word contains four tx
-        * power values and the order is the same as used in the TX_PWR_CFG
-        * registers.
-        */
        offset = TX_PWR_CFG_0;
 
        for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) {
@@ -1681,73 +1911,99 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
                rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i,
                                   &eeprom);
 
-               /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
+               is_rate_b = i ? 0 : 1;
+               /*
+                * TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS,
                 * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE0);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0, txpower);
 
-               /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
+               /*
+                * TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS,
                 * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE1);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1, txpower);
 
-               /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS,
+               /*
+                * TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS,
                 * TX_PWR_CFG_2: MCS6,  TX_PWR_CFG_3: MCS14,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE2);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2, txpower);
 
-               /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
+               /*
+                * TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS,
                 * TX_PWR_CFG_2: MCS7,  TX_PWR_CFG_3: MCS15,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE3);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
 
                /* read the next four txpower values */
                rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1,
                                   &eeprom);
 
-               /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0,
+               is_rate_b = 0;
+               /*
+                * TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0,
                 * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE0);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4, txpower);
 
-               /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1,
+               /*
+                * TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1,
                 * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE1);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5, txpower);
 
-               /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2,
+               /*
+                * TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2,
                 * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE2);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6, txpower);
 
-               /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3,
+               /*
+                * TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3,
                 * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown,
-                * TX_PWR_CFG_4: unknown */
+                * TX_PWR_CFG_4: unknown
+                */
                txpower = rt2x00_get_field16(eeprom,
                                             EEPROM_TXPOWER_BYRATE_RATE3);
-               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7,
-                                  min(txpower, max_value));
+               txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
+                                            power_level, txpower);
+               rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7, txpower);
 
                rt2800_register_write(rt2x00dev, offset, reg);
 
@@ -1806,11 +2062,13 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
        /* Always recalculate LNA gain before changing configuration */
        rt2800_config_lna_gain(rt2x00dev, libconf);
 
-       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
                rt2800_config_channel(rt2x00dev, libconf->conf,
                                      &libconf->rf, &libconf->channel);
+               rt2800_config_txpower(rt2x00dev, libconf->conf);
+       }
        if (flags & IEEE80211_CONF_CHANGE_POWER)
-               rt2800_config_txpower(rt2x00dev, libconf->conf->power_level);
+               rt2800_config_txpower(rt2x00dev, libconf->conf);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt2800_config_retry_limit(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
@@ -1839,7 +2097,8 @@ 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, RT3390))
+                   rt2x00_rt(rt2x00dev, RT3390) ||
+                   rt2x00_rt(rt2x00dev, RT5390))
                        return 0x1c + (2 * rt2x00dev->lna_gain);
                else
                        return 0x2e + rt2x00dev->lna_gain;
@@ -1971,6 +2230,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
                rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f);
+       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+               rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+               rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
        } else {
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2039,7 +2302,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 3);
        rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2052,7 +2315,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 3);
        rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2065,7 +2328,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
        rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2078,7 +2341,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
        rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2091,7 +2354,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
        rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2104,7 +2367,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
        rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
        rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
-       rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1);
        rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
        rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
        rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
@@ -2346,15 +2609,31 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
                     rt2800_wait_bbp_ready(rt2x00dev)))
                return -EACCES;
 
-       if (rt2800_is_305x_soc(rt2x00dev))
+       if (rt2x00_rt(rt2x00dev, RT5390)) {
+               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, RT5390))
                rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
        rt2800_bbp_write(rt2x00dev, 65, 0x2c);
        rt2800_bbp_write(rt2x00dev, 66, 0x38);
 
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               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)) {
+               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);
        } else {
                rt2800_bbp_write(rt2x00dev, 69, 0x12);
                rt2800_bbp_write(rt2x00dev, 73, 0x10);
@@ -2365,7 +2644,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_rt(rt2x00dev, RT3070) ||
            rt2x00_rt(rt2x00dev, RT3071) ||
            rt2x00_rt(rt2x00dev, RT3090) ||
-           rt2x00_rt(rt2x00dev, RT3390)) {
+           rt2x00_rt(rt2x00dev, RT3390) ||
+           rt2x00_rt(rt2x00dev, RT5390)) {
                rt2800_bbp_write(rt2x00dev, 79, 0x13);
                rt2800_bbp_write(rt2x00dev, 80, 0x05);
                rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -2377,35 +2657,62 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
        }
 
        rt2800_bbp_write(rt2x00dev, 82, 0x62);
-       rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               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))
+               rt2800_bbp_write(rt2x00dev, 84, 0x9a);
        else
                rt2800_bbp_write(rt2x00dev, 84, 0x99);
 
-       rt2800_bbp_write(rt2x00dev, 86, 0x00);
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 86, 0x38);
+       else
+               rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
        rt2800_bbp_write(rt2x00dev, 91, 0x04);
-       rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 92, 0x02);
+       else
+               rt2800_bbp_write(rt2x00dev, 92, 0x00);
 
        if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
            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, RT5390) ||
            rt2800_is_305x_soc(rt2x00dev))
                rt2800_bbp_write(rt2x00dev, 103, 0xc0);
        else
                rt2800_bbp_write(rt2x00dev, 103, 0x00);
 
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 104, 0x92);
+
        if (rt2800_is_305x_soc(rt2x00dev))
                rt2800_bbp_write(rt2x00dev, 105, 0x01);
+       else if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 105, 0x3c);
        else
                rt2800_bbp_write(rt2x00dev, 105, 0x05);
-       rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 106, 0x03);
+       else
+               rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+       if (rt2x00_rt(rt2x00dev, RT5390))
+               rt2800_bbp_write(rt2x00dev, 128, 0x12);
 
        if (rt2x00_rt(rt2x00dev, RT3071) ||
            rt2x00_rt(rt2x00dev, RT3090) ||
-           rt2x00_rt(rt2x00dev, RT3390)) {
+           rt2x00_rt(rt2x00dev, RT3390) ||
+           rt2x00_rt(rt2x00dev, RT5390)) {
                rt2800_bbp_read(rt2x00dev, 138, &value);
 
                rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
@@ -2417,6 +2724,41 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
                rt2800_bbp_write(rt2x00dev, 138, value);
        }
 
+       if (rt2x00_rt(rt2x00dev, RT5390)) {
+               int ant, div_mode;
+
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+               div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
+               ant = (div_mode == 3) ? 1 : 0;
+
+               /* check if this is a Bluetooth combo card */
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+                       u32 reg;
+
+                       rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+                       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
+                       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT6, 0);
+                       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, 0);
+                       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT6, 0);
+                       if (ant == 0)
+                               rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT3, 1);
+                       else if (ant == 1)
+                               rt2x00_set_field32(&reg, GPIO_CTRL_CFG_BIT6, 1);
+                       rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+               }
+
+               rt2800_bbp_read(rt2x00dev, 152, &value);
+               if (ant == 0)
+                       rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
+               else
+                       rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
+               rt2800_bbp_write(rt2x00dev, 152, value);
+
+               /* Init frequency calibration */
+               rt2800_bbp_write(rt2x00dev, 142, 1);
+               rt2800_bbp_write(rt2x00dev, 143, 57);
+       }
 
        for (i = 0; i < EEPROM_BBP_SIZE; i++) {
                rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
@@ -2506,18 +2848,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rt(rt2x00dev, RT3071) &&
            !rt2x00_rt(rt2x00dev, RT3090) &&
            !rt2x00_rt(rt2x00dev, RT3390) &&
+           !rt2x00_rt(rt2x00dev, RT5390) &&
            !rt2800_is_305x_soc(rt2x00dev))
                return 0;
 
        /*
         * Init RF calibration.
         */
-       rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
-       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
-       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
-       msleep(1);
-       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
-       rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+       if (rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
+               rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+               msleep(1);
+               rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0);
+               rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+       } else {
+               rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+               rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+               msleep(1);
+               rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+               rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+       }
 
        if (rt2x00_rt(rt2x00dev, RT3070) ||
            rt2x00_rt(rt2x00dev, RT3071) ||
@@ -2608,6 +2960,87 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
                return 0;
+       } else if (rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
+               rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
+               rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
+               rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
+               rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
+               rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
+               rt2800_rfcsr_write(rt2x00dev, 12, 0xc6);
+               rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
+               rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
+               rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
+
+               rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+               rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
+               rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
+               rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
+
+               rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+               rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+               rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
+               rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
+               rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
+               rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
+               rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
+
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
+               rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
+               rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
+               rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
+               rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
+               rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 46, 0x7b);
+               rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
+               rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
+
+               rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
+               rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
+               rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
+               rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
+               rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
+               rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
+               rt2800_rfcsr_write(rt2x00dev, 59, 0x63);
+
+               rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
+               if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
+               else
+                       rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
+               rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+               rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
        }
 
        if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -2661,21 +3094,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
        }
 
-       /*
-        * Set back to initial state
-        */
-       rt2800_bbp_write(rt2x00dev, 24, 0);
+       if (!rt2x00_rt(rt2x00dev, RT5390)) {
+               /*
+                * Set back to initial state
+                */
+               rt2800_bbp_write(rt2x00dev, 24, 0);
 
-       rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
-       rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
-       rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
+               rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+               rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
 
-       /*
-        * set BBP back to BW20
-        */
-       rt2800_bbp_read(rt2x00dev, 4, &bbp);
-       rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
-       rt2800_bbp_write(rt2x00dev, 4, bbp);
+               /*
+                * Set BBP back to BW20
+                */
+               rt2800_bbp_read(rt2x00dev, 4, &bbp);
+               rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+               rt2800_bbp_write(rt2x00dev, 4, bbp);
+       }
 
        if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) ||
            rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
@@ -2687,21 +3122,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, OPT_14_CSR_BIT0, 1);
        rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
 
-       rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
-       rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
-       if (rt2x00_rt(rt2x00dev, RT3070) ||
-           rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
-           rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
-           rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
-               if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
-                       rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
-       }
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
-       if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
-               rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
-                                 rt2x00_get_field16(eeprom,
-                                                  EEPROM_TXMIXER_GAIN_BG_VAL));
-       rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+       if (!rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
+               if (rt2x00_rt(rt2x00dev, RT3070) ||
+                   rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
+                   rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
+                   rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
+                       if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+                               rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
+               }
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
+               if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
+                       rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
+                                       rt2x00_get_field16(eeprom,
+                                               EEPROM_TXMIXER_GAIN_BG_VAL));
+               rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
+       }
 
        if (rt2x00_rt(rt2x00dev, RT3090)) {
                rt2800_bbp_read(rt2x00dev, 138, &bbp);
@@ -2752,6 +3189,20 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
        }
 
+       if (rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
+               rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
+
+               rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0);
+               rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+
+               rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+               rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2);
+               rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+       }
+
        return 0;
 }
 
@@ -3000,13 +3451,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
                                   default_lna_gain);
        rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word);
-       if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff)
-               rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER);
-       if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff)
-               rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER);
-       rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
@@ -3023,10 +3467,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
 
        /*
-        * Identify RF chipset.
+        * Identify RF chipset by EEPROM value
+        * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field
+        * RT53xx: defined in "EEPROM_CHIP_ID" field
         */
-       value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
        rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+       if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390)
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
+       else
+               value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
 
        rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
                        value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
@@ -3038,7 +3487,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rt(rt2x00dev, RT3071) &&
            !rt2x00_rt(rt2x00dev, RT3090) &&
            !rt2x00_rt(rt2x00dev, RT3390) &&
-           !rt2x00_rt(rt2x00dev, RT3572)) {
+           !rt2x00_rt(rt2x00dev, RT3572) &&
+           !rt2x00_rt(rt2x00dev, RT5390)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
@@ -3052,7 +3502,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
            !rt2x00_rf(rt2x00dev, RF3021) &&
            !rt2x00_rf(rt2x00dev, RF3022) &&
            !rt2x00_rf(rt2x00dev, RF3052) &&
-           !rt2x00_rf(rt2x00dev, RF3320)) {
+           !rt2x00_rf(rt2x00dev, RF3320) &&
+           !rt2x00_rf(rt2x00dev, RF5390)) {
                ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
                return -ENODEV;
        }
@@ -3060,11 +3511,35 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->default_ant.tx =
+       rt2x00dev->default_ant.tx_chain_num =
            rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
-       rt2x00dev->default_ant.rx =
+       rt2x00dev->default_ant.rx_chain_num =
            rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
 
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+
+       if (rt2x00_rt(rt2x00dev, RT3070) ||
+           rt2x00_rt(rt2x00dev, RT3090) ||
+           rt2x00_rt(rt2x00dev, RT3390)) {
+               value = rt2x00_get_field16(eeprom,
+                               EEPROM_NIC_CONF1_ANT_DIVERSITY);
+               switch (value) {
+               case 0:
+               case 1:
+               case 2:
+                       rt2x00dev->default_ant.tx = ANTENNA_A;
+                       rt2x00dev->default_ant.rx = ANTENNA_A;
+                       break;
+               case 3:
+                       rt2x00dev->default_ant.tx = ANTENNA_A;
+                       rt2x00dev->default_ant.rx = ANTENNA_B;
+                       break;
+               }
+       } else {
+               rt2x00dev->default_ant.tx = ANTENNA_A;
+               rt2x00dev->default_ant.rx = ANTENNA_A;
+       }
+
        /*
         * Read frequency offset and RF programming sequence.
         */
@@ -3098,6 +3573,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg);
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
+       /*
+        * Check if support EIRP tx power limit feature.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom);
+
+       if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
+                                       EIRP_MAX_TX_POWER_LIMIT)
+               __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2800_init_eeprom);
@@ -3250,7 +3734,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        char *default_power1;
        char *default_power2;
        unsigned int i;
-       unsigned short max_power;
        u16 eeprom;
 
        /*
@@ -3317,7 +3800,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
                   rt2x00_rf(rt2x00dev, RF2020) ||
                   rt2x00_rf(rt2x00dev, RF3021) ||
                   rt2x00_rf(rt2x00dev, RF3022) ||
-                  rt2x00_rf(rt2x00dev, RF3320)) {
+                  rt2x00_rf(rt2x00dev, RF3320) ||
+                  rt2x00_rf(rt2x00dev, RF5390)) {
                spec->num_channels = 14;
                spec->channels = rf_vals_3x;
        } else if (rt2x00_rf(rt2x00dev, RF3052)) {
@@ -3375,26 +3859,21 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 
        spec->channels_info = info;
 
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom);
-       max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ);
        default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
        default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
 
        for (i = 0; i < 14; i++) {
-               info[i].max_power = max_power;
-               info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]);
-               info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]);
+               info[i].default_power1 = default_power1[i];
+               info[i].default_power2 = default_power2[i];
        }
 
        if (spec->num_channels > 14) {
-               max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ);
                default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
                default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
 
                for (i = 14; i < spec->num_channels; i++) {
-                       info[i].max_power = max_power;
-                       info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]);
-                       info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]);
+                       info[i].default_power1 = default_power1[i];
+                       info[i].default_power2 = default_power2[i];
                }
        }
 
index 8f4dfc3..38605e9 100644 (file)
@@ -493,6 +493,13 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
        rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
 
+       if (rt2x00_rt(rt2x00dev, RT5390)) {
+               rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
+               rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
+               rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
+               rt2800_register_write(rt2x00dev, AUX_CTRL, reg);
+       }
+
        rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
        rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
@@ -1119,12 +1126,17 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
        { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
 #endif
 #ifdef CONFIG_RT2800PCI_RT35XX
+       { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
+       { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
        { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
        { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
        { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
        { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
        { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
 #endif
+#ifdef CONFIG_RT2800PCI_RT53XX
+       { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) },
+#endif
        { 0, }
 };
 #endif /* CONFIG_PCI */
index 39bc2fa..1df432c 100644 (file)
@@ -189,6 +189,7 @@ struct rt2x00_chip {
 #define RT3572         0x3572
 #define RT3593         0x3593  /* PCIe */
 #define RT3883         0x3883  /* WSOC */
+#define RT5390         0x5390  /* 2.4GHz */
 
        u16 rf;
        u16 rev;
@@ -225,6 +226,8 @@ struct channel_info {
 struct antenna_setup {
        enum antenna rx;
        enum antenna tx;
+       u8 rx_chain_num;
+       u8 tx_chain_num;
 };
 
 /*
@@ -665,6 +668,7 @@ enum rt2x00_flags {
         */
        CONFIG_SUPPORT_HW_BUTTON,
        CONFIG_SUPPORT_HW_CRYPTO,
+       CONFIG_SUPPORT_POWER_LIMIT,
        DRIVER_SUPPORT_CONTROL_FILTERS,
        DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
        DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,
index b7ad46e..03d9579 100644 (file)
@@ -69,7 +69,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
                        txdesc->mcs |= 0x08;
        }
 
-
        /*
         * This frame is eligible for an AMPDU, however, don't aggregate
         * frames that are intended to probe a specific tx rate.
index 6a66021..1b3edef 100644 (file)
@@ -139,9 +139,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
         * either RTS or CTS-to-self frame and handles everything
         * inside the hardware.
         */
-       if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
-                                               IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
-           !rt2x00dev->ops->hw->set_rts_threshold) {
+       if (!rt2x00dev->ops->hw->set_rts_threshold &&
+           (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
+                                               IEEE80211_TX_RC_USE_CTS_PROTECT))) {
                if (rt2x00queue_available(queue) <= 1)
                        goto exit_fail;
 
index fa17c83..bf9bba3 100644 (file)
@@ -365,13 +365,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 
        /*
         * Beacons and probe responses require the tsf timestamp
-        * to be inserted into the frame, except for a frame that has been injected
-        * through a monitor interface. This latter is needed for testing a
-        * monitor interface.
+        * to be inserted into the frame.
         */
-       if ((ieee80211_is_beacon(hdr->frame_control) ||
-           ieee80211_is_probe_resp(hdr->frame_control)) &&
-           (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
+       if (ieee80211_is_beacon(hdr->frame_control) ||
+           ieee80211_is_probe_resp(hdr->frame_control))
                __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
 
        /*
index dd2164d..927a4a3 100644 (file)
@@ -1978,13 +1978,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
        unsigned int beacon_base;
        unsigned int padding_len;
-       u32 reg;
+       u32 orig_reg, reg;
 
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -2002,7 +2003,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
         * Write entire beacon with descriptor and padding to register.
         */
        padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
-       skb_pad(entry->skb, padding_len);
+       if (padding_len && skb_pad(entry->skb, padding_len)) {
+               ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
+               /* skb freed by skb_pad() on failure */
+               entry->skb = NULL;
+               rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
+               return;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
                                      entry_priv->desc, TXINFO_SIZE);
index 5ff72de..6e9981a 100644 (file)
@@ -1533,13 +1533,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        unsigned int beacon_base;
        unsigned int padding_len;
-       u32 reg;
+       u32 orig_reg, reg;
 
        /*
         * Disable beaconing while we are reloading the beacon data,
         * otherwise we might be sending out invalid data.
         */
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       orig_reg = reg;
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -1563,7 +1564,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
         * Write entire beacon with descriptor and padding to register.
         */
        padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
-       skb_pad(entry->skb, padding_len);
+       if (padding_len && skb_pad(entry->skb, padding_len)) {
+               ERROR(rt2x00dev, "Failure padding beacon, aborting\n");
+               /* skb freed by skb_pad() on failure */
+               entry->skb = NULL;
+               rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
+               return;
+       }
+
        beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
        rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
                                      entry->skb->len + padding_len);
index 7f6573f..86f8d4d 100644 (file)
@@ -1,6 +1,6 @@
 config RTL8192CE
-       tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
-       depends on MAC80211 && EXPERIMENTAL
+       tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter"
+       depends on MAC80211 && PCI && EXPERIMENTAL
        select FW_LOADER
        select RTLWIFI
        ---help---
@@ -9,7 +9,18 @@ config RTL8192CE
 
        If you choose to build it as a module, it will be called rtl8192ce
 
+config RTL8192CU
+       tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
+       depends on MAC80211 && USB && EXPERIMENTAL
+       select FW_LOADER
+       select RTLWIFI
+       ---help---
+       This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
+       wireless network adapters.
+
+       If you choose to build it as a module, it will be called rtl8192cu
+
 config RTLWIFI
        tristate
-       depends on RTL8192CE
+       depends on RTL8192CE || RTL8192CU
        default m
index 2a7a438..c3e83a1 100644 (file)
@@ -8,6 +8,10 @@ rtlwifi-objs   :=              \
                pci.o           \
                ps.o            \
                rc.o            \
-               regd.o
+               regd.o          \
+               usb.o
 
 obj-$(CONFIG_RTL8192CE)                += rtl8192ce/
+obj-$(CONFIG_RTL8192CU)                += rtl8192cu/
+
+ccflags-y += -D__CHECK_ENDIAN__
index cf0b73e..3f40dc2 100644 (file)
@@ -144,7 +144,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
                ht_cap->mcs.rx_mask[1] = 0xFF;
                ht_cap->mcs.rx_mask[4] = 0x01;
 
-               ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
+               ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
        } else if (get_rf_type(rtlphy) == RF_1T1R) {
 
                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
@@ -153,7 +153,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
                ht_cap->mcs.rx_mask[1] = 0x00;
                ht_cap->mcs.rx_mask[4] = 0x01;
 
-               ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
+               ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
        }
 }
 
@@ -399,21 +399,21 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
        u8 rate_flag = info->control.rates[0].flags;
 
        /* Common Settings */
-       tcb_desc->b_rts_stbc = false;
-       tcb_desc->b_cts_enable = false;
+       tcb_desc->rts_stbc = false;
+       tcb_desc->cts_enable = false;
        tcb_desc->rts_sc = 0;
-       tcb_desc->b_rts_bw = false;
-       tcb_desc->b_rts_use_shortpreamble = false;
-       tcb_desc->b_rts_use_shortgi = false;
+       tcb_desc->rts_bw = false;
+       tcb_desc->rts_use_shortpreamble = false;
+       tcb_desc->rts_use_shortgi = false;
 
        if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                /* Use CTS-to-SELF in protection mode. */
-               tcb_desc->b_rts_enable = true;
-               tcb_desc->b_cts_enable = true;
+               tcb_desc->rts_enable = true;
+               tcb_desc->cts_enable = true;
                tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
        } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
                /* Use RTS-CTS in protection mode. */
-               tcb_desc->b_rts_enable = true;
+               tcb_desc->rts_enable = true;
                tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
        }
 
@@ -429,7 +429,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
                if (mac->opmode == NL80211_IFTYPE_STATION)
                        tcb_desc->ratr_index = 0;
                else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
-                       if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
+                       if (tcb_desc->multicast || tcb_desc->broadcast) {
                                tcb_desc->hw_rate =
                                    rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
                                tcb_desc->use_driver_rate = 1;
@@ -439,7 +439,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
                }
        }
 
-       if (rtlpriv->dm.b_useramask) {
+       if (rtlpriv->dm.useramask) {
                /* TODO we will differentiate adhoc and station futrue  */
                tcb_desc->mac_id = 0;
 
@@ -461,19 +461,19 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
-       tcb_desc->b_packet_bw = false;
+       tcb_desc->packet_bw = false;
 
        if (!mac->bw_40 || !mac->ht_enable)
                return;
 
-       if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
+       if (tcb_desc->multicast || tcb_desc->broadcast)
                return;
 
        /*use legency rate, shall use 20MHz */
        if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
                return;
 
-       tcb_desc->b_packet_bw = true;
+       tcb_desc->packet_bw = true;
 }
 
 static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
@@ -498,7 +498,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
        struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
        struct ieee80211_rate *txrate;
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
 
        memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
 
@@ -545,9 +545,9 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
                }
 
                if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
-                       tcb_desc->b_multicast = 1;
+                       tcb_desc->multicast = 1;
                else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
-                       tcb_desc->b_broadcast = 1;
+                       tcb_desc->broadcast = 1;
 
                _rtl_txrate_selectmode(hw, tcb_desc);
                _rtl_query_bandwidth_mode(hw, tcb_desc);
@@ -570,7 +570,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
 
        if (ieee80211_is_auth(fc)) {
                RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
@@ -587,7 +587,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
        struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
        u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
        u8 category;
 
@@ -632,7 +632,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
        u16 ether_type;
        u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
        const struct iphdr *ip;
@@ -646,7 +646,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
        ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
                              SNAP_SIZE + PROTOC_TYPE_SIZE);
        ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
-       ether_type = ntohs(ether_type);
 
        if (ETH_P_IP == ether_type) {
                if (IPPROTO_UDP == ip->protocol) {
@@ -690,7 +689,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                }
 
                return true;
-       } else if (0x86DD == ether_type) {
+       } else if (ETH_P_IPV6 == ether_type) {
+               /* IPv6 */
                return true;
        }
 
@@ -777,10 +777,10 @@ void rtl_watchdog_wq_callback(void *data)
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
-       bool b_busytraffic = false;
-       bool b_higher_busytraffic = false;
-       bool b_higher_busyrxtraffic = false;
-       bool b_higher_busytxtraffic = false;
+       bool busytraffic = false;
+       bool higher_busytraffic = false;
+       bool higher_busyrxtraffic = false;
+       bool higher_busytxtraffic = false;
 
        u8 idx = 0;
        u32 rx_cnt_inp4eriod = 0;
@@ -788,7 +788,7 @@ void rtl_watchdog_wq_callback(void *data)
        u32 aver_rx_cnt_inperiod = 0;
        u32 aver_tx_cnt_inperiod = 0;
 
-       bool benter_ps = false;
+       bool enter_ps = false;
 
        if (is_hal_stop(rtlhal))
                return;
@@ -832,29 +832,29 @@ void rtl_watchdog_wq_callback(void *data)
 
                /* (2) check traffic busy */
                if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
-                       b_busytraffic = true;
+                       busytraffic = true;
 
                /* Higher Tx/Rx data. */
                if (aver_rx_cnt_inperiod > 4000 ||
                    aver_tx_cnt_inperiod > 4000) {
-                       b_higher_busytraffic = true;
+                       higher_busytraffic = true;
 
                        /* Extremely high Rx data. */
                        if (aver_rx_cnt_inperiod > 5000)
-                               b_higher_busyrxtraffic = true;
+                               higher_busyrxtraffic = true;
                        else
-                               b_higher_busytxtraffic = false;
+                               higher_busytxtraffic = false;
                }
 
                if (((rtlpriv->link_info.num_rx_inperiod +
                      rtlpriv->link_info.num_tx_inperiod) > 8) ||
                    (rtlpriv->link_info.num_rx_inperiod > 2))
-                       benter_ps = false;
+                       enter_ps = false;
                else
-                       benter_ps = true;
+                       enter_ps = true;
 
                /* LeisurePS only work in infra mode. */
-               if (benter_ps)
+               if (enter_ps)
                        rtl_lps_enter(hw);
                else
                        rtl_lps_leave(hw);
@@ -863,9 +863,9 @@ void rtl_watchdog_wq_callback(void *data)
        rtlpriv->link_info.num_rx_inperiod = 0;
        rtlpriv->link_info.num_tx_inperiod = 0;
 
-       rtlpriv->link_info.b_busytraffic = b_busytraffic;
-       rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
-       rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
+       rtlpriv->link_info.busytraffic = busytraffic;
+       rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
+       rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
 
 }
 
index 3de5a14..0430453 100644 (file)
@@ -30,6 +30,7 @@
 #define __RTL_BASE_H__
 
 #define RTL_DUMMY_OFFSET       0
+#define RTL_RX_DESC_SIZE       24
 #define RTL_DUMMY_UNIT         8
 #define RTL_TX_DUMMY_SIZE      (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
 #define RTL_TX_DESC_SIZE       32
 #define FRAME_OFFSET_SEQUENCE          22
 #define FRAME_OFFSET_ADDRESS4          24
 
-#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val)                \
-       WRITEEF2BYTE(_hdr, _val)
-#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val)     \
-       WRITEEF1BYTE(_hdr, _val)
-#define SET_80211_HDR_PWR_MGNT(_hdr, _val)             \
-       SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
-#define SET_80211_HDR_TO_DS(_hdr, _val)                        \
-       SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
 
 #define SET_80211_PS_POLL_AID(_hdr, _val)              \
-       WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
+       (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val))
 #define SET_80211_PS_POLL_BSSID(_hdr, _val)            \
-       CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
+       memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN)
 #define SET_80211_PS_POLL_TA(_hdr, _val)               \
-       CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
+       memcpy(((u8 *)(_hdr)) + 10, (u8 *)(_val), ETH_ALEN)
 
 #define SET_80211_HDR_DURATION(_hdr, _val)     \
-       WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
+       (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
 #define SET_80211_HDR_ADDRESS1(_hdr, _val)     \
-       CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
+       memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN)
 #define SET_80211_HDR_ADDRESS2(_hdr, _val)     \
-       CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
+       memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN)
 #define SET_80211_HDR_ADDRESS3(_hdr, _val)     \
-       CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
-#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val)  \
-       WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
-
-#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val)     \
-       WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
-#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
-       WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
-#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
-       WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
-#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr)   \
-       READEF2BYTE(((u8 *)(__phdr)) + 34)
-#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
-       WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
-#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
-       SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
-       (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
+       memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN)
 
 int rtl_init_core(struct ieee80211_hw *hw);
 void rtl_deinit_core(struct ieee80211_hw *hw);
index 25d2d66..b0996bf 100644 (file)
@@ -434,9 +434,9 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
 
        aci = _rtl_get_hal_qnum(queue);
        mac->ac[aci].aifs = param->aifs;
-       mac->ac[aci].cw_min = param->cw_min;
-       mac->ac[aci].cw_max = param->cw_max;
-       mac->ac[aci].tx_op = param->txop;
+       mac->ac[aci].cw_min = cpu_to_le16(param->cw_min);
+       mac->ac[aci].cw_max = cpu_to_le16(param->cw_max);
+       mac->ac[aci].tx_op = cpu_to_le16(param->txop);
        memcpy(&mac->edca_param[aci], param, sizeof(*param));
        rtlpriv->cfg->ops->set_qos(hw, aci);
        return 0;
@@ -666,7 +666,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
                                        (u8 *) (&basic_rates));
 
-                       if (rtlpriv->dm.b_useramask)
+                       if (rtlpriv->dm.useramask)
                                rtlpriv->cfg->ops->update_rate_mask(hw, 0);
                        else
                                rtlpriv->cfg->ops->update_rate_table(hw);
@@ -681,7 +681,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
         */
        if (changed & BSS_CHANGED_ASSOC) {
                if (bss_conf->assoc) {
-                       if (ppsc->b_fwctrl_lps) {
+                       if (ppsc->fwctrl_lps) {
                                u8 mstatus = RT_MEDIA_CONNECT;
                                rtlpriv->cfg->ops->set_hw_reg(hw,
                                                      HW_VAR_H2C_FW_JOINBSSRPT,
@@ -689,7 +689,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                                ppsc->report_linked = true;
                        }
                } else {
-                       if (ppsc->b_fwctrl_lps) {
+                       if (ppsc->fwctrl_lps) {
                                u8 mstatus = RT_MEDIA_DISCONNECT;
                                rtlpriv->cfg->ops->set_hw_reg(hw,
                                                      HW_VAR_H2C_FW_JOINBSSRPT,
@@ -818,7 +818,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
                /* fix fwlps issue */
                rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
 
-               if (rtlpriv->dm.b_useramask)
+               if (rtlpriv->dm.useramask)
                        rtlpriv->cfg->ops->update_rate_mask(hw, 0);
                else
                        rtlpriv->cfg->ops->update_rate_table(hw);
index 08bdec2..e4aa868 100644 (file)
 #define COMP_MAC80211          BIT(26)
 #define COMP_REGD                      BIT(27)
 #define COMP_CHAN                      BIT(28)
+#define COMP_USB                       BIT(29)
 
 /*--------------------------------------------------------------
                Define the rt_print components
index 1758d44..1f18bf7 100644 (file)
@@ -50,7 +50,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
        u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
 
        ppsc->reg_rfps_level = 0;
-       ppsc->b_support_aspm = 0;
+       ppsc->support_aspm = 0;
 
        /*Update PCI ASPM setting */
        ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
@@ -115,29 +115,29 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
        switch (rtlpci->const_support_pciaspm) {
        case 0:{
                        /*Not support ASPM. */
-                       bool b_support_aspm = false;
-                       ppsc->b_support_aspm = b_support_aspm;
+                       bool support_aspm = false;
+                       ppsc->support_aspm = support_aspm;
                        break;
                }
        case 1:{
                        /*Support ASPM. */
-                       bool b_support_aspm = true;
-                       bool b_support_backdoor = true;
-                       ppsc->b_support_aspm = b_support_aspm;
+                       bool support_aspm = true;
+                       bool support_backdoor = true;
+                       ppsc->support_aspm = support_aspm;
 
                        /*if(priv->oem_id == RT_CID_TOSHIBA &&
                           !priv->ndis_adapter.amd_l1_patch)
-                          b_support_backdoor = false; */
+                          support_backdoor = false; */
 
-                       ppsc->b_support_backdoor = b_support_backdoor;
+                       ppsc->support_backdoor = support_backdoor;
 
                        break;
                }
        case 2:
                /*ASPM value set by chipset. */
                if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
-                       bool b_support_aspm = true;
-                       ppsc->b_support_aspm = b_support_aspm;
+                       bool support_aspm = true;
+                       ppsc->support_aspm = support_aspm;
                }
                break;
        default:
@@ -476,9 +476,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
 
                skb = __skb_dequeue(&ring->queue);
                pci_unmap_single(rtlpci->pdev,
-                                le32_to_cpu(rtlpriv->cfg->ops->
+                                rtlpriv->cfg->ops->
                                             get_desc((u8 *) entry, true,
-                                                     HW_DESC_TXBUFF_ADDR)),
+                                                     HW_DESC_TXBUFF_ADDR),
                                 skb->len, PCI_DMA_TODEVICE);
 
                RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
@@ -557,7 +557,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        return;
                } else {
                        struct ieee80211_hdr *hdr;
-                       u16 fc;
+                       __le16 fc;
                        struct sk_buff *new_skb = NULL;
 
                        rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
@@ -583,9 +583,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                         */
 
                        hdr = (struct ieee80211_hdr *)(skb->data);
-                       fc = le16_to_cpu(hdr->frame_control);
+                       fc = hdr->frame_control;
 
-                       if (!stats.b_crc) {
+                       if (!stats.crc) {
                                memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
                                       sizeof(rx_status));
 
@@ -666,7 +666,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 
                }
 done:
-               bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb));
+               bufferaddress = (u32)(*((dma_addr_t *) skb->cb));
                tmp_one = 1;
                rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
                                            HW_DESC_RXBUFF_ADDR,
@@ -690,75 +690,6 @@ done:
 
 }
 
-void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       int prio;
-
-       for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) {
-               struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
-
-               while (skb_queue_len(&ring->queue)) {
-                       struct rtl_tx_desc *entry = &ring->desc[ring->idx];
-                       struct sk_buff *skb;
-                       struct ieee80211_tx_info *info;
-                       u8 own;
-
-                       /*
-                        *beacon packet will only use the first
-                        *descriptor defautly, and the own may not
-                        *be cleared by the hardware, and
-                        *beacon will free in prepare beacon
-                        */
-                       if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE ||
-                           prio == HCCA_QUEUE)
-                               break;
-
-                       own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry,
-                                                              true,
-                                                              HW_DESC_OWN);
-
-                       if (own)
-                               break;
-
-                       skb = __skb_dequeue(&ring->queue);
-                       pci_unmap_single(rtlpci->pdev,
-                                        le32_to_cpu(rtlpriv->cfg->ops->
-                                                    get_desc((u8 *) entry,
-                                                    true,
-                                                    HW_DESC_TXBUFF_ADDR)),
-                                        skb->len, PCI_DMA_TODEVICE);
-
-                       ring->idx = (ring->idx + 1) % ring->entries;
-
-                       info = IEEE80211_SKB_CB(skb);
-                       ieee80211_tx_info_clear_status(info);
-
-                       info->flags |= IEEE80211_TX_STAT_ACK;
-                       /*info->status.rates[0].count = 1; */
-
-                       ieee80211_tx_status_irqsafe(hw, skb);
-
-                       if ((ring->entries - skb_queue_len(&ring->queue))
-                           == 2 && prio != BEACON_QUEUE) {
-                               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                                        ("more desc left, wake "
-                                         "skb_queue@%d,ring->idx = %d,"
-                                         "skb_queue_len = 0x%d\n",
-                                         prio, ring->idx,
-                                         skb_queue_len(&ring->queue)));
-
-                               ieee80211_wake_queue(hw,
-                                                    skb_get_queue_mapping
-                                                    (skb));
-                       }
-
-                       skb = NULL;
-               }
-       }
-}
-
 static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 {
        struct ieee80211_hw *hw = dev_id;
@@ -959,17 +890,17 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
        rtlhal->hw = hw;
        rtlpci->pdev = pdev;
 
-       ppsc->b_inactiveps = false;
-       ppsc->b_leisure_ps = true;
-       ppsc->b_fwctrl_lps = true;
-       ppsc->b_reg_fwctrl_lps = 3;
+       ppsc->inactiveps = false;
+       ppsc->leisure_ps = true;
+       ppsc->fwctrl_lps = true;
+       ppsc->reg_fwctrl_lps = 3;
        ppsc->reg_max_lps_awakeintvl = 5;
 
-       if (ppsc->b_reg_fwctrl_lps == 1)
+       if (ppsc->reg_fwctrl_lps == 1)
                ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
-       else if (ppsc->b_reg_fwctrl_lps == 2)
+       else if (ppsc->reg_fwctrl_lps == 2)
                ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
-       else if (ppsc->b_reg_fwctrl_lps == 3)
+       else if (ppsc->reg_fwctrl_lps == 3)
                ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
 
        /*Tx/Rx related var */
@@ -1024,9 +955,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
                 ("queue:%d, ring_addr:%p\n", prio, ring));
 
        for (i = 0; i < entries; i++) {
-               nextdescaddress = cpu_to_le32((u32) dma +
-                                             ((i + 1) % entries) *
-                                             sizeof(*ring));
+               nextdescaddress = (u32) dma + ((i + 1) % entries) *
+                                             sizeof(*ring);
 
                rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
                                            true, HW_DESC_TX_NEXTDESC_ADDR,
@@ -1090,7 +1020,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
                                           rtlpci->rxbuffersize,
                                           PCI_DMA_FROMDEVICE);
 
-                       bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
+                       bufferaddress = (u32)(*((dma_addr_t *)skb->cb));
                        rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
                                                    HW_DESC_RXBUFF_ADDR,
                                                    (u8 *)&bufferaddress);
@@ -1121,9 +1051,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
                struct sk_buff *skb = __skb_dequeue(&ring->queue);
 
                pci_unmap_single(rtlpci->pdev,
-                                le32_to_cpu(rtlpriv->cfg->
+                                rtlpriv->cfg->
                                             ops->get_desc((u8 *) entry, true,
-                                                  HW_DESC_TXBUFF_ADDR)),
+                                                  HW_DESC_TXBUFF_ADDR),
                                 skb->len, PCI_DMA_TODEVICE);
                kfree_skb(skb);
                ring->idx = (ring->idx + 1) % ring->entries;
@@ -1255,11 +1185,11 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
                                    __skb_dequeue(&ring->queue);
 
                                pci_unmap_single(rtlpci->pdev,
-                                                le32_to_cpu(rtlpriv->cfg->ops->
+                                                rtlpriv->cfg->ops->
                                                         get_desc((u8 *)
                                                         entry,
                                                         true,
-                                                        HW_DESC_TXBUFF_ADDR)),
+                                                        HW_DESC_TXBUFF_ADDR),
                                                 skb->len, PCI_DMA_TODEVICE);
                                kfree_skb(skb);
                                ring->idx = (ring->idx + 1) % ring->entries;
@@ -1273,7 +1203,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
        return 0;
 }
 
-unsigned int _rtl_mac_to_hwqueue(u16 fc,
+static unsigned int _rtl_mac_to_hwqueue(__le16 fc,
                unsigned int mac80211_queue_index)
 {
        unsigned int hw_queue_index;
@@ -1312,7 +1242,7 @@ out:
        return hw_queue_index;
 }
 
-int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -1323,7 +1253,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        unsigned int queue_index, hw_queue;
        unsigned long flags;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
-       u16 fc = le16_to_cpu(hdr->frame_control);
+       __le16 fc = hdr->frame_control;
        u8 *pda_addr = hdr->addr1;
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        /*ssn */
@@ -1429,7 +1359,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        return 0;
 }
 
-void rtl_pci_deinit(struct ieee80211_hw *hw)
+static void rtl_pci_deinit(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1444,7 +1374,7 @@ void rtl_pci_deinit(struct ieee80211_hw *hw)
 
 }
 
-int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
+static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        int err;
@@ -1461,7 +1391,7 @@ int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
        return 1;
 }
 
-int rtl_pci_start(struct ieee80211_hw *hw)
+static int rtl_pci_start(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -1496,7 +1426,7 @@ int rtl_pci_start(struct ieee80211_hw *hw)
        return 0;
 }
 
-void rtl_pci_stop(struct ieee80211_hw *hw)
+static void rtl_pci_stop(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1838,7 +1768,7 @@ fail3:
        ieee80211_free_hw(hw);
 
        if (rtlpriv->io.pci_mem_start != 0)
-               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+               pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
 
 fail2:
        pci_release_regions(pdev);
@@ -1888,7 +1818,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
        }
 
        if (rtlpriv->io.pci_mem_start != 0) {
-               pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
+               pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
                pci_release_regions(pdev);
        }
 
index d36a669..0caa814 100644 (file)
@@ -244,34 +244,34 @@ int rtl_pci_resume(struct pci_dev *pdev);
 
 static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
+       return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
 {
-       writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write16_async(struct rtl_priv *rtlpriv,
                                     u32 addr, u16 val)
 {
-       writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void pci_write32_async(struct rtl_priv *rtlpriv,
                                     u32 addr, u32 val)
 {
-       writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
+       writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
 }
 
 static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
index d2326c1..6b7e217 100644 (file)
@@ -86,7 +86,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        enum rf_pwrstate rtstate;
-       bool b_actionallowed = false;
+       bool actionallowed = false;
        u16 rfwait_cnt = 0;
        unsigned long flag;
 
@@ -139,13 +139,13 @@ no_protect:
                ppsc->rfoff_reason &= (~changesource);
 
                if ((changesource == RF_CHANGE_BY_HW) &&
-                   (ppsc->b_hwradiooff == true)) {
-                       ppsc->b_hwradiooff = false;
+                   (ppsc->hwradiooff == true)) {
+                       ppsc->hwradiooff = false;
                }
 
                if (!ppsc->rfoff_reason) {
                        ppsc->rfoff_reason = 0;
-                       b_actionallowed = true;
+                       actionallowed = true;
                }
 
                break;
@@ -153,17 +153,17 @@ no_protect:
        case ERFOFF:
 
                if ((changesource == RF_CHANGE_BY_HW)
-                   && (ppsc->b_hwradiooff == false)) {
-                       ppsc->b_hwradiooff = true;
+                   && (ppsc->hwradiooff == false)) {
+                       ppsc->hwradiooff = true;
                }
 
                ppsc->rfoff_reason |= changesource;
-               b_actionallowed = true;
+               actionallowed = true;
                break;
 
        case ERFSLEEP:
                ppsc->rfoff_reason |= changesource;
-               b_actionallowed = true;
+               actionallowed = true;
                break;
 
        default:
@@ -172,7 +172,7 @@ no_protect:
                break;
        }
 
-       if (b_actionallowed)
+       if (actionallowed)
                rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
 
        if (!protect_or_not) {
@@ -181,7 +181,7 @@ no_protect:
                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
        }
 
-       return b_actionallowed;
+       return actionallowed;
 }
 EXPORT_SYMBOL(rtl_ps_set_rf_state);
 
@@ -191,7 +191,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
-       ppsc->b_swrf_processing = true;
+       ppsc->swrf_processing = true;
 
        if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
                if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
@@ -213,7 +213,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
                }
        }
 
-       ppsc->b_swrf_processing = false;
+       ppsc->swrf_processing = false;
 }
 
 void rtl_ips_nic_off_wq_callback(void *data)
@@ -239,13 +239,13 @@ void rtl_ips_nic_off_wq_callback(void *data)
        if (rtlpriv->sec.being_setkey)
                return;
 
-       if (ppsc->b_inactiveps) {
+       if (ppsc->inactiveps) {
                rtstate = ppsc->rfpwr_state;
 
                /*
                 *Do not enter IPS in the following conditions:
                 *(1) RF is already OFF or Sleep
-                *(2) b_swrf_processing (indicates the IPS is still under going)
+                *(2) swrf_processing (indicates the IPS is still under going)
                 *(3) Connectted (only disconnected can trigger IPS)
                 *(4) IBSS (send Beacon)
                 *(5) AP mode (send Beacon)
@@ -253,14 +253,14 @@ void rtl_ips_nic_off_wq_callback(void *data)
                 */
 
                if (rtstate == ERFON &&
-                   !ppsc->b_swrf_processing &&
+                   !ppsc->swrf_processing &&
                    (mac->link_state == MAC80211_NOLINK) &&
                    !mac->act_scanning) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
                                 ("IPSEnter(): Turn off RF.\n"));
 
                        ppsc->inactive_pwrstate = ERFOFF;
-                       ppsc->b_in_powersavemode = true;
+                       ppsc->in_powersavemode = true;
 
                        /*rtl_pci_reset_trx_ring(hw); */
                        _rtl_ps_inactive_ps(hw);
@@ -290,15 +290,15 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
 
        spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
 
-       if (ppsc->b_inactiveps) {
+       if (ppsc->inactiveps) {
                rtstate = ppsc->rfpwr_state;
 
                if (rtstate != ERFON &&
-                   !ppsc->b_swrf_processing &&
+                   !ppsc->swrf_processing &&
                    ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
 
                        ppsc->inactive_pwrstate = ERFON;
-                       ppsc->b_in_powersavemode = false;
+                       ppsc->in_powersavemode = false;
 
                        _rtl_ps_inactive_ps(hw);
                }
@@ -370,9 +370,9 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
         *   mode and set RPWM to turn RF on.
         */
 
-       if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
+       if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) &&
             ppsc->report_linked) {
-               bool b_fw_current_inps;
+               bool fw_current_inps;
                if (ppsc->dot11_psmode == EACTIVE) {
                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
                                 ("FW LPS leave ps_mode:%x\n",
@@ -385,11 +385,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
                        rtlpriv->cfg->ops->set_hw_reg(hw,
                                        HW_VAR_H2C_FW_PWRMODE,
                                        (u8 *) (&fw_pwrmode));
-                       b_fw_current_inps = false;
+                       fw_current_inps = false;
 
                        rtlpriv->cfg->ops->set_hw_reg(hw,
                                        HW_VAR_FW_PSMODE_STATUS,
-                                       (u8 *) (&b_fw_current_inps));
+                                       (u8 *) (&fw_current_inps));
 
                } else {
                        if (rtl_get_fwlps_doze(hw)) {
@@ -398,10 +398,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
                                                 ppsc->fwctrl_psmode));
 
                                rpwm_val = 0x02;        /* RF off */
-                               b_fw_current_inps = true;
+                               fw_current_inps = true;
                                rtlpriv->cfg->ops->set_hw_reg(hw,
                                                HW_VAR_FW_PSMODE_STATUS,
-                                               (u8 *) (&b_fw_current_inps));
+                                               (u8 *) (&fw_current_inps));
                                rtlpriv->cfg->ops->set_hw_reg(hw,
                                                HW_VAR_H2C_FW_PWRMODE,
                                                (u8 *) (&ppsc->fwctrl_psmode));
@@ -425,13 +425,13 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        unsigned long flag;
 
-       if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
+       if (!(ppsc->fwctrl_lps && ppsc->leisure_ps))
                return;
 
        if (rtlpriv->sec.being_setkey)
                return;
 
-       if (rtlpriv->link_info.b_busytraffic)
+       if (rtlpriv->link_info.busytraffic)
                return;
 
        /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
@@ -446,7 +446,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
 
        spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
 
-       if (ppsc->b_leisure_ps) {
+       if (ppsc->leisure_ps) {
                /* Idle for a while if we connect to AP a while ago. */
                if (mac->cnt_after_linked >= 2) {
                        if (ppsc->dot11_psmode == EACTIVE) {
@@ -470,7 +470,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
 
        spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
 
-       if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
+       if (ppsc->fwctrl_lps && ppsc->leisure_ps) {
                if (ppsc->dot11_psmode != EACTIVE) {
 
                        /*FIX ME */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
new file mode 100644 (file)
index 0000000..b4f1e4e
--- /dev/null
@@ -0,0 +1,1388 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+struct dig_t dm_digtable;
+static struct ps_t dm_pstable;
+
+static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
+       0x7f8001fe,
+       0x788001e2,
+       0x71c001c7,
+       0x6b8001ae,
+       0x65400195,
+       0x5fc0017f,
+       0x5a400169,
+       0x55400155,
+       0x50800142,
+       0x4c000130,
+       0x47c0011f,
+       0x43c0010f,
+       0x40000100,
+       0x3c8000f2,
+       0x390000e4,
+       0x35c000d7,
+       0x32c000cb,
+       0x300000c0,
+       0x2d4000b5,
+       0x2ac000ab,
+       0x288000a2,
+       0x26000098,
+       0x24000090,
+       0x22000088,
+       0x20000080,
+       0x1e400079,
+       0x1c800072,
+       0x1b00006c,
+       0x19800066,
+       0x18000060,
+       0x16c0005b,
+       0x15800056,
+       0x14400051,
+       0x1300004c,
+       0x12000048,
+       0x11000044,
+       0x10000040,
+};
+
+static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
+       {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
+       {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
+       {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
+       {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
+       {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
+       {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
+       {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
+       {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
+       {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
+       {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
+       {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
+       {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
+       {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
+       {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
+       {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
+       {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
+       {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
+       {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
+       {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
+       {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
+       {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
+       {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
+       {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
+       {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
+       {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
+       {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
+       {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
+       {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
+       {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
+       {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
+       {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
+       {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
+       {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
+};
+
+static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
+       {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
+       {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
+       {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
+       {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
+       {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
+       {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
+       {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
+       {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
+       {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
+       {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
+       {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
+       {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
+       {0x1b, 0x1a, 0x17