diff options
Diffstat (limited to 'drivers/net/wireless')
307 files changed, 23567 insertions, 22798 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 880ad9d170c..a105087af96 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -373,8 +373,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) pktlen = status & RDES0_STATUS_FL; if (pktlen > RX_PKT_SIZE) { if (net_ratelimit()) - printk(KERN_DEBUG "%s: frame too long (%d)\n", - wiphy_name(dev->wiphy), pktlen); + wiphy_debug(dev->wiphy, "frame too long (%d)\n", + pktlen); pktlen = RX_PKT_SIZE; } @@ -454,10 +454,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) static irqreturn_t adm8211_interrupt(int irq, void *dev_id) { -#define ADM8211_INT(x) \ -do { \ - if (unlikely(stsr & ADM8211_STSR_ ## x)) \ - printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \ +#define ADM8211_INT(x) \ +do { \ + if (unlikely(stsr & ADM8211_STSR_ ## x)) \ + wiphy_debug(dev->wiphy, "%s\n", #x); \ } while (0) struct ieee80211_hw *dev = dev_id; @@ -570,9 +570,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) } if (timeout == 0) { - printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" - " prewrite (reg=0x%08x)\n", - wiphy_name(dev->wiphy), addr, data, reg); + wiphy_debug(dev->wiphy, + "adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n", + addr, data, reg); return -ETIMEDOUT; } @@ -605,9 +605,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data) if (timeout == 0) { ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) & ~ADM8211_BBPCTL_WR); - printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed" - " postwrite (reg=0x%08x)\n", - wiphy_name(dev->wiphy), addr, data, reg); + wiphy_debug(dev->wiphy, + "adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n", + addr, data, reg); return -ETIMEDOUT; } @@ -675,8 +675,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) break; default: - printk(KERN_DEBUG "%s: unsupported transceiver type %d\n", - wiphy_name(dev->wiphy), priv->transceiver_type); + wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n", + priv->transceiver_type); break; } @@ -732,8 +732,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) /* Nothing to do for ADMtek BBP */ } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) - printk(KERN_DEBUG "%s: unsupported BBP type %d\n", - wiphy_name(dev->wiphy), priv->bbp_type); + wiphy_debug(dev->wiphy, "unsupported bbp type %d\n", + priv->bbp_type); ADM8211_RESTORE(); @@ -1027,13 +1027,12 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev) break; default: - printk(KERN_DEBUG "%s: unsupported transceiver %d\n", - wiphy_name(dev->wiphy), priv->transceiver_type); + wiphy_debug(dev->wiphy, "unsupported transceiver %d\n", + priv->transceiver_type); break; } } else - printk(KERN_DEBUG "%s: unsupported BBP %d\n", - wiphy_name(dev->wiphy), priv->bbp_type); + wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type); ADM8211_CSR_WRITE(SYNRF, 0); @@ -1509,15 +1508,13 @@ static int adm8211_start(struct ieee80211_hw *dev) /* Power up MAC and RF chips */ retval = adm8211_hw_reset(dev); if (retval) { - printk(KERN_ERR "%s: hardware reset failed\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "hardware reset failed\n"); goto fail; } retval = adm8211_init_rings(dev); if (retval) { - printk(KERN_ERR "%s: failed to initialize rings\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "failed to initialize rings\n"); goto fail; } @@ -1528,8 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev) retval = request_irq(priv->pdev->irq, adm8211_interrupt, IRQF_SHARED, "adm8211", dev); if (retval) { - printk(KERN_ERR "%s: failed to register IRQ handler\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "failed to register irq handler\n"); goto fail; } @@ -1903,15 +1899,17 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, if (err) { printk(KERN_ERR "%s (adm8211): Cannot register device\n", pci_name(pdev)); - goto err_free_desc; + goto err_free_eeprom; } - printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n", - wiphy_name(dev->wiphy), dev->wiphy->perm_addr, - pdev->revision); + wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n", + dev->wiphy->perm_addr, pdev->revision); return 0; + err_free_eeprom: + kfree(priv->eeprom); + err_free_desc: pci_free_consistent(pdev, sizeof(struct adm8211_desc) * priv->rx_ring_size + diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h index b07e4d3a6b4..bbc10b1cde8 100644 --- a/drivers/net/wireless/adm8211.h +++ b/drivers/net/wireless/adm8211.h @@ -80,7 +80,7 @@ struct adm8211_csr { __le32 FEMR; /* 0x104 */ __le32 FPSR; /* 0x108 */ __le32 FFER; /* 0x10C */ -} __attribute__ ((packed)); +} __packed; /* CSR0 - PAR (PCI Address Register) */ #define ADM8211_PAR_MWIE (1 << 24) @@ -484,7 +484,7 @@ struct adm8211_tx_hdr { u8 entry_control; // huh?? u16 reserved_1; u32 reserved_2; -} __attribute__ ((packed)); +} __packed; #define RX_COPY_BREAK 128 @@ -531,7 +531,7 @@ struct adm8211_eeprom { u8 lnags_threshold[14]; /* 0x70 */ __le16 checksum; /* 0x7E */ u8 cis_data[0]; /* 0x80, 384 bytes */ -} __attribute__ ((packed)); +} __packed; struct adm8211_priv { struct pci_dev *pdev; diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 3b7ab20a5c5..1d05445d4ba 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -506,20 +506,20 @@ struct WepKeyRid { u8 mac[ETH_ALEN]; __le16 klen; u8 key[16]; -} __attribute__ ((packed)); +} __packed; /* These structures are from the Aironet's PC4500 Developers Manual */ typedef struct Ssid Ssid; struct Ssid { __le16 len; u8 ssid[32]; -} __attribute__ ((packed)); +} __packed; typedef struct SsidRid SsidRid; struct SsidRid { __le16 len; Ssid ssids[3]; -} __attribute__ ((packed)); +} __packed; typedef struct ModulationRid ModulationRid; struct ModulationRid { @@ -528,7 +528,7 @@ struct ModulationRid { #define MOD_DEFAULT cpu_to_le16(0) #define MOD_CCK cpu_to_le16(1) #define MOD_MOK cpu_to_le16(2) -} __attribute__ ((packed)); +} __packed; typedef struct ConfigRid ConfigRid; struct ConfigRid { @@ -652,7 +652,7 @@ struct ConfigRid { #define MAGIC_STAY_IN_CAM (1<<10) u8 magicControl; __le16 autoWake; -} __attribute__ ((packed)); +} __packed; typedef struct StatusRid StatusRid; struct StatusRid { @@ -711,20 +711,20 @@ struct StatusRid { #define STAT_LEAPFAILED 91 #define STAT_LEAPTIMEDOUT 92 #define STAT_LEAPCOMPLETE 93 -} __attribute__ ((packed)); +} __packed; typedef struct StatsRid StatsRid; struct StatsRid { __le16 len; __le16 spacer; __le32 vals[100]; -} __attribute__ ((packed)); +} __packed; typedef struct APListRid APListRid; struct APListRid { __le16 len; u8 ap[4][ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; typedef struct CapabilityRid CapabilityRid; struct CapabilityRid { @@ -754,7 +754,7 @@ struct CapabilityRid { __le16 bootBlockVer; __le16 requiredHard; __le16 extSoftCap; -} __attribute__ ((packed)); +} __packed; /* Only present on firmware >= 5.30.17 */ typedef struct BSSListRidExtra BSSListRidExtra; @@ -762,7 +762,7 @@ struct BSSListRidExtra { __le16 unknown[4]; u8 fixed[12]; /* WLAN management frame */ u8 iep[624]; -} __attribute__ ((packed)); +} __packed; typedef struct BSSListRid BSSListRid; struct BSSListRid { @@ -796,7 +796,7 @@ struct BSSListRid { /* Only present on firmware >= 5.30.17 */ BSSListRidExtra extra; -} __attribute__ ((packed)); +} __packed; typedef struct { BSSListRid bss; @@ -807,13 +807,13 @@ typedef struct tdsRssiEntry tdsRssiEntry; struct tdsRssiEntry { u8 rssipct; u8 rssidBm; -} __attribute__ ((packed)); +} __packed; typedef struct tdsRssiRid tdsRssiRid; struct tdsRssiRid { u16 len; tdsRssiEntry x[256]; -} __attribute__ ((packed)); +} __packed; typedef struct MICRid MICRid; struct MICRid { @@ -823,7 +823,7 @@ struct MICRid { u8 multicast[16]; __le16 unicastValid; u8 unicast[16]; -} __attribute__ ((packed)); +} __packed; typedef struct MICBuffer MICBuffer; struct MICBuffer { @@ -841,7 +841,7 @@ struct MICBuffer { } u; __be32 mic; __be32 seq; -} __attribute__ ((packed)); +} __packed; typedef struct { u8 da[ETH_ALEN]; @@ -996,7 +996,7 @@ struct rx_hdr { u8 rate; u8 freq; __le16 tmp[4]; -} __attribute__ ((packed)); +} __packed; typedef struct { unsigned int ctl: 15; @@ -2931,8 +2931,8 @@ err_out_res: release_region( dev->base_addr, 64 ); err_out_nets: airo_networks_free(ai); - del_airo_dev(ai); err_out_free: + del_airo_dev(ai); free_netdev(dev); return NULL; } @@ -4657,7 +4657,7 @@ static ssize_t proc_write( struct file *file, loff_t *offset ) { loff_t pos = *offset; - struct proc_data *priv = (struct proc_data*)file->private_data; + struct proc_data *priv = file->private_data; if (!priv->wbuffer) return -EINVAL; @@ -4689,7 +4689,7 @@ static int proc_status_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -4772,7 +4772,7 @@ static int proc_stats_rid_open( struct inode *inode, if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5045,7 +5045,7 @@ static int proc_config_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5127,7 +5127,7 @@ static int proc_config_open(struct inode *inode, struct file *file) static void proc_SSID_on_close(struct inode *inode, struct file *file) { - struct proc_data *data = (struct proc_data *)file->private_data; + struct proc_data *data = file->private_data; struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = dev->ml_priv; @@ -5163,7 +5163,7 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file) } static void proc_APList_on_close( struct inode *inode, struct file *file ) { - struct proc_data *data = (struct proc_data *)file->private_data; + struct proc_data *data = file->private_data; struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = dev->ml_priv; @@ -5309,7 +5309,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { memset(key, 0, sizeof(key)); - data = (struct proc_data *)file->private_data; + data = file->private_data; if ( !data->writelen ) return; if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' && @@ -5363,7 +5363,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(&wkr, 0, sizeof(wkr)); - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5409,7 +5409,7 @@ static int proc_SSID_open(struct inode *inode, struct file *file) if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5453,7 +5453,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; @@ -5495,7 +5495,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; - data = (struct proc_data *)file->private_data; + data = file->private_data; if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { kfree (file->private_data); return -ENOMEM; diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 8a2d4afc74f..d5140a87f07 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -7,6 +7,7 @@ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org> * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi> + * Copyright (c) 2010 Sebastian Smolorz <sesmo@gmx.net> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -88,22 +89,19 @@ #define DBG_DEFAULTS 0 /* Use our own dbg macro */ -#define at76_dbg(bits, format, arg...) \ - do { \ - if (at76_debug & (bits)) \ - printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ - ## arg); \ - } while (0) - -#define at76_dbg_dump(bits, buf, len, format, arg...) \ - do { \ - if (at76_debug & (bits)) { \ - printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \ - ## arg); \ - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, \ - buf, len); \ - } \ - } while (0) +#define at76_dbg(bits, format, arg...) \ +do { \ + if (at76_debug & (bits)) \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \ +} while (0) + +#define at76_dbg_dump(bits, buf, len, format, arg...) \ +do { \ + if (at76_debug & (bits)) { \ + printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \ + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \ + } \ +} while (0) static uint at76_debug = DBG_DEFAULTS; @@ -305,7 +303,7 @@ struct dfu_status { unsigned char poll_timeout[3]; unsigned char state; unsigned char string; -} __attribute__((packed)); +} __packed; static inline int at76_is_intersil(enum board_type board) { @@ -657,8 +655,8 @@ static int at76_get_hw_config(struct at76_priv *priv) exit: kfree(hwcfg); if (ret < 0) - printk(KERN_ERR "%s: cannot get HW Config (error %d)\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n", + ret); return ret; } @@ -793,8 +791,9 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) do { status = at76_get_cmd_status(priv->udev, cmd); if (status < 0) { - printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n", - wiphy_name(priv->hw->wiphy), status); + wiphy_err(priv->hw->wiphy, + "at76_get_cmd_status failed: %d\n", + status); break; } @@ -809,9 +808,8 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd) schedule_timeout_interruptible(HZ / 10); /* 100 ms */ if (time_after(jiffies, timeout)) { - printk(KERN_ERR - "%s: completion timeout for command %d\n", - wiphy_name(priv->hw->wiphy), cmd); + wiphy_err(priv->hw->wiphy, + "completion timeout for command %d\n", cmd); status = -ETIMEDOUT; break; } @@ -832,9 +830,9 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf) ret = at76_wait_completion(priv, CMD_SET_MIB); if (ret != CMD_STATUS_COMPLETE) { - printk(KERN_INFO - "%s: set_mib: at76_wait_completion failed " - "with %d\n", wiphy_name(priv->hw->wiphy), ret); + wiphy_info(priv->hw->wiphy, + "set_mib: at76_wait_completion failed with %d\n", + ret); ret = -EIO; } @@ -854,8 +852,8 @@ static int at76_set_radio(struct at76_priv *priv, int enable) ret = at76_set_card_command(priv->udev, cmd, NULL, 0); if (ret < 0) - printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n", - wiphy_name(priv->hw->wiphy), cmd, ret); + wiphy_err(priv->hw->wiphy, + "at76_set_card_command(%d) failed: %d\n", cmd, ret); else ret = 1; @@ -875,8 +873,8 @@ static int at76_set_pm_mode(struct at76_priv *priv) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "set_mib (pm_mode) failed: %d\n", + ret); return ret; } @@ -892,8 +890,8 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "set_mib (preamble) failed: %d\n", + ret); return ret; } @@ -909,8 +907,8 @@ static int at76_set_frag(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "set_mib (frag threshold) failed: %d\n", ret); return ret; } @@ -926,8 +924,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (rts) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "set_mib (rts) failed: %d\n", ret); return ret; } @@ -943,8 +940,8 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "set_mib (autorate fallback) failed: %d\n", ret); return ret; } @@ -962,8 +959,8 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m, sizeof(struct mib_mac_addr)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (mac_addr) failed: %d\n", ret); goto exit; } @@ -991,8 +988,8 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m, sizeof(struct mib_mac_wep)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (mac_wep) failed: %d\n", ret); goto exit; } @@ -1028,8 +1025,8 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m, sizeof(struct mib_mac_mgmt)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (mac_mgmt) failed: %d\n", ret); goto exit; } @@ -1064,8 +1061,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (mac) failed: %d\n", ret); goto exit; } @@ -1101,8 +1098,8 @@ static void at76_dump_mib_phy(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (phy) failed: %d\n", ret); goto exit; } @@ -1134,8 +1131,8 @@ static void at76_dump_mib_local(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (local) failed: %d\n", ret); goto exit; } @@ -1160,8 +1157,8 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m, sizeof(struct mib_mdomain)); if (ret < 0) { - printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "at76_get_mib (mdomain) failed: %d\n", ret); goto exit; } @@ -1232,16 +1229,16 @@ static int at76_submit_rx_urb(struct at76_priv *priv) struct sk_buff *skb = priv->rx_skb; if (!priv->rx_urb) { - printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n", - wiphy_name(priv->hw->wiphy), __func__); + wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n", + __func__); return -EFAULT; } if (!skb) { skb = dev_alloc_skb(sizeof(struct at76_rx_buffer)); if (!skb) { - printk(KERN_ERR "%s: cannot allocate rx skbuff\n", - wiphy_name(priv->hw->wiphy)); + wiphy_err(priv->hw->wiphy, + "cannot allocate rx skbuff\n"); ret = -ENOMEM; goto exit; } @@ -1260,15 +1257,14 @@ static int at76_submit_rx_urb(struct at76_priv *priv) at76_dbg(DBG_DEVSTART, "usb_submit_urb returned -ENODEV"); else - printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "rx, usb_submit_urb failed: %d\n", ret); } exit: if (ret < 0 && ret != -ENODEV) - printk(KERN_ERR "%s: cannot submit rx urb - please unload the " - "driver and/or power cycle the device\n", - wiphy_name(priv->hw->wiphy)); + wiphy_err(priv->hw->wiphy, + "cannot submit rx urb - please unload the driver and/or power cycle the device\n"); return ret; } @@ -1437,8 +1433,8 @@ static int at76_startup_device(struct at76_priv *priv) ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config, sizeof(struct at76_card_config)); if (ret < 0) { - printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", + ret); return ret; } @@ -1503,8 +1499,8 @@ static void at76_work_set_promisc(struct work_struct *work) ret = at76_set_mib(priv, &priv->mib_buf); if (ret < 0) - printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, + "set_mib (promiscuous_mode) failed: %d\n", ret); mutex_unlock(&priv->mtx); } @@ -1649,6 +1645,58 @@ exit: return NULL; } +static int at76_join(struct at76_priv *priv) +{ + struct at76_req_join join; + int ret; + + memset(&join, 0, sizeof(struct at76_req_join)); + memcpy(join.essid, priv->essid, priv->essid_size); + join.essid_size = priv->essid_size; + memcpy(join.bssid, priv->bssid, ETH_ALEN); + join.bss_type = INFRASTRUCTURE_MODE; + join.channel = priv->channel; + join.timeout = cpu_to_le16(2000); + + at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); + ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, + sizeof(struct at76_req_join)); + + if (ret < 0) { + wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n", + ret); + return 0; + } + + ret = at76_wait_completion(priv, CMD_JOIN); + at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); + if (ret != CMD_STATUS_COMPLETE) { + wiphy_err(priv->hw->wiphy, "at76_wait_completion failed: %d\n", + ret); + return 0; + } + + at76_set_pm_mode(priv); + + return 0; +} + +static void at76_work_join_bssid(struct work_struct *work) +{ + struct at76_priv *priv = container_of(work, struct at76_priv, + work_join_bssid); + + if (priv->device_unplugged) + return; + + mutex_lock(&priv->mtx); + + if (is_valid_ether_addr(priv->bssid)) + at76_join(priv); + + mutex_unlock(&priv->mtx); +} + static void at76_mac80211_tx_callback(struct urb *urb) { struct at76_priv *priv = urb->context; @@ -1686,16 +1734,32 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct at76_priv *priv = hw->priv; struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; int padding, submit_len, ret; at76_dbg(DBG_MAC80211, "%s()", __func__); if (priv->tx_urb->status == -EINPROGRESS) { - printk(KERN_ERR "%s: %s called while tx urb is pending\n", - wiphy_name(priv->hw->wiphy), __func__); + wiphy_err(priv->hw->wiphy, + "%s called while tx urb is pending\n", __func__); return NETDEV_TX_BUSY; } + /* The following code lines are important when the device is going to + * authenticate with a new bssid. The driver must send CMD_JOIN before + * an authentication frame is transmitted. For this to succeed, the + * correct bssid of the AP must be known. As mac80211 does not inform + * drivers about the bssid prior to the authentication process the + * following workaround is necessary. If the TX frame is an + * authentication frame extract the bssid and send the CMD_JOIN. */ + if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) { + if (compare_ether_addr(priv->bssid, mgmt->bssid)) { + memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); + ieee80211_queue_work(hw, &priv->work_join_bssid); + return NETDEV_TX_BUSY; + } + } + ieee80211_stop_queues(hw); at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */ @@ -1725,13 +1789,12 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) submit_len, at76_mac80211_tx_callback, priv); ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC); if (ret) { - printk(KERN_ERR "%s: error in tx submit urb: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); if (ret == -EINVAL) - printk(KERN_ERR - "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n", - wiphy_name(priv->hw->wiphy), priv->tx_urb, - priv->tx_urb->hcpriv, priv->tx_urb->complete); + wiphy_err(priv->hw->wiphy, + "-einval: tx urb %p hcpriv %p complete %p\n", + priv->tx_urb, + priv->tx_urb->hcpriv, priv->tx_urb->complete); } return 0; @@ -1748,8 +1811,8 @@ static int at76_mac80211_start(struct ieee80211_hw *hw) ret = at76_submit_rx_urb(priv); if (ret < 0) { - printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); + wiphy_err(priv->hw->wiphy, "open: submit_rx_urb failed: %d\n", + ret); goto error; } @@ -1770,6 +1833,7 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw) at76_dbg(DBG_MAC80211, "%s()", __func__); cancel_delayed_work(&priv->dwork_hw_scan); + cancel_work_sync(&priv->work_join_bssid); cancel_work_sync(&priv->work_set_promisc); mutex_lock(&priv->mtx); @@ -1818,42 +1882,6 @@ static void at76_remove_interface(struct ieee80211_hw *hw, at76_dbg(DBG_MAC80211, "%s()", __func__); } -static int at76_join(struct at76_priv *priv) -{ - struct at76_req_join join; - int ret; - - memset(&join, 0, sizeof(struct at76_req_join)); - memcpy(join.essid, priv->essid, priv->essid_size); - join.essid_size = priv->essid_size; - memcpy(join.bssid, priv->bssid, ETH_ALEN); - join.bss_type = INFRASTRUCTURE_MODE; - join.channel = priv->channel; - join.timeout = cpu_to_le16(2000); - - at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__); - ret = at76_set_card_command(priv->udev, CMD_JOIN, &join, - sizeof(struct at76_req_join)); - - if (ret < 0) { - printk(KERN_ERR "%s: at76_set_card_command failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); - return 0; - } - - ret = at76_wait_completion(priv, CMD_JOIN); - at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret); - if (ret != CMD_STATUS_COMPLETE) { - printk(KERN_ERR "%s: at76_wait_completion failed: %d\n", - wiphy_name(priv->hw->wiphy), ret); - return 0; - } - - at76_set_pm_mode(priv); - - return 0; -} - static void at76_dwork_hw_scan(struct work_struct *work) { struct at76_priv *priv = container_of(work, struct at76_priv, @@ -2107,6 +2135,7 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev) mutex_init(&priv->mtx); INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc); INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx); + INIT_WORK(&priv->work_join_bssid, at76_work_join_bssid); INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan); tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0); @@ -2281,14 +2310,12 @@ static int at76_init_new_device(struct at76_priv *priv, priv->mac80211_registered = 1; - printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n", - wiphy_name(priv->hw->wiphy), - dev_name(&interface->dev), priv->mac_addr, - priv->fw_version.major, priv->fw_version.minor, - priv->fw_version.patch, priv->fw_version.build); - printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", - wiphy_name(priv->hw->wiphy), - priv->regulatory_domain, priv->domain->name); + wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n", + dev_name(&interface->dev), priv->mac_addr, + priv->fw_version.major, priv->fw_version.minor, + priv->fw_version.patch, priv->fw_version.build); + wiphy_info(priv->hw->wiphy, "regulatory domain 0x%02x: %s\n", + priv->regulatory_domain, priv->domain->name); exit: return ret; @@ -2450,7 +2477,7 @@ static void at76_disconnect(struct usb_interface *interface) if (!priv) return; - printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy)); + wiphy_info(priv->hw->wiphy, "disconnecting\n"); at76_delete_device(priv); dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); } @@ -2508,5 +2535,6 @@ MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>"); MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>"); MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>"); +MODULE_AUTHOR("Sebastian Smolorz <sesmo@gmx.net>"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h index 1ec5ccffdbc..4a37447dfc0 100644 --- a/drivers/net/wireless/at76c50x-usb.h +++ b/drivers/net/wireless/at76c50x-usb.h @@ -99,7 +99,7 @@ struct hwcfg_r505 { u8 reserved2[14]; u8 cr15_values[14]; u8 reserved3[3]; -} __attribute__((packed)); +} __packed; struct hwcfg_rfmd { u8 cr20_values[14]; @@ -111,7 +111,7 @@ struct hwcfg_rfmd { u8 low_power_values[14]; u8 normal_power_values[14]; u8 reserved1[3]; -} __attribute__((packed)); +} __packed; struct hwcfg_intersil { u8 mac_addr[ETH_ALEN]; @@ -120,7 +120,7 @@ struct hwcfg_intersil { u8 pidvid[4]; u8 regulatory_domain; u8 reserved[1]; -} __attribute__((packed)); +} __packed; union at76_hwcfg { struct hwcfg_intersil i; @@ -149,14 +149,14 @@ struct at76_card_config { u8 ssid_len; u8 short_preamble; __le16 beacon_period; -} __attribute__((packed)); +} __packed; struct at76_command { u8 cmd; u8 reserved; __le16 size; u8 data[0]; -} __attribute__((packed)); +} __packed; /* Length of Atmel-specific Rx header before 802.11 frame */ #define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet) @@ -171,7 +171,7 @@ struct at76_rx_buffer { u8 noise_level; __le32 rx_time; u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; -} __attribute__((packed)); +} __packed; /* Length of Atmel-specific Tx header before 802.11 frame */ #define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet) @@ -182,7 +182,7 @@ struct at76_tx_buffer { u8 padding; u8 reserved[4]; u8 packet[IEEE80211_MAX_FRAG_THRESHOLD]; -} __attribute__((packed)); +} __packed; /* defines for scan_type below */ #define SCAN_TYPE_ACTIVE 0 @@ -198,7 +198,7 @@ struct at76_req_scan { __le16 max_channel_time; u8 essid_size; u8 international_scan; -} __attribute__((packed)); +} __packed; struct at76_req_ibss { u8 bssid[ETH_ALEN]; @@ -207,7 +207,7 @@ struct at76_req_ibss { u8 channel; u8 essid_size; u8 reserved[3]; -} __attribute__((packed)); +} __packed; struct at76_req_join { u8 bssid[ETH_ALEN]; @@ -217,7 +217,7 @@ struct at76_req_join { __le16 timeout; u8 essid_size; u8 reserved; -} __attribute__((packed)); +} __packed; struct set_mib_buffer { u8 type; @@ -229,7 +229,7 @@ struct set_mib_buffer { __le16 word; u8 addr[ETH_ALEN]; } data; -} __attribute__((packed)); +} __packed; struct mib_local { u16 reserved0; @@ -241,14 +241,14 @@ struct mib_local { u16 reserved2; u8 preamble_type; u16 reserved3; -} __attribute__((packed)); +} __packed; struct mib_mac_addr { u8 mac_addr[ETH_ALEN]; u8 res[2]; /* ??? */ u8 group_addr[4][ETH_ALEN]; u8 group_addr_status[4]; -} __attribute__((packed)); +} __packed; struct mib_mac { __le32 max_tx_msdu_lifetime; @@ -269,7 +269,7 @@ struct mib_mac { u8 desired_bssid[ETH_ALEN]; u8 desired_bsstype; /* ad-hoc or infrastructure */ u8 reserved2; -} __attribute__((packed)); +} __packed; struct mib_mac_mgmt { __le16 beacon_period; @@ -292,7 +292,7 @@ struct mib_mac_mgmt { u8 multi_domain_capability_enabled; u8 country_string[3]; u8 reserved[3]; -} __attribute__((packed)); +} __packed; struct mib_mac_wep { u8 privacy_invoked; /* 0 disable encr., 1 enable encr */ @@ -303,7 +303,7 @@ struct mib_mac_wep { __le32 wep_excluded_count; u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN]; u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */ -} __attribute__((packed)); +} __packed; struct mib_phy { __le32 ed_threshold; @@ -320,19 +320,19 @@ struct mib_phy { u8 current_cca_mode; u8 phy_type; u8 current_reg_domain; -} __attribute__((packed)); +} __packed; struct mib_fw_version { u8 major; u8 minor; u8 patch; u8 build; -} __attribute__((packed)); +} __packed; struct mib_mdomain { u8 tx_powerlevel[14]; u8 channel_list[14]; /* 0 for invalid channels */ -} __attribute__((packed)); +} __packed; struct at76_fw_header { __le32 crc; /* CRC32 of the whole image */ @@ -346,7 +346,7 @@ struct at76_fw_header { __le32 int_fw_len; /* internal firmware image length */ __le32 ext_fw_offset; /* external firmware image offset */ __le32 ext_fw_len; /* external firmware image length */ -} __attribute__((packed)); +} __packed; /* a description of a regulatory domain and the allowed channels */ struct reg_domain { @@ -387,6 +387,7 @@ struct at76_priv { /* work queues */ struct work_struct work_set_promisc; struct work_struct work_submit_rx; + struct work_struct work_join_bssid; struct delayed_work dwork_hw_scan; struct tasklet_struct rx_tasklet; diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c index cf6f5c4174a..4604de09a8b 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.c +++ b/drivers/net/wireless/ath/ar9170/cmd.c @@ -48,8 +48,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len) err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL); if (err) - printk(KERN_DEBUG "%s: writing memory failed\n", - wiphy_name(ar->hw->wiphy)); + wiphy_debug(ar->hw->wiphy, "writing memory failed\n"); return err; } @@ -67,8 +66,8 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf), (u8 *) buf, 0, NULL); if (err) - printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n", - wiphy_name(ar->hw->wiphy), reg, val); + wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n", + reg, val); return err; } diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c index 86c4e79f6bc..832d90087f8 100644 --- a/drivers/net/wireless/ath/ar9170/led.c +++ b/drivers/net/wireless/ath/ar9170/led.c @@ -133,8 +133,8 @@ static int ar9170_register_led(struct ar9170 *ar, int i, char *name, err = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds[i].l); if (err) - printk(KERN_ERR "%s: failed to register %s LED (%d).\n", - wiphy_name(ar->hw->wiphy), ar->leds[i].name, err); + wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", + ar->leds[i].name, err); else ar->leds[i].registered = true; diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 2abc8757899..c67b05f3bcb 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -198,12 +198,13 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; struct ieee80211_hdr *hdr = (void *) txc->frame_data; - printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d " - "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", - wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), - ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), - le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), - jiffies_to_msecs(arinfo->timeout - jiffies)); + wiphy_debug(ar->hw->wiphy, + "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d " + "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", + skb, skb_get_queue_mapping(skb), + ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr), + le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), + jiffies_to_msecs(arinfo->timeout - jiffies)); } static void __ar9170_dump_txqueue(struct ar9170 *ar, @@ -213,8 +214,8 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar, int i = 0; printk(KERN_DEBUG "---[ cut here ]---\n"); - printk(KERN_DEBUG "%s: %d entries in queue.\n", - wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); + wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n", + skb_queue_len(queue)); skb_queue_walk(queue, skb) { printk(KERN_DEBUG "index:%d =>\n", i++); @@ -244,15 +245,14 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) { int i; - printk(KERN_DEBUG "%s: QoS queue stats\n", - wiphy_name(ar->hw->wiphy)); + wiphy_debug(ar->hw->wiphy, "qos queue stats\n"); for (i = 0; i < __AR9170_NUM_TXQ; i++) - printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d " - " stopped:%d\n", wiphy_name(ar->hw->wiphy), i, - ar->tx_stats[i].limit, ar->tx_stats[i].len, - skb_queue_len(&ar->tx_status[i]), - ieee80211_queue_stopped(ar->hw, i)); + wiphy_debug(ar->hw->wiphy, + "queue:%d limit:%d len:%d waitack:%d stopped:%d\n", + i, ar->tx_stats[i].limit, ar->tx_stats[i].len, + skb_queue_len(&ar->tx_status[i]), + ieee80211_queue_stopped(ar->hw, i)); } #endif /* AR9170_QUEUE_STOP_DEBUG */ @@ -274,9 +274,9 @@ static void ar9170_recycle_expired(struct ar9170 *ar, if (time_is_before_jiffies(arinfo->timeout)) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " - "recycle\n", wiphy_name(ar->hw->wiphy), - jiffies, arinfo->timeout); + wiphy_debug(ar->hw->wiphy, + "[%ld > %ld] frame expired => recycle\n", + jiffies, arinfo->timeout); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ __skb_unlink(skb, queue); @@ -317,8 +317,8 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, break; default: - printk(KERN_ERR "%s: invalid tx_status response (%x).\n", - wiphy_name(ar->hw->wiphy), tx_status); + wiphy_err(ar->hw->wiphy, + "invalid tx_status response (%x)\n", tx_status); break; } @@ -339,8 +339,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) { #ifdef AR9170_QUEUE_STOP_DEBUG - printk(KERN_DEBUG "%s: wake queue %d\n", - wiphy_name(ar->hw->wiphy), queue); + wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_wake_queue(ar->hw, queue); @@ -387,9 +386,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", - wiphy_name(ar->hw->wiphy), mac, - ieee80211_get_DA(hdr)); + wiphy_debug(ar->hw->wiphy, + "skip frame => da %pm != %pm\n", + mac, ieee80211_get_DA(hdr)); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ continue; @@ -400,8 +399,8 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", - wiphy_name(ar->hw->wiphy), rate, r); + wiphy_debug(ar->hw->wiphy, + "skip frame => rate %d != %d\n", rate, r); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ continue; @@ -413,9 +412,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, } #ifdef AR9170_QUEUE_DEBUG - printk(KERN_ERR "%s: ESS:[%pM] does not have any " - "outstanding frames in queue.\n", - wiphy_name(ar->hw->wiphy), mac); + wiphy_err(ar->hw->wiphy, + "ESS:[%pM] does not have any outstanding frames in queue.\n", + mac); __ar9170_dump_txqueue(ar, queue); #endif /* AR9170_QUEUE_DEBUG */ spin_unlock_irqrestore(&queue->lock, flags); @@ -444,8 +443,8 @@ static void ar9170_tx_janitor(struct work_struct *work) for (i = 0; i < __AR9170_NUM_TXQ; i++) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", - wiphy_name(ar->hw->wiphy), i); + wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n", + i); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); ar9170_dump_txqueue(ar, &ar->tx_status[i]); #endif /* AR9170_QUEUE_DEBUG */ @@ -495,8 +494,9 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", - wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); + wiphy_debug(ar->hw->wiphy, + "recv tx_status for %pm, p:%08x, q:%d\n", + cmd->tx_status.dst, phy, q); #endif /* AR9170_QUEUE_DEBUG */ skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, @@ -582,7 +582,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) break; default: - printk(KERN_INFO "received unhandled event %x\n", cmd->type); + pr_info("received unhandled event %x\n", cmd->type); print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); break; } @@ -675,9 +675,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, /* TODO: update netdevice's RX dropped/errors statistics */ if (ar9170_nag_limiter(ar)) - printk(KERN_DEBUG "%s: received frame with " - "suspicious error code (%#x).\n", - wiphy_name(ar->hw->wiphy), error); + wiphy_debug(ar->hw->wiphy, + "received frame with suspicious error code (%#x).\n", + error); return -EINVAL; } @@ -704,9 +704,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, break; default: if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: invalid plcp cck rate " - "(%x).\n", wiphy_name(ar->hw->wiphy), - head->plcp[0]); + wiphy_err(ar->hw->wiphy, + "invalid plcp cck rate (%x).\n", + head->plcp[0]); return -EINVAL; } break; @@ -740,9 +740,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, break; default: if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: invalid plcp ofdm rate " - "(%x).\n", wiphy_name(ar->hw->wiphy), - head->plcp[0]); + wiphy_err(ar->hw->wiphy, + "invalid plcp ofdm rate (%x).\n", + head->plcp[0]); return -EINVAL; } if (status->band == IEEE80211_BAND_2GHZ) @@ -761,8 +761,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar, default: if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: invalid modulation\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, "invalid modulation\n"); return -EINVAL; } @@ -863,8 +862,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) ar->rx_mpdu.has_plcp = true; } else { if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: plcp info is clipped.\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "plcp info is clipped.\n"); return ; } break; @@ -877,8 +876,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) phy = (void *)(buf + mpdu_len); } else { if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: frame tail is clipped.\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "frame tail is clipped.\n"); return ; } @@ -888,9 +887,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (!ar9170_nag_limiter(ar)) return ; - printk(KERN_ERR "%s: rx stream did not start " - "with a first_mpdu frame tag.\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "rx stream did not start with a first_mpdu frame tag.\n"); return ; } @@ -954,8 +952,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (!ar->rx_failover_missing) { /* this is no "short read". */ if (ar9170_nag_limiter(ar)) { - printk(KERN_ERR "%s: missing tag!\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "missing tag!\n"); goto err_telluser; } else goto err_silent; @@ -963,9 +961,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (ar->rx_failover_missing > tlen) { if (ar9170_nag_limiter(ar)) { - printk(KERN_ERR "%s: possible multi " - "stream corruption!\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "possible multi stream corruption!\n"); goto err_telluser; } else goto err_silent; @@ -997,9 +994,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (ar->rx_failover_missing) { /* TODO: handle double stream corruption. */ if (ar9170_nag_limiter(ar)) { - printk(KERN_ERR "%s: double rx stream " - "corruption!\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "double rx stream corruption!\n"); goto err_telluser; } else goto err_silent; @@ -1042,9 +1038,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (tlen) { if (net_ratelimit()) - printk(KERN_ERR "%s: %d bytes of unprocessed " - "data left in rx stream!\n", - wiphy_name(ar->hw->wiphy), tlen); + wiphy_err(ar->hw->wiphy, + "%d bytes of unprocessed data left in rx stream!\n", + tlen); goto err_telluser; } @@ -1052,10 +1048,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) return ; err_telluser: - printk(KERN_ERR "%s: damaged RX stream data [want:%d, " - "data:%d, rx:%d, pending:%d ]\n", - wiphy_name(ar->hw->wiphy), clen, wlen, tlen, - ar->rx_failover_missing); + wiphy_err(ar->hw->wiphy, + "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n", + clen, wlen, tlen, ar->rx_failover_missing); if (ar->rx_failover_missing) print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, @@ -1065,9 +1060,8 @@ err_telluser: print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, skb->data, skb->len); - printk(KERN_ERR "%s: please check your hardware and cables, if " - "you see this message frequently.\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "If you see this message frequently, please check your hardware and cables.\n"); err_silent: if (ar->rx_failover_missing) { @@ -1384,10 +1378,10 @@ static void ar9170_tx(struct ar9170 *ar) if (remaining_space < frames) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: tx quota reached queue:%d, " - "remaining slots:%d, needed:%d\n", - wiphy_name(ar->hw->wiphy), i, remaining_space, - frames); + wiphy_debug(ar->hw->wiphy, + "tx quota reached queue:%d, " + "remaining slots:%d, needed:%d\n", + i, remaining_space, frames); #endif /* AR9170_QUEUE_DEBUG */ frames = remaining_space; } @@ -1396,18 +1390,14 @@ static void ar9170_tx(struct ar9170 *ar) ar->tx_stats[i].count += frames; if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: queue %d full\n", - wiphy_name(ar->hw->wiphy), i); - - printk(KERN_DEBUG "%s: stuck frames: ===>\n", - wiphy_name(ar->hw->wiphy)); + wiphy_debug(ar->hw->wiphy, "queue %d full\n", i); + wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n"); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); ar9170_dump_txqueue(ar, &ar->tx_status[i]); #endif /* AR9170_QUEUE_DEBUG */ #ifdef AR9170_QUEUE_STOP_DEBUG - printk(KERN_DEBUG "%s: stop queue %d\n", - wiphy_name(ar->hw->wiphy), i); + wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_stop_queue(ar->hw, i); @@ -1435,8 +1425,7 @@ static void ar9170_tx(struct ar9170 *ar) msecs_to_jiffies(AR9170_TX_TIMEOUT); #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: send frame q:%d =>\n", - wiphy_name(ar->hw->wiphy), i); + wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i); ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ @@ -1453,26 +1442,25 @@ static void ar9170_tx(struct ar9170 *ar) } #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", - wiphy_name(ar->hw->wiphy), i); + wiphy_debug(ar->hw->wiphy, + "ar9170_tx report for queue %d\n", i); - printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", - wiphy_name(ar->hw->wiphy)); + wiphy_debug(ar->hw->wiphy, + "unprocessed pending frames left:\n"); ar9170_dump_txqueue(ar, &ar->tx_pending[i]); #endif /* AR9170_QUEUE_DEBUG */ if (unlikely(frames_failed)) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: frames failed %d =>\n", - wiphy_name(ar->hw->wiphy), frames_failed); + wiphy_debug(ar->hw->wiphy, + "frames failed %d =>\n", frames_failed); #endif /* AR9170_QUEUE_DEBUG */ spin_lock_irqsave(&ar->tx_stats_lock, flags); ar->tx_stats[i].len -= frames_failed; ar->tx_stats[i].count -= frames_failed; #ifdef AR9170_QUEUE_STOP_DEBUG - printk(KERN_DEBUG "%s: wake queue %d\n", - wiphy_name(ar->hw->wiphy), i); + wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i); __ar9170_dump_txstats(ar); #endif /* AR9170_QUEUE_STOP_DEBUG */ ieee80211_wake_queue(ar->hw, i); @@ -1917,6 +1905,24 @@ static int ar9170_get_stats(struct ieee80211_hw *hw, return 0; } +static int ar9170_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ar9170 *ar = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + /* TODO: update noise value, e.g. call ar9170_set_channel */ + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = ar->noise[0]; + + return 0; +} + static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *param) { @@ -1969,6 +1975,7 @@ static const struct ieee80211_ops ar9170_ops = { .get_tsf = ar9170_op_get_tsf, .set_key = ar9170_set_key, .get_stats = ar9170_get_stats, + .get_survey = ar9170_get_survey, .ampdu_action = ar9170_ampdu_action, }; diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c index 45a415ea809..0dbfcf79ac9 100644 --- a/drivers/net/wireless/ath/ar9170/phy.c +++ b/drivers/net/wireless/ath/ar9170/phy.c @@ -670,8 +670,7 @@ static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) ar9170_regwrite_finish(); err = ar9170_regwrite_result(); if (err) - printk(KERN_ERR "%s: rf init failed\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, "rf init failed\n"); return err; } @@ -1702,9 +1701,8 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 0x200 | ar->phy_heavy_clip); if (err) { if (ar9170_nag_limiter(ar)) - printk(KERN_ERR "%s: failed to set " - "heavy clip\n", - wiphy_name(ar->hw->wiphy)); + wiphy_err(ar->hw->wiphy, + "failed to set heavy clip\n"); } } diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index cc09595b781..2242a140e4f 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -13,5 +13,6 @@ ath5k-y += base.o ath5k-y += led.o ath5k-y += rfkill.o ath5k-y += ani.o +ath5k-y += sysfs.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index f2311ab3550..26dbe65fedb 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -74,8 +74,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) const s8 fr[] = { -78, -80 }; #endif if (level < 0 || level >= ARRAY_SIZE(sz)) { - ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, - "level out of range %d", level); + ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", + level); return; } @@ -106,8 +106,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) if (level < 0 || level >= ARRAY_SIZE(val) || level > ah->ah_sc->ani_state.max_spur_level) { - ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, - "level out of range %d", level); + ATH5K_ERR(ah->ah_sc, "spur immunity level %d out of range", + level); return; } @@ -130,8 +130,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) const int val[] = { 0, 4, 8 }; if (level < 0 || level >= ARRAY_SIZE(val)) { - ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, - "level out of range %d", level); + ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level); return; } @@ -481,14 +480,15 @@ ath5k_ani_calibration(struct ath5k_hw *ah) struct ath5k_ani_state *as = &ah->ah_sc->ani_state; int listen, ofdm_high, ofdm_low, cck_high, cck_low; - if (as->ani_mode != ATH5K_ANI_MODE_AUTO) - return; - /* get listen time since last call and add it to the counter because we - * might not have restarted the "ani period" last time */ + * might not have restarted the "ani period" last time. + * always do this to calculate the busy time also in manual mode */ listen = ath5k_hw_ani_get_listen_time(ah, as); as->listen_time += listen; + if (as->ani_mode != ATH5K_ANI_MODE_AUTO) + return; + ath5k_ani_save_and_clear_phy_errors(ah, as); ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 2785946f659..ea6362a8988 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -204,6 +204,7 @@ #define AR5K_TUNE_TPC_TXPOWER false #define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */ #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ +#define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ #define AR5K_INIT_CARR_SENSE_EN 1 @@ -565,7 +566,7 @@ enum ath5k_pkt_type { ) /* - * DMA size definitions (2^n+2) + * DMA size definitions (2^(n+2)) */ enum ath5k_dmasize { AR5K_DMASIZE_4B = 0, @@ -1118,6 +1119,7 @@ struct ath5k_hw { /* Calibration timestamp */ unsigned long ah_cal_next_full; unsigned long ah_cal_next_ani; + unsigned long ah_cal_next_nf; /* Calibration mask */ u8 ah_cal_mask; @@ -1125,15 +1127,10 @@ struct ath5k_hw { /* * Function pointers */ - int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, - u32 size, unsigned int flags); int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); - int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, - unsigned int, unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int); int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, struct ath5k_tx_status *); int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *, @@ -1148,6 +1145,9 @@ struct ath5k_hw { int ath5k_hw_attach(struct ath5k_softc *sc); void ath5k_hw_detach(struct ath5k_hw *ah); +int ath5k_sysfs_register(struct ath5k_softc *sc); +void ath5k_sysfs_unregister(struct ath5k_softc *sc); + /* LED functions */ int ath5k_init_leds(struct ath5k_softc *sc); void ath5k_led_enable(struct ath5k_softc *sc); @@ -1231,6 +1231,11 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); /* Hardware Descriptor Functions */ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); +int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, + u32 size, unsigned int flags); +int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, + unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, + u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3); /* GPIO Functions */ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); @@ -1270,6 +1275,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); +void ath5k_hw_update_noise_floor(struct ath5k_hw *ah); /* Spur mitigation */ bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, struct ieee80211_channel *channel); @@ -1280,6 +1286,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); int ath5k_hw_phy_disable(struct ath5k_hw *ah); /* Antenna control */ void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); +void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); /* TX power setup */ int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 31c008042bf..b32e28caeee 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -352,8 +352,6 @@ err_free: */ void ath5k_hw_detach(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); - __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); if (ah->ah_rf_banks != NULL) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 648972df369..0d5de2574dd 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -311,7 +311,8 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc, static int ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, struct ath5k_txq *txq, int padsize); -static inline void ath5k_txbuf_free(struct ath5k_softc *sc, + +static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { BUG_ON(!bf); @@ -321,9 +322,11 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc, PCI_DMA_TODEVICE); dev_kfree_skb_any(bf->skb); bf->skb = NULL; + bf->skbaddr = 0; + bf->desc->ds_data = 0; } -static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, +static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { struct ath5k_hw *ah = sc->ah; @@ -336,6 +339,8 @@ static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, PCI_DMA_FROMDEVICE); dev_kfree_skb_any(bf->skb); bf->skb = NULL; + bf->skbaddr = 0; + bf->desc->ds_data = 0; } @@ -352,7 +357,6 @@ static void ath5k_txq_release(struct ath5k_softc *sc); static int ath5k_rx_start(struct ath5k_softc *sc); static void ath5k_rx_stop(struct ath5k_softc *sc); static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, - struct ath5k_desc *ds, struct sk_buff *skb, struct ath5k_rx_status *rs); static void ath5k_tasklet_rx(unsigned long data); @@ -384,7 +388,7 @@ static int ath5k_init(struct ath5k_softc *sc); static int ath5k_stop_locked(struct ath5k_softc *sc); static int ath5k_stop_hw(struct ath5k_softc *sc); static irqreturn_t ath5k_intr(int irq, void *dev_id); -static void ath5k_tasklet_reset(unsigned long data); +static void ath5k_reset_work(struct work_struct *work); static void ath5k_tasklet_calibrate(unsigned long data); @@ -578,7 +582,7 @@ ath5k_pci_probe(struct pci_dev *pdev, spin_lock_init(&sc->block); /* Set private data */ - pci_set_drvdata(pdev, hw); + pci_set_drvdata(pdev, sc); /* Setup interrupt handler */ ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); @@ -694,25 +698,23 @@ err: static void __devexit ath5k_pci_remove(struct pci_dev *pdev) { - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = pci_get_drvdata(pdev); ath5k_debug_finish_device(sc); - ath5k_detach(pdev, hw); + ath5k_detach(pdev, sc->hw); ath5k_hw_detach(sc->ah); kfree(sc->ah); free_irq(pdev->irq, sc); pci_iounmap(pdev, sc->iobase); pci_release_region(pdev, 0); pci_disable_device(pdev); - ieee80211_free_hw(hw); + ieee80211_free_hw(sc->hw); } #ifdef CONFIG_PM_SLEEP static int ath5k_pci_suspend(struct device *dev) { - struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); ath5k_led_off(sc); return 0; @@ -721,8 +723,7 @@ static int ath5k_pci_suspend(struct device *dev) static int ath5k_pci_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = pci_get_drvdata(pdev); /* * Suspend/Resume resets the PCI configuration space, so we have to @@ -768,7 +769,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) * return false w/o doing anything. MAC's that do * support it will return true w/o doing anything. */ - ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + if (ret < 0) goto err; if (ret > 0) @@ -829,11 +831,12 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); - tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); + INIT_WORK(&sc->reset_work, ath5k_reset_work); + ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", @@ -864,6 +867,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ath5k_init_leds(sc); + ath5k_sysfs_register(sc); + return 0; err_queues: ath5k_txq_release(sc); @@ -899,6 +904,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); ath5k_unregister_leds(sc); + ath5k_sysfs_unregister(sc); /* * NB: can't reclaim these until after ieee80211_ifdetach * returns because we'll get called back to reclaim node @@ -1111,8 +1117,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw) static int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) { - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", - sc->curchan->center_freq, chan->center_freq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "channel set, resetting (%u -> %u MHz)\n", + sc->curchan->center_freq, chan->center_freq); /* * To switch channels clear any pending DMA operations; @@ -1228,21 +1235,23 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) * not get overrun under high load (as can happen with a * 5212 when ANI processing enables PHY error frames). * - * To insure the last descriptor is self-linked we create + * To ensure the last descriptor is self-linked we create * each descriptor as self-linked and add it to the end. As * each additional descriptor is added the previous self-linked - * entry is ``fixed'' naturally. This should be safe even + * entry is "fixed" naturally. This should be safe even * if DMA is happening. When processing RX interrupts we * never remove/process the last, self-linked, entry on the - * descriptor list. This insures the hardware always has + * descriptor list. This ensures the hardware always has * someplace to write a new frame. */ ds = bf->desc; ds->ds_link = bf->daddr; /* link to self */ ds->ds_data = bf->skbaddr; - ret = ah->ah_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); - if (ret) + ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); + if (ret) { + ATH5K_ERR(sc, "%s: could not setup RX desc\n", __func__); return ret; + } if (sc->rxlink != NULL) *sc->rxlink = bf->daddr; @@ -1347,7 +1356,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, mrr_tries[i] = info->control.rates[i + 1].count; } - ah->ah_setup_mrr_tx_desc(ah, ds, + ath5k_hw_setup_mrr_tx_desc(ah, ds, mrr_rate[0], mrr_tries[0], mrr_rate[1], mrr_tries[1], mrr_rate[2], mrr_tries[2]); @@ -1443,17 +1452,20 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) { struct ath5k_buf *bf; - ath5k_txbuf_free(sc, sc->bbuf); + ath5k_txbuf_free_skb(sc, sc->bbuf); list_for_each_entry(bf, &sc->txbuf, list) - ath5k_txbuf_free(sc, bf); + ath5k_txbuf_free_skb(sc, bf); list_for_each_entry(bf, &sc->rxbuf, list) - ath5k_rxbuf_free(sc, bf); + ath5k_rxbuf_free_skb(sc, bf); /* Free memory associated with all descriptors */ pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); + sc->desc = NULL; + sc->desc_daddr = 0; kfree(sc->bufptr); sc->bufptr = NULL; + sc->bbuf = NULL; } @@ -1602,7 +1614,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) list_for_each_entry_safe(bf, bf0, &txq->q, list) { ath5k_debug_printtxbuf(sc, bf); - ath5k_txbuf_free(sc, bf); + ath5k_txbuf_free_skb(sc, bf); spin_lock_bh(&sc->txbuflock); list_move_tail(&bf->list, &sc->txbuf); @@ -1716,13 +1728,11 @@ ath5k_rx_stop(struct ath5k_softc *sc) ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ ath5k_debug_printrxbuffs(sc, ah); - - sc->rxlink = NULL; /* just in case */ } static unsigned int -ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, - struct sk_buff *skb, struct ath5k_rx_status *rs) +ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_rx_status *rs) { struct ath5k_hw *ah = sc->ah; struct ath_common *common = ath5k_hw_common(ah); @@ -1889,9 +1899,138 @@ static int ath5k_remove_padding(struct sk_buff *skb) } static void -ath5k_tasklet_rx(unsigned long data) +ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_rx_status *rs) { struct ieee80211_rx_status *rxs; + + /* The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = (4 - hdrlen % 4) % 4; However, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. In addition, we must + * not try to remove padding from short control frames that do + * not have payload. */ + ath5k_remove_padding(skb); + + rxs = IEEE80211_SKB_RXCB(skb); + + rxs->flag = 0; + if (unlikely(rs->rs_status & AR5K_RXERR_MIC)) + rxs->flag |= RX_FLAG_MMIC_ERROR; + + /* + * always extend the mac timestamp, since this information is + * also needed for proper IBSS merging. + * + * XXX: it might be too late to do it here, since rs_tstamp is + * 15bit only. that means TSF extension has to be done within + * 32768usec (about 32ms). it might be necessary to move this to + * the interrupt handler, like it is done in madwifi. + * + * Unfortunately we don't know when the hardware takes the rx + * timestamp (beginning of phy frame, data frame, end of rx?). + * The only thing we know is that it is hardware specific... + * On AR5213 it seems the rx timestamp is at the end of the + * frame, but i'm not sure. + * + * NOTE: mac80211 defines mactime at the beginning of the first + * data symbol. Since we don't have any time references it's + * impossible to comply to that. This affects IBSS merge only + * right now, so it's not too bad... + */ + rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); + rxs->flag |= RX_FLAG_TSFT; + + rxs->freq = sc->curchan->center_freq; + rxs->band = sc->curband->band; + + rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; + + rxs->antenna = rs->rs_antenna; + + if (rs->rs_antenna > 0 && rs->rs_antenna < 5) + sc->stats.antenna_rx[rs->rs_antenna]++; + else + sc->stats.antenna_rx[0]++; /* invalid */ + + rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs->rs_rate); + rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); + + if (rxs->rate_idx >= 0 && rs->rs_rate == + sc->curband->bitrates[rxs->rate_idx].hw_value_short) + rxs->flag |= RX_FLAG_SHORTPRE; + + ath5k_debug_dump_skb(sc, skb, "RX ", 0); + + ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); + + /* check beacons in IBSS mode */ + if (sc->opmode == NL80211_IFTYPE_ADHOC) + ath5k_check_ibss_tsf(sc, skb, rxs); + + ieee80211_rx(sc->hw, skb); +} + +/** ath5k_frame_receive_ok() - Do we want to receive this frame or not? + * + * Check if we want to further process this frame or not. Also update + * statistics. Return true if we want this frame, false if not. + */ +static bool +ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) +{ + sc->stats.rx_all_count++; + + if (unlikely(rs->rs_status)) { + if (rs->rs_status & AR5K_RXERR_CRC) + sc->stats.rxerr_crc++; + if (rs->rs_status & AR5K_RXERR_FIFO) + sc->stats.rxerr_fifo++; + if (rs->rs_status & AR5K_RXERR_PHY) { + sc->stats.rxerr_phy++; + if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32) + sc->stats.rxerr_phy_code[rs->rs_phyerr]++; + return false; + } + if (rs->rs_status & AR5K_RXERR_DECRYPT) { + /* + * Decrypt error. If the error occurred + * because there was no hardware key, then + * let the frame through so the upper layers + * can process it. This is necessary for 5210 + * parts which have no way to setup a ``clear'' + * key cache entry. + * + * XXX do key cache faulting + */ + sc->stats.rxerr_decrypt++; + if (rs->rs_keyix == AR5K_RXKEYIX_INVALID && + !(rs->rs_status & AR5K_RXERR_CRC)) + return true; + } + if (rs->rs_status & AR5K_RXERR_MIC) { + sc->stats.rxerr_mic++; + return true; + } + + /* let crypto-error packets fall through in MNTR */ + if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || + sc->opmode != NL80211_IFTYPE_MONITOR) + return false; + } + + if (unlikely(rs->rs_more)) { + sc->stats.rxerr_jumbo++; + return false; + } + return true; +} + +static void +ath5k_tasklet_rx(unsigned long data) +{ struct ath5k_rx_status rs = {}; struct sk_buff *skb, *next_skb; dma_addr_t next_skb_addr; @@ -1901,7 +2040,6 @@ ath5k_tasklet_rx(unsigned long data) struct ath5k_buf *bf; struct ath5k_desc *ds; int ret; - int rx_flag; spin_lock(&sc->rxbuflock); if (list_empty(&sc->rxbuf)) { @@ -1909,8 +2047,6 @@ ath5k_tasklet_rx(unsigned long data) goto unlock; } do { - rx_flag = 0; - bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); BUG_ON(bf->skb == NULL); skb = bf->skb; @@ -1926,137 +2062,30 @@ ath5k_tasklet_rx(unsigned long data) else if (unlikely(ret)) { ATH5K_ERR(sc, "error in processing rx descriptor\n"); sc->stats.rxerr_proc++; - spin_unlock(&sc->rxbuflock); - return; + break; } - sc->stats.rx_all_count++; - - if (unlikely(rs.rs_status)) { - if (rs.rs_status & AR5K_RXERR_CRC) - sc->stats.rxerr_crc++; - if (rs.rs_status & AR5K_RXERR_FIFO) - sc->stats.rxerr_fifo++; - if (rs.rs_status & AR5K_RXERR_PHY) { - sc->stats.rxerr_phy++; - if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32) - sc->stats.rxerr_phy_code[rs.rs_phyerr]++; - goto next; - } - if (rs.rs_status & AR5K_RXERR_DECRYPT) { - /* - * Decrypt error. If the error occurred - * because there was no hardware key, then - * let the frame through so the upper layers - * can process it. This is necessary for 5210 - * parts which have no way to setup a ``clear'' - * key cache entry. - * - * XXX do key cache faulting - */ - sc->stats.rxerr_decrypt++; - if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && - !(rs.rs_status & AR5K_RXERR_CRC)) - goto accept; - } - if (rs.rs_status & AR5K_RXERR_MIC) { - rx_flag |= RX_FLAG_MMIC_ERROR; - sc->stats.rxerr_mic++; - goto accept; - } + if (ath5k_receive_frame_ok(sc, &rs)) { + next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); - /* let crypto-error packets fall through in MNTR */ - if ((rs.rs_status & - ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || - sc->opmode != NL80211_IFTYPE_MONITOR) + /* + * If we can't replace bf->skb with a new skb under + * memory pressure, just skip this packet + */ + if (!next_skb) goto next; - } - if (unlikely(rs.rs_more)) { - sc->stats.rxerr_jumbo++; - goto next; + pci_unmap_single(sc->pdev, bf->skbaddr, + common->rx_bufsize, + PCI_DMA_FROMDEVICE); - } -accept: - next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); + skb_put(skb, rs.rs_datalen); - /* - * If we can't replace bf->skb with a new skb under memory - * pressure, just skip this packet - */ - if (!next_skb) - goto next; - - pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, - PCI_DMA_FROMDEVICE); - skb_put(skb, rs.rs_datalen); - - /* The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = (4 - hdrlen % 4) % 4; However, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. In addition, we must - * not try to remove padding from short control frames that do - * not have payload. */ - ath5k_remove_padding(skb); - - rxs = IEEE80211_SKB_RXCB(skb); - - /* - * always extend the mac timestamp, since this information is - * also needed for proper IBSS merging. - * - * XXX: it might be too late to do it here, since rs_tstamp is - * 15bit only. that means TSF extension has to be done within - * 32768usec (about 32ms). it might be necessary to move this to - * the interrupt handler, like it is done in madwifi. - * - * Unfortunately we don't know when the hardware takes the rx - * timestamp (beginning of phy frame, data frame, end of rx?). - * The only thing we know is that it is hardware specific... - * On AR5213 it seems the rx timestamp is at the end of the - * frame, but i'm not sure. - * - * NOTE: mac80211 defines mactime at the beginning of the first - * data symbol. Since we don't have any time references it's - * impossible to comply to that. This affects IBSS merge only - * right now, so it's not too bad... - */ - rxs->mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp); - rxs->flag = rx_flag | RX_FLAG_TSFT; - - rxs->freq = sc->curchan->center_freq; - rxs->band = sc->curband->band; - - rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi; - - rxs->antenna = rs.rs_antenna; - - if (rs.rs_antenna > 0 && rs.rs_antenna < 5) - sc->stats.antenna_rx[rs.rs_antenna]++; - else - sc->stats.antenna_rx[0]++; /* invalid */ - - rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); - rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); + ath5k_receive_frame(sc, skb, &rs); - if (rxs->rate_idx >= 0 && rs.rs_rate == - sc->curband->bitrates[rxs->rate_idx].hw_value_short) - rxs->flag |= RX_FLAG_SHORTPRE; - - ath5k_debug_dump_skb(sc, skb, "RX ", 0); - - ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi); - - /* check beacons in IBSS mode */ - if (sc->opmode == NL80211_IFTYPE_ADHOC) - ath5k_check_ibss_tsf(sc, skb, rxs); - - ieee80211_rx(sc->hw, skb); - - bf->skb = next_skb; - bf->skbaddr = next_skb_addr; + bf->skb = next_skb; + bf->skbaddr = next_skb_addr; + } next: list_move_tail(&bf->list, &sc->rxbuf); } while (ath5k_rxbuf_setup(sc, bf) == 0); @@ -2065,8 +2094,6 @@ unlock: } - - /*************\ * TX Handling * \*************/ @@ -2266,8 +2293,8 @@ err_unmap: * frame contents are done as needed and the slot time is * also adjusted based on current state. * - * This is called from software irq context (beacontq or restq - * tasklets) or user context from ath5k_beacon_config. + * This is called from software irq context (beacontq tasklets) + * or user context from ath5k_beacon_config. */ static void ath5k_beacon_send(struct ath5k_softc *sc) @@ -2298,7 +2325,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "stuck beacon time (%u missed)\n", sc->bmisscount); - tasklet_schedule(&sc->restq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "stuck beacon, resetting\n"); + ieee80211_queue_work(sc->hw, &sc->reset_work); } return; } @@ -2602,12 +2631,20 @@ ath5k_stop_locked(struct ath5k_softc *sc) if (!test_bit(ATH_STAT_INVALID, sc->status)) { ath5k_rx_stop(sc); ath5k_hw_phy_disable(ah); - } else - sc->rxlink = NULL; + } return 0; } +static void stop_tasklets(struct ath5k_softc *sc) +{ + tasklet_kill(&sc->rxtq); + tasklet_kill(&sc->txtq); + tasklet_kill(&sc->calib); + tasklet_kill(&sc->beacontq); + tasklet_kill(&sc->ani_tasklet); +} + /* * Stop the device, grabbing the top-level lock to protect * against concurrent entry through ath5k_init (which can happen @@ -2647,17 +2684,12 @@ ath5k_stop_hw(struct ath5k_softc *sc) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "putting device to sleep\n"); } - ath5k_txbuf_free(sc, sc->bbuf); + ath5k_txbuf_free_skb(sc, sc->bbuf); mmiowb(); mutex_unlock(&sc->lock); - tasklet_kill(&sc->rxtq); - tasklet_kill(&sc->txtq); - tasklet_kill(&sc->restq); - tasklet_kill(&sc->calib); - tasklet_kill(&sc->beacontq); - tasklet_kill(&sc->ani_tasklet); + stop_tasklets(sc); ath5k_rfkill_hw_stop(sc->ah); @@ -2705,7 +2737,9 @@ ath5k_intr(int irq, void *dev_id) * Fatal errors are unrecoverable. * Typically these are caused by DMA errors. */ - tasklet_schedule(&sc->restq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "fatal int, resetting\n"); + ieee80211_queue_work(sc->hw, &sc->reset_work); } else if (unlikely(status & AR5K_INT_RXORN)) { /* * Receive buffers are full. Either the bus is busy or @@ -2717,8 +2751,11 @@ ath5k_intr(int irq, void *dev_id) * this guess is copied from the HAL. */ sc->stats.rxorn_intr++; - if (ah->ah_mac_srev < AR5K_SREV_AR5212) - tasklet_schedule(&sc->restq); + if (ah->ah_mac_srev < AR5K_SREV_AR5212) { + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "rx overrun, resetting\n"); + ieee80211_queue_work(sc->hw, &sc->reset_work); + } else tasklet_schedule(&sc->rxtq); } else { @@ -2731,7 +2768,7 @@ ath5k_intr(int irq, void *dev_id) * RXE bit is written, but it doesn't work at * least on older hardware revs. */ - sc->rxlink = NULL; + sc->stats.rxeol_intr++; } if (status & AR5K_INT_TXURN) { /* bump tx trigger level */ @@ -2764,14 +2801,6 @@ ath5k_intr(int irq, void *dev_id) return IRQ_HANDLED; } -static void -ath5k_tasklet_reset(unsigned long data) -{ - struct ath5k_softc *sc = (void *)data; - - ath5k_reset(sc, sc->curchan); -} - /* * Periodically recalibrate the PHY to account * for temperature/environment changes. @@ -2785,10 +2814,6 @@ ath5k_tasklet_calibrate(unsigned long data) /* Only full calibration for now */ ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; - /* Stop queues so that calibration - * doesn't interfere with tx */ - ieee80211_stop_queues(sc->hw); - ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", ieee80211_frequency_to_channel(sc->curchan->center_freq), sc->curchan->hw_value); @@ -2799,15 +2824,23 @@ ath5k_tasklet_calibrate(unsigned long data) * to load new gain values. */ ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); - ath5k_reset(sc, sc->curchan); + ieee80211_queue_work(sc->hw, &sc->reset_work); } if (ath5k_hw_phy_calibrate(ah, sc->curchan)) ATH5K_ERR(sc, "calibration of channel %u failed\n", ieee80211_frequency_to_channel( sc->curchan->center_freq)); - /* Wake queues */ - ieee80211_wake_queues(sc->hw); + /* Noise floor calibration interrupts rx/tx path while I/Q calibration + * doesn't. We stop the queues so that calibration doesn't interfere + * with TX and don't run it as often */ + if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { + ah->ah_cal_next_nf = jiffies + + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); + ieee80211_stop_queues(sc->hw); + ath5k_hw_update_noise_floor(ah); + ieee80211_wake_queues(sc->hw); + } ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; } @@ -2895,6 +2928,8 @@ drop_packet: /* * Reset the hardware. If chan is not NULL, then also pause rx/tx * and change to the given channel. + * + * This should be called with sc->lock. */ static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) @@ -2904,8 +2939,11 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); + ath5k_hw_set_imr(ah, 0); + synchronize_irq(sc->pdev->irq); + stop_tasklets(sc); + if (chan) { - ath5k_hw_set_imr(ah, 0); ath5k_txq_cleanup(sc); ath5k_rx_stop(sc); @@ -2926,6 +2964,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); + ah->ah_cal_next_full = jiffies; + ah->ah_cal_next_ani = jiffies; + ah->ah_cal_next_nf = jiffies; + /* * Change channels and update the h/w rate map if we're switching; * e.g. 11a to 11b/g. @@ -2947,6 +2989,16 @@ err: return ret; } +static void ath5k_reset_work(struct work_struct *work) +{ + struct ath5k_softc *sc = container_of(work, struct ath5k_softc, + reset_work); + + mutex_lock(&sc->lock); + ath5k_reset(sc, sc->curchan); + mutex_unlock(&sc->lock); +} + static int ath5k_start(struct ieee80211_hw *hw) { return ath5k_init(hw->priv); @@ -3360,7 +3412,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ath5k_debug_dump_skb(sc, skb, "BC ", 1); - ath5k_txbuf_free(sc, sc->bbuf); + ath5k_txbuf_free_skb(sc, sc->bbuf); sc->bbuf->skb = skb; ret = ath5k_beacon_setup(sc, sc->bbuf); if (ret) diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 56221bc7c8c..dc1241f9c4e 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -47,6 +47,7 @@ #include <linux/if_ether.h> #include <linux/leds.h> #include <linux/rfkill.h> +#include <linux/workqueue.h> #include "ath5k.h" #include "debug.h" @@ -136,6 +137,7 @@ struct ath5k_statistics { unsigned int mib_intr; unsigned int rxorn_intr; + unsigned int rxeol_intr; }; #if CHAN_DEBUG @@ -189,7 +191,7 @@ struct ath5k_softc { unsigned int led_pin, /* GPIO pin for driving LED */ led_on; /* pin setting for LED on */ - struct tasklet_struct restq; /* reset tasklet */ + struct work_struct reset_work; /* deferred chip reset */ unsigned int rxbufsize; /* rx size based on mtu */ struct list_head rxbuf; /* receive buffer */ diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 74f007126f4..beae519aa73 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -34,7 +34,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) { u16 ee_header; - ATH5K_TRACE(ah->ah_sc); /* Capabilities stored in the EEPROM */ ee_header = ah->ah_capabilities.cap_eeprom.ee_header; @@ -123,8 +122,6 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result) { - ATH5K_TRACE(ah->ah_sc); - switch (cap_type) { case AR5K_CAP_NUM_TXQUEUES: if (result) { @@ -173,8 +170,6 @@ yes: int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id) { - ATH5K_TRACE(ah->ah_sc); - if (ah->ah_version == AR5K_AR5210) { AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); @@ -186,8 +181,6 @@ int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); - if (ah->ah_version == AR5K_AR5210) { AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 6fb5c5ffa5b..4cccc29964f 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -239,6 +239,9 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf, "TSF\t\t0x%016llx\tTU: %08x\n", (unsigned long long)tsf, TSF_TO_TU(tsf)); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -278,7 +281,8 @@ static ssize_t write_file_reset(struct file *file, size_t count, loff_t *ppos) { struct ath5k_softc *sc = file->private_data; - tasklet_schedule(&sc->restq); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n"); + ieee80211_queue_work(sc->hw, &sc->reset_work); return count; } @@ -307,7 +311,6 @@ static const struct { { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, - { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, }; @@ -334,6 +337,9 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, sc->debug.level == dbg_info[i].level ? '+' : ' ', dbg_info[i].level, dbg_info[i].desc); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -426,6 +432,16 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf, "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); + v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0); + len += snprintf(buf+len, sizeof(buf)-len, + "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v); + v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1); + len += snprintf(buf+len, sizeof(buf)-len, + "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v); + + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -535,6 +551,9 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", st->tx_all_count); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -674,6 +693,9 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2))); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -729,6 +751,69 @@ static const struct file_operations fops_ani = { }; +/* debugfs: queues etc */ + +static ssize_t read_file_queue(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath5k_softc *sc = file->private_data; + char buf[700]; + unsigned int len = 0; + + struct ath5k_txq *txq; + struct ath5k_buf *bf, *bf0; + int i, n = 0; + + len += snprintf(buf+len, sizeof(buf)-len, + "available txbuffers: %d\n", sc->txbuf_len); + + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { + txq = &sc->txqs[i]; + + len += snprintf(buf+len, sizeof(buf)-len, + "%02d: %ssetup\n", i, txq->setup ? "" : "not "); + + if (!txq->setup) + continue; + + list_for_each_entry_safe(bf, bf0, &txq->q, list) + n++; + len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); + } + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_queue(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct ath5k_softc *sc = file->private_data; + char buf[20]; + + if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) + return -EFAULT; + + if (strncmp(buf, "start", 5) == 0) + ieee80211_wake_queues(sc->hw); + else if (strncmp(buf, "stop", 4) == 0) + ieee80211_stop_queues(sc->hw); + + return count; +} + + +static const struct file_operations fops_queue = { + .read = read_file_queue, + .write = write_file_queue, + .open = ath5k_debugfs_open, + .owner = THIS_MODULE, +}; + + /* init */ void @@ -772,6 +857,11 @@ ath5k_debug_init_device(struct ath5k_softc *sc) S_IWUSR | S_IRUSR, sc->debug.debugfs_phydir, sc, &fops_ani); + + sc->debug.debugfs_queue = debugfs_create_file("queue", + S_IWUSR | S_IRUSR, + sc->debug.debugfs_phydir, sc, + &fops_queue); } void @@ -790,6 +880,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) debugfs_remove(sc->debug.debugfs_antenna); debugfs_remove(sc->debug.debugfs_frameerrors); debugfs_remove(sc->debug.debugfs_ani); + debugfs_remove(sc->debug.debugfs_queue); debugfs_remove(sc->debug.debugfs_phydir); } @@ -852,7 +943,7 @@ ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done, ds, (unsigned long long)bf->daddr, ds->ds_link, ds->ds_data, rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, - rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0, + rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1, !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); } @@ -867,7 +958,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) return; - printk(KERN_DEBUG "rx queue %x, link %p\n", + printk(KERN_DEBUG "rxdp %x, rxlink %p\n", ath5k_hw_get_rxdp(ah), sc->rxlink); spin_lock_bh(&sc->rxbuflock); diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index ddd5b3a99e8..606ae94a915 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -77,6 +77,7 @@ struct ath5k_dbg_info { struct dentry *debugfs_antenna; struct dentry *debugfs_frameerrors; struct dentry *debugfs_ani; + struct dentry *debugfs_queue; }; /** @@ -115,18 +116,12 @@ enum ath5k_debug_level { ATH5K_DEBUG_DUMP_RX = 0x00000100, ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMPBANDS = 0x00000400, - ATH5K_DEBUG_TRACE = 0x00001000, ATH5K_DEBUG_ANI = 0x00002000, ATH5K_DEBUG_ANY = 0xffffffff }; #ifdef CONFIG_ATH5K_DEBUG -#define ATH5K_TRACE(_sc) do { \ - if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ - printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \ - } while (0) - #define ATH5K_DBG(_sc, _m, _fmt, ...) do { \ if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \ ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \ @@ -168,8 +163,6 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); #include <linux/compiler.h> -#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc)) - static inline void __attribute__ ((format (printf, 3, 4))) ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 7d7b646ab65..43244382f21 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -91,14 +91,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; /* - * Verify and set header length - * XXX: I only found that on 5210 code, does it work on 5211 ? + * Verify and set header length (only 5210) */ if (ah->ah_version == AR5K_AR5210) { - if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) + if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210) return -EINVAL; tx_ctl->tx_control_0 |= - AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); + AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210); } /*Differences between 5210-5211*/ @@ -110,11 +109,11 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, case AR5K_PKT_TYPE_PIFS: frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; default: - frame_type = type /*<< 2 ?*/; + frame_type = type; } tx_ctl->tx_control_0 |= - AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | + AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); } else { @@ -123,21 +122,30 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); tx_ctl->tx_control_1 |= - AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); + AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211); } + #define _TX_FLAGS(_c, _flag) \ if (flags & AR5K_TXDESC_##_flag) { \ tx_ctl->tx_control_##_c |= \ AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ } - +#define _TX_FLAGS_5211(_c, _flag) \ + if (flags & AR5K_TXDESC_##_flag) { \ + tx_ctl->tx_control_##_c |= \ + AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \ + } _TX_FLAGS(0, CLRDMASK); - _TX_FLAGS(0, VEOL); _TX_FLAGS(0, INTREQ); _TX_FLAGS(0, RTSENA); - _TX_FLAGS(1, NOACK); + + if (ah->ah_version == AR5K_AR5211) { + _TX_FLAGS_5211(0, VEOL); + _TX_FLAGS_5211(1, NOACK); + } #undef _TX_FLAGS +#undef _TX_FLAGS_5211 /* * WEP crap @@ -147,7 +155,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, - AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); + AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX); } /* @@ -156,7 +164,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, if ((ah->ah_version == AR5K_AR5210) && (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) tx_ctl->tx_control_1 |= rtscts_duration & - AR5K_2W_TX_DESC_CTL1_RTS_DURATION; + AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210; return 0; } @@ -176,7 +184,6 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, struct ath5k_hw_4w_tx_ctl *tx_ctl; unsigned int frame_len; - ATH5K_TRACE(ah->ah_sc); tx_ctl = &desc->ud.ds_tx5212.tx_ctl; /* @@ -256,7 +263,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, if (key_index != AR5K_TXKEYIX_INVALID) { tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, - AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); + AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); } /* @@ -278,13 +285,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* * Initialize a 4-word multi rate retry tx control descriptor on 5212 */ -static int +int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) { struct ath5k_hw_4w_tx_ctl *tx_ctl; + /* no mrr support for cards older than 5212 */ + if (ah->ah_version < AR5K_AR5212) + return 0; + /* * Rates can be 0 as long as the retry count is 0 too. * A zero rate and nonzero retry count will put the HW into a mode where @@ -324,15 +335,6 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, return 0; } -/* no mrr support for cards older than 5212 */ -static int -ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc, - unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, - u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) -{ - return 0; -} - /* * Proccess the tx status descriptor on 5210/5211 */ @@ -342,8 +344,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, struct ath5k_hw_2w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - ATH5K_TRACE(ah->ah_sc); - tx_ctl = &desc->ud.ds_tx5210.tx_ctl; tx_status = &desc->ud.ds_tx5210.tx_stat; @@ -396,8 +396,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, struct ath5k_hw_4w_tx_ctl *tx_ctl; struct ath5k_hw_tx_status *tx_status; - ATH5K_TRACE(ah->ah_sc); - tx_ctl = &desc->ud.ds_tx5212.tx_ctl; tx_status = &desc->ud.ds_tx5212.tx_stat; @@ -419,11 +417,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); ts->ts_antenna = (tx_status->tx_status_1 & - AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; + AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; ts->ts_status = 0; ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); + AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); /* The longretry counter has the number of un-acked retries * for the final rate. To get the total number of retries @@ -485,12 +483,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, /* * Initialize an rx control descriptor */ -static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, - u32 size, unsigned int flags) +int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, + u32 size, unsigned int flags) { struct ath5k_hw_rx_ctl *rx_ctl; - ATH5K_TRACE(ah->ah_sc); rx_ctl = &desc->ud.ds_rx.rx_ctl; /* @@ -502,10 +499,11 @@ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, */ memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); + if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN)) + return -EINVAL; + /* Setup descriptor */ rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; - if (unlikely(rx_ctl->rx_control_1 != size)) - return -EINVAL; if (flags & AR5K_RXDESC_INTREQ) rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; @@ -521,13 +519,15 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, { struct ath5k_hw_rx_status *rx_status; - rx_status = &desc->ud.ds_rx.u.rx_stat; + rx_status = &desc->ud.ds_rx.rx_stat; /* No frame received / not ready */ if (unlikely(!(rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_DONE))) + AR5K_5210_RX_DESC_STATUS1_DONE))) return -EINPROGRESS; + memset(rs, 0, sizeof(struct ath5k_rx_status)); + /* * Frame receive status */ @@ -537,15 +537,23 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); - rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA); rs->rs_more = !!(rx_status->rx_status_0 & AR5K_5210_RX_DESC_STATUS0_MORE); - /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ + /* TODO: this timestamp is 13 bit, later on we assume 15 bit! + * also the HAL code for 5210 says the timestamp is bits [10..22] of the + * TSF, and extends the timestamp here to 15 bit. + * we need to check on 5210... + */ rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - rs->rs_status = 0; - rs->rs_phyerr = 0; + + if (ah->ah_version == AR5K_AR5211) + rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, + AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211); + else + rs->rs_antenna = (rx_status->rx_status_0 & + AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) + ? 2 : 1; /* * Key table status @@ -560,19 +568,21 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, * Receive/descriptor errors */ if (!(rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { + AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; - if (rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) + /* only on 5210 */ + if ((ah->ah_version == AR5K_AR5210) && + (rx_status->rx_status_1 & + AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210)) rs->rs_status |= AR5K_RXERR_FIFO; if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); } @@ -588,22 +598,20 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, * Proccess the rx status descriptor on 5212 */ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc, struct ath5k_rx_status *rs) + struct ath5k_desc *desc, + struct ath5k_rx_status *rs) { struct ath5k_hw_rx_status *rx_status; - struct ath5k_hw_rx_error *rx_err; - ATH5K_TRACE(ah->ah_sc); - rx_status = &desc->ud.ds_rx.u.rx_stat; - - /* Overlay on error */ - rx_err = &desc->ud.ds_rx.u.rx_err; + rx_status = &desc->ud.ds_rx.rx_stat; /* No frame received / not ready */ if (unlikely(!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_DONE))) + AR5K_5212_RX_DESC_STATUS1_DONE))) return -EINPROGRESS; + memset(rs, 0, sizeof(struct ath5k_rx_status)); + /* * Frame receive status */ @@ -619,15 +627,13 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, AR5K_5212_RX_DESC_STATUS0_MORE); rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - rs->rs_status = 0; - rs->rs_phyerr = 0; /* * Key table status */ if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); + AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); else rs->rs_keyix = AR5K_RXKEYIX_INVALID; @@ -635,7 +641,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, * Receive/descriptor errors */ if (!(rx_status->rx_status_1 & - AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { + AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) rs->rs_status |= AR5K_RXERR_CRC; @@ -643,9 +649,10 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, - AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); - ath5k_ani_phy_error_report(ah, rs->rs_phyerr); + rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, + AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); + if (!ah->ah_capabilities.cap_has_phyerr_counters) + ath5k_ani_phy_error_report(ah, rs->rs_phyerr); } if (rx_status->rx_status_1 & @@ -656,7 +663,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) rs->rs_status |= AR5K_RXERR_MIC; } - return 0; } @@ -665,29 +671,15 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, */ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) { - - if (ah->ah_version != AR5K_AR5210 && - ah->ah_version != AR5K_AR5211 && - ah->ah_version != AR5K_AR5212) - return -ENOTSUPP; - if (ah->ah_version == AR5K_AR5212) { - ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; - ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc; ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; - } else { - ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; + ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; + } else if (ah->ah_version <= AR5K_AR5211) { ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; - ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr; ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; - } - - if (ah->ah_version == AR5K_AR5212) - ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; - else if (ah->ah_version <= AR5K_AR5211) ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; - + } else + return -ENOTSUPP; return 0; } - diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h index 64538fbe416..b2adb2a281c 100644 --- a/drivers/net/wireless/ath/ath5k/desc.h +++ b/drivers/net/wireless/ath/ath5k/desc.h @@ -17,28 +17,24 @@ */ /* - * Internal RX/TX descriptor structures - * (rX: reserved fields possibily used by future versions of the ar5k chipset) + * RX/TX descriptor structures */ /* - * common hardware RX control descriptor + * Common hardware RX control descriptor */ struct ath5k_hw_rx_ctl { u32 rx_control_0; /* RX control word 0 */ u32 rx_control_1; /* RX control word 1 */ } __packed; -/* RX control word 0 field/sflags */ -#define AR5K_DESC_RX_CTL0 0x00000000 - /* RX control word 1 fields/flags */ -#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff -#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 +#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */ +#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 /* RX interrupt request */ /* - * common hardware RX status descriptor - * 5210/11 and 5212 differ only in the flags defined below + * Common hardware RX status descriptor + * 5210, 5211 and 5212 differ only in the fields and flags defined below */ struct ath5k_hw_rx_status { u32 rx_status_0; /* RX status word 0 */ @@ -47,81 +43,69 @@ struct ath5k_hw_rx_status { /* 5210/5211 */ /* RX status word 0 fields/flags */ -#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff -#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 +#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */ +#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */ +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 0x00004000 /* [5210] receive on ant 1 */ +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 /* reception rate */ #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 /* rssi */ #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 0x38000000 /* [5211] receive antenna */ +#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211_S 27 /* RX status word 1 fields/flags */ -#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 -#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 -#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 -#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008 -#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 -#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 +#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */ +#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* reception success */ +#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */ +#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 0x00000008 /* [5210] FIFO overrun */ +#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 /* decyption CRC failure */ +#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 /* PHY error */ #define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */ +#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 /* decyption key index */ #define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 +#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 /* 13 bit of TSF */ #define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 -#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 +#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 /* key cache miss */ /* 5212 */ /* RX status word 0 fields/flags */ -#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff -#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 -#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 +#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */ +#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */ +#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 /* decompression CRC error */ +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 /* reception rate */ #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 /* rssi */ #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 +#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 /* receive antenna */ #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 /* RX status word 1 fields/flags */ -#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 -#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 -#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 -#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 -#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 -#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 -#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 -#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 +#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */ +#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* frame reception success */ +#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */ +#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 /* decryption CRC failure */ +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 /* PHY error */ +#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 /* MIC decrypt error */ +#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */ +#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 /* decryption key index */ #define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 +#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 /* first 15bit of the TSF */ #define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 -#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 - -/* - * common hardware RX error descriptor - */ -struct ath5k_hw_rx_error { - u32 rx_error_0; /* RX status word 0 */ - u32 rx_error_1; /* RX status word 1 */ -} __packed; - -/* RX error word 0 fields/flags */ -#define AR5K_RX_DESC_ERROR0 0x00000000 - -/* RX error word 1 fields/flags */ -#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 -#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 +#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 /* key cache miss */ +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE 0x0000ff00 /* phy error code overlays key index and valid fields */ +#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE_S 8 /** * enum ath5k_phy_error_code - PHY Error codes */ enum ath5k_phy_error_code { - AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */ + AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun, [5210] No error */ AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */ AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */ AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */ AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */ - AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */ + AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect, [5210] 64 QAM rate */ AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */ AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */ /* these are specific to the 5212 */ @@ -148,112 +132,111 @@ struct ath5k_hw_2w_tx_ctl { } __packed; /* TX control word 0 fields/flags */ -#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff -#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ -#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 -#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 +#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ +#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 0x0003f000 /* [5210] header length */ +#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210_S 12 +#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 /* tx rate */ #define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18 -#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 -#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 -#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET 0x00800000 /*[5210]*/ -#define AR5K_2W_TX_DESC_CTL0_VEOL 0x00800000 /*[5211]*/ -#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE 0x1c000000 /*[5210]*/ -#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 - +#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */ +#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET_5210 0x00800000 /* [5210] long packet */ +#define AR5K_2W_TX_DESC_CTL0_VEOL_5211 0x00800000 /* [5211] virtual end-of-list */ +#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */ +#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 /* [5210] antenna selection */ +#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 /* [5211] antenna selection */ #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \ (ah->ah_version == AR5K_AR5210 ? \ AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) - #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 -#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 -#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 +#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210 0x1c000000 /* [5210] frame type */ +#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210_S 26 +#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */ +#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* key is valid */ /* TX control word 1 fields/flags */ -#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff -#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 -#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 -#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 - -#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX \ +#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */ +#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */ +#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 0x0007e000 /* [5210] key table index */ +#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211 0x000fe000 /* [5211] key table index */ +#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX \ (ah->ah_version == AR5K_AR5210 ? \ - AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ - AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) - -#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 -#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ -#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 -#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ -#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/ + AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 : \ + AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211) +#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_S 13 +#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 0x00700000 /* [5211] frame type */ +#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211_S 20 +#define AR5K_2W_TX_DESC_CTL1_NOACK_5211 0x00800000 /* [5211] no ACK */ +#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 0xfff80000 /* [5210] lower 13 bit of duration */ /* Frame types */ -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 1 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 2 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 3 +#define AR5K_AR5211_TX_DESC_FRAME_TYPE_BEACON 3 +#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 4 +#define AR5K_AR5211_TX_DESC_FRAME_TYPE_PRESP 4 /* * 5212 hardware 4-word TX control descriptor */ struct ath5k_hw_4w_tx_ctl { u32 tx_control_0; /* TX control word 0 */ + u32 tx_control_1; /* TX control word 1 */ + u32 tx_control_2; /* TX control word 2 */ + u32 tx_control_3; /* TX control word 3 */ +} __packed; -#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff -#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 +/* TX control word 0 fields/flags */ +#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ +#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 /* transmit power */ #define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16 -#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 -#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 -#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 -#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 +#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */ +#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 /* virtual end-of-list */ +#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */ +#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 /* TX antenna selection */ #define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 -#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 -#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 -#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 - - u32 tx_control_1; /* TX control word 1 */ +#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */ +#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* destination index valid */ +#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 /* precede frame with CTS */ -#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff -#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 -#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000 -#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 -#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 +/* TX control word 1 fields/flags */ +#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */ +#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */ +#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX 0x000fe000 /* destination table index */ +#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX_S 13 +#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 /* frame type */ #define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20 -#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 -#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 +#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 /* no ACK */ +#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 /* compression processing */ #define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25 -#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 +#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 /* length of frame IV */ #define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27 -#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 +#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 /* length of frame ICV */ #define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29 - u32 tx_control_2; /* TX control word 2 */ - -#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff -#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE 0x00008000 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28 - - u32 tx_control_3; /* TX control word 3 */ - -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0 +/* TX control word 2 fields/flags */ +#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff /* RTS/CTS duration */ +#define AR5K_4W_TX_DESC_CTL2_DURATION_UPD_EN 0x00008000 /* frame duration update */ +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 /* series 0 max attempts */ +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16 +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 /* series 1 max attempts */ +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20 +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 /* series 2 max attempts */ +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24 +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 /* series 3 max attempts */ +#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28 + +/* TX control word 3 fields/flags */ +#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f /* series 0 tx rate */ +#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0 /* series 1 tx rate */ #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5 -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 +#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 /* series 2 tx rate */ #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10 -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 +#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 /* series 3 tx rate */ #define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15 -#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 +#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 /* RTS or CTS rate */ #define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20 -} __packed; /* * Common TX status descriptor @@ -264,37 +247,34 @@ struct ath5k_hw_tx_status { } __packed; /* TX status word 0 fields/flags */ -#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 -#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 -#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 -#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 -/*??? -#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT 0x000000f0 -#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S 4 -*/ -#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 +#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */ +#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 /* excessive retries */ +#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 /* FIFO underrun */ +#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 /* TX filter indication */ +/* according to the HAL sources the spec has short/long retry counts reversed. + * we have it reversed to the HAL sources as well, for 5210 and 5211. + * For 5212 these fields are defined as RTS_FAIL_COUNT and DATA_FAIL_COUNT, + * but used respectively as SHORT and LONG retry count in the code later. This + * is consistent with the definitions here... TODO: check */ +#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 /* short retry count */ #define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4 -/*??? -#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT 0x00000f00 -#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8 -*/ -#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00 +#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00 /* long retry count */ #define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8 -#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT 0x0000f000 -#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12 -#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 +#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5211 0x0000f000 /* [5211+] virtual collision count */ +#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5212_S 12 +#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 /* TX timestamp */ #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 /* TX status word 1 fields/flags */ -#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 -#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe +#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 /* descriptor complete */ +#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe /* TX sequence number */ #define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 -#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 +#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 /* signal strength of ACK */ #define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13 -#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX 0x00600000 -#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 -#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 -#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 +#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212 0x00600000 /* [5212] final TX attempt series ix */ +#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212_S 21 +#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS_5212 0x00800000 /* [5212] compression status */ +#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212 0x01000000 /* [5212] transmit antenna */ /* * 5210/5211 hardware TX descriptor @@ -313,18 +293,15 @@ struct ath5k_hw_5212_tx_desc { } __packed; /* - * common hardware RX descriptor + * Common hardware RX descriptor */ struct ath5k_hw_all_rx_desc { - struct ath5k_hw_rx_ctl rx_ctl; - union { - struct ath5k_hw_rx_status rx_stat; - struct ath5k_hw_rx_error rx_err; - } u; + struct ath5k_hw_rx_ctl rx_ctl; + struct ath5k_hw_rx_status rx_stat; } __packed; /* - * Atheros hardware descriptor + * Atheros hardware DMA descriptor * This is read and written to by the hardware */ struct ath5k_desc { @@ -346,4 +323,3 @@ struct ath5k_desc { #define AR5K_TXDESC_CTSENA 0x0008 #define AR5K_TXDESC_INTREQ 0x0010 #define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ - diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 941b51130a6..484f31870ba 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -48,7 +48,6 @@ */ void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); ath5k_hw_reg_read(ah, AR5K_CR); } @@ -62,7 +61,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) { unsigned int i; - ATH5K_TRACE(ah->ah_sc); ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); /* @@ -96,8 +94,6 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) */ void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) { - ATH5K_TRACE(ah->ah_sc); - ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); } @@ -125,7 +121,6 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) { u32 tx_queue; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); /* Return if queue is declared inactive */ @@ -186,7 +181,6 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) unsigned int i = 40; u32 tx_queue, pending; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); /* Return if queue is declared inactive */ @@ -297,7 +291,6 @@ u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue) { u16 tx_reg; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); /* @@ -340,7 +333,6 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) { u16 tx_reg; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); /* @@ -400,8 +392,6 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) u32 trigger_level, imr; int ret = -EIO; - ATH5K_TRACE(ah->ah_sc); - /* * Disable interrupts by setting the mask */ @@ -451,7 +441,6 @@ done: */ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; } @@ -475,8 +464,6 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) { u32 data; - ATH5K_TRACE(ah->ah_sc); - /* * Read interrupt status from the Interrupt Status register * on 5210 diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index ed0263672d6..ae316fec4a6 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -35,7 +35,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) { u32 status, timeout; - ATH5K_TRACE(ah->ah_sc); /* * Initialize EEPROM access */ @@ -715,7 +714,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, /* Only one curve for RF5111 * find out which one and place - * in in pd_curves. + * in pd_curves. * Note: ee_x_gain is reversed here */ for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { diff --git a/drivers/net/wireless/ath/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c index 64a27e73d02..bc90503f4b7 100644 --- a/drivers/net/wireless/ath/ath5k/gpio.c +++ b/drivers/net/wireless/ath/ath5k/gpio.c @@ -34,8 +34,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) /*5210 has different led mode handling*/ u32 led_5210; - ATH5K_TRACE(ah->ah_sc); - /*Reset led status*/ if (ah->ah_version != AR5K_AR5210) AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, @@ -82,7 +80,6 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) */ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) { - ATH5K_TRACE(ah->ah_sc); if (gpio >= AR5K_NUM_GPIO) return -EINVAL; @@ -98,7 +95,6 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) */ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) { - ATH5K_TRACE(ah->ah_sc); if (gpio >= AR5K_NUM_GPIO) return -EINVAL; @@ -114,7 +110,6 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) */ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) { - ATH5K_TRACE(ah->ah_sc); if (gpio >= AR5K_NUM_GPIO) return 0xffffffff; @@ -129,7 +124,6 @@ u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) { u32 data; - ATH5K_TRACE(ah->ah_sc); if (gpio >= AR5K_NUM_GPIO) return -EINVAL; @@ -153,7 +147,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, { u32 data; - ATH5K_TRACE(ah->ah_sc); if (gpio >= AR5K_NUM_GPIO) return; diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 5212e275f1c..86fdb6ddfaa 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -59,8 +59,6 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) beacon_reg = 0; - ATH5K_TRACE(ah->ah_sc); - switch (op_mode) { case NL80211_IFTYPE_ADHOC: pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; @@ -173,7 +171,6 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) */ static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) { - ATH5K_TRACE(ah->ah_sc); if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) <= timeout) return -EINVAL; @@ -192,7 +189,6 @@ static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) */ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) { - ATH5K_TRACE(ah->ah_sc); if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) <= timeout) return -EINVAL; @@ -297,7 +293,6 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) u32 low_id, high_id; u32 pcu_reg; - ATH5K_TRACE(ah->ah_sc); /* Set new station ID */ memcpy(common->macaddr, mac, ETH_ALEN); @@ -357,7 +352,6 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah) void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) { struct ath_common *common = ath5k_hw_common(ah); - ATH5K_TRACE(ah->ah_sc); /* Cache bssid mask so that we can restore it * on reset */ @@ -382,7 +376,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) */ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); } @@ -397,7 +390,6 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) */ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); } @@ -406,8 +398,6 @@ void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) */ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) { - ATH5K_TRACE(ah->ah_sc); - /* Set the multicat filter */ ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); } @@ -427,7 +417,6 @@ u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah) { u32 data, filter = 0; - ATH5K_TRACE(ah->ah_sc); filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); /*Radar detection for 5212*/ @@ -457,8 +446,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) { u32 data = 0; - ATH5K_TRACE(ah->ah_sc); - /* Set PHY error filter register on 5212*/ if (ah->ah_version == AR5K_AR5212) { if (filter & AR5K_RX_FILTER_RADARERR) @@ -533,8 +520,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) WARN_ON( i == ATH5K_MAX_TSF_READ ); - ATH5K_TRACE(ah->ah_sc); - return (((u64)tsf_upper1 << 32) | tsf_lower); } @@ -548,8 +533,6 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) */ void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64) { - ATH5K_TRACE(ah->ah_sc); - ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32); ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32); } @@ -565,8 +548,6 @@ void ath5k_hw_reset_tsf(struct ath5k_hw *ah) { u32 val; - ATH5K_TRACE(ah->ah_sc); - val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; /* @@ -586,7 +567,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) { u32 timer1, timer2, timer3; - ATH5K_TRACE(ah->ah_sc); /* * Set the additional timers by mode */ @@ -674,7 +654,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) unsigned int i, type; u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); @@ -749,8 +728,6 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, bool is_tkip; const u8 *key_ptr; - ATH5K_TRACE(ah->ah_sc); - is_tkip = (key->alg == ALG_TKIP); /* @@ -836,7 +813,6 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) { u32 low_id, high_id; - ATH5K_TRACE(ah->ah_sc); /* Invalid entry (key table overflow) */ AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 492cbb15720..6284c389ba1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -378,8 +378,6 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) u32 data, type; struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - ATH5K_TRACE(ah->ah_sc); - if (ah->ah_rf_banks == NULL || ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE) return AR5K_RFGAIN_INACTIVE; @@ -1167,7 +1165,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) * The median of the values in the history is then loaded into the * hardware for its own use for RSSI and CCA measurements. */ -static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) +void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 val; @@ -1248,7 +1246,6 @@ static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) /* * Perform a PHY calibration on RF5110 * -Fix BPSK/QAM Constellation (I/Q correction) - * -Calculate Noise Floor */ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel) @@ -1335,8 +1332,6 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, return ret; } - ath5k_hw_update_noise_floor(ah); - /* * Re-enable RX/TX and beacons */ @@ -1348,22 +1343,20 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, } /* - * Perform a PHY calibration on RF5111/5112 and newer chips + * Perform I/Q calibration on RF5111/5112 and newer chips */ -static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, - struct ieee80211_channel *channel) +static int +ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah) { u32 i_pwr, q_pwr; s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; int i; - ATH5K_TRACE(ah->ah_sc); if (!ah->ah_calibration || ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) - goto done; + return 0; /* Calibration has finished, get the results and re-run */ - /* work around empty results which can apparently happen on 5212 */ for (i = 0; i <= 10; i++) { iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); @@ -1384,7 +1377,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, /* protect against divide by 0 and loss of sign bits */ if (i_coffd == 0 || q_coffd < 2) - goto done; + return -1; i_coff = (-iq_corr) / i_coffd; i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ @@ -1410,17 +1403,6 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); -done: - - /* TODO: Separate noise floor calibration from I/Q calibration - * since noise floor calibration interrupts rx path while I/Q - * calibration doesn't. We don't need to run noise floor calibration - * as often as I/Q calibration.*/ - ath5k_hw_update_noise_floor(ah); - - /* Initiate a gain_F calibration */ - ath5k_hw_request_rfgain_probe(ah); - return 0; } @@ -1434,8 +1416,10 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, if (ah->ah_radio == AR5K_RF5110) ret = ath5k_hw_rf5110_calibrate(ah, channel); - else - ret = ath5k_hw_rf511x_calibrate(ah, channel); + else { + ret = ath5k_hw_rf511x_iq_calibrate(ah); + ath5k_hw_request_rfgain_probe(ah); + } return ret; } @@ -1693,7 +1677,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, int ath5k_hw_phy_disable(struct ath5k_hw *ah) { - ATH5K_TRACE(ah->ah_sc); /*Just a try M.F.*/ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); @@ -1709,8 +1692,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) u32 srev; u16 ret; - ATH5K_TRACE(ah->ah_sc); - /* * Set the radio chip access register */ @@ -1755,8 +1736,6 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) static void /*TODO:Boundary check*/ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) { - ATH5K_TRACE(ah->ah_sc); - if (ah->ah_version != AR5K_AR5210) ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); } @@ -1789,19 +1768,50 @@ ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable) if (enable) { AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, - AR5K_PHY_RESTART_DIV_GC, 0xc); + AR5K_PHY_RESTART_DIV_GC, 4); AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, AR5K_PHY_FAST_ANT_DIV_EN); } else { AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, - AR5K_PHY_RESTART_DIV_GC, 0x8); + AR5K_PHY_RESTART_DIV_GC, 0); AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, AR5K_PHY_FAST_ANT_DIV_EN); } } +void +ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode) +{ + u8 ant0, ant1; + + /* + * In case a fixed antenna was set as default + * use the same switch table twice. + */ + if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A) + ant0 = ant1 = AR5K_ANT_SWTABLE_A; + else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B) + ant0 = ant1 = AR5K_ANT_SWTABLE_B; + else { + ant0 = AR5K_ANT_SWTABLE_A; + ant1 = AR5K_ANT_SWTABLE_B; + } + + /* Set antenna idle switch table */ + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, + AR5K_PHY_ANT_CTL_SWTABLE_IDLE, + (ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] | + AR5K_PHY_ANT_CTL_TXRX_EN)); + + /* Set antenna switch tables */ + ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0], + AR5K_PHY_ANT_SWITCH_TABLE_0); + ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1], + AR5K_PHY_ANT_SWITCH_TABLE_1); +} + /* * Set antenna operating mode */ @@ -1823,8 +1833,6 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) def_ant = ah->ah_def_ant; - ATH5K_TRACE(ah->ah_sc); - switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: case CHANNEL_T: @@ -1923,6 +1931,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) if (sta_id1) AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1); + ath5k_hw_set_antenna_switch(ah, ee_mode); /* Note: set diversity before default antenna * because it won't work correctly */ ath5k_hw_set_fast_div(ah, ee_mode, fast_div); @@ -2988,7 +2997,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 type; int ret; - ATH5K_TRACE(ah->ah_sc); if (txpower > AR5K_TUNE_MAX_TXPOWER) { ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); return -EINVAL; @@ -3084,8 +3092,6 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) struct ieee80211_channel *channel = ah->ah_current_channel; u8 ee_mode; - ATH5K_TRACE(ah->ah_sc); - switch (channel->hw_value & CHANNEL_MODES) { case CHANNEL_A: case CHANNEL_T: diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index f5831da33f7..4186ff4c6e9 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -31,7 +31,6 @@ Queue Control Unit, DFS Control Unit Functions int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info) { - ATH5K_TRACE(ah->ah_sc); memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); return 0; } @@ -42,7 +41,6 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, const struct ath5k_txq_info *queue_info) { - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) @@ -69,8 +67,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, unsigned int queue; int ret; - ATH5K_TRACE(ah->ah_sc); - /* * Get queue by type */ @@ -149,7 +145,6 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) { u32 pending; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); /* Return if queue is declared inactive */ @@ -177,7 +172,6 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) */ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) { - ATH5K_TRACE(ah->ah_sc); if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) return; @@ -195,7 +189,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) u32 cw_min, cw_max, retry_lg, retry_sh; struct ath5k_txq_info *tq = &ah->ah_txq[queue]; - ATH5K_TRACE(ah->ah_sc); AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); tq = &ah->ah_txq[queue]; @@ -523,8 +516,6 @@ int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) { u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); - ATH5K_TRACE(ah->ah_sc); - if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) return -EINVAL; diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 307f80e83f9..498aa28ea9e 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -201,8 +201,6 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) int ret; u32 mask = val ? val : ~0U; - ATH5K_TRACE(ah->ah_sc); - /* Read-and-clear RX Descriptor Pointer*/ ath5k_hw_reg_read(ah, AR5K_RXDP); @@ -246,7 +244,6 @@ static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, unsigned int i; u32 staid, data; - ATH5K_TRACE(ah->ah_sc); staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); switch (mode) { @@ -393,8 +390,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) mode = 0; clock = 0; - ATH5K_TRACE(ah->ah_sc); - /* Wakeup the device */ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); if (ret) { @@ -734,7 +729,7 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, } static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, - struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) + struct ieee80211_channel *channel, u8 ee_mode) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; s16 cck_ofdm_pwr_delta; @@ -768,17 +763,9 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, ee->ee_cck_ofdm_gain_delta; } - /* Set antenna idle switch table */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, - AR5K_PHY_ANT_CTL_SWTABLE_IDLE, - (ah->ah_ant_ctl[ee_mode][0] | - AR5K_PHY_ANT_CTL_TXRX_EN)); - - /* Set antenna switch tables */ - ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]], - AR5K_PHY_ANT_SWITCH_TABLE_0); - ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]], - AR5K_PHY_ANT_SWITCH_TABLE_1); + /* XXX: necessary here? is called from ath5k_hw_set_antenna_mode() + * too */ + ath5k_hw_set_antenna_switch(ah, ee_mode); /* Noise floor threshold */ ath5k_hw_reg_write(ah, @@ -855,7 +842,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, AR5K_PHY_NF_THRESH62, ee->ee_thr_62[ee_mode]); - /* False detect backoff for channels * that have spur noise. Write the new * cyclic power RSSI threshold. */ @@ -891,14 +877,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel) { struct ath_common *common = ath5k_hw_common(ah); - u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; + u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; u32 phy_tst1; - u8 mode, freq, ee_mode, ant[2]; + u8 mode, freq, ee_mode; int i, ret; - ATH5K_TRACE(ah->ah_sc); - - s_ant = 0; ee_mode = 0; staid1_flags = 0; tsf_up = 0; @@ -995,9 +978,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, } } - /* Save default antenna */ - s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); - if (ah->ah_version == AR5K_AR5212) { /* Restore normal 32/40MHz clock operation * to avoid register access delay on certain @@ -1094,22 +1074,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* Write OFDM timings on 5212*/ if (ah->ah_version == AR5K_AR5212 && channel->hw_value & CHANNEL_OFDM) { - struct ath5k_eeprom_info *ee = - &ah->ah_capabilities.cap_eeprom; ret = ath5k_hw_write_ofdm_timings(ah, channel); if (ret) return ret; - /* Note: According to docs we can have a newer - * EEPROM on old hardware, so we need to verify - * that our hardware is new enough to have spur - * mitigation registers (delta phase etc) */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424 || - (ah->ah_mac_srev >= AR5K_SREV_AR5424 && - ee->ee_version >= AR5K_EEPROM_VERSION_5_3)) + /* Spur info is available only from EEPROM versions + * bigger than 5.3 but but the EEPOM routines will use + * static values for older versions */ + if (ah->ah_mac_srev >= AR5K_SREV_AR5424) ath5k_hw_set_spur_mitigation_filter(ah, - channel); + channel); } /*Enable/disable 802.11b mode on 5111 @@ -1123,21 +1098,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, AR5K_TXCFG_B_MODE); } - /* - * In case a fixed antenna was set as default - * use the same switch table twice. - */ - if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A) - ant[0] = ant[1] = AR5K_ANT_SWTABLE_A; - else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B) - ant[0] = ant[1] = AR5K_ANT_SWTABLE_B; - else { - ant[0] = AR5K_ANT_SWTABLE_A; - ant[1] = AR5K_ANT_SWTABLE_B; - } - /* Commit values from EEPROM */ - ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); + ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode); } else { /* @@ -1175,8 +1137,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); } } - - ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); } /* Ledstate */ diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c new file mode 100644 index 00000000000..90757de7bf5 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/sysfs.c @@ -0,0 +1,116 @@ +#include <linux/device.h> +#include <linux/pci.h> + +#include "base.h" +#include "ath5k.h" +#include "reg.h" + +#define SIMPLE_SHOW_STORE(name, get, set) \ +static ssize_t ath5k_attr_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct ath5k_softc *sc = dev_get_drvdata(dev); \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ +} \ + \ +static ssize_t ath5k_attr_store_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct ath5k_softc *sc = dev_get_drvdata(dev); \ + int val; \ + \ + val = (int)simple_strtoul(buf, NULL, 10); \ + set(sc->ah, val); \ + return count; \ +} \ +static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \ + ath5k_attr_show_##name, ath5k_attr_store_##name) + +#define SIMPLE_SHOW(name, get) \ +static ssize_t ath5k_attr_show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct ath5k_softc *sc = dev_get_drvdata(dev); \ + return snprintf(buf, PAGE_SIZE, "%d\n", get); \ +} \ +static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) + +/*** ANI ***/ + +SIMPLE_SHOW_STORE(ani_mode, sc->ani_state.ani_mode, ath5k_ani_init); +SIMPLE_SHOW_STORE(noise_immunity_level, sc->ani_state.noise_imm_level, + ath5k_ani_set_noise_immunity_level); +SIMPLE_SHOW_STORE(spur_level, sc->ani_state.spur_level, + ath5k_ani_set_spur_immunity_level); +SIMPLE_SHOW_STORE(firstep_level, sc->ani_state.firstep_level, + ath5k_ani_set_firstep_level); +SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, sc->ani_state.ofdm_weak_sig, + ath5k_ani_set_ofdm_weak_signal_detection); +SIMPLE_SHOW_STORE(cck_weak_signal_detection, sc->ani_state.cck_weak_sig, + ath5k_ani_set_cck_weak_signal_detection); +SIMPLE_SHOW(spur_level_max, sc->ani_state.max_spur_level); + +static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL); +} +static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO, + ath5k_attr_show_noise_immunity_level_max, NULL); + +static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL); +} +static DEVICE_ATTR(firstep_level_max, S_IRUGO, + ath5k_attr_show_firstep_level_max, NULL); + +static struct attribute *ath5k_sysfs_entries_ani[] = { + &dev_attr_ani_mode.attr, + &dev_attr_noise_immunity_level.attr, + &dev_attr_spur_level.attr, + &dev_attr_firstep_level.attr, + &dev_attr_ofdm_weak_signal_detection.attr, + &dev_attr_cck_weak_signal_detection.attr, + &dev_attr_noise_immunity_level_max.attr, + &dev_attr_spur_level_max.attr, + &dev_attr_firstep_level_max.attr, + NULL +}; + +static struct attribute_group ath5k_attribute_group_ani = { + .name = "ani", + .attrs = ath5k_sysfs_entries_ani, +}; + + +/*** register / unregister ***/ + +int +ath5k_sysfs_register(struct ath5k_softc *sc) +{ + struct device *dev = &sc->pdev->dev; + int err; + + err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani); + if (err) { + ATH5K_ERR(sc, "failed to create sysfs group\n"); + return err; + } + + return 0; +} + +void +ath5k_sysfs_unregister(struct ath5k_softc *sc) +{ + struct device *dev = &sc->pdev->dev; + + sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani); +} diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index dd112be218a..973ae4f49f3 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -32,7 +32,8 @@ ath9k_hw-y:= \ mac.o \ ar9002_mac.o \ ar9003_mac.o \ - ar9003_eeprom.o + ar9003_eeprom.o \ + ar9003_paprd.o obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 85fdd26039c..1a984b02e9e 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -131,11 +131,8 @@ static int ath_ahb_probe(struct platform_device *pdev) ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); - printk(KERN_INFO - "%s: %s mem=0x%lx, irq=%d\n", - wiphy_name(hw->wiphy), - hw_name, - (unsigned long)mem, irq); + wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", + hw_name, (unsigned long)mem, irq); return 0; diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index ba8b20f0159..cc648b6ae31 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2008-2010 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,8 +17,99 @@ #include "hw.h" #include "hw-ops.h" -static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, - struct ath9k_channel *chan) +struct ani_ofdm_level_entry { + int spur_immunity_level; + int fir_step_level; + int ofdm_weak_signal_on; +}; + +/* values here are relative to the INI */ + +/* + * Legend: + * + * SI: Spur immunity + * FS: FIR Step + * WS: OFDM / CCK Weak Signal detection + * MRC-CCK: Maximal Ratio Combining for CCK + */ + +static const struct ani_ofdm_level_entry ofdm_level_table[] = { + /* SI FS WS */ + { 0, 0, 1 }, /* lvl 0 */ + { 1, 1, 1 }, /* lvl 1 */ + { 2, 2, 1 }, /* lvl 2 */ + { 3, 2, 1 }, /* lvl 3 (default) */ + { 4, 3, 1 }, /* lvl 4 */ + { 5, 4, 1 }, /* lvl 5 */ + { 6, 5, 1 }, /* lvl 6 */ + { 7, 6, 1 }, /* lvl 7 */ + { 7, 7, 1 }, /* lvl 8 */ + { 7, 8, 0 } /* lvl 9 */ +}; +#define ATH9K_ANI_OFDM_NUM_LEVEL \ + (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0])) +#define ATH9K_ANI_OFDM_MAX_LEVEL \ + (ATH9K_ANI_OFDM_NUM_LEVEL-1) +#define ATH9K_ANI_OFDM_DEF_LEVEL \ + 3 /* default level - matches the INI settings */ + +/* + * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm. + * With OFDM for single stream you just add up all antenna inputs, you're + * only interested in what you get after FFT. Signal aligment is also not + * required for OFDM because any phase difference adds up in the frequency + * domain. + * + * MRC requires extra work for use with CCK. You need to align the antenna + * signals from the different antenna before you can add the signals together. + * You need aligment of signals as CCK is in time domain, so addition can cancel + * your signal completely if phase is 180 degrees (think of adding sine waves). + * You also need to remove noise before the addition and this is where ANI + * MRC CCK comes into play. One of the antenna inputs may be stronger but + * lower SNR, so just adding after alignment can be dangerous. + * + * Regardless of alignment in time, the antenna signals add constructively after + * FFT and improve your reception. For more information: + * + * http://en.wikipedia.org/wiki/Maximal-ratio_combining + */ + +struct ani_cck_level_entry { + int fir_step_level; + int mrc_cck_on; +}; + +static const struct ani_cck_level_entry cck_level_table[] = { + /* FS MRC-CCK */ + { 0, 1 }, /* lvl 0 */ + { 1, 1 }, /* lvl 1 */ + { 2, 1 }, /* lvl 2 (default) */ + { 3, 1 }, /* lvl 3 */ + { 4, 0 }, /* lvl 4 */ + { 5, 0 }, /* lvl 5 */ + { 6, 0 }, /* lvl 6 */ + { 7, 0 }, /* lvl 7 (only for high rssi) */ + { 8, 0 } /* lvl 8 (only for high rssi) */ +}; + +#define ATH9K_ANI_CCK_NUM_LEVEL \ + (sizeof(cck_level_table)/sizeof(cck_level_table[0])) +#define ATH9K_ANI_CCK_MAX_LEVEL \ + (ATH9K_ANI_CCK_NUM_LEVEL-1) +#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \ + (ATH9K_ANI_CCK_NUM_LEVEL-3) +#define ATH9K_ANI_CCK_DEF_LEVEL \ + 2 /* default level - matches the INI settings */ + +/* Private to ani.c */ +static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) +{ + ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); +} + +int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, + struct ath9k_channel *chan) { int i; @@ -48,7 +139,7 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, stats->beacons += REG_READ(ah, AR_BEACON_CNT); } -static void ath9k_ani_restart(struct ath_hw *ah) +static void ath9k_ani_restart_old(struct ath_hw *ah) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); @@ -96,7 +187,42 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState->cckPhyErrCount = 0; } -static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) +static void ath9k_ani_restart_new(struct ath_hw *ah) +{ + struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); + + if (!DO_ANI(ah)) + return; + + aniState = ah->curani; + aniState->listenTime = 0; + + aniState->ofdmPhyErrBase = 0; + aniState->cckPhyErrBase = 0; + + ath_print(common, ATH_DBG_ANI, + "Writing ofdmbase=%08x cckbase=%08x\n", + aniState->ofdmPhyErrBase, + aniState->cckPhyErrBase); + + ENABLE_REGWRITE_BUFFER(ah); + + REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + + REGWRITE_BUFFER_FLUSH(ah); + DISABLE_REGWRITE_BUFFER(ah); + + ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + + aniState->ofdmPhyErrCount = 0; + aniState->cckPhyErrCount = 0; +} + +static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) { struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; struct ar5416AniState *aniState; @@ -168,7 +294,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) } } -static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) +static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) { struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; struct ar5416AniState *aniState; @@ -206,7 +332,125 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) } } -static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) +/* Adjust the OFDM Noise Immunity Level */ +static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) +{ + struct ar5416AniState *aniState = ah->curani; + struct ath_common *common = ath9k_hw_common(ah); + const struct ani_ofdm_level_entry *entry_ofdm; + const struct ani_cck_level_entry *entry_cck; + + aniState->noiseFloor = BEACON_RSSI(ah); + + ath_print(common, ATH_DBG_ANI, + "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", + aniState->ofdmNoiseImmunityLevel, + immunityLevel, aniState->noiseFloor, + aniState->rssiThrLow, aniState->rssiThrHigh); + + aniState->ofdmNoiseImmunityLevel = immunityLevel; + + entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; + entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; + + if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level) + ath9k_hw_ani_control(ah, + ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + entry_ofdm->spur_immunity_level); + + if (aniState->firstepLevel != entry_ofdm->fir_step_level && + entry_ofdm->fir_step_level >= entry_cck->fir_step_level) + ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, + entry_ofdm->fir_step_level); + + if ((ah->opmode != NL80211_IFTYPE_STATION && + ah->opmode != NL80211_IFTYPE_ADHOC) || + aniState->noiseFloor <= aniState->rssiThrHigh) { + if (aniState->ofdmWeakSigDetectOff) + /* force on ofdm weak sig detect */ + ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + true); + else if (aniState->ofdmWeakSigDetectOff == + entry_ofdm->ofdm_weak_signal_on) + ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + entry_ofdm->ofdm_weak_signal_on); + } +} + +static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) +{ + struct ar5416AniState *aniState; + + if (!DO_ANI(ah)) + return; + + aniState = ah->curani; + + if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); +} + +/* + * Set the ANI settings to match an CCK level. + */ +static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) +{ + struct ar5416AniState *aniState = ah->curani; + struct ath_common *common = ath9k_hw_common(ah); + const struct ani_ofdm_level_entry *entry_ofdm; + const struct ani_cck_level_entry *entry_cck; + + aniState->noiseFloor = BEACON_RSSI(ah); + ath_print(common, ATH_DBG_ANI, + "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", + aniState->cckNoiseImmunityLevel, immunityLevel, + aniState->noiseFloor, aniState->rssiThrLow, + aniState->rssiThrHigh); + + if ((ah->opmode == NL80211_IFTYPE_STATION || + ah->opmode == NL80211_IFTYPE_ADHOC) && + aniState->noiseFloor <= aniState->rssiThrLow && + immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) + immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; + + aniState->cckNoiseImmunityLevel = immunityLevel; + + entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; + entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; + + if (aniState->firstepLevel != entry_cck->fir_step_level && + entry_cck->fir_step_level >= entry_ofdm->fir_step_level) + ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, + entry_cck->fir_step_level); + + /* Skip MRC CCK for pre AR9003 families */ + if (!AR_SREV_9300_20_OR_LATER(ah)) + return; + + if (aniState->mrcCCKOff == entry_cck->mrc_cck_on) + ath9k_hw_ani_control(ah, + ATH9K_ANI_MRC_CCK, + entry_cck->mrc_cck_on); +} + +static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) +{ + struct ar5416AniState *aniState; + + if (!DO_ANI(ah)) + return; + + aniState = ah->curani; + + if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); +} + +static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) { struct ar5416AniState *aniState; int32_t rssi; @@ -259,9 +503,53 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) } } +/* + * only lower either OFDM or CCK errors per turn + * we lower the other one next time + */ +static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) +{ + struct ar5416AniState *aniState; + + aniState = ah->curani; + + /* lower OFDM noise immunity */ + if (aniState->ofdmNoiseImmunityLevel > 0 && + (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) { + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1); + return; + } + + /* lower CCK noise immunity */ + if (aniState->cckNoiseImmunityLevel > 0) + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); +} + +static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) +{ + struct ath9k_channel *chan = ah->curchan; + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + u8 clockrate; /* in MHz */ + + if (!ah->curchan) /* should really check for CCK instead */ + clockrate = ATH9K_CLOCK_RATE_CCK; + else if (conf->channel->band == IEEE80211_BAND_2GHZ) + clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; + else if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; + else + clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; + + if (conf_is_ht40(conf)) + return clockrate * 2; + + return clockrate * 2; +} + static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) { struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); u32 txFrameCount, rxFrameCount, cycleCount; int32_t listenTime; @@ -271,15 +559,31 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) aniState = ah->curani; if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { - listenTime = 0; ah->stats.ast_ani_lzero++; + ath_print(common, ATH_DBG_ANI, + "1st call: aniState->cycleCount=%d\n", + aniState->cycleCount); } else { int32_t ccdelta = cycleCount - aniState->cycleCount; int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; int32_t tfdelta = txFrameCount - aniState->txFrameCount; - listenTime = (ccdelta - rfdelta - tfdelta) / 44000; + int32_t clock_rate; + + /* + * convert HW counter values to ms using mode + * specifix clock rate + */ + clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;; + + listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate; + + ath_print(common, ATH_DBG_ANI, + "cyclecount=%d, rfcount=%d, " + "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n", + ccdelta, rfdelta, tfdelta, listenTime, clock_rate); } + aniState->cycleCount = cycleCount; aniState->txFrameCount = txFrameCount; aniState->rxFrameCount = rxFrameCount; @@ -287,7 +591,7 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) return listenTime; } -void ath9k_ani_reset(struct ath_hw *ah) +static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) { struct ar5416AniState *aniState; struct ath9k_channel *chan = ah->curchan; @@ -340,7 +644,7 @@ void ath9k_ani_reset(struct ath_hw *ah) ah->curani->cckTrigLow = ah->config.cck_trig_low; } - ath9k_ani_restart(ah); + ath9k_ani_restart_old(ah); return; } @@ -362,7 +666,7 @@ void ath9k_ani_reset(struct ath_hw *ah) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & ~ATH9K_RX_FILTER_PHYERR); - ath9k_ani_restart(ah); + ath9k_ani_restart_old(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -373,8 +677,102 @@ void ath9k_ani_reset(struct ath_hw *ah) DISABLE_REGWRITE_BUFFER(ah); } -void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan) +/* + * Restore the ANI parameters in the HAL and reset the statistics. + * This routine should be called for every hardware reset and for + * every channel change. + */ +static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) +{ + struct ar5416AniState *aniState = ah->curani; + struct ath9k_channel *chan = ah->curchan; + struct ath_common *common = ath9k_hw_common(ah); + + if (!DO_ANI(ah)) + return; + + BUG_ON(aniState == NULL); + ah->stats.ast_ani_reset++; + + /* only allow a subset of functions in AP mode */ + if (ah->opmode == NL80211_IFTYPE_AP) { + if (IS_CHAN_2GHZ(chan)) { + ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | + ATH9K_ANI_FIRSTEP_LEVEL); + if (AR_SREV_9300_20_OR_LATER(ah)) + ah->ani_function |= ATH9K_ANI_MRC_CCK; + } else + ah->ani_function = 0; + } + + /* always allow mode (on/off) to be controlled */ + ah->ani_function |= ATH9K_ANI_MODE; + + if (is_scanning || + (ah->opmode != NL80211_IFTYPE_STATION && + ah->opmode != NL80211_IFTYPE_ADHOC)) { + /* + * If we're scanning or in AP mode, the defaults (ini) + * should be in place. For an AP we assume the historical + * levels for this channel are probably outdated so start + * from defaults instead. + */ + if (aniState->ofdmNoiseImmunityLevel != + ATH9K_ANI_OFDM_DEF_LEVEL || + aniState->cckNoiseImmunityLevel != + ATH9K_ANI_CCK_DEF_LEVEL) { + ath_print(common, ATH_DBG_ANI, + "Restore defaults: opmode %u " + "chan %d Mhz/0x%x is_scanning=%d " + "ofdm:%d cck:%d\n", + ah->opmode, + chan->channel, + chan->channelFlags, + is_scanning, + aniState->ofdmNoiseImmunityLevel, + aniState->cckNoiseImmunityLevel); + + ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); + ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); + } + } else { + /* + * restore historical levels for this channel + */ + ath_print(common, ATH_DBG_ANI, + "Restore history: opmode %u " + "chan %d Mhz/0x%x is_scanning=%d " + "ofdm:%d cck:%d\n", + ah->opmode, + chan->channel, + chan->channelFlags, + is_scanning, + aniState->ofdmNoiseImmunityLevel, + aniState->cckNoiseImmunityLevel); + + ath9k_hw_set_ofdm_nil(ah, + aniState->ofdmNoiseImmunityLevel); + ath9k_hw_set_cck_nil(ah, + aniState->cckNoiseImmunityLevel); + } + + /* + * enable phy counters if hw supports or if not, enable phy + * interrupts (so we can count each one) + */ + ath9k_ani_restart_new(ah); + + ENABLE_REGWRITE_BUFFER(ah); + + REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + + REGWRITE_BUFFER_FLUSH(ah); + DISABLE_REGWRITE_BUFFER(ah); +} + +static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, + struct ath9k_channel *chan) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); @@ -390,7 +788,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, listenTime = ath9k_hw_ani_get_listen_time(ah); if (listenTime < 0) { ah->stats.ast_ani_lneg++; - ath9k_ani_restart(ah); + ath9k_ani_restart_old(ah); return; } @@ -444,21 +842,166 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, aniState->cckPhyErrCount <= aniState->listenTime * aniState->cckTrigLow / 1000) ath9k_hw_ani_lower_immunity(ah); - ath9k_ani_restart(ah); + ath9k_ani_restart_old(ah); } else if (aniState->listenTime > ah->aniperiod) { if (aniState->ofdmPhyErrCount > aniState->listenTime * aniState->ofdmTrigHigh / 1000) { - ath9k_hw_ani_ofdm_err_trigger(ah); - ath9k_ani_restart(ah); + ath9k_hw_ani_ofdm_err_trigger_old(ah); + ath9k_ani_restart_old(ah); } else if (aniState->cckPhyErrCount > aniState->listenTime * aniState->cckTrigHigh / 1000) { - ath9k_hw_ani_cck_err_trigger(ah); - ath9k_ani_restart(ah); + ath9k_hw_ani_cck_err_trigger_old(ah); + ath9k_ani_restart_old(ah); + } + } +} + +static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); + int32_t listenTime; + u32 phyCnt1, phyCnt2; + u32 ofdmPhyErrCnt, cckPhyErrCnt; + u32 ofdmPhyErrRate, cckPhyErrRate; + + if (!DO_ANI(ah)) + return; + + aniState = ah->curani; + if (WARN_ON(!aniState)) + return; + + listenTime = ath9k_hw_ani_get_listen_time(ah); + if (listenTime <= 0) { + ah->stats.ast_ani_lneg++; + /* restart ANI period if listenTime is invalid */ + ath_print(common, ATH_DBG_ANI, + "listenTime=%d - on new ani monitor\n", + listenTime); + ath9k_ani_restart_new(ah); + return; + } + + aniState->listenTime += listenTime; + + ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + + phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); + phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); + + if (phyCnt1 < aniState->ofdmPhyErrBase || + phyCnt2 < aniState->cckPhyErrBase) { + if (phyCnt1 < aniState->ofdmPhyErrBase) { + ath_print(common, ATH_DBG_ANI, + "phyCnt1 0x%x, resetting " + "counter value to 0x%x\n", + phyCnt1, + aniState->ofdmPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_1, + aniState->ofdmPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_MASK_1, + AR_PHY_ERR_OFDM_TIMING); + } + if (phyCnt2 < aniState->cckPhyErrBase) { + ath_print(common, ATH_DBG_ANI, + "phyCnt2 0x%x, resetting " + "counter value to 0x%x\n", + phyCnt2, + aniState->cckPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_2, + aniState->cckPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_MASK_2, + AR_PHY_ERR_CCK_TIMING); + } + return; + } + + ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; + ah->stats.ast_ani_ofdmerrs += + ofdmPhyErrCnt - aniState->ofdmPhyErrCount; + aniState->ofdmPhyErrCount = ofdmPhyErrCnt; + + cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; + ah->stats.ast_ani_cckerrs += + cckPhyErrCnt - aniState->cckPhyErrCount; + aniState->cckPhyErrCount = cckPhyErrCnt; + + ath_print(common, ATH_DBG_ANI, + "Errors: OFDM=0x%08x-0x%08x=%d " + "CCK=0x%08x-0x%08x=%d\n", + phyCnt1, + aniState->ofdmPhyErrBase, + ofdmPhyErrCnt, + phyCnt2, + aniState->cckPhyErrBase, + cckPhyErrCnt); + + ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / + aniState->listenTime; + cckPhyErrRate = aniState->cckPhyErrCount * 1000 / + aniState->listenTime; + + ath_print(common, ATH_DBG_ANI, + "listenTime=%d OFDM:%d errs=%d/s CCK:%d " + "errs=%d/s ofdm_turn=%d\n", + listenTime, aniState->ofdmNoiseImmunityLevel, + ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, + cckPhyErrRate, aniState->ofdmsTurn); + + if (aniState->listenTime > 5 * ah->aniperiod) { + if (ofdmPhyErrRate <= aniState->ofdmTrigLow && + cckPhyErrRate <= aniState->cckTrigLow) { + ath_print(common, ATH_DBG_ANI, + "1. listenTime=%d OFDM:%d errs=%d/s(<%d) " + "CCK:%d errs=%d/s(<%d) -> " + "ath9k_hw_ani_lower_immunity()\n", + aniState->listenTime, + aniState->ofdmNoiseImmunityLevel, + ofdmPhyErrRate, + aniState->ofdmTrigLow, + aniState->cckNoiseImmunityLevel, + cckPhyErrRate, + aniState->cckTrigLow); + ath9k_hw_ani_lower_immunity(ah); + aniState->ofdmsTurn = !aniState->ofdmsTurn; + } + ath_print(common, ATH_DBG_ANI, + "1 listenTime=%d ofdm=%d/s cck=%d/s - " + "calling ath9k_ani_restart_new()\n", + aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate); + ath9k_ani_restart_new(ah); + } else if (aniState->listenTime > ah->aniperiod) { + /* check to see if need to raise immunity */ + if (ofdmPhyErrRate > aniState->ofdmTrigHigh && + (cckPhyErrRate <= aniState->cckTrigHigh || + aniState->ofdmsTurn)) { + ath_print(common, ATH_DBG_ANI, + "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " + "ath9k_hw_ani_ofdm_err_trigger_new()\n", + aniState->listenTime, + aniState->ofdmNoiseImmunityLevel, + ofdmPhyErrRate, + aniState->ofdmTrigHigh); + ath9k_hw_ani_ofdm_err_trigger_new(ah); + ath9k_ani_restart_new(ah); + aniState->ofdmsTurn = false; + } else if (cckPhyErrRate > aniState->cckTrigHigh) { + ath_print(common, ATH_DBG_ANI, + "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " + "ath9k_hw_ani_cck_err_trigger_new()\n", + aniState->listenTime, + aniState->cckNoiseImmunityLevel, + cckPhyErrRate, + aniState->cckTrigHigh); + ath9k_hw_ani_cck_err_trigger_new(ah); + ath9k_ani_restart_new(ah); + aniState->ofdmsTurn = true; } } } -EXPORT_SYMBOL(ath9k_hw_ani_monitor); void ath9k_enable_mib_counters(struct ath_hw *ah) { @@ -495,6 +1038,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_CCK, 0); } +EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, @@ -542,7 +1086,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ -void ath9k_hw_procmibevent(struct ath_hw *ah) +static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) { u32 phyCnt1, phyCnt2; @@ -555,8 +1099,15 @@ void ath9k_hw_procmibevent(struct ath_hw *ah) /* Clear the mib counters and save them in the stats */ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - if (!DO_ANI(ah)) + if (!DO_ANI(ah)) { + /* + * We must always clear the interrupt cause by + * resetting the phy error regs. + */ + REG_WRITE(ah, AR_PHY_ERR_1, 0); + REG_WRITE(ah, AR_PHY_ERR_2, 0); return; + } /* NB: these are not reset-on-read */ phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); @@ -584,14 +1135,51 @@ void ath9k_hw_procmibevent(struct ath_hw *ah) * check will never be true. */ if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) - ath9k_hw_ani_ofdm_err_trigger(ah); + ath9k_hw_ani_ofdm_err_trigger_new(ah); if (aniState->cckPhyErrCount > aniState->cckTrigHigh) - ath9k_hw_ani_cck_err_trigger(ah); + ath9k_hw_ani_cck_err_trigger_old(ah); /* NB: always restart to insure the h/w counters are reset */ - ath9k_ani_restart(ah); + ath9k_ani_restart_old(ah); } } -EXPORT_SYMBOL(ath9k_hw_procmibevent); + +/* + * Process a MIB interrupt. We may potentially be invoked because + * any of the MIB counters overflow/trigger so don't assume we're + * here because a PHY error counter triggered. + */ +static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah) +{ + u32 phyCnt1, phyCnt2; + + /* Reset these counters regardless */ + REG_WRITE(ah, AR_FILT_OFDM, 0); + REG_WRITE(ah, AR_FILT_CCK, 0); + if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) + REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); + + /* Clear the mib counters and save them in the stats */ + ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + + if (!DO_ANI(ah)) { + /* + * We must always clear the interrupt cause by + * resetting the phy error regs. + */ + REG_WRITE(ah, AR_PHY_ERR_1, 0); + REG_WRITE(ah, AR_PHY_ERR_2, 0); + return; + } + + /* NB: these are not reset-on-read */ + phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); + phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); + + /* NB: always restart to insure the h/w counters are reset */ + if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || + ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) + ath9k_ani_restart_new(ah); +} void ath9k_hw_ani_setup(struct ath_hw *ah) { @@ -619,22 +1207,70 @@ void ath9k_hw_ani_init(struct ath_hw *ah) memset(ah->ani, 0, sizeof(ah->ani)); for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW; - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW; + if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { + ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; + ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW; + + ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW; + ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW; + + ah->ani[i].spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + + ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + + ah->ani[i].ofdmPhyErrBase = 0; + ah->ani[i].cckPhyErrBase = 0; + + if (AR_SREV_9300_20_OR_LATER(ah)) + ah->ani[i].mrcCCKOff = + !ATH9K_ANI_ENABLE_MRC_CCK; + else + ah->ani[i].mrcCCKOff = true; + + ah->ani[i].ofdmsTurn = true; + } else { + ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; + ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD; + + ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD; + ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD; + + ah->ani[i].spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; + ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; + + ah->ani[i].ofdmPhyErrBase = + AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD; + ah->ani[i].cckPhyErrBase = + AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD; + ah->ani[i].cckWeakSigThreshold = + ATH9K_ANI_CCK_WEAK_SIG_THR; + } + ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; ah->ani[i].ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; - ah->ani[i].cckWeakSigThreshold = - ATH9K_ANI_CCK_WEAK_SIG_THR; - ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; - ah->ani[i].ofdmPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; - ah->ani[i].cckPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH; + ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; + } + + /* + * since we expect some ongoing maintenance on the tables, let's sanity + * check here default level should not modify INI setting. + */ + if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { + const struct ani_ofdm_level_entry *entry_ofdm; + const struct ani_cck_level_entry *entry_cck; + + entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL]; + entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL]; + + ah->aniperiod = ATH9K_ANI_PERIOD_NEW; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; + } else { + ah->aniperiod = ATH9K_ANI_PERIOD_OLD; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; } ath_print(common, ATH_DBG_ANI, @@ -653,7 +1289,34 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath9k_enable_mib_counters(ah); - ah->aniperiod = ATH9K_ANI_PERIOD; if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; } + +void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) +{ + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + struct ath_hw_ops *ops = ath9k_hw_ops(ah); + + priv_ops->ani_reset = ath9k_ani_reset_old; + priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old; + + ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old; + ops->ani_monitor = ath9k_hw_ani_monitor_old; + + ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n"); +} + +void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah) +{ + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + struct ath_hw_ops *ops = ath9k_hw_ops(ah); + + priv_ops->ani_reset = ath9k_ani_reset_new; + priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new; + + ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new; + ops->ani_monitor = ath9k_hw_ani_monitor_new; + + ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n"); +} diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 3356762ea38..f4d0a4d48b3 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -23,23 +23,55 @@ #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) -#define ATH9K_ANI_OFDM_TRIG_HIGH 500 -#define ATH9K_ANI_OFDM_TRIG_LOW 200 -#define ATH9K_ANI_CCK_TRIG_HIGH 200 -#define ATH9K_ANI_CCK_TRIG_LOW 100 +/* units are errors per second */ +#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 +#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 1000 + +/* units are errors per second */ +#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 +#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400 + +/* units are errors per second */ +#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 +#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600 + +/* units are errors per second */ +#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100 +#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300 + #define ATH9K_ANI_NOISE_IMMUNE_LVL 4 #define ATH9K_ANI_USE_OFDM_WEAK_SIG true #define ATH9K_ANI_CCK_WEAK_SIG_THR false -#define ATH9K_ANI_SPUR_IMMUNE_LVL 7 -#define ATH9K_ANI_FIRSTEP_LVL 0 + +#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7 +#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3 + +#define ATH9K_ANI_FIRSTEP_LVL_OLD 0 +#define ATH9K_ANI_FIRSTEP_LVL_NEW 2 + #define ATH9K_ANI_RSSI_THR_HIGH 40 #define ATH9K_ANI_RSSI_THR_LOW 7 -#define ATH9K_ANI_PERIOD 100 + +#define ATH9K_ANI_PERIOD_OLD 100 +#define ATH9K_ANI_PERIOD_NEW 1000 + +/* in ms */ +#define ATH9K_ANI_POLLINTERVAL_OLD 100 +#define ATH9K_ANI_POLLINTERVAL_NEW 1000 #define HAL_NOISE_IMMUNE_MAX 4 #define HAL_SPUR_IMMUNE_MAX 7 #define HAL_FIRST_STEP_MAX 2 +#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0 +#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20 +#define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0 +#define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22 + +#define ATH9K_ANI_ENABLE_MRC_CCK true + +/* values here are relative to the INI */ + enum ath9k_ani_cmd { ATH9K_ANI_PRESENT = 0x1, ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2, @@ -49,7 +81,8 @@ enum ath9k_ani_cmd { ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20, ATH9K_ANI_MODE = 0x40, ATH9K_ANI_PHYERR_RESET = 0x80, - ATH9K_ANI_ALL = 0xff + ATH9K_ANI_MRC_CCK = 0x100, + ATH9K_ANI_ALL = 0xfff }; struct ath9k_mib_stats { @@ -60,9 +93,31 @@ struct ath9k_mib_stats { u32 beacons; }; +/* INI default values for ANI registers */ +struct ath9k_ani_default { + u16 m1ThreshLow; + u16 m2ThreshLow; + u16 m1Thresh; + u16 m2Thresh; + u16 m2CountThr; + u16 m2CountThrLow; + u16 m1ThreshLowExt; + u16 m2ThreshLowExt; + u16 m1ThreshExt; + u16 m2ThreshExt; + u16 firstep; + u16 firstepLow; + u16 cycpwrThr1; + u16 cycpwrThr1Ext; +}; + struct ar5416AniState { struct ath9k_channel *c; u8 noiseImmunityLevel; + u8 ofdmNoiseImmunityLevel; + u8 cckNoiseImmunityLevel; + bool ofdmsTurn; + u8 mrcCCKOff; u8 spurImmunityLevel; u8 firstepLevel; u8 ofdmWeakSigDetectOff; @@ -85,6 +140,7 @@ struct ar5416AniState { int16_t pktRssi[2]; int16_t ofdmErrRssi[2]; int16_t cckErrRssi[2]; + struct ath9k_ani_default iniDef; }; struct ar5416Stats { @@ -108,15 +164,13 @@ struct ar5416Stats { }; #define ah_mibStats stats.ast_mibstats -void ath9k_ani_reset(struct ath_hw *ah); -void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan); void ath9k_enable_mib_counters(struct ath_hw *ah); void ath9k_hw_disable_mib_counters(struct ath_hw *ah); u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, u32 *rxf_pcnt, u32 *txf_pcnt); -void ath9k_hw_procmibevent(struct ath_hw *ah); void ath9k_hw_ani_setup(struct ath_hw *ah); void ath9k_hw_ani_init(struct ath_hw *ah); +int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, + struct ath9k_channel *chan); #endif /* ANI_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 025c31ac614..36f7d0639db 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 Atheros Communications Inc. + * Copyright (c) 2010 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,729 +14,660 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef INITVALS_AR5008_H -#define INITVALS_AR5008_H - static const u32 ar5416Modes[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, - { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, - { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, - { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de }, - { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, - { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e }, - { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 }, - { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 }, - { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 }, - { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b }, - { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, - { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, - { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, - { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 }, - { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 }, - { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, - { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, - { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, - { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, - { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, - { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, - { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, - { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, - { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, - { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, - { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, - { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, - { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, - { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134}, + {0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b}, + {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, + {0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, + {0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, + {0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, + {0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120}, + {0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar5416Common[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00007010, 0x00000000 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x000080c0, 0x2a82301a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88000010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x00008300, 0x00000000 }, - { 0x00008304, 0x00000000 }, - { 0x00008308, 0x00000000 }, - { 0x0000830c, 0x00000000 }, - { 0x00008310, 0x00000000 }, - { 0x00008314, 0x00000000 }, - { 0x00008318, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00070000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xad848e19 }, - { 0x00009810, 0x7d14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x00009840, 0x206a002e }, - { 0x0000984c, 0x1284233c }, - { 0x00009854, 0x00000859 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x05100000 }, - { 0x0000a920, 0x05100000 }, - { 0x0000b920, 0x05100000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280b212 }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5d50e188 }, - { 0x00009958, 0x00081fff }, - { 0x0000c95c, 0x004b6a8e }, - { 0x0000c968, 0x000003ce }, - { 0x00009970, 0x190fb515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x001fff00 }, - { 0x000099ac, 0x00000000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000200 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x000000aa }, - { 0x000099fc, 0x00001042 }, - { 0x00009b00, 0x00000000 }, - { 0x00009b04, 0x00000001 }, - { 0x00009b08, 0x00000002 }, - { 0x00009b0c, 0x00000003 }, - { 0x00009b10, 0x00000004 }, - { 0x00009b14, 0x00000005 }, - { 0x00009b18, 0x00000008 }, - { 0x00009b1c, 0x00000009 }, - { 0x00009b20, 0x0000000a }, - { 0x00009b24, 0x0000000b }, - { 0x00009b28, 0x0000000c }, - { 0x00009b2c, 0x0000000d }, - { 0x00009b30, 0x00000010 }, - { 0x00009b34, 0x00000011 }, - { 0x00009b38, 0x00000012 }, - { 0x00009b3c, 0x00000013 }, - { 0x00009b40, 0x00000014 }, - { 0x00009b44, 0x00000015 }, - { 0x00009b48, 0x00000018 }, - { 0x00009b4c, 0x00000019 }, - { 0x00009b50, 0x0000001a }, - { 0x00009b54, 0x0000001b }, - { 0x00009b58, 0x0000001c }, - { 0x00009b5c, 0x0000001d }, - { 0x00009b60, 0x00000020 }, - { 0x00009b64, 0x00000021 }, - { 0x00009b68, 0x00000022 }, - { 0x00009b6c, 0x00000023 }, - { 0x00009b70, 0x00000024 }, - { 0x00009b74, 0x00000025 }, - { 0x00009b78, 0x00000028 }, - { 0x00009b7c, 0x00000029 }, - { 0x00009b80, 0x0000002a }, - { 0x00009b84, 0x0000002b }, - { 0x00009b88, 0x0000002c }, - { 0x00009b8c, 0x0000002d }, - { 0x00009b90, 0x00000030 }, - { 0x00009b94, 0x00000031 }, - { 0x00009b98, 0x00000032 }, - { 0x00009b9c, 0x00000033 }, - { 0x00009ba0, 0x00000034 }, - { 0x00009ba4, 0x00000035 }, - { 0x00009ba8, 0x00000035 }, - { 0x00009bac, 0x00000035 }, - { 0x00009bb0, 0x00000035 }, - { 0x00009bb4, 0x00000035 }, - { 0x00009bb8, 0x00000035 }, - { 0x00009bbc, 0x00000035 }, - { 0x00009bc0, 0x00000035 }, - { 0x00009bc4, 0x00000035 }, - { 0x00009bc8, 0x00000035 }, - { 0x00009bcc, 0x00000035 }, - { 0x00009bd0, 0x00000035 }, - { 0x00009bd4, 0x00000035 }, - { 0x00009bd8, 0x00000035 }, - { 0x00009bdc, 0x00000035 }, - { 0x00009be0, 0x00000035 }, - { 0x00009be4, 0x00000035 }, - { 0x00009be8, 0x00000035 }, - { 0x00009bec, 0x00000035 }, - { 0x00009bf0, 0x00000035 }, - { 0x00009bf4, 0x00000035 }, - { 0x00009bf8, 0x00000010 }, - { 0x00009bfc, 0x0000001a }, - { 0x0000a210, 0x40806333 }, - { 0x0000a214, 0x00106c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x018830c6 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x00000bb5 }, - { 0x0000a22c, 0x00000011 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889af }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00007bb6 }, - { 0x0000a248, 0x0fff3ffc }, - { 0x0000a24c, 0x00000001 }, - { 0x0000a250, 0x0000a000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cc75380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0e79e5c6 }, - { 0x0000b26c, 0x0e79e5c6 }, - { 0x0000c26c, 0x0e79e5c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x051701ce }, - { 0x0000a338, 0x00000000 }, - { 0x0000a33c, 0x00000000 }, - { 0x0000a340, 0x00000000 }, - { 0x0000a344, 0x00000000 }, - { 0x0000a348, 0x3fffffff }, - { 0x0000a34c, 0x3fffffff }, - { 0x0000a350, 0x3fffffff }, - { 0x0000a354, 0x0003ffff }, - { 0x0000a358, 0x79a8aa1f }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x08000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00007010, 0x00000000}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x000080c0, 0x2a82301a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88000010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x00008300, 0x00000000}, + {0x00008304, 0x00000000}, + {0x00008308, 0x00000000}, + {0x0000830c, 0x00000000}, + {0x00008310, 0x00000000}, + {0x00008314, 0x00000000}, + {0x00008318, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00070000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xad848e19}, + {0x00009810, 0x7d14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x00009840, 0x206a002e}, + {0x0000984c, 0x1284233c}, + {0x00009854, 0x00000859}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x05100000}, + {0x0000a920, 0x05100000}, + {0x0000b920, 0x05100000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280b212}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5d50e188}, + {0x00009958, 0x00081fff}, + {0x0000c95c, 0x004b6a8e}, + {0x0000c968, 0x000003ce}, + {0x00009970, 0x190fb515}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x001fff00}, + {0x000099ac, 0x00000000}, + {0x000099b0, 0x03051000}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000200}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x000000aa}, + {0x000099fc, 0x00001042}, + {0x00009b00, 0x00000000}, + {0x00009b04, 0x00000001}, + {0x00009b08, 0x00000002}, + {0x00009b0c, 0x00000003}, + {0x00009b10, 0x00000004}, + {0x00009b14, 0x00000005}, + {0x00009b18, 0x00000008}, + {0x00009b1c, 0x00000009}, + {0x00009b20, 0x0000000a}, + {0x00009b24, 0x0000000b}, + {0x00009b28, 0x0000000c}, + {0x00009b2c, 0x0000000d}, + {0x00009b30, 0x00000010}, + {0x00009b34, 0x00000011}, + {0x00009b38, 0x00000012}, + {0x00009b3c, 0x00000013}, + {0x00009b40, 0x00000014}, + {0x00009b44, 0x00000015}, + {0x00009b48, 0x00000018}, + {0x00009b4c, 0x00000019}, + {0x00009b50, 0x0000001a}, + {0x00009b54, 0x0000001b}, + {0x00009b58, 0x0000001c}, + {0x00009b5c, 0x0000001d}, + {0x00009b60, 0x00000020}, + {0x00009b64, 0x00000021}, + {0x00009b68, 0x00000022}, + {0x00009b6c, 0x00000023}, + {0x00009b70, 0x00000024}, + {0x00009b74, 0x00000025}, + {0x00009b78, 0x00000028}, + {0x00009b7c, 0x00000029}, + {0x00009b80, 0x0000002a}, + {0x00009b84, 0x0000002b}, + {0x00009b88, 0x0000002c}, + {0x00009b8c, 0x0000002d}, + {0x00009b90, 0x00000030}, + {0x00009b94, 0x00000031}, + {0x00009b98, 0x00000032}, + {0x00009b9c, 0x00000033}, + {0x00009ba0, 0x00000034}, + {0x00009ba4, 0x00000035}, + {0x00009ba8, 0x00000035}, + {0x00009bac, 0x00000035}, + {0x00009bb0, 0x00000035}, + {0x00009bb4, 0x00000035}, + {0x00009bb8, 0x00000035}, + {0x00009bbc, 0x00000035}, + {0x00009bc0, 0x00000035}, + {0x00009bc4, 0x00000035}, + {0x00009bc8, 0x00000035}, + {0x00009bcc, 0x00000035}, + {0x00009bd0, 0x00000035}, + {0x00009bd4, 0x00000035}, + {0x00009bd8, 0x00000035}, + {0x00009bdc, 0x00000035}, + {0x00009be0, 0x00000035}, + {0x00009be4, 0x00000035}, + {0x00009be8, 0x00000035}, + {0x00009bec, 0x00000035}, + {0x00009bf0, 0x00000035}, + {0x00009bf4, 0x00000035}, + {0x00009bf8, 0x00000010}, + {0x00009bfc, 0x0000001a}, + {0x0000a210, 0x40806333}, + {0x0000a214, 0x00106c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x018830c6}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x00000bb5}, + {0x0000a22c, 0x00000011}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00007bb6}, + {0x0000a248, 0x0fff3ffc}, + {0x0000a24c, 0x00000001}, + {0x0000a250, 0x0000a000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cc75380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000c26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x051701ce}, + {0x0000a338, 0x00000000}, + {0x0000a33c, 0x00000000}, + {0x0000a340, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a348, 0x3fffffff}, + {0x0000a34c, 0x3fffffff}, + {0x0000a350, 0x3fffffff}, + {0x0000a354, 0x0003ffff}, + {0x0000a358, 0x79a8aa1f}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x08000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, }; static const u32 ar5416Bank0[][2] = { - { 0x000098b0, 0x1e5795e5 }, - { 0x000098e0, 0x02008020 }, + /* Addr allmodes */ + {0x000098b0, 0x1e5795e5}, + {0x000098e0, 0x02008020}, }; static const u32 ar5416BB_RfGain[][3] = { - { 0x00009a00, 0x00000000, 0x00000000 }, - { 0x00009a04, 0x00000040, 0x00000040 }, - { 0x00009a08, 0x00000080, 0x00000080 }, - { 0x00009a0c, 0x000001a1, 0x00000141 }, - { 0x00009a10, 0x000001e1, 0x00000181 }, - { 0x00009a14, 0x00000021, 0x000001c1 }, - { 0x00009a18, 0x00000061, 0x00000001 }, - { 0x00009a1c, 0x00000168, 0x00000041 }, - { 0x00009a20, 0x000001a8, 0x000001a8 }, - { 0x00009a24, 0x000001e8, 0x000001e8 }, - { 0x00009a28, 0x00000028, 0x00000028 }, - { 0x00009a2c, 0x00000068, 0x00000068 }, - { 0x00009a30, 0x00000189, 0x000000a8 }, - { 0x00009a34, 0x000001c9, 0x00000169 }, - { 0x00009a38, 0x00000009, 0x000001a9 }, - { 0x00009a3c, 0x00000049, 0x000001e9 }, - { 0x00009a40, 0x00000089, 0x00000029 }, - { 0x00009a44, 0x00000170, 0x00000069 }, - { 0x00009a48, 0x000001b0, 0x00000190 }, - { 0x00009a4c, 0x000001f0, 0x000001d0 }, - { 0x00009a50, 0x00000030, 0x00000010 }, - { 0x00009a54, 0x00000070, 0x00000050 }, - { 0x00009a58, 0x00000191, 0x00000090 }, - { 0x00009a5c, 0x000001d1, 0x00000151 }, - { 0x00009a60, 0x00000011, 0x00000191 }, - { 0x00009a64, 0x00000051, 0x000001d1 }, - { 0x00009a68, 0x00000091, 0x00000011 }, - { 0x00009a6c, 0x000001b8, 0x00000051 }, - { 0x00009a70, 0x000001f8, 0x00000198 }, - { 0x00009a74, 0x00000038, 0x000001d8 }, - { 0x00009a78, 0x00000078, 0x00000018 }, - { 0x00009a7c, 0x00000199, 0x00000058 }, - { 0x00009a80, 0x000001d9, 0x00000098 }, - { 0x00009a84, 0x00000019, 0x00000159 }, - { 0x00009a88, 0x00000059, 0x00000199 }, - { 0x00009a8c, 0x00000099, 0x000001d9 }, - { 0x00009a90, 0x000000d9, 0x00000019 }, - { 0x00009a94, 0x000000f9, 0x00000059 }, - { 0x00009a98, 0x000000f9, 0x00000099 }, - { 0x00009a9c, 0x000000f9, 0x000000d9 }, - { 0x00009aa0, 0x000000f9, 0x000000f9 }, - { 0x00009aa4, 0x000000f9, 0x000000f9 }, - { 0x00009aa8, 0x000000f9, 0x000000f9 }, - { 0x00009aac, 0x000000f9, 0x000000f9 }, - { 0x00009ab0, 0x000000f9, 0x000000f9 }, - { 0x00009ab4, 0x000000f9, 0x000000f9 }, - { 0x00009ab8, 0x000000f9, 0x000000f9 }, - { 0x00009abc, 0x000000f9, 0x000000f9 }, - { 0x00009ac0, 0x000000f9, 0x000000f9 }, - { 0x00009ac4, 0x000000f9, 0x000000f9 }, - { 0x00009ac8, 0x000000f9, 0x000000f9 }, - { 0x00009acc, 0x000000f9, 0x000000f9 }, - { 0x00009ad0, 0x000000f9, 0x000000f9 }, - { 0x00009ad4, 0x000000f9, 0x000000f9 }, - { 0x00009ad8, 0x000000f9, 0x000000f9 }, - { 0x00009adc, 0x000000f9, 0x000000f9 }, - { 0x00009ae0, 0x000000f9, 0x000000f9 }, - { 0x00009ae4, 0x000000f9, 0x000000f9 }, - { 0x00009ae8, 0x000000f9, 0x000000f9 }, - { 0x00009aec, 0x000000f9, 0x000000f9 }, - { 0x00009af0, 0x000000f9, 0x000000f9 }, - { 0x00009af4, 0x000000f9, 0x000000f9 }, - { 0x00009af8, 0x000000f9, 0x000000f9 }, - { 0x00009afc, 0x000000f9, 0x000000f9 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x00009a00, 0x00000000, 0x00000000}, + {0x00009a04, 0x00000040, 0x00000040}, + {0x00009a08, 0x00000080, 0x00000080}, + {0x00009a0c, 0x000001a1, 0x00000141}, + {0x00009a10, 0x000001e1, 0x00000181}, + {0x00009a14, 0x00000021, 0x000001c1}, + {0x00009a18, 0x00000061, 0x00000001}, + {0x00009a1c, 0x00000168, 0x00000041}, + {0x00009a20, 0x000001a8, 0x000001a8}, + {0x00009a24, 0x000001e8, 0x000001e8}, + {0x00009a28, 0x00000028, 0x00000028}, + {0x00009a2c, 0x00000068, 0x00000068}, + {0x00009a30, 0x00000189, 0x000000a8}, + {0x00009a34, 0x000001c9, 0x00000169}, + {0x00009a38, 0x00000009, 0x000001a9}, + {0x00009a3c, 0x00000049, 0x000001e9}, + {0x00009a40, 0x00000089, 0x00000029}, + {0x00009a44, 0x00000170, 0x00000069}, + {0x00009a48, 0x000001b0, 0x00000190}, + {0x00009a4c, 0x000001f0, 0x000001d0}, + {0x00009a50, 0x00000030, 0x00000010}, + {0x00009a54, 0x00000070, 0x00000050}, + {0x00009a58, 0x00000191, 0x00000090}, + {0x00009a5c, 0x000001d1, 0x00000151}, + {0x00009a60, 0x00000011, 0x00000191}, + {0x00009a64, 0x00000051, 0x000001d1}, + {0x00009a68, 0x00000091, 0x00000011}, + {0x00009a6c, 0x000001b8, 0x00000051}, + {0x00009a70, 0x000001f8, 0x00000198}, + {0x00009a74, 0x00000038, 0x000001d8}, + {0x00009a78, 0x00000078, 0x00000018}, + {0x00009a7c, 0x00000199, 0x00000058}, + {0x00009a80, 0x000001d9, 0x00000098}, + {0x00009a84, 0x00000019, 0x00000159}, + {0x00009a88, 0x00000059, 0x00000199}, + {0x00009a8c, 0x00000099, 0x000001d9}, + {0x00009a90, 0x000000d9, 0x00000019}, + {0x00009a94, 0x000000f9, 0x00000059}, + {0x00009a98, 0x000000f9, 0x00000099}, + {0x00009a9c, 0x000000f9, 0x000000d9}, + {0x00009aa0, 0x000000f9, 0x000000f9}, + {0x00009aa4, 0x000000f9, 0x000000f9}, + {0x00009aa8, 0x000000f9, 0x000000f9}, + {0x00009aac, 0x000000f9, 0x000000f9}, + {0x00009ab0, 0x000000f9, 0x000000f9}, + {0x00009ab4, 0x000000f9, 0x000000f9}, + {0x00009ab8, 0x000000f9, 0x000000f9}, + {0x00009abc, 0x000000f9, 0x000000f9}, + {0x00009ac0, 0x000000f9, 0x000000f9}, + {0x00009ac4, 0x000000f9, 0x000000f9}, + {0x00009ac8, 0x000000f9, 0x000000f9}, + {0x00009acc, 0x000000f9, 0x000000f9}, + {0x00009ad0, 0x000000f9, 0x000000f9}, + {0x00009ad4, 0x000000f9, 0x000000f9}, + {0x00009ad8, 0x000000f9, 0x000000f9}, + {0x00009adc, 0x000000f9, 0x000000f9}, + {0x00009ae0, 0x000000f9, 0x000000f9}, + {0x00009ae4, 0x000000f9, 0x000000f9}, + {0x00009ae8, 0x000000f9, 0x000000f9}, + {0x00009aec, 0x000000f9, 0x000000f9}, + {0x00009af0, 0x000000f9, 0x000000f9}, + {0x00009af4, 0x000000f9, 0x000000f9}, + {0x00009af8, 0x000000f9, 0x000000f9}, + {0x00009afc, 0x000000f9, 0x000000f9}, }; static const u32 ar5416Bank1[][2] = { - { 0x000098b0, 0x02108421 }, - { 0x000098ec, 0x00000008 }, + /* Addr allmodes */ + {0x000098b0, 0x02108421}, + {0x000098ec, 0x00000008}, }; static const u32 ar5416Bank2[][2] = { - { 0x000098b0, 0x0e73ff17 }, - { 0x000098e0, 0x00000420 }, + /* Addr allmodes */ + {0x000098b0, 0x0e73ff17}, + {0x000098e0, 0x00000420}, }; static const u32 ar5416Bank3[][3] = { - { 0x000098f0, 0x01400018, 0x01c00018 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x000098f0, 0x01400018, 0x01c00018}, }; static const u32 ar5416Bank6[][3] = { - - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x40ff0000, 0x40ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x004210a2, 0x004210a2 }, - { 0x0000989c, 0x0014008f, 0x0014008f }, - { 0x0000989c, 0x00c40003, 0x00c40003 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x0001805e, 0x0001805e }, - { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, - { 0x0000989c, 0x000000f1, 0x000000f1 }, - { 0x0000989c, 0x00002081, 0x00002081 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x40ff0000, 0x40ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x004210a2, 0x004210a2}, + {0x0000989c, 0x0014008f, 0x0014008f}, + {0x0000989c, 0x00c40003, 0x00c40003}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x0001805e, 0x0001805e}, + {0x0000989c, 0x0000c0ab, 0x0000c0ab}, + {0x0000989c, 0x000000f1, 0x000000f1}, + {0x0000989c, 0x00002081, 0x00002081}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; static const u32 ar5416Bank6TPC[][3] = { - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x40ff0000, 0x40ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x00423022, 0x00423022 }, - { 0x0000989c, 0x201400df, 0x201400df }, - { 0x0000989c, 0x00c40002, 0x00c40002 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x0001805e, 0x0001805e }, - { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, - { 0x0000989c, 0x000000e1, 0x000000e1 }, - { 0x0000989c, 0x00007081, 0x00007081 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x40ff0000, 0x40ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x00423022, 0x00423022}, + {0x0000989c, 0x201400df, 0x201400df}, + {0x0000989c, 0x00c40002, 0x00c40002}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x0001805e, 0x0001805e}, + {0x0000989c, 0x0000c0ab, 0x0000c0ab}, + {0x0000989c, 0x000000e1, 0x000000e1}, + {0x0000989c, 0x00007081, 0x00007081}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; static const u32 ar5416Bank7[][2] = { - { 0x0000989c, 0x00000500 }, - { 0x0000989c, 0x00000800 }, - { 0x000098cc, 0x0000000e }, + /* Addr allmodes */ + {0x0000989c, 0x00000500}, + {0x0000989c, 0x00000800}, + {0x000098cc, 0x0000000e}, }; static const u32 ar5416Addac[][2] = { - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000003 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x0000000c }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000030 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000060 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000058 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x000098cc, 0x00000000 }, -}; - -static const u32 ar5416Modes_9100[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, - { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 }, - { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, - { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, - { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, - { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, - { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 }, - { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 }, - { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e }, - { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff }, -#ifdef TB243 - { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, - { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, - { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 }, -#else - { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, - { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, - { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, - { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, -#endif - { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 }, - { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, - { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, - { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, - { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, - { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, - { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, - { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, - { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, - { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, - { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, - { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, - { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, - { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, - { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + /* Addr allmodes */ + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000003}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x0000000c}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000030}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000060}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000058}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x000098cc, 0x00000000}, }; -#endif /* INITVALS_AR5008_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index b2c17c98bb3..3d2c8679bc8 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -19,7 +19,30 @@ #include "../regd.h" #include "ar9002_phy.h" -/* All code below is for non single-chip solutions */ +/* All code below is for AR5008, AR9001, AR9002 */ + +static const int firstep_table[] = +/* level: 0 1 2 3 4 5 6 7 8 */ + { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ + +static const int cycpwrThr1_table[] = +/* level: 0 1 2 3 4 5 6 7 8 */ + { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ + +/* + * register values to turn OFDM weak signal detection OFF + */ +static const int m1ThreshLow_off = 127; +static const int m2ThreshLow_off = 127; +static const int m1Thresh_off = 127; +static const int m2Thresh_off = 127; +static const int m2CountThr_off = 31; +static const int m2CountThrLow_off = 63; +static const int m1ThreshLowExt_off = 127; +static const int m2ThreshLowExt_off = 127; +static const int m1ThreshExt_off = 127; +static const int m2ThreshExt_off = 127; + /** * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters @@ -742,17 +765,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, return -EINVAL; } - if (AR_SREV_9287_12_OR_LATER(ah)) { - /* Enable ASYNC FIFO */ - REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, - AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); - REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); - REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, - AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); - REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, - AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); - } - /* * Set correct baseband to analog shift setting to * access analog chips. @@ -1037,8 +1049,9 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah, return pll; } -static bool ar5008_hw_ani_control(struct ath_hw *ah, - enum ath9k_ani_cmd cmd, int param) +static bool ar5008_hw_ani_control_old(struct ath_hw *ah, + enum ath9k_ani_cmd cmd, + int param) { struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); @@ -1220,129 +1233,377 @@ static bool ar5008_hw_ani_control(struct ath_hw *ah, return true; } +static bool ar5008_hw_ani_control_new(struct ath_hw *ah, + enum ath9k_ani_cmd cmd, + int param) +{ + struct ar5416AniState *aniState = ah->curani; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; + s32 value, value2; + + switch (cmd & ah->ani_function) { + case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ + /* + * on == 1 means ofdm weak signal detection is ON + * on == 1 is the default, for less noise immunity + * + * on == 0 means ofdm weak signal detection is OFF + * on == 0 means more noise imm + */ + u32 on = param ? 1 : 0; + /* + * make register setting for default + * (weak sig detect ON) come from INI file + */ + int m1ThreshLow = on ? + aniState->iniDef.m1ThreshLow : m1ThreshLow_off; + int m2ThreshLow = on ? + aniState->iniDef.m2ThreshLow : m2ThreshLow_off; + int m1Thresh = on ? + aniState->iniDef.m1Thresh : m1Thresh_off; + int m2Thresh = on ? + aniState->iniDef.m2Thresh : m2Thresh_off; + int m2CountThr = on ? + aniState->iniDef.m2CountThr : m2CountThr_off; + int m2CountThrLow = on ? + aniState->iniDef.m2CountThrLow : m2CountThrLow_off; + int m1ThreshLowExt = on ? + aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; + int m2ThreshLowExt = on ? + aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; + int m1ThreshExt = on ? + aniState->iniDef.m1ThreshExt : m1ThreshExt_off; + int m2ThreshExt = on ? + aniState->iniDef.m2ThreshExt : m2ThreshExt_off; + + REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_M1_THRESH_LOW, + m1ThreshLow); + REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_M2_THRESH_LOW, + m2ThreshLow); + REG_RMW_FIELD(ah, AR_PHY_SFCORR, + AR_PHY_SFCORR_M1_THRESH, m1Thresh); + REG_RMW_FIELD(ah, AR_PHY_SFCORR, + AR_PHY_SFCORR_M2_THRESH, m2Thresh); + REG_RMW_FIELD(ah, AR_PHY_SFCORR, + AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); + REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, + m2CountThrLow); + + REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, + AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); + REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, + AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); + REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, + AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); + REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, + AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); + + if (on) + REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + else + REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + + if (!on != aniState->ofdmWeakSigDetectOff) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: ofdm weak signal: %s=>%s\n", + chan->channel, + !aniState->ofdmWeakSigDetectOff ? + "on" : "off", + on ? "on" : "off"); + if (on) + ah->stats.ast_ani_ofdmon++; + else + ah->stats.ast_ani_ofdmoff++; + aniState->ofdmWeakSigDetectOff = !on; + } + break; + } + case ATH9K_ANI_FIRSTEP_LEVEL:{ + u32 level = param; + + if (level >= ARRAY_SIZE(firstep_table)) { + ath_print(common, ATH_DBG_ANI, + "ATH9K_ANI_FIRSTEP_LEVEL: level " + "out of range (%u > %u)\n", + level, + (unsigned) ARRAY_SIZE(firstep_table)); + return false; + } + + /* + * make register setting relative to default + * from INI file & cap value + */ + value = firstep_table[level] - + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + aniState->iniDef.firstep; + if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) + value = ATH9K_SIG_FIRSTEP_SETTING_MIN; + if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) + value = ATH9K_SIG_FIRSTEP_SETTING_MAX; + REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, + AR_PHY_FIND_SIG_FIRSTEP, + value); + /* + * we need to set first step low register too + * make register setting relative to default + * from INI file & cap value + */ + value2 = firstep_table[level] - + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + aniState->iniDef.firstepLow; + if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) + value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; + if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) + value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; + + REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, + AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); + + if (level != aniState->firstepLevel) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "firstep[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value, + aniState->iniDef.firstep); + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "firstep_low[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value2, + aniState->iniDef.firstepLow); + if (level > aniState->firstepLevel) + ah->stats.ast_ani_stepup++; + else if (level < aniState->firstepLevel) + ah->stats.ast_ani_stepdown++; + aniState->firstepLevel = level; + } + break; + } + case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ + u32 level = param; + + if (level >= ARRAY_SIZE(cycpwrThr1_table)) { + ath_print(common, ATH_DBG_ANI, + "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " + "out of range (%u > %u)\n", + level, + (unsigned) ARRAY_SIZE(cycpwrThr1_table)); + return false; + } + /* + * make register setting relative to default + * from INI file & cap value + */ + value = cycpwrThr1_table[level] - + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + aniState->iniDef.cycpwrThr1; + if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) + value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; + if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) + value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; + REG_RMW_FIELD(ah, AR_PHY_TIMING5, + AR_PHY_TIMING5_CYCPWR_THR1, + value); + + /* + * set AR_PHY_EXT_CCA for extension channel + * make register setting relative to default + * from INI file & cap value + */ + value2 = cycpwrThr1_table[level] - + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + aniState->iniDef.cycpwrThr1Ext; + if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) + value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; + if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) + value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; + REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, + AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); + + if (level != aniState->spurImmunityLevel) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "cycpwrThr1[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value, + aniState->iniDef.cycpwrThr1); + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "cycpwrThr1Ext[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value2, + aniState->iniDef.cycpwrThr1Ext); + if (level > aniState->spurImmunityLevel) + ah->stats.ast_ani_spurup++; + else if (level < aniState->spurImmunityLevel) + ah->stats.ast_ani_spurdown++; + aniState->spurImmunityLevel = level; + } + break; + } + case ATH9K_ANI_MRC_CCK: + /* + * You should not see this as AR5008, AR9001, AR9002 + * does not have hardware support for MRC CCK. + */ + WARN_ON(1); + break; + case ATH9K_ANI_PRESENT: + break; + default: + ath_print(common, ATH_DBG_ANI, + "invalid cmd %u\n", cmd); + return false; + } + + ath_print(common, ATH_DBG_ANI, + "ANI parameters: SI=%d, ofdmWS=%s FS=%d " + "MRCcck=%s listenTime=%d CC=%d listen=%d " + "ofdmErrs=%d cckErrs=%d\n", + aniState->spurImmunityLevel, + !aniState->ofdmWeakSigDetectOff ? "on" : "off", + aniState->firstepLevel, + !aniState->mrcCCKOff ? "on" : "off", + aniState->listenTime, + aniState->cycleCount, + aniState->listenTime, + aniState->ofdmPhyErrCount, + aniState->cckPhyErrCount); + return true; +} + static void ar5008_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { - struct ath_common *common = ath9k_hw_common(ah); int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 0] is %d\n", nf); - nfarray[0] = nf; + nfarray[0] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 1] is %d\n", nf); - nfarray[1] = nf; + nfarray[1] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 2] is %d\n", nf); - nfarray[2] = nf; + nfarray[2] = sign_extend(nf, 9); + + if (!IS_CHAN_HT40(ah->curchan)) + return; nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 0] is %d\n", nf); - nfarray[3] = nf; + nfarray[3] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 1] is %d\n", nf); - nfarray[4] = nf; + nfarray[4] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 2] is %d\n", nf); - nfarray[5] = nf; + nfarray[5] = sign_extend(nf, 9); } -static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) +/* + * Initialize the ANI register values with default (ini) values. + * This routine is called during a (full) hardware reset after + * all the registers are initialised from the INI. + */ +static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) { - struct ath9k_nfcal_hist *h; - int i, j; - int32_t val; - const u32 ar5416_cca_regs[6] = { - AR_PHY_CCA, - AR_PHY_CH1_CCA, - AR_PHY_CH2_CCA, - AR_PHY_EXT_CCA, - AR_PHY_CH1_EXT_CCA, - AR_PHY_CH2_EXT_CCA - }; - u8 chainmask, rx_chain_status; - - rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) - chainmask = 0x9; - else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { - if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) - chainmask = 0x1B; - else - chainmask = 0x09; - } else { - if (rx_chain_status & 0x4) - chainmask = 0x3F; - else if (rx_chain_status & 0x2) - chainmask = 0x1B; - else - chainmask = 0x09; - } - - h = ah->nfCalHist; - - for (i = 0; i < NUM_NF_READINGS; i++) { - if (chainmask & (1 << i)) { - val = REG_READ(ah, ar5416_cca_regs[i]); - val &= 0xFFFFFE00; - val |= (((u32) (h[i].privNF) << 1) & 0x1ff); - REG_WRITE(ah, ar5416_cca_regs[i], val); - } - } - - REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, - AR_PHY_AGC_CONTROL_ENABLE_NF); - REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, - AR_PHY_AGC_CONTROL_NO_UPDATE_NF); - REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); - - for (j = 0; j < 5; j++) { - if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & - AR_PHY_AGC_CONTROL_NF) == 0) - break; - udelay(50); - } + struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; + struct ath9k_ani_default *iniDef; + int index; + u32 val; - ENABLE_REGWRITE_BUFFER(ah); + index = ath9k_hw_get_ani_channel_idx(ah, chan); + aniState = &ah->ani[index]; + ah->curani = aniState; + iniDef = &aniState->iniDef; - for (i = 0; i < NUM_NF_READINGS; i++) { - if (chainmask & (1 << i)) { - val = REG_READ(ah, ar5416_cca_regs[i]); - val &= 0xFFFFFE00; - val |= (((u32) (-50) << 1) & 0x1ff); - REG_WRITE(ah, ar5416_cca_regs[i], val); - } - } + ath_print(common, ATH_DBG_ANI, + "ver %d.%d opmode %u chan %d Mhz/0x%x\n", + ah->hw_version.macVersion, + ah->hw_version.macRev, + ah->opmode, + chan->channel, + chan->channelFlags); + + val = REG_READ(ah, AR_PHY_SFCORR); + iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); + iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH); + iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR); + + val = REG_READ(ah, AR_PHY_SFCORR_LOW); + iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW); + iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW); + iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); + + val = REG_READ(ah, AR_PHY_SFCORR_EXT); + iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH); + iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH); + iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW); + iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW); + iniDef->firstep = REG_READ_FIELD(ah, + AR_PHY_FIND_SIG, + AR_PHY_FIND_SIG_FIRSTEP); + iniDef->firstepLow = REG_READ_FIELD(ah, + AR_PHY_FIND_SIG_LOW, + AR_PHY_FIND_SIG_FIRSTEP_LOW); + iniDef->cycpwrThr1 = REG_READ_FIELD(ah, + AR_PHY_TIMING5, + AR_PHY_TIMING5_CYCPWR_THR1); + iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah, + AR_PHY_EXT_CCA, + AR_PHY_EXT_TIMING5_CYCPWR_THR1); + + /* these levels just got reset to defaults by the INI */ + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->mrcCCKOff = true; /* not available on pre AR9003 */ + + aniState->cycleCount = 0; +} - REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); +static void ar5008_hw_set_nf_limits(struct ath_hw *ah) +{ + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ; + ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ; + ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ; + ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ; } void ar5008_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + const u32 ar5416_cca_regs[6] = { + AR_PHY_CCA, + AR_PHY_CH1_CCA, + AR_PHY_CH2_CCA, + AR_PHY_EXT_CCA, + AR_PHY_CH1_EXT_CCA, + AR_PHY_CH2_EXT_CCA + }; priv_ops->rf_set_freq = ar5008_hw_set_channel; priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; @@ -1361,9 +1622,13 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; priv_ops->restore_chainmask = ar5008_restore_chainmask; priv_ops->set_diversity = ar5008_set_diversity; - priv_ops->ani_control = ar5008_hw_ani_control; priv_ops->do_getnf = ar5008_hw_do_getnf; - priv_ops->loadnf = ar5008_hw_loadnf; + + if (modparam_force_new_ani) { + priv_ops->ani_control = ar5008_hw_ani_control_new; + priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; + } else + priv_ops->ani_control = ar5008_hw_ani_control_old; if (AR_SREV_9100(ah)) priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; @@ -1371,4 +1636,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; else priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; + + ar5008_hw_set_nf_limits(ah); + memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); } diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index 0b94bd385b0..69a94c7e45c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h @@ -1,1254 +1,1357 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +static const u32 ar5416Modes_9100[][6] = { + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, + {0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204}, + {0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020}, + {0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e}, + {0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff}, + {0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, + {0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; static const u32 ar5416Common_9100[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00020010, 0x00000003 }, - { 0x00020038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00004000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x000080c0, 0x2a82301a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04800 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0x00000000 }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081d0, 0x00003210 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x00008300, 0x00000000 }, - { 0x00008304, 0x00000000 }, - { 0x00008308, 0x00000000 }, - { 0x0000830c, 0x00000000 }, - { 0x00008310, 0x00000000 }, - { 0x00008314, 0x00000000 }, - { 0x00008318, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00000000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xad848e19 }, - { 0x00009810, 0x7d14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x00009840, 0x206a01ae }, - { 0x0000984c, 0x1284233c }, - { 0x00009854, 0x00000859 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x05100000 }, - { 0x0000a920, 0x05100000 }, - { 0x0000b920, 0x05100000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280b212 }, - { 0x0000994c, 0x00020028 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x0000c968, 0x000003ce }, - { 0x00009970, 0x190fb515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x006f0000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000200 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099fc, 0x00001042 }, - { 0x00009b00, 0x00000000 }, - { 0x00009b04, 0x00000001 }, - { 0x00009b08, 0x00000002 }, - { 0x00009b0c, 0x00000003 }, - { 0x00009b10, 0x00000004 }, - { 0x00009b14, 0x00000005 }, - { 0x00009b18, 0x00000008 }, - { 0x00009b1c, 0x00000009 }, - { 0x00009b20, 0x0000000a }, - { 0x00009b24, 0x0000000b }, - { 0x00009b28, 0x0000000c }, - { 0x00009b2c, 0x0000000d }, - { 0x00009b30, 0x00000010 }, - { 0x00009b34, 0x00000011 }, - { 0x00009b38, 0x00000012 }, - { 0x00009b3c, 0x00000013 }, - { 0x00009b40, 0x00000014 }, - { 0x00009b44, 0x00000015 }, - { 0x00009b48, 0x00000018 }, - { 0x00009b4c, 0x00000019 }, - { 0x00009b50, 0x0000001a }, - { 0x00009b54, 0x0000001b }, - { 0x00009b58, 0x0000001c }, - { 0x00009b5c, 0x0000001d }, - { 0x00009b60, 0x00000020 }, - { 0x00009b64, 0x00000021 }, - { 0x00009b68, 0x00000022 }, - { 0x00009b6c, 0x00000023 }, - { 0x00009b70, 0x00000024 }, - { 0x00009b74, 0x00000025 }, - { 0x00009b78, 0x00000028 }, - { 0x00009b7c, 0x00000029 }, - { 0x00009b80, 0x0000002a }, - { 0x00009b84, 0x0000002b }, - { 0x00009b88, 0x0000002c }, - { 0x00009b8c, 0x0000002d }, - { 0x00009b90, 0x00000030 }, - { 0x00009b94, 0x00000031 }, - { 0x00009b98, 0x00000032 }, - { 0x00009b9c, 0x00000033 }, - { 0x00009ba0, 0x00000034 }, - { 0x00009ba4, 0x00000035 }, - { 0x00009ba8, 0x00000035 }, - { 0x00009bac, 0x00000035 }, - { 0x00009bb0, 0x00000035 }, - { 0x00009bb4, 0x00000035 }, - { 0x00009bb8, 0x00000035 }, - { 0x00009bbc, 0x00000035 }, - { 0x00009bc0, 0x00000035 }, - { 0x00009bc4, 0x00000035 }, - { 0x00009bc8, 0x00000035 }, - { 0x00009bcc, 0x00000035 }, - { 0x00009bd0, 0x00000035 }, - { 0x00009bd4, 0x00000035 }, - { 0x00009bd8, 0x00000035 }, - { 0x00009bdc, 0x00000035 }, - { 0x00009be0, 0x00000035 }, - { 0x00009be4, 0x00000035 }, - { 0x00009be8, 0x00000035 }, - { 0x00009bec, 0x00000035 }, - { 0x00009bf0, 0x00000035 }, - { 0x00009bf4, 0x00000035 }, - { 0x00009bf8, 0x00000010 }, - { 0x00009bfc, 0x0000001a }, - { 0x0000a210, 0x40806333 }, - { 0x0000a214, 0x00106c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x018830c6 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x001a0bb5 }, - { 0x0000a22c, 0x00000000 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889ae }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00007bb6 }, - { 0x0000a248, 0x0fff3ffc }, - { 0x0000a24c, 0x00000001 }, - { 0x0000a250, 0x0000a000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cc75380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a268, 0x00000001 }, - { 0x0000a26c, 0x0ebae9c6 }, - { 0x0000b26c, 0x0ebae9c6 }, - { 0x0000c26c, 0x0ebae9c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x050701ce }, - { 0x0000a338, 0x00000000 }, - { 0x0000a33c, 0x00000000 }, - { 0x0000a340, 0x00000000 }, - { 0x0000a344, 0x00000000 }, - { 0x0000a348, 0x3fffffff }, - { 0x0000a34c, 0x3fffffff }, - { 0x0000a350, 0x3fffffff }, - { 0x0000a354, 0x0003ffff }, - { 0x0000a358, 0x79a8aa33 }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00020010, 0x00000003}, + {0x00020038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00004000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x000080c0, 0x2a82301a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04800}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0x00000000}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081d0, 0x00003210}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x00008300, 0x00000000}, + {0x00008304, 0x00000000}, + {0x00008308, 0x00000000}, + {0x0000830c, 0x00000000}, + {0x00008310, 0x00000000}, + {0x00008314, 0x00000000}, + {0x00008318, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00000000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xad848e19}, + {0x00009810, 0x7d14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x00009840, 0x206a01ae}, + {0x0000984c, 0x1284233c}, + {0x00009854, 0x00000859}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x05100000}, + {0x0000a920, 0x05100000}, + {0x0000b920, 0x05100000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280b212}, + {0x0000994c, 0x00020028}, + {0x0000c95c, 0x004b6a8e}, + {0x0000c968, 0x000003ce}, + {0x00009970, 0x190fb515}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x006f0000}, + {0x000099b0, 0x03051000}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000200}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099fc, 0x00001042}, + {0x00009b00, 0x00000000}, + {0x00009b04, 0x00000001}, + {0x00009b08, 0x00000002}, + {0x00009b0c, 0x00000003}, + {0x00009b10, 0x00000004}, + {0x00009b14, 0x00000005}, + {0x00009b18, 0x00000008}, + {0x00009b1c, 0x00000009}, + {0x00009b20, 0x0000000a}, + {0x00009b24, 0x0000000b}, + {0x00009b28, 0x0000000c}, + {0x00009b2c, 0x0000000d}, + {0x00009b30, 0x00000010}, + {0x00009b34, 0x00000011}, + {0x00009b38, 0x00000012}, + {0x00009b3c, 0x00000013}, + {0x00009b40, 0x00000014}, + {0x00009b44, 0x00000015}, + {0x00009b48, 0x00000018}, + {0x00009b4c, 0x00000019}, + {0x00009b50, 0x0000001a}, + {0x00009b54, 0x0000001b}, + {0x00009b58, 0x0000001c}, + {0x00009b5c, 0x0000001d}, + {0x00009b60, 0x00000020}, + {0x00009b64, 0x00000021}, + {0x00009b68, 0x00000022}, + {0x00009b6c, 0x00000023}, + {0x00009b70, 0x00000024}, + {0x00009b74, 0x00000025}, + {0x00009b78, 0x00000028}, + {0x00009b7c, 0x00000029}, + {0x00009b80, 0x0000002a}, + {0x00009b84, 0x0000002b}, + {0x00009b88, 0x0000002c}, + {0x00009b8c, 0x0000002d}, + {0x00009b90, 0x00000030}, + {0x00009b94, 0x00000031}, + {0x00009b98, 0x00000032}, + {0x00009b9c, 0x00000033}, + {0x00009ba0, 0x00000034}, + {0x00009ba4, 0x00000035}, + {0x00009ba8, 0x00000035}, + {0x00009bac, 0x00000035}, + {0x00009bb0, 0x00000035}, + {0x00009bb4, 0x00000035}, + {0x00009bb8, 0x00000035}, + {0x00009bbc, 0x00000035}, + {0x00009bc0, 0x00000035}, + {0x00009bc4, 0x00000035}, + {0x00009bc8, 0x00000035}, + {0x00009bcc, 0x00000035}, + {0x00009bd0, 0x00000035}, + {0x00009bd4, 0x00000035}, + {0x00009bd8, 0x00000035}, + {0x00009bdc, 0x00000035}, + {0x00009be0, 0x00000035}, + {0x00009be4, 0x00000035}, + {0x00009be8, 0x00000035}, + {0x00009bec, 0x00000035}, + {0x00009bf0, 0x00000035}, + {0x00009bf4, 0x00000035}, + {0x00009bf8, 0x00000010}, + {0x00009bfc, 0x0000001a}, + {0x0000a210, 0x40806333}, + {0x0000a214, 0x00106c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x018830c6}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x001a0bb5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00007bb6}, + {0x0000a248, 0x0fff3ffc}, + {0x0000a24c, 0x00000001}, + {0x0000a250, 0x0000e000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cc75380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a268, 0x00000001}, + {0x0000a26c, 0x0ebae9c6}, + {0x0000b26c, 0x0ebae9c6}, + {0x0000c26c, 0x0ebae9c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, + {0x0000a338, 0x00000000}, + {0x0000a33c, 0x00000000}, + {0x0000a340, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a348, 0x3fffffff}, + {0x0000a34c, 0x3fffffff}, + {0x0000a350, 0x3fffffff}, + {0x0000a354, 0x0003ffff}, + {0x0000a358, 0x79a8aa33}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, }; static const u32 ar5416Bank0_9100[][2] = { - { 0x000098b0, 0x1e5795e5 }, - { 0x000098e0, 0x02008020 }, + /* Addr allmodes */ + {0x000098b0, 0x1e5795e5}, + {0x000098e0, 0x02008020}, }; static const u32 ar5416BB_RfGain_9100[][3] = { - { 0x00009a00, 0x00000000, 0x00000000 }, - { 0x00009a04, 0x00000040, 0x00000040 }, - { 0x00009a08, 0x00000080, 0x00000080 }, - { 0x00009a0c, 0x000001a1, 0x00000141 }, - { 0x00009a10, 0x000001e1, 0x00000181 }, - { 0x00009a14, 0x00000021, 0x000001c1 }, - { 0x00009a18, 0x00000061, 0x00000001 }, - { 0x00009a1c, 0x00000168, 0x00000041 }, - { 0x00009a20, 0x000001a8, 0x000001a8 }, - { 0x00009a24, 0x000001e8, 0x000001e8 }, - { 0x00009a28, 0x00000028, 0x00000028 }, - { 0x00009a2c, 0x00000068, 0x00000068 }, - { 0x00009a30, 0x00000189, 0x000000a8 }, - { 0x00009a34, 0x000001c9, 0x00000169 }, - { 0x00009a38, 0x00000009, 0x000001a9 }, - { 0x00009a3c, 0x00000049, 0x000001e9 }, - { 0x00009a40, 0x00000089, 0x00000029 }, - { 0x00009a44, 0x00000170, 0x00000069 }, - { 0x00009a48, 0x000001b0, 0x00000190 }, - { 0x00009a4c, 0x000001f0, 0x000001d0 }, - { 0x00009a50, 0x00000030, 0x00000010 }, - { 0x00009a54, 0x00000070, 0x00000050 }, - { 0x00009a58, 0x00000191, 0x00000090 }, - { 0x00009a5c, 0x000001d1, 0x00000151 }, - { 0x00009a60, 0x00000011, 0x00000191 }, - { 0x00009a64, 0x00000051, 0x000001d1 }, - { 0x00009a68, 0x00000091, 0x00000011 }, - { 0x00009a6c, 0x000001b8, 0x00000051 }, - { 0x00009a70, 0x000001f8, 0x00000198 }, - { 0x00009a74, 0x00000038, 0x000001d8 }, - { 0x00009a78, 0x00000078, 0x00000018 }, - { 0x00009a7c, 0x00000199, 0x00000058 }, - { 0x00009a80, 0x000001d9, 0x00000098 }, - { 0x00009a84, 0x00000019, 0x00000159 }, - { 0x00009a88, 0x00000059, 0x00000199 }, - { 0x00009a8c, 0x00000099, 0x000001d9 }, - { 0x00009a90, 0x000000d9, 0x00000019 }, - { 0x00009a94, 0x000000f9, 0x00000059 }, - { 0x00009a98, 0x000000f9, 0x00000099 }, - { 0x00009a9c, 0x000000f9, 0x000000d9 }, - { 0x00009aa0, 0x000000f9, 0x000000f9 }, - { 0x00009aa4, 0x000000f9, 0x000000f9 }, - { 0x00009aa8, 0x000000f9, 0x000000f9 }, - { 0x00009aac, 0x000000f9, 0x000000f9 }, - { 0x00009ab0, 0x000000f9, 0x000000f9 }, - { 0x00009ab4, 0x000000f9, 0x000000f9 }, - { 0x00009ab8, 0x000000f9, 0x000000f9 }, - { 0x00009abc, 0x000000f9, 0x000000f9 }, - { 0x00009ac0, 0x000000f9, 0x000000f9 }, - { 0x00009ac4, 0x000000f9, 0x000000f9 }, - { 0x00009ac8, 0x000000f9, 0x000000f9 }, - { 0x00009acc, 0x000000f9, 0x000000f9 }, - { 0x00009ad0, 0x000000f9, 0x000000f9 }, - { 0x00009ad4, 0x000000f9, 0x000000f9 }, - { 0x00009ad8, 0x000000f9, 0x000000f9 }, - { 0x00009adc, 0x000000f9, 0x000000f9 }, - { 0x00009ae0, 0x000000f9, 0x000000f9 }, - { 0x00009ae4, 0x000000f9, 0x000000f9 }, - { 0x00009ae8, 0x000000f9, 0x000000f9 }, - { 0x00009aec, 0x000000f9, 0x000000f9 }, - { 0x00009af0, 0x000000f9, 0x000000f9 }, - { 0x00009af4, 0x000000f9, 0x000000f9 }, - { 0x00009af8, 0x000000f9, 0x000000f9 }, - { 0x00009afc, 0x000000f9, 0x000000f9 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x00009a00, 0x00000000, 0x00000000}, + {0x00009a04, 0x00000040, 0x00000040}, + {0x00009a08, 0x00000080, 0x00000080}, + {0x00009a0c, 0x000001a1, 0x00000141}, + {0x00009a10, 0x000001e1, 0x00000181}, + {0x00009a14, 0x00000021, 0x000001c1}, + {0x00009a18, 0x00000061, 0x00000001}, + {0x00009a1c, 0x00000168, 0x00000041}, + {0x00009a20, 0x000001a8, 0x000001a8}, + {0x00009a24, 0x000001e8, 0x000001e8}, + {0x00009a28, 0x00000028, 0x00000028}, + {0x00009a2c, 0x00000068, 0x00000068}, + {0x00009a30, 0x00000189, 0x000000a8}, + {0x00009a34, 0x000001c9, 0x00000169}, + {0x00009a38, 0x00000009, 0x000001a9}, + {0x00009a3c, 0x00000049, 0x000001e9}, + {0x00009a40, 0x00000089, 0x00000029}, + {0x00009a44, 0x00000170, 0x00000069}, + {0x00009a48, 0x000001b0, 0x00000190}, + {0x00009a4c, 0x000001f0, 0x000001d0}, + {0x00009a50, 0x00000030, 0x00000010}, + {0x00009a54, 0x00000070, 0x00000050}, + {0x00009a58, 0x00000191, 0x00000090}, + {0x00009a5c, 0x000001d1, 0x00000151}, + {0x00009a60, 0x00000011, 0x00000191}, + {0x00009a64, 0x00000051, 0x000001d1}, + {0x00009a68, 0x00000091, 0x00000011}, + {0x00009a6c, 0x000001b8, 0x00000051}, + {0x00009a70, 0x000001f8, 0x00000198}, + {0x00009a74, 0x00000038, 0x000001d8}, + {0x00009a78, 0x00000078, 0x00000018}, + {0x00009a7c, 0x00000199, 0x00000058}, + {0x00009a80, 0x000001d9, 0x00000098}, + {0x00009a84, 0x00000019, 0x00000159}, + {0x00009a88, 0x00000059, 0x00000199}, + {0x00009a8c, 0x00000099, 0x000001d9}, + {0x00009a90, 0x000000d9, 0x00000019}, + {0x00009a94, 0x000000f9, 0x00000059}, + {0x00009a98, 0x000000f9, 0x00000099}, + {0x00009a9c, 0x000000f9, 0x000000d9}, + {0x00009aa0, 0x000000f9, 0x000000f9}, + {0x00009aa4, 0x000000f9, 0x000000f9}, + {0x00009aa8, 0x000000f9, 0x000000f9}, + {0x00009aac, 0x000000f9, 0x000000f9}, + {0x00009ab0, 0x000000f9, 0x000000f9}, + {0x00009ab4, 0x000000f9, 0x000000f9}, + {0x00009ab8, 0x000000f9, 0x000000f9}, + {0x00009abc, 0x000000f9, 0x000000f9}, + {0x00009ac0, 0x000000f9, 0x000000f9}, + {0x00009ac4, 0x000000f9, 0x000000f9}, + {0x00009ac8, 0x000000f9, 0x000000f9}, + {0x00009acc, 0x000000f9, 0x000000f9}, + {0x00009ad0, 0x000000f9, 0x000000f9}, + {0x00009ad4, 0x000000f9, 0x000000f9}, + {0x00009ad8, 0x000000f9, 0x000000f9}, + {0x00009adc, 0x000000f9, 0x000000f9}, + {0x00009ae0, 0x000000f9, 0x000000f9}, + {0x00009ae4, 0x000000f9, 0x000000f9}, + {0x00009ae8, 0x000000f9, 0x000000f9}, + {0x00009aec, 0x000000f9, 0x000000f9}, + {0x00009af0, 0x000000f9, 0x000000f9}, + {0x00009af4, 0x000000f9, 0x000000f9}, + {0x00009af8, 0x000000f9, 0x000000f9}, + {0x00009afc, 0x000000f9, 0x000000f9}, }; static const u32 ar5416Bank1_9100[][2] = { - { 0x000098b0, 0x02108421}, - { 0x000098ec, 0x00000008}, + /* Addr allmodes */ + {0x000098b0, 0x02108421}, + {0x000098ec, 0x00000008}, }; static const u32 ar5416Bank2_9100[][2] = { - { 0x000098b0, 0x0e73ff17}, - { 0x000098e0, 0x00000420}, + /* Addr allmodes */ + {0x000098b0, 0x0e73ff17}, + {0x000098e0, 0x00000420}, }; static const u32 ar5416Bank3_9100[][3] = { - { 0x000098f0, 0x01400018, 0x01c00018 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x000098f0, 0x01400018, 0x01c00018}, }; static const u32 ar5416Bank6_9100[][3] = { - - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x004210a2, 0x004210a2 }, - { 0x0000989c, 0x0014000f, 0x0014000f }, - { 0x0000989c, 0x00c40002, 0x00c40002 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x000180d6, 0x000180d6 }, - { 0x0000989c, 0x0000c0aa, 0x0000c0aa }, - { 0x0000989c, 0x000000b1, 0x000000b1 }, - { 0x0000989c, 0x00002000, 0x00002000 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x004210a2, 0x004210a2}, + {0x0000989c, 0x0014000f, 0x0014000f}, + {0x0000989c, 0x00c40002, 0x00c40002}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x000180d6, 0x000180d6}, + {0x0000989c, 0x0000c0aa, 0x0000c0aa}, + {0x0000989c, 0x000000b1, 0x000000b1}, + {0x0000989c, 0x00002000, 0x00002000}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; - static const u32 ar5416Bank6TPC_9100[][3] = { - - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x40ff0000, 0x40ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x00423022, 0x00423022 }, - { 0x0000989c, 0x2014008f, 0x2014008f }, - { 0x0000989c, 0x00c40002, 0x00c40002 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x0001805e, 0x0001805e }, - { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, - { 0x0000989c, 0x000000e1, 0x000000e1 }, - { 0x0000989c, 0x00007080, 0x00007080 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x40ff0000, 0x40ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x00423022, 0x00423022}, + {0x0000989c, 0x2014008f, 0x2014008f}, + {0x0000989c, 0x00c40002, 0x00c40002}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x0001805e, 0x0001805e}, + {0x0000989c, 0x0000c0ab, 0x0000c0ab}, + {0x0000989c, 0x000000e1, 0x000000e1}, + {0x0000989c, 0x00007080, 0x00007080}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; static const u32 ar5416Bank7_9100[][2] = { - { 0x0000989c, 0x00000500 }, - { 0x0000989c, 0x00000800 }, - { 0x000098cc, 0x0000000e }, + /* Addr allmodes */ + {0x0000989c, 0x00000500}, + {0x0000989c, 0x00000800}, + {0x000098cc, 0x0000000e}, }; static const u32 ar5416Addac_9100[][2] = { - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000010 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x000000c0 }, - {0x0000989c, 0x00000015 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x000098cc, 0x00000000 }, + /* Addr allmodes */ + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000010}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x000000c0}, + {0x0000989c, 0x00000015}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x000098cc, 0x00000000}, }; static const u32 ar5416Modes_9160[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, - { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, - { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 }, - { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, - { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e }, - { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, - { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, - { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, - { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, - { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, - { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, - { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, - { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce }, - { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 }, - { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, - { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, - { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, - { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, - { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, - { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, - { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, - { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, - { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, - { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, - { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, - { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, - { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, - { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, + {0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, + {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar5416Common_9160[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00007010, 0x00000020 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x000080c0, 0x2a82301a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04800 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081d0, 0x00003210 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x00008300, 0x00000000 }, - { 0x00008304, 0x00000000 }, - { 0x00008308, 0x00000000 }, - { 0x0000830c, 0x00000000 }, - { 0x00008310, 0x00000000 }, - { 0x00008314, 0x00000000 }, - { 0x00008318, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xad848e19 }, - { 0x00009810, 0x7d14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x00009840, 0x206a01ae }, - { 0x0000984c, 0x1284233c }, - { 0x00009854, 0x00000859 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x05100000 }, - { 0x0000a920, 0x05100000 }, - { 0x0000b920, 0x05100000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280b212 }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x2108ecff }, - { 0x00009940, 0x00750604 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x00009970, 0x190fb515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x006f0000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000200 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099fc, 0x00001042 }, - { 0x00009b00, 0x00000000 }, - { 0x00009b04, 0x00000001 }, - { 0x00009b08, 0x00000002 }, - { 0x00009b0c, 0x00000003 }, - { 0x00009b10, 0x00000004 }, - { 0x00009b14, 0x00000005 }, - { 0x00009b18, 0x00000008 }, - { 0x00009b1c, 0x00000009 }, - { 0x00009b20, 0x0000000a }, - { 0x00009b24, 0x0000000b }, - { 0x00009b28, 0x0000000c }, - { 0x00009b2c, 0x0000000d }, - { 0x00009b30, 0x00000010 }, - { 0x00009b34, 0x00000011 }, - { 0x00009b38, 0x00000012 }, - { 0x00009b3c, 0x00000013 }, - { 0x00009b40, 0x00000014 }, - { 0x00009b44, 0x00000015 }, - { 0x00009b48, 0x00000018 }, - { 0x00009b4c, 0x00000019 }, - { 0x00009b50, 0x0000001a }, - { 0x00009b54, 0x0000001b }, - { 0x00009b58, 0x0000001c }, - { 0x00009b5c, 0x0000001d }, - { 0x00009b60, 0x00000020 }, - { 0x00009b64, 0x00000021 }, - { 0x00009b68, 0x00000022 }, - { 0x00009b6c, 0x00000023 }, - { 0x00009b70, 0x00000024 }, - { 0x00009b74, 0x00000025 }, - { 0x00009b78, 0x00000028 }, - { 0x00009b7c, 0x00000029 }, - { 0x00009b80, 0x0000002a }, - { 0x00009b84, 0x0000002b }, - { 0x00009b88, 0x0000002c }, - { 0x00009b8c, 0x0000002d }, - { 0x00009b90, 0x00000030 }, - { 0x00009b94, 0x00000031 }, - { 0x00009b98, 0x00000032 }, - { 0x00009b9c, 0x00000033 }, - { 0x00009ba0, 0x00000034 }, - { 0x00009ba4, 0x00000035 }, - { 0x00009ba8, 0x00000035 }, - { 0x00009bac, 0x00000035 }, - { 0x00009bb0, 0x00000035 }, - { 0x00009bb4, 0x00000035 }, - { 0x00009bb8, 0x00000035 }, - { 0x00009bbc, 0x00000035 }, - { 0x00009bc0, 0x00000035 }, - { 0x00009bc4, 0x00000035 }, - { 0x00009bc8, 0x00000035 }, - { 0x00009bcc, 0x00000035 }, - { 0x00009bd0, 0x00000035 }, - { 0x00009bd4, 0x00000035 }, - { 0x00009bd8, 0x00000035 }, - { 0x00009bdc, 0x00000035 }, - { 0x00009be0, 0x00000035 }, - { 0x00009be4, 0x00000035 }, - { 0x00009be8, 0x00000035 }, - { 0x00009bec, 0x00000035 }, - { 0x00009bf0, 0x00000035 }, - { 0x00009bf4, 0x00000035 }, - { 0x00009bf8, 0x00000010 }, - { 0x00009bfc, 0x0000001a }, - { 0x0000a210, 0x40806333 }, - { 0x0000a214, 0x00106c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x018830c6 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x001a0bb5 }, - { 0x0000a22c, 0x00000000 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889af }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00007bb6 }, - { 0x0000a248, 0x0fff3ffc }, - { 0x0000a24c, 0x00000001 }, - { 0x0000a250, 0x0000e000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cc75380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a268, 0x00000001 }, - { 0x0000a26c, 0x0ebae9c6 }, - { 0x0000b26c, 0x0ebae9c6 }, - { 0x0000c26c, 0x0ebae9c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x050701ce }, - { 0x0000a338, 0x00000000 }, - { 0x0000a33c, 0x00000000 }, - { 0x0000a340, 0x00000000 }, - { 0x0000a344, 0x00000000 }, - { 0x0000a348, 0x3fffffff }, - { 0x0000a34c, 0x3fffffff }, - { 0x0000a350, 0x3fffffff }, - { 0x0000a354, 0x0003ffff }, - { 0x0000a358, 0x79bfaa03 }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00007010, 0x00000020}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x000080c0, 0x2a82301a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x00008300, 0x00000000}, + {0x00008304, 0x00000000}, + {0x00008308, 0x00000000}, + {0x0000830c, 0x00000000}, + {0x00008310, 0x00000000}, + {0x00008314, 0x00000000}, + {0x00008318, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xad848e19}, + {0x00009810, 0x7d14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x00009840, 0x206a01ae}, + {0x0000984c, 0x1284233c}, + {0x00009854, 0x00000859}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x05100000}, + {0x0000a920, 0x05100000}, + {0x0000b920, 0x05100000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280b212}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009940, 0x00750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x190fb515}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x006f0000}, + {0x000099b0, 0x03051000}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000200}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099fc, 0x00001042}, + {0x00009b00, 0x00000000}, + {0x00009b04, 0x00000001}, + {0x00009b08, 0x00000002}, + {0x00009b0c, 0x00000003}, + {0x00009b10, 0x00000004}, + {0x00009b14, 0x00000005}, + {0x00009b18, 0x00000008}, + {0x00009b1c, 0x00000009}, + {0x00009b20, 0x0000000a}, + {0x00009b24, 0x0000000b}, + {0x00009b28, 0x0000000c}, + {0x00009b2c, 0x0000000d}, + {0x00009b30, 0x00000010}, + {0x00009b34, 0x00000011}, + {0x00009b38, 0x00000012}, + {0x00009b3c, 0x00000013}, + {0x00009b40, 0x00000014}, + {0x00009b44, 0x00000015}, + {0x00009b48, 0x00000018}, + {0x00009b4c, 0x00000019}, + {0x00009b50, 0x0000001a}, + {0x00009b54, 0x0000001b}, + {0x00009b58, 0x0000001c}, + {0x00009b5c, 0x0000001d}, + {0x00009b60, 0x00000020}, + {0x00009b64, 0x00000021}, + {0x00009b68, 0x00000022}, + {0x00009b6c, 0x00000023}, + {0x00009b70, 0x00000024}, + {0x00009b74, 0x00000025}, + {0x00009b78, 0x00000028}, + {0x00009b7c, 0x00000029}, + {0x00009b80, 0x0000002a}, + {0x00009b84, 0x0000002b}, + {0x00009b88, 0x0000002c}, + {0x00009b8c, 0x0000002d}, + {0x00009b90, 0x00000030}, + {0x00009b94, 0x00000031}, + {0x00009b98, 0x00000032}, + {0x00009b9c, 0x00000033}, + {0x00009ba0, 0x00000034}, + {0x00009ba4, 0x00000035}, + {0x00009ba8, 0x00000035}, + {0x00009bac, 0x00000035}, + {0x00009bb0, 0x00000035}, + {0x00009bb4, 0x00000035}, + {0x00009bb8, 0x00000035}, + {0x00009bbc, 0x00000035}, + {0x00009bc0, 0x00000035}, + {0x00009bc4, 0x00000035}, + {0x00009bc8, 0x00000035}, + {0x00009bcc, 0x00000035}, + {0x00009bd0, 0x00000035}, + {0x00009bd4, 0x00000035}, + {0x00009bd8, 0x00000035}, + {0x00009bdc, 0x00000035}, + {0x00009be0, 0x00000035}, + {0x00009be4, 0x00000035}, + {0x00009be8, 0x00000035}, + {0x00009bec, 0x00000035}, + {0x00009bf0, 0x00000035}, + {0x00009bf4, 0x00000035}, + {0x00009bf8, 0x00000010}, + {0x00009bfc, 0x0000001a}, + {0x0000a210, 0x40806333}, + {0x0000a214, 0x00106c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x018830c6}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x001a0bb5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00007bb6}, + {0x0000a248, 0x0fff3ffc}, + {0x0000a24c, 0x00000001}, + {0x0000a250, 0x0000e000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cc75380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a268, 0x00000001}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000c26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, + {0x0000a338, 0x00000000}, + {0x0000a33c, 0x00000000}, + {0x0000a340, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a348, 0x3fffffff}, + {0x0000a34c, 0x3fffffff}, + {0x0000a350, 0x3fffffff}, + {0x0000a354, 0x0003ffff}, + {0x0000a358, 0x79bfaa03}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, }; static const u32 ar5416Bank0_9160[][2] = { - { 0x000098b0, 0x1e5795e5 }, - { 0x000098e0, 0x02008020 }, + /* Addr allmodes */ + {0x000098b0, 0x1e5795e5}, + {0x000098e0, 0x02008020}, }; static const u32 ar5416BB_RfGain_9160[][3] = { - { 0x00009a00, 0x00000000, 0x00000000 }, - { 0x00009a04, 0x00000040, 0x00000040 }, - { 0x00009a08, 0x00000080, 0x00000080 }, - { 0x00009a0c, 0x000001a1, 0x00000141 }, - { 0x00009a10, 0x000001e1, 0x00000181 }, - { 0x00009a14, 0x00000021, 0x000001c1 }, - { 0x00009a18, 0x00000061, 0x00000001 }, - { 0x00009a1c, 0x00000168, 0x00000041 }, - { 0x00009a20, 0x000001a8, 0x000001a8 }, - { 0x00009a24, 0x000001e8, 0x000001e8 }, - { 0x00009a28, 0x00000028, 0x00000028 }, - { 0x00009a2c, 0x00000068, 0x00000068 }, - { 0x00009a30, 0x00000189, 0x000000a8 }, - { 0x00009a34, 0x000001c9, 0x00000169 }, - { 0x00009a38, 0x00000009, 0x000001a9 }, - { 0x00009a3c, 0x00000049, 0x000001e9 }, - { 0x00009a40, 0x00000089, 0x00000029 }, - { 0x00009a44, 0x00000170, 0x00000069 }, - { 0x00009a48, 0x000001b0, 0x00000190 }, - { 0x00009a4c, 0x000001f0, 0x000001d0 }, - { 0x00009a50, 0x00000030, 0x00000010 }, - { 0x00009a54, 0x00000070, 0x00000050 }, - { 0x00009a58, 0x00000191, 0x00000090 }, - { 0x00009a5c, 0x000001d1, 0x00000151 }, - { 0x00009a60, 0x00000011, 0x00000191 }, - { 0x00009a64, 0x00000051, 0x000001d1 }, - { 0x00009a68, 0x00000091, 0x00000011 }, - { 0x00009a6c, 0x000001b8, 0x00000051 }, - { 0x00009a70, 0x000001f8, 0x00000198 }, - { 0x00009a74, 0x00000038, 0x000001d8 }, - { 0x00009a78, 0x00000078, 0x00000018 }, - { 0x00009a7c, 0x00000199, 0x00000058 }, - { 0x00009a80, 0x000001d9, 0x00000098 }, - { 0x00009a84, 0x00000019, 0x00000159 }, - { 0x00009a88, 0x00000059, 0x00000199 }, - { 0x00009a8c, 0x00000099, 0x000001d9 }, - { 0x00009a90, 0x000000d9, 0x00000019 }, - { 0x00009a94, 0x000000f9, 0x00000059 }, - { 0x00009a98, 0x000000f9, 0x00000099 }, - { 0x00009a9c, 0x000000f9, 0x000000d9 }, - { 0x00009aa0, 0x000000f9, 0x000000f9 }, - { 0x00009aa4, 0x000000f9, 0x000000f9 }, - { 0x00009aa8, 0x000000f9, 0x000000f9 }, - { 0x00009aac, 0x000000f9, 0x000000f9 }, - { 0x00009ab0, 0x000000f9, 0x000000f9 }, - { 0x00009ab4, 0x000000f9, 0x000000f9 }, - { 0x00009ab8, 0x000000f9, 0x000000f9 }, - { 0x00009abc, 0x000000f9, 0x000000f9 }, - { 0x00009ac0, 0x000000f9, 0x000000f9 }, - { 0x00009ac4, 0x000000f9, 0x000000f9 }, - { 0x00009ac8, 0x000000f9, 0x000000f9 }, - { 0x00009acc, 0x000000f9, 0x000000f9 }, - { 0x00009ad0, 0x000000f9, 0x000000f9 }, - { 0x00009ad4, 0x000000f9, 0x000000f9 }, - { 0x00009ad8, 0x000000f9, 0x000000f9 }, - { 0x00009adc, 0x000000f9, 0x000000f9 }, - { 0x00009ae0, 0x000000f9, 0x000000f9 }, - { 0x00009ae4, 0x000000f9, 0x000000f9 }, - { 0x00009ae8, 0x000000f9, 0x000000f9 }, - { 0x00009aec, 0x000000f9, 0x000000f9 }, - { 0x00009af0, 0x000000f9, 0x000000f9 }, - { 0x00009af4, 0x000000f9, 0x000000f9 }, - { 0x00009af8, 0x000000f9, 0x000000f9 }, - { 0x00009afc, 0x000000f9, 0x000000f9 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x00009a00, 0x00000000, 0x00000000}, + {0x00009a04, 0x00000040, 0x00000040}, + {0x00009a08, 0x00000080, 0x00000080}, + {0x00009a0c, 0x000001a1, 0x00000141}, + {0x00009a10, 0x000001e1, 0x00000181}, + {0x00009a14, 0x00000021, 0x000001c1}, + {0x00009a18, 0x00000061, 0x00000001}, + {0x00009a1c, 0x00000168, 0x00000041}, + {0x00009a20, 0x000001a8, 0x000001a8}, + {0x00009a24, 0x000001e8, 0x000001e8}, + {0x00009a28, 0x00000028, 0x00000028}, + {0x00009a2c, 0x00000068, 0x00000068}, + {0x00009a30, 0x00000189, 0x000000a8}, + {0x00009a34, 0x000001c9, 0x00000169}, + {0x00009a38, 0x00000009, 0x000001a9}, + {0x00009a3c, 0x00000049, 0x000001e9}, + {0x00009a40, 0x00000089, 0x00000029}, + {0x00009a44, 0x00000170, 0x00000069}, + {0x00009a48, 0x000001b0, 0x00000190}, + {0x00009a4c, 0x000001f0, 0x000001d0}, + {0x00009a50, 0x00000030, 0x00000010}, + {0x00009a54, 0x00000070, 0x00000050}, + {0x00009a58, 0x00000191, 0x00000090}, + {0x00009a5c, 0x000001d1, 0x00000151}, + {0x00009a60, 0x00000011, 0x00000191}, + {0x00009a64, 0x00000051, 0x000001d1}, + {0x00009a68, 0x00000091, 0x00000011}, + {0x00009a6c, 0x000001b8, 0x00000051}, + {0x00009a70, 0x000001f8, 0x00000198}, + {0x00009a74, 0x00000038, 0x000001d8}, + {0x00009a78, 0x00000078, 0x00000018}, + {0x00009a7c, 0x00000199, 0x00000058}, + {0x00009a80, 0x000001d9, 0x00000098}, + {0x00009a84, 0x00000019, 0x00000159}, + {0x00009a88, 0x00000059, 0x00000199}, + {0x00009a8c, 0x00000099, 0x000001d9}, + {0x00009a90, 0x000000d9, 0x00000019}, + {0x00009a94, 0x000000f9, 0x00000059}, + {0x00009a98, 0x000000f9, 0x00000099}, + {0x00009a9c, 0x000000f9, 0x000000d9}, + {0x00009aa0, 0x000000f9, 0x000000f9}, + {0x00009aa4, 0x000000f9, 0x000000f9}, + {0x00009aa8, 0x000000f9, 0x000000f9}, + {0x00009aac, 0x000000f9, 0x000000f9}, + {0x00009ab0, 0x000000f9, 0x000000f9}, + {0x00009ab4, 0x000000f9, 0x000000f9}, + {0x00009ab8, 0x000000f9, 0x000000f9}, + {0x00009abc, 0x000000f9, 0x000000f9}, + {0x00009ac0, 0x000000f9, 0x000000f9}, + {0x00009ac4, 0x000000f9, 0x000000f9}, + {0x00009ac8, 0x000000f9, 0x000000f9}, + {0x00009acc, 0x000000f9, 0x000000f9}, + {0x00009ad0, 0x000000f9, 0x000000f9}, + {0x00009ad4, 0x000000f9, 0x000000f9}, + {0x00009ad8, 0x000000f9, 0x000000f9}, + {0x00009adc, 0x000000f9, 0x000000f9}, + {0x00009ae0, 0x000000f9, 0x000000f9}, + {0x00009ae4, 0x000000f9, 0x000000f9}, + {0x00009ae8, 0x000000f9, 0x000000f9}, + {0x00009aec, 0x000000f9, 0x000000f9}, + {0x00009af0, 0x000000f9, 0x000000f9}, + {0x00009af4, 0x000000f9, 0x000000f9}, + {0x00009af8, 0x000000f9, 0x000000f9}, + {0x00009afc, 0x000000f9, 0x000000f9}, }; static const u32 ar5416Bank1_9160[][2] = { - { 0x000098b0, 0x02108421 }, - { 0x000098ec, 0x00000008 }, + /* Addr allmodes */ + {0x000098b0, 0x02108421}, + {0x000098ec, 0x00000008}, }; static const u32 ar5416Bank2_9160[][2] = { - { 0x000098b0, 0x0e73ff17 }, - { 0x000098e0, 0x00000420 }, + /* Addr allmodes */ + {0x000098b0, 0x0e73ff17}, + {0x000098e0, 0x00000420}, }; static const u32 ar5416Bank3_9160[][3] = { - { 0x000098f0, 0x01400018, 0x01c00018 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x000098f0, 0x01400018, 0x01c00018}, }; static const u32 ar5416Bank6_9160[][3] = { - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x40ff0000, 0x40ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x004210a2, 0x004210a2 }, - { 0x0000989c, 0x0014008f, 0x0014008f }, - { 0x0000989c, 0x00c40003, 0x00c40003 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x0001805e, 0x0001805e }, - { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, - { 0x0000989c, 0x000000f1, 0x000000f1 }, - { 0x0000989c, 0x00002081, 0x00002081 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x40ff0000, 0x40ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x004210a2, 0x004210a2}, + {0x0000989c, 0x0014008f, 0x0014008f}, + {0x0000989c, 0x00c40003, 0x00c40003}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x0001805e, 0x0001805e}, + {0x0000989c, 0x0000c0ab, 0x0000c0ab}, + {0x0000989c, 0x000000f1, 0x000000f1}, + {0x0000989c, 0x00002081, 0x00002081}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; static const u32 ar5416Bank6TPC_9160[][3] = { - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00000000, 0x00000000 }, - { 0x0000989c, 0x00e00000, 0x00e00000 }, - { 0x0000989c, 0x005e0000, 0x005e0000 }, - { 0x0000989c, 0x00120000, 0x00120000 }, - { 0x0000989c, 0x00620000, 0x00620000 }, - { 0x0000989c, 0x00020000, 0x00020000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x40ff0000, 0x40ff0000 }, - { 0x0000989c, 0x005f0000, 0x005f0000 }, - { 0x0000989c, 0x00870000, 0x00870000 }, - { 0x0000989c, 0x00f90000, 0x00f90000 }, - { 0x0000989c, 0x007b0000, 0x007b0000 }, - { 0x0000989c, 0x00ff0000, 0x00ff0000 }, - { 0x0000989c, 0x00f50000, 0x00f50000 }, - { 0x0000989c, 0x00dc0000, 0x00dc0000 }, - { 0x0000989c, 0x00110000, 0x00110000 }, - { 0x0000989c, 0x006100a8, 0x006100a8 }, - { 0x0000989c, 0x00423022, 0x00423022 }, - { 0x0000989c, 0x2014008f, 0x2014008f }, - { 0x0000989c, 0x00c40002, 0x00c40002 }, - { 0x0000989c, 0x003000f2, 0x003000f2 }, - { 0x0000989c, 0x00440016, 0x00440016 }, - { 0x0000989c, 0x00410040, 0x00410040 }, - { 0x0000989c, 0x0001805e, 0x0001805e }, - { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, - { 0x0000989c, 0x000000e1, 0x000000e1 }, - { 0x0000989c, 0x00007080, 0x00007080 }, - { 0x0000989c, 0x000000d4, 0x000000d4 }, - { 0x000098d0, 0x0000000f, 0x0010000f }, + /* Addr 5G_HT20 5G_HT40 */ + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00000000, 0x00000000}, + {0x0000989c, 0x00e00000, 0x00e00000}, + {0x0000989c, 0x005e0000, 0x005e0000}, + {0x0000989c, 0x00120000, 0x00120000}, + {0x0000989c, 0x00620000, 0x00620000}, + {0x0000989c, 0x00020000, 0x00020000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x40ff0000, 0x40ff0000}, + {0x0000989c, 0x005f0000, 0x005f0000}, + {0x0000989c, 0x00870000, 0x00870000}, + {0x0000989c, 0x00f90000, 0x00f90000}, + {0x0000989c, 0x007b0000, 0x007b0000}, + {0x0000989c, 0x00ff0000, 0x00ff0000}, + {0x0000989c, 0x00f50000, 0x00f50000}, + {0x0000989c, 0x00dc0000, 0x00dc0000}, + {0x0000989c, 0x00110000, 0x00110000}, + {0x0000989c, 0x006100a8, 0x006100a8}, + {0x0000989c, 0x00423022, 0x00423022}, + {0x0000989c, 0x2014008f, 0x2014008f}, + {0x0000989c, 0x00c40002, 0x00c40002}, + {0x0000989c, 0x003000f2, 0x003000f2}, + {0x0000989c, 0x00440016, 0x00440016}, + {0x0000989c, 0x00410040, 0x00410040}, + {0x0000989c, 0x0001805e, 0x0001805e}, + {0x0000989c, 0x0000c0ab, 0x0000c0ab}, + {0x0000989c, 0x000000e1, 0x000000e1}, + {0x0000989c, 0x00007080, 0x00007080}, + {0x0000989c, 0x000000d4, 0x000000d4}, + {0x000098d0, 0x0000000f, 0x0010000f}, }; static const u32 ar5416Bank7_9160[][2] = { - { 0x0000989c, 0x00000500 }, - { 0x0000989c, 0x00000800 }, - { 0x000098cc, 0x0000000e }, + /* Addr allmodes */ + {0x0000989c, 0x00000500}, + {0x0000989c, 0x00000800}, + {0x000098cc, 0x0000000e}, }; static const u32 ar5416Addac_9160[][2] = { - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x000000c0 }, - {0x0000989c, 0x00000018 }, - {0x0000989c, 0x00000004 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x000000c0 }, - {0x0000989c, 0x00000019 }, - {0x0000989c, 0x00000004 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000004 }, - {0x0000989c, 0x00000003 }, - {0x0000989c, 0x00000008 }, - {0x0000989c, 0x00000000 }, - {0x000098cc, 0x00000000 }, + /* Addr allmodes */ + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x000000c0}, + {0x0000989c, 0x00000018}, + {0x0000989c, 0x00000004}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x000000c0}, + {0x0000989c, 0x00000019}, + {0x0000989c, 0x00000004}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000004}, + {0x0000989c, 0x00000003}, + {0x0000989c, 0x00000008}, + {0x0000989c, 0x00000000}, + {0x000098cc, 0x00000000}, }; -static const u32 ar5416Addac_91601_1[][2] = { - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x000000c0 }, - {0x0000989c, 0x00000018 }, - {0x0000989c, 0x00000004 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x000000c0 }, - {0x0000989c, 0x00000019 }, - {0x0000989c, 0x00000004 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x0000989c, 0x00000000 }, - {0x000098cc, 0x00000000 }, +static const u32 ar5416Addac_9160_1_1[][2] = { + /* Addr allmodes */ + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x000000c0}, + {0x0000989c, 0x00000018}, + {0x0000989c, 0x00000004}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x000000c0}, + {0x0000989c, 0x00000019}, + {0x0000989c, 0x00000004}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x0000989c, 0x00000000}, + {0x000098cc, 0x00000000}, }; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 5fdbb53b47e..dabafb874c3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -239,7 +239,7 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) if (qCoff > 15) qCoff = 15; else if (qCoff <= -16) - qCoff = 16; + qCoff = -16; ath_print(common, ATH_DBG_CALIBRATE, "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index a8a8cdc04af..303c63da5ea 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -18,6 +18,11 @@ #include "ar5008_initvals.h" #include "ar9001_initvals.h" #include "ar9002_initvals.h" +#include "ar9002_phy.h" + +int modparam_force_new_ani; +module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); +MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002"); /* General hardware code for the A5008/AR9001/AR9002 hadware families */ @@ -80,21 +85,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ar9287PciePhy_clkreq_always_on_L1_9287_1_1, ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1), 2); - } else if (AR_SREV_9287_10_OR_LATER(ah)) { - INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0, - ARRAY_SIZE(ar9287Modes_9287_1_0), 6); - INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0, - ARRAY_SIZE(ar9287Common_9287_1_0), 2); - - if (ah->config.pcie_clock_req) - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9287PciePhy_clkreq_off_L1_9287_1_0, - ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2); - else - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9287PciePhy_clkreq_always_on_L1_9287_1_0, - ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0), - 2); } else if (AR_SREV_9285_12_OR_LATER(ah)) { @@ -113,21 +103,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), 2); } - } else if (AR_SREV_9285_10_OR_LATER(ah)) { - INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285, - ARRAY_SIZE(ar9285Modes_9285), 6); - INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285, - ARRAY_SIZE(ar9285Common_9285), 2); - - if (ah->config.pcie_clock_req) { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9285PciePhy_clkreq_off_L1_9285, - ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); - } else { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9285PciePhy_clkreq_always_on_L1_9285, - ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); - } } else if (AR_SREV_9280_20_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, ARRAY_SIZE(ar9280Modes_9280_2), 6); @@ -146,11 +121,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesAdditional, ar9280Modes_fast_clock_9280_2, ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); - } else if (AR_SREV_9280_10_OR_LATER(ah)) { - INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280, - ARRAY_SIZE(ar9280Modes_9280), 6); - INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280, - ARRAY_SIZE(ar9280Common_9280), 2); } else if (AR_SREV_9160_10_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, ARRAY_SIZE(ar5416Modes_9160), 6); @@ -174,8 +144,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar5416Bank7_9160), 2); if (AR_SREV_9160_11(ah)) { INIT_INI_ARRAY(&ah->iniAddac, - ar5416Addac_91601_1, - ARRAY_SIZE(ar5416Addac_91601_1), 2); + ar5416Addac_9160_1_1, + ARRAY_SIZE(ar5416Addac_9160_1_1), 2); } else { INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, ARRAY_SIZE(ar5416Addac_9160), 2); @@ -234,12 +204,12 @@ void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) { if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniCckfirNormal, - ar9287Common_normal_cck_fir_coeff_92871_1, - ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), + ar9287Common_normal_cck_fir_coeff_9287_1_1, + ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2); INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9287Common_japan_2484_cck_fir_coeff_92871_1, - ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), + ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, + ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2); } } @@ -300,10 +270,6 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); - else if (AR_SREV_9287_10(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9287Modes_rx_gain_9287_1_0, - ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6); else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); @@ -311,10 +277,6 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); - } else if (AR_SREV_9287_10(ah)) { - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9287Modes_tx_gain_9287_1_0, - ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6); } else if (AR_SREV_9280_20(ah)) { ar9280_20_hw_init_txgain_ini(ah); } else if (AR_SREV_9285_12_OR_LATER(ah)) { @@ -384,29 +346,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), INI_RA(&ah->iniPcieSerdes, i, 1)); } - } else if (AR_SREV_9280(ah) && - (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { - REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); - REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); - - /* RX shut off when elecidle is asserted */ - REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); - REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); - REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); - - /* Shut off CLKREQ active in L1 */ - if (ah->config.pcie_clock_req) - REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); - else - REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); - - REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); - REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); - REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); - - /* Load the new settings */ - REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); - } else { ENABLE_REGWRITE_BUFFER(ah); @@ -436,55 +375,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, } udelay(1000); + } - /* set bit 19 to allow forcing of pcie core into L1 state */ - REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); + if (power_off) { + /* clear bit 19 to disable L1 */ + REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); + + val = REG_READ(ah, AR_WA); - /* Several PCIe massages to ensure proper behaviour */ + /* + * Set PCIe workaround bits + * In AR9280 and AR9285, bit 14 in WA register (disable L1) + * should only be set when device enters D3 and be + * cleared when device comes back to D0. + */ + if (ah->config.pcie_waen) { + if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) + val |= AR_WA_D3_L1_DISABLE; + } else { + if (((AR_SREV_9285(ah) || + AR_SREV_9271(ah) || + AR_SREV_9287(ah)) && + (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || + (AR_SREV_9280(ah) && + (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { + val |= AR_WA_D3_L1_DISABLE; + } + } + + if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { + /* + * Disable bit 6 and 7 before entering D3 to + * prevent system hang. + */ + val &= ~(AR_WA_BIT6 | AR_WA_BIT7); + } + + if (AR_SREV_9285E_20(ah)) + val |= AR_WA_BIT23; + + REG_WRITE(ah, AR_WA, val); + } else { if (ah->config.pcie_waen) { val = ah->config.pcie_waen; if (!power_off) val &= (~AR_WA_D3_L1_DISABLE); } else { - if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || + if (AR_SREV_9285(ah) || + AR_SREV_9271(ah) || AR_SREV_9287(ah)) { val = AR9285_WA_DEFAULT; if (!power_off) val &= (~AR_WA_D3_L1_DISABLE); - } else if (AR_SREV_9280(ah)) { + } + else if (AR_SREV_9280(ah)) { /* - * On AR9280 chips bit 22 of 0x4004 needs to be - * set otherwise card may disappear. + * For AR9280 chips, bit 22 of 0x4004 + * needs to be set. */ val = AR9280_WA_DEFAULT; if (!power_off) val &= (~AR_WA_D3_L1_DISABLE); - } else + } else { val = AR_WA_DEFAULT; + } + } + + /* WAR for ASPM system hang */ + if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { + val |= (AR_WA_BIT6 | AR_WA_BIT7); } + if (AR_SREV_9285E_20(ah)) + val |= AR_WA_BIT23; + REG_WRITE(ah, AR_WA, val); - } - if (power_off) { - /* - * Set PCIe workaround bits - * bit 14 in WA register (disable L1) should only - * be set when device enters D3 and be cleared - * when device comes back to D0. - */ - if (ah->config.pcie_waen) { - if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) - REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); - } else { - if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) || - AR_SREV_9287(ah)) && - (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || - (AR_SREV_9280(ah) && - (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { - REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); - } - } + /* set bit 19 to allow forcing of pcie core into L1 state */ + REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); } } @@ -536,18 +504,29 @@ int ar9002_hw_rf_claim(struct ath_hw *ah) return 0; } +void ar9002_hw_enable_async_fifo(struct ath_hw *ah) +{ + if (AR_SREV_9287_13_OR_LATER(ah)) { + REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); + REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); + REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); + REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, + AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); + } +} + /* - * Enable ASYNC FIFO - * * If Async FIFO is enabled, the following counters change as MAC now runs * at 117 Mhz instead of 88/44MHz when async FIFO is disabled. * * The values below tested for ht40 2 chain. * Overwrite the delay/timeouts initialized in process ini. */ -void ar9002_hw_enable_async_fifo(struct ath_hw *ah) +void ar9002_hw_update_async_fifo(struct ath_hw *ah) { - if (AR_SREV_9287_12_OR_LATER(ah)) { + if (AR_SREV_9287_13_OR_LATER(ah)) { REG_WRITE(ah, AR_D_GBL_IFS_SIFS, AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); REG_WRITE(ah, AR_D_GBL_IFS_SLOT, @@ -571,9 +550,9 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) */ void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) { - if (AR_SREV_9287_12_OR_LATER(ah)) { + if (AR_SREV_9287_13_OR_LATER(ah)) { REG_SET_BIT(ah, AR_PCU_MISC_MODE2, - AR_PCU_MISC_MODE2_ENABLE_AGGWEP); + AR_PCU_MISC_MODE2_ENABLE_AGGWEP); } } @@ -595,4 +574,9 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) ar9002_hw_attach_calib_ops(ah); ar9002_hw_attach_mac_ops(ah); + + if (modparam_force_new_ani) + ath9k_hw_attach_ani_ops_new(ah); + else + ath9k_hw_attach_ani_ops_old(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index dae7f3304eb..6203eed860d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -14,5217 +14,3252 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef INITVALS_9002_10_H -#define INITVALS_9002_10_H - -static const u32 ar9280Modes_9280[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 }, - { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, - { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 }, - { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 }, - { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, - { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, - { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 }, - { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 }, - { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 }, - { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, - { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, - { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 }, - { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a }, - { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 }, - { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 }, - { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 }, - { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 }, - { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c }, - { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 }, - { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 }, - { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 }, - { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac }, - { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 }, - { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 }, - { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 }, - { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 }, - { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 }, - { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 }, - { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 }, - { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 }, - { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac }, - { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 }, - { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 }, - { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 }, - { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 }, - { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 }, - { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad }, - { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, - { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, - { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, - { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, - { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, - { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, - { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, - { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, - { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, - { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, - { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, - { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, - { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, - { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, - { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, - { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, - { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, - { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, - { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, - { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, - { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, - { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, - { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, - { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, - { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, - { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, - { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, - { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, - { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, - { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, - { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, - { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, - { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, - { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, - { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c }, - { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 }, - { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 }, - { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 }, - { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 }, - { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 }, - { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 }, - { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 }, - { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 }, - { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 }, - { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 }, - { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 }, - { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 }, - { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c }, - { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 }, - { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 }, - { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 }, - { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 }, - { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 }, - { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 }, - { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 }, - { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 }, - { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad }, - { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 }, - { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 }, - { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 }, - { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 }, - { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 }, - { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 }, - { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 }, - { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 }, - { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 }, - { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca }, - { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce }, - { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 }, - { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 }, - { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 }, - { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 }, - { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb }, - { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf }, - { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 }, - { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 }, - { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 }, - { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 }, - { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 }, - { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 }, - { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b }, - { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 }, - { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 }, - { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a }, - { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 }, - { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, - { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b }, - { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 }, - { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 }, - { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a }, - { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 }, - { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b }, - { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 }, - { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 }, - { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a }, - { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 }, - { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a }, - { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 }, - { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, - { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c }, - { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 }, - { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 }, - { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 }, -}; - -static const u32 ar9280Common_9280[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00007010, 0x00000033 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a82301a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04800 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0x00000000 }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081d0, 0x00003210 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x00008300, 0x00000000 }, - { 0x00008304, 0x00000000 }, - { 0x00008308, 0x00000000 }, - { 0x0000830c, 0x00000000 }, - { 0x00008310, 0x00000000 }, - { 0x00008314, 0x00000000 }, - { 0x00008318, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00000000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00008344, 0x00000000 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xaf268e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x00009840, 0x206a01ae }, - { 0x0000984c, 0x0040233c }, - { 0x0000a84c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x0000a920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0xe250a51e }, - { 0x00009958, 0x3388ffff }, - { 0x00009940, 0x00781204 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x0000c968, 0x000003ce }, - { 0x00009970, 0x190fb514 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x006f00c4 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099fc, 0x00001042 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x40206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x23277200 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889af }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00007bb6 }, - { 0x0000a248, 0x0fff3ffc }, - { 0x0000a24c, 0x00000001 }, - { 0x0000a250, 0x001da000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cdbd380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0ebae9c6 }, - { 0x0000b26c, 0x0ebae9c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x050701ce }, - { 0x0000a358, 0x7999aa0f }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f38081 }, - { 0x00007800, 0x00040000 }, - { 0x00007804, 0xdb005012 }, - { 0x00007808, 0x04924914 }, - { 0x0000780c, 0x21084210 }, - { 0x00007810, 0x6d801300 }, - { 0x00007814, 0x0019beff }, - { 0x00007818, 0x07e40000 }, - { 0x0000781c, 0x00492000 }, - { 0x00007820, 0x92492480 }, - { 0x00007824, 0x00040000 }, - { 0x00007828, 0xdb005012 }, - { 0x0000782c, 0x04924914 }, - { 0x00007830, 0x21084210 }, - { 0x00007834, 0x6d801300 }, - { 0x00007838, 0x0019beff }, - { 0x0000783c, 0x07e40000 }, - { 0x00007840, 0x00492000 }, - { 0x00007844, 0x92492480 }, - { 0x00007848, 0x00120000 }, - { 0x00007850, 0x54214514 }, - { 0x00007858, 0x92592692 }, - { 0x00007860, 0x52802000 }, - { 0x00007864, 0x0a8e370e }, - { 0x00007868, 0xc0102850 }, - { 0x0000786c, 0x812d4000 }, - { 0x00007874, 0x001b6db0 }, - { 0x00007878, 0x00376b63 }, - { 0x0000787c, 0x06db6db6 }, - { 0x00007880, 0x006d8000 }, - { 0x00007884, 0xffeffffe }, - { 0x00007888, 0xffeffffe }, - { 0x00007890, 0x00060aeb }, - { 0x00007894, 0x5a108000 }, - { 0x00007898, 0x2a850160 }, -}; - -/* XXX 9280 2 */ static const u32 ar9280Modes_9280_2[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, - { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, - { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, - { 0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 }, - { 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e }, - { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, - { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010 }, - { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, - { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 }, - { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 }, - { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce }, - { 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c }, - { 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 }, - { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 }, - { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000 }, - { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, - { 0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000 }, - { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 }, + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, + {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010}, + {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000}, + {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, + {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000}, }; static const u32 ar9280Common_9280_2[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00007010, 0x00000033 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00008344, 0x00481043 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafa68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x0000a84c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x00009910, 0x01002310 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x0000a920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x2108ecff }, - { 0x00009940, 0x14750604 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x00009970, 0x190fb515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x006f0000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x000099fc, 0x00001042 }, - { 0x0000a208, 0x803e4788 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x40206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x233f7180 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00007bb6 }, - { 0x0000a248, 0x0fff3ffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cdbd380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0e79e5c6 }, - { 0x0000b26c, 0x0e79e5c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x00007800, 0x00040000 }, - { 0x00007804, 0xdb005012 }, - { 0x00007808, 0x04924914 }, - { 0x0000780c, 0x21084210 }, - { 0x00007810, 0x6d801300 }, - { 0x00007818, 0x07e41000 }, - { 0x00007824, 0x00040000 }, - { 0x00007828, 0xdb005012 }, - { 0x0000782c, 0x04924914 }, - { 0x00007830, 0x21084210 }, - { 0x00007834, 0x6d801300 }, - { 0x0000783c, 0x07e40000 }, - { 0x00007848, 0x00100000 }, - { 0x0000784c, 0x773f0567 }, - { 0x00007850, 0x54214514 }, - { 0x00007854, 0x12035828 }, - { 0x00007858, 0x9259269a }, - { 0x00007860, 0x52802000 }, - { 0x00007864, 0x0a8e370e }, - { 0x00007868, 0xc0102850 }, - { 0x0000786c, 0x812d4000 }, - { 0x00007870, 0x807ec400 }, - { 0x00007874, 0x001b6db0 }, - { 0x00007878, 0x00376b63 }, - { 0x0000787c, 0x06db6db6 }, - { 0x00007880, 0x006d8000 }, - { 0x00007884, 0xffeffffe }, - { 0x00007888, 0xffeffffe }, - { 0x0000788c, 0x00010000 }, - { 0x00007890, 0x02060aeb }, - { 0x00007898, 0x2a850160 }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000033}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0x00481043}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafa68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x0000a84c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x01002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x0000a920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009940, 0x14750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x190fb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x006f0000}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099c4, 0x06336f77}, + {0x000099c8, 0x6af6532f}, + {0x000099cc, 0x08f186c8}, + {0x000099d0, 0x00046384}, + {0x000099d4, 0x00000000}, + {0x000099d8, 0x00000000}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x000099fc, 0x00001042}, + {0x0000a208, 0x803e4788}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x40206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x233f7180}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00007bb6}, + {0x0000a248, 0x0fff3ffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cdbd380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x00007800, 0x00040000}, + {0x00007804, 0xdb005012}, + {0x00007808, 0x04924914}, + {0x0000780c, 0x21084210}, + {0x00007810, 0x6d801300}, + {0x00007818, 0x07e41000}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb005012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x6d801300}, + {0x0000783c, 0x07e40000}, + {0x00007848, 0x00100000}, + {0x0000784c, 0x773f0567}, + {0x00007850, 0x54214514}, + {0x00007854, 0x12035828}, + {0x00007858, 0x9259269a}, + {0x00007860, 0x52802000}, + {0x00007864, 0x0a8e370e}, + {0x00007868, 0xc0102850}, + {0x0000786c, 0x812d4000}, + {0x00007870, 0x807ec400}, + {0x00007874, 0x001b6db0}, + {0x00007878, 0x00376b63}, + {0x0000787c, 0x06db6db6}, + {0x00007880, 0x006d8000}, + {0x00007884, 0xffeffffe}, + {0x00007888, 0xffeffffe}, + {0x0000788c, 0x00010000}, + {0x00007890, 0x02060aeb}, + {0x00007898, 0x2a850160}, }; static const u32 ar9280Modes_fast_clock_9280_2[][3] = { - { 0x00001030, 0x00000268, 0x000004d0 }, - { 0x00001070, 0x0000018c, 0x00000318 }, - { 0x000010b0, 0x00000fd0, 0x00001fa0 }, - { 0x00008014, 0x044c044c, 0x08980898 }, - { 0x0000801c, 0x148ec02b, 0x148ec057 }, - { 0x00008318, 0x000044c0, 0x00008980 }, - { 0x00009820, 0x02020200, 0x02020200 }, - { 0x00009824, 0x01000f0f, 0x01000f0f }, - { 0x00009828, 0x0b020001, 0x0b020001 }, - { 0x00009834, 0x00000f0f, 0x00000f0f }, - { 0x00009844, 0x03721821, 0x03721821 }, - { 0x00009914, 0x00000898, 0x00001130 }, - { 0x00009918, 0x0000000b, 0x00000016 }, + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009820, 0x02020200, 0x02020200}, + {0x00009824, 0x01000f0f, 0x01000f0f}, + {0x00009828, 0x0b020001, 0x0b020001}, + {0x00009834, 0x00000f0f, 0x00000f0f}, + {0x00009844, 0x03721821, 0x03721821}, + {0x00009914, 0x00000898, 0x00001130}, + {0x00009918, 0x0000000b, 0x00000016}, }; static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { - { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, - { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, - { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, - { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, - { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, - { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, - { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, - { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, - { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, - { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, - { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, - { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, - { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, - { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, - { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, - { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, - { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, - { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, - { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, - { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, - { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, - { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, - { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, - { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, - { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, - { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, - { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, - { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, - { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, - { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, - { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, - { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, - { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, - { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, - { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, - { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, - { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, - { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, - { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, - { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, - { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, - { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, - { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, - { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, - { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, - { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, - { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, - { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, - { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10 }, - { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b14, 0x00008b14, 0x00008b14 }, - { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b01, 0x00008b01, 0x00008b01 }, - { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b05, 0x00008b05, 0x00008b05 }, - { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b09, 0x00008b09, 0x00008b09 }, - { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b0d, 0x00008b0d, 0x00008b0d }, - { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b11, 0x00008b11, 0x00008b11 }, - { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008b15, 0x00008b15, 0x00008b15 }, - { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008b02, 0x00008b02, 0x00008b02 }, - { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008b06, 0x00008b06, 0x00008b06 }, - { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00008b0a, 0x00008b0a, 0x00008b0a }, - { 0x00009aec, 0x0000b784, 0x0000b784, 0x00008b0e, 0x00008b0e, 0x00008b0e }, - { 0x00009af0, 0x0000b788, 0x0000b788, 0x00008b12, 0x00008b12, 0x00008b12 }, - { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008b16, 0x00008b16, 0x00008b16 }, - { 0x00009af8, 0x0000b790, 0x0000b790, 0x00008b03, 0x00008b03, 0x00008b03 }, - { 0x00009afc, 0x0000b794, 0x0000b794, 0x00008b07, 0x00008b07, 0x00008b07 }, - { 0x00009b00, 0x0000b798, 0x0000b798, 0x00008b0b, 0x00008b0b, 0x00008b0b }, - { 0x00009b04, 0x0000d784, 0x0000d784, 0x00008b0f, 0x00008b0f, 0x00008b0f }, - { 0x00009b08, 0x0000d788, 0x0000d788, 0x00008b13, 0x00008b13, 0x00008b13 }, - { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008b17, 0x00008b17, 0x00008b17 }, - { 0x00009b10, 0x0000d790, 0x0000d790, 0x00008b23, 0x00008b23, 0x00008b23 }, - { 0x00009b14, 0x0000f780, 0x0000f780, 0x00008b27, 0x00008b27, 0x00008b27 }, - { 0x00009b18, 0x0000f784, 0x0000f784, 0x00008b2b, 0x00008b2b, 0x00008b2b }, - { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00008b2f, 0x00008b2f, 0x00008b2f }, - { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008b33, 0x00008b33, 0x00008b33 }, - { 0x00009b24, 0x0000f790, 0x0000f790, 0x00008b37, 0x00008b37, 0x00008b37 }, - { 0x00009b28, 0x0000f794, 0x0000f794, 0x00008b43, 0x00008b43, 0x00008b43 }, - { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008b47, 0x00008b47, 0x00008b47 }, - { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008b4b, 0x00008b4b, 0x00008b4b }, - { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008b4f, 0x00008b4f, 0x00008b4f }, - { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008b53, 0x00008b53, 0x00008b53 }, - { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008b57, 0x00008b57, 0x00008b57 }, - { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b }, - { 0x00009848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 }, - { 0x0000a848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 }, + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94, 0x00008b94}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98, 0x00008b98}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4, 0x00008ba4}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8, 0x00008ba8}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac, 0x00008bac}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0, 0x00008bb0}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4, 0x00008bb4}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1, 0x00008ba1}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5, 0x00008ba5}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9, 0x00008ba9}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad, 0x00008bad}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1, 0x00008bb1}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5, 0x00008bb5}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2, 0x00008ba2}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6, 0x00008ba6}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa, 0x00008baa}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae, 0x00008bae}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2, 0x00008bb2}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6, 0x00008bb6}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3, 0x00008ba3}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7, 0x00008ba7}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab, 0x00008bab}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf, 0x00008baf}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3, 0x00008bb3}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7, 0x00008bb7}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3, 0x00008bc3}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7, 0x00008bc7}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb, 0x00008bcb}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf, 0x00008bcf}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3, 0x00008bd3}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7, 0x00008bd7}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, + {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, }; static const u32 ar9280Modes_original_rxgain_9280_2[][6] = { - { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, - { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, - { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, - { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, - { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, - { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, - { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, - { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, - { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, - { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, - { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, - { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, - { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, - { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, - { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, - { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, - { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, - { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, - { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, - { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, - { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, - { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, - { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, - { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, - { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, - { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, - { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, - { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, - { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, - { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, - { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, - { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, - { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, - { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, - { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, - { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, - { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, - { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, - { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, - { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, - { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, - { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, - { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, - { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, - { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, - { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, - { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, - { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, - { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, - { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, - { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, - { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, - { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, - { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, - { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, - { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, - { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, - { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, - { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c }, - { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 }, - { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 }, - { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 }, - { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 }, - { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 }, - { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 }, - { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 }, - { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 }, - { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 }, - { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 }, - { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 }, - { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 }, - { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c }, - { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 }, - { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 }, - { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 }, - { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 }, - { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 }, - { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 }, - { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 }, - { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 }, - { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad }, - { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 }, - { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 }, - { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 }, - { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 }, - { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 }, - { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 }, - { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 }, - { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 }, - { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 }, - { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca }, - { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce }, - { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 }, - { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 }, - { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 }, - { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 }, - { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb }, - { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf }, - { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 }, - { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db }, - { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 }, - { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 }, + {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, + {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, }; static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = { - { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 }, - { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 }, - { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 }, - { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 }, - { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c }, - { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 }, - { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 }, - { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 }, - { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c }, - { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 }, - { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 }, - { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 }, - { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c }, - { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 }, - { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 }, - { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 }, - { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c }, - { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 }, - { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 }, - { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 }, - { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 }, - { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 }, - { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c }, - { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 }, - { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 }, - { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 }, - { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c }, - { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 }, - { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 }, - { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 }, - { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 }, - { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 }, - { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 }, - { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 }, - { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 }, - { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c }, - { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 }, - { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 }, - { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 }, - { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 }, - { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 }, - { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c }, - { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 }, - { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 }, - { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 }, - { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 }, - { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 }, - { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c }, - { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 }, - { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 }, - { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 }, - { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c }, - { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 }, - { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 }, - { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 }, - { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 }, - { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c }, - { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 }, - { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310 }, - { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314 }, - { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320 }, - { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324 }, - { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328 }, - { 0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c }, - { 0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330 }, - { 0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334 }, - { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321 }, - { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325 }, - { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329 }, - { 0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d }, - { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331 }, - { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335 }, - { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322 }, - { 0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326 }, - { 0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a }, - { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e }, - { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332 }, - { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336 }, - { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323 }, - { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327 }, - { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b }, - { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f }, - { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333 }, - { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337 }, - { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343 }, - { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347 }, - { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b }, - { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f }, - { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353 }, - { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357 }, - { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b }, - { 0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a }, - { 0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a }, + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, + {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, + {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, }; static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { - { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, - { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce }, - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002 }, - { 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008 }, - { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010 }, - { 0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012 }, - { 0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014 }, - { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a }, - { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 }, - { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, - { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 }, - { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 }, - { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 }, - { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 }, - { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 }, - { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 }, - { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c }, - { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a }, - { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 }, - { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 }, - { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 }, - { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 }, - { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 }, - { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, - { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, - { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, - { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, - { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, - { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, + {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411}, + {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413}, + {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811}, + {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813}, + {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14}, + {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50}, + {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c}, + {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a}, + {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92}, + {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2}, + {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5}, + {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54}, + {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, + {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, }; static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { - { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, - { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 }, - { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 }, - { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b }, - { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 }, - { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 }, - { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a }, - { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 }, - { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, - { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b }, - { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 }, - { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 }, - { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a }, - { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 }, - { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b }, - { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 }, - { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 }, - { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a }, - { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 }, - { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a }, - { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 }, - { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, - { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, - { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, - { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, - { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, - { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, - { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, + {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b}, + {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412}, + {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414}, + {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a}, + {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649}, + {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b}, + {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49}, + {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48}, + {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a}, + {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88}, + {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a}, + {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9}, + {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, + {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, }; static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffc }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffd }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, -}; - -/* AR9285 Revsion 10*/ -static const u32 ar9285Modes_9285[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 }, - { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 }, - { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, - { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e }, - { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, - { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, - { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 }, - { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c }, - { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, - { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, - { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, - { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, - { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, - { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, - { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, - { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, - { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 }, - { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, - { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, - { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, - { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, - { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, - { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, - { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, - { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, - { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, - { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 }, - { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 }, - { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 }, - { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, - { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, - { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 }, - { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, - { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, - { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 }, - { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 }, - { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, - { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, - { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, - { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, - { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, - { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, - { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 }, - { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, - { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, - { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 }, - { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 }, - { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 }, - { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 }, - { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 }, - { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 }, - { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 }, - { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, - { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, - { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 }, - { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 }, - { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 }, - { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 }, - { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, - { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, - { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 }, - { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 }, - { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 }, - { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 }, - { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, - { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, - { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 }, - { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 }, - { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 }, - { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 }, - { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 }, - { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 }, - { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, - { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, - { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 }, - { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, - { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, - { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, - { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 }, - { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, - { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, - { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 }, - { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 }, - { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, - { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, - { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 }, - { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, - { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, - { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, - { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, - { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, - { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, - { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, - { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 }, - { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, - { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 }, - { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 }, - { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, - { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 }, - { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 }, - { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, - { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, - { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, - { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, - { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, - { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, - { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, - { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, - { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, - { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, - { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, - { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, - { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, - { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, - { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, - { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, - { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, - { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, - { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 }, - { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 }, - { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 }, - { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, - { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, - { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, - { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, - { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 }, - { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 }, - { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 }, - { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 }, - { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 }, - { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 }, - { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 }, - { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 }, - { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 }, - { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 }, - { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 }, - { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 }, - { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 }, - { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 }, - { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 }, - { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 }, - { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 }, - { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 }, - { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, - { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, - { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, - { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 }, - { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, - { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, - { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 }, - { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 }, - { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 }, - { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 }, - { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, - { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, - { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 }, - { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 }, - { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 }, - { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 }, - { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 }, - { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 }, - { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 }, - { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 }, - { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, - { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, - { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, - { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, - { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, - { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 }, - { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 }, - { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, - { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, - { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, - { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, - { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 }, - { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, - { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 }, - { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, - { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, - { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 }, - { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, - { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, - { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, - { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, - { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, - { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, - { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, - { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, - { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, - { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 }, - { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 }, - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 }, - { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 }, - { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 }, - { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, -}; - -static const u32 ar9285Common_9285[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020045 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00007010, 0x00000031 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x00000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04800 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0x00000000 }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081d0, 0x00003210 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000001 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00000000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x00010380 }, - { 0x00008344, 0x00481043 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafe68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x00009910, 0x01002310 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009940, 0x14750604 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x2108ecff }, - { 0x00009968, 0x000003ce }, - { 0x00009970, 0x1927b515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x2def0a00 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x0000a208, 0x803e6788 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x00206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x00000000 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a244, 0x00000000 }, - { 0x0000a248, 0xfffffffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0ccb5380 }, - { 0x0000a25c, 0x15151501 }, - { 0x0000a260, 0xdfa90f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0ebae9e6 }, - { 0x0000d270, 0x0d820820 }, - { 0x0000a278, 0x39ce739c }, - { 0x0000a27c, 0x050e039c }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x39ce739c }, - { 0x0000a398, 0x0000039c }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x39ce739c }, - { 0x0000a3e0, 0x0000039c }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x00007800, 0x00140000 }, - { 0x00007804, 0x0e4548d8 }, - { 0x00007808, 0x54214514 }, - { 0x0000780c, 0x02025820 }, - { 0x00007810, 0x71c0d388 }, - { 0x00007814, 0x924934a8 }, - { 0x0000781c, 0x00000000 }, - { 0x00007820, 0x00000c04 }, - { 0x00007824, 0x00d86fff }, - { 0x00007828, 0x26d2491b }, - { 0x0000782c, 0x6e36d97b }, - { 0x00007830, 0xedb6d96c }, - { 0x00007834, 0x71400086 }, - { 0x00007838, 0xfac68800 }, - { 0x0000783c, 0x0001fffe }, - { 0x00007840, 0xffeb1a20 }, - { 0x00007844, 0x000c0db6 }, - { 0x00007848, 0x6db61b6f }, - { 0x0000784c, 0x6d9b66db }, - { 0x00007850, 0x6d8c6dba }, - { 0x00007854, 0x00040000 }, - { 0x00007858, 0xdb003012 }, - { 0x0000785c, 0x04924914 }, - { 0x00007860, 0x21084210 }, - { 0x00007864, 0xf7d7ffde }, - { 0x00007868, 0xc2034080 }, - { 0x0000786c, 0x48609eb4 }, - { 0x00007870, 0x10142c00 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffd }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffc }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; -/* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */ static const u32 ar9285Modes_9285_1_2[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 }, - { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, - { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, - { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, - { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, - { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, - { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, - { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 }, - { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c }, - { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, - { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, - { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, - { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, - { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, - { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, - { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, - { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, - { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, - { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, - { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, - { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, - { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, - { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, - { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, - { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, - { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, - { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, - { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, - { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, - { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, - { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, - { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, - { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, - { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, - { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, - { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, - { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, - { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, - { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, - { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, - { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, - { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, - { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, - { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, - { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, - { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, - { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, - { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, - { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, - { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, - { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, - { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, - { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, - { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, - { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, - { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, - { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, - { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, - { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, - { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, - { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, - { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, - { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, - { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, - { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, - { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, - { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, - { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, - { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, - { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, - { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, - { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, - { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, - { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, - { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, - { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, - { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, - { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, - { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, - { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, - { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, - { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, - { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, - { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, - { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, - { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, - { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, - { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, - { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, - { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, - { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, - { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, - { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, - { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, - { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, - { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, - { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, - { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, - { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, - { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, - { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, - { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, - { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, - { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, - { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, - { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, - { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, - { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, - { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, - { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, - { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, - { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, - { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, - { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, - { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, - { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, - { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, - { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, - { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, - { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, - { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, - { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, - { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, - { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, - { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, - { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, - { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, - { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, - { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, - { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, - { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, - { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, - { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, - { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, - { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, - { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, - { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, - { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, - { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, - { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, - { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, - { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, - { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, - { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, - { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, - { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, - { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, - { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, - { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, - { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, - { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, - { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, - { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, - { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, - { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, - { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, - { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, - { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, - { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, - { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, - { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, - { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, - { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, - { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, - { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, - { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, - { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, - { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, - { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, - { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, - { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, - { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, - { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, - { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, - { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, - { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, - { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, - { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, - { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, - { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, - { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, - { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, - { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, - { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, - { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, - { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, - { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, - { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, - { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, - { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0}, + {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, + {0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18}, + {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, + {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, + {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, + {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, + {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, + {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, + {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, + {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, + {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, + {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, + {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, + {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, + {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, + {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, + {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, + {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, + {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, + {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, + {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, + {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, + {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, + {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, + {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, + {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, + {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, + {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, + {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, + {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, + {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, + {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, + {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, + {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, + {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, + {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, + {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, + {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, + {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, + {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, + {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, + {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, + {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, + {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, + {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, + {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, + {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, + {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, + {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, + {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, + {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, + {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, + {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, + {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, + {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, + {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, + {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, + {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, + {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, + {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, + {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, + {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, + {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, + {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, + {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, + {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, + {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, + {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, + {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, + {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, + {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, + {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, + {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, + {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, + {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, + {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, + {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, + {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, + {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, + {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, + {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, + {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, + {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, + {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, + {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, + {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, + {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, + {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, + {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, + {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, + {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, + {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, + {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, + {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, + {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, + {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, + {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, + {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, + {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, + {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, + {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, + {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, + {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, + {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, + {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, + {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, + {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, + {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, + {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, + {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, + {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, + {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, + {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, + {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, + {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, + {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, + {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, + {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, + {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, + {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, + {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, + {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, + {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, + {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, + {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, + {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, + {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, + {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, + {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, + {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, + {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, + {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, + {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, + {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, + {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, + {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, + {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, + {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, + {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, + {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, + {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, + {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, + {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, + {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, + {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, + {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, + {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, + {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, + {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, + {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, + {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, + {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, + {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, + {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, }; static const u32 ar9285Common_9285_1_2[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020045 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00007010, 0x00000031 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x00000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04810 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081d0, 0x0000320a }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000001 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x00010380 }, - { 0x00008344, 0x00481043 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafe68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x00009910, 0x01002310 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009940, 0x14750604 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x2108ecff }, - { 0x00009968, 0x000003ce }, - { 0x00009970, 0x192bb514 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x2def0400 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x0000a208, 0x803e68c8 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x00206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x00000000 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a244, 0x00000000 }, - { 0x0000a248, 0xfffffffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0ccb5380 }, - { 0x0000a25c, 0x15151501 }, - { 0x0000a260, 0xdfa90f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0ebae9e6 }, - { 0x0000d270, 0x0d820820 }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x00007800, 0x00140000 }, - { 0x00007804, 0x0e4548d8 }, - { 0x00007808, 0x54214514 }, - { 0x0000780c, 0x02025830 }, - { 0x00007810, 0x71c0d388 }, - { 0x0000781c, 0x00000000 }, - { 0x00007824, 0x00d86fff }, - { 0x0000782c, 0x6e36d97b }, - { 0x00007834, 0x71400087 }, - { 0x00007844, 0x000c0db6 }, - { 0x00007848, 0x6db6246f }, - { 0x0000784c, 0x6d9b66db }, - { 0x00007850, 0x6d8c6dba }, - { 0x00007854, 0x00040000 }, - { 0x00007858, 0xdb003012 }, - { 0x0000785c, 0x04924914 }, - { 0x00007860, 0x21084210 }, - { 0x00007864, 0xf7d7ffde }, - { 0x00007868, 0xc2034080 }, - { 0x00007870, 0x10142c00 }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020045}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000031}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x00000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04810}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081d0, 0x0000320a}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000001}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x00010380}, + {0x00008344, 0x00481043}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x01002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009940, 0x14750604}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x2108ecff}, + {0x00009968, 0x000003ce}, + {0x00009970, 0x192bb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x2def0400}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x0000a208, 0x803e68c8}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x00206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0ccb5380}, + {0x0000a25c, 0x15151501}, + {0x0000a260, 0xdfa90f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0ebae9e6}, + {0x0000d270, 0x0d820820}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x00007800, 0x00140000}, + {0x00007804, 0x0e4548d8}, + {0x00007808, 0x54214514}, + {0x0000780c, 0x02025830}, + {0x00007810, 0x71c0d388}, + {0x0000781c, 0x00000000}, + {0x00007824, 0x00d86fff}, + {0x0000782c, 0x6e36d97b}, + {0x00007834, 0x71400087}, + {0x00007844, 0x000c0db6}, + {0x00007848, 0x6db6246f}, + {0x0000784c, 0x6d9b66db}, + {0x00007850, 0x6d8c6dba}, + {0x00007854, 0x00040000}, + {0x00007858, 0xdb003012}, + {0x0000785c, 0x04924914}, + {0x00007860, 0x21084210}, + {0x00007864, 0xf7d7ffde}, + {0x00007868, 0xc2034080}, + {0x00007870, 0x10142c00}, }; static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 }, - { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b }, - { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e }, - { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, - { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe }, - { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 }, - { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, - { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, - { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 }, - { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, - { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, }; static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 }, - { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b }, - { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e }, - { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, - { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe }, - { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 }, - { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, - { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, - { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, - { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c }, - { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, - { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, }; static const u32 ar9285Modes_XE2_0_normal_power[][6] = { - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 }, - { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b }, - { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae }, - { 0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441 }, - { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe }, - { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c }, - { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, - { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, - { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, - { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c }, - { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, - { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, - { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae}, + {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, }; static const u32 ar9285Modes_XE2_0_high_power[][6] = { - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 }, - { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b }, - { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e }, - { 0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443 }, - { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe }, - { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c }, - { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, - { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, - { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 }, - { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, - { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, + {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, }; static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffd }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffc }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, -}; - -/* AR9287 Revision 10 */ -static const u32 ar9287Modes_9287_1_0[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, - { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a }, - { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e }, - { 0x00009828, 0x00000000, 0x00000000, 0x0a020001, 0x0a020001, 0x0a020001 }, - { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 }, - { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 }, - { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e }, - { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 }, - { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 }, - { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 }, - { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 }, - { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce }, - { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c }, - { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 }, - { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, - { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, -}; - -static const u32 ar9287Common_9287_1_0[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00007010, 0x00000033 }, - { 0x00007020, 0x00000000 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x18487320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081d4, 0x00000000 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x000000ff }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00008344, 0x01c81043 }, - { 0x00008360, 0xffffffff }, - { 0x00008364, 0xffffffff }, - { 0x00008368, 0x00000000 }, - { 0x00008370, 0x00000000 }, - { 0x00008374, 0x000000ff }, - { 0x00008378, 0x00000000 }, - { 0x0000837c, 0x00000000 }, - { 0x00008380, 0xffffffff }, - { 0x00008384, 0xffffffff }, - { 0x00008390, 0x0fffffff }, - { 0x00008394, 0x0fffffff }, - { 0x00008398, 0x00000000 }, - { 0x0000839c, 0x00000000 }, - { 0x000083a0, 0x00000000 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafe68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x0000a84c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x00009910, 0x10002310 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x0000a920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009930, 0x00000000 }, - { 0x0000a930, 0x00000000 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x0108ecff }, - { 0x00009940, 0x14750604 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x00009970, 0x990bb515 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x0c6f0000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099c4, 0x06336f77 }, - { 0x000099c8, 0x6af65329 }, - { 0x000099cc, 0x08f186c8 }, - { 0x000099d0, 0x00046384 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x000099fc, 0x00001042 }, - { 0x0000a1f4, 0x00fffeff }, - { 0x0000a1f8, 0x00f5f9ff }, - { 0x0000a1fc, 0xb79f6427 }, - { 0x0000a208, 0x803e4788 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x40206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x233f7180 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889af }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00000000 }, - { 0x0000a248, 0xfffffffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cdbd380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a264, 0x00418a11 }, - { 0x0000b264, 0x00418a11 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0e79e5c6 }, - { 0x0000b26c, 0x0e79e5c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x050701ce }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000b398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x0000a3f0, 0x01036a1e }, - { 0x0000a3f4, 0x00000000 }, - { 0x0000b3f4, 0x00000000 }, - { 0x0000a7d8, 0x00000001 }, - { 0x00007800, 0x00000800 }, - { 0x00007804, 0x6c35ffb0 }, - { 0x00007808, 0x6db6c000 }, - { 0x0000780c, 0x6db6cb30 }, - { 0x00007810, 0x6db6cb6c }, - { 0x00007814, 0x0501e200 }, - { 0x00007818, 0x0094128d }, - { 0x0000781c, 0x976ee392 }, - { 0x00007820, 0xf75ff6fc }, - { 0x00007824, 0x00040000 }, - { 0x00007828, 0xdb003012 }, - { 0x0000782c, 0x04924914 }, - { 0x00007830, 0x21084210 }, - { 0x00007834, 0x00140000 }, - { 0x00007838, 0x0e4548d8 }, - { 0x0000783c, 0x54214514 }, - { 0x00007840, 0x02025820 }, - { 0x00007844, 0x71c0d388 }, - { 0x00007848, 0x934934a8 }, - { 0x00007850, 0x00000000 }, - { 0x00007854, 0x00000800 }, - { 0x00007858, 0x6c35ffb0 }, - { 0x0000785c, 0x6db6c000 }, - { 0x00007860, 0x6db6cb2c }, - { 0x00007864, 0x6db6cb6c }, - { 0x00007868, 0x0501e200 }, - { 0x0000786c, 0x0094128d }, - { 0x00007870, 0x976ee392 }, - { 0x00007874, 0xf75ff6fc }, - { 0x00007878, 0x00040000 }, - { 0x0000787c, 0xdb003012 }, - { 0x00007880, 0x04924914 }, - { 0x00007884, 0x21084210 }, - { 0x00007888, 0x001b6db0 }, - { 0x0000788c, 0x00376b63 }, - { 0x00007890, 0x06db6db6 }, - { 0x00007894, 0x006d8000 }, - { 0x00007898, 0x48100000 }, - { 0x0000789c, 0x00000000 }, - { 0x000078a0, 0x08000000 }, - { 0x000078a4, 0x0007ffd8 }, - { 0x000078a8, 0x0007ffd8 }, - { 0x000078ac, 0x001c0020 }, - { 0x000078b0, 0x000611eb }, - { 0x000078b4, 0x40008080 }, - { 0x000078b8, 0x2a850160 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; -static const u32 ar9287Modes_tx_gain_9287_1_0[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b }, - { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a }, - { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a }, - { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a }, - { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c }, - { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc }, - { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 }, - { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc }, - { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede }, - { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e }, - { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e }, - { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e }, - { 0x0000a780, 0x00000000, 0x00000000, 0x00000060, 0x00000060, 0x00000060 }, - { 0x0000a784, 0x00000000, 0x00000000, 0x00004062, 0x00004062, 0x00004062 }, - { 0x0000a788, 0x00000000, 0x00000000, 0x00008064, 0x00008064, 0x00008064 }, - { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0a4, 0x0000c0a4, 0x0000c0a4 }, - { 0x0000a790, 0x00000000, 0x00000000, 0x000100b0, 0x000100b0, 0x000100b0 }, - { 0x0000a794, 0x00000000, 0x00000000, 0x000140b2, 0x000140b2, 0x000140b2 }, - { 0x0000a798, 0x00000000, 0x00000000, 0x000180b4, 0x000180b4, 0x000180b4 }, - { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c0f4, 0x0001c0f4, 0x0001c0f4 }, - { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020134, 0x00020134, 0x00020134 }, - { 0x0000a7a4, 0x00000000, 0x00000000, 0x000240fe, 0x000240fe, 0x000240fe }, - { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002813e, 0x0002813e, 0x0002813e }, - { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c17e, 0x0002c17e, 0x0002c17e }, - { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301be, 0x000301be, 0x000301be }, - { 0x0000a7b4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7b8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7bc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7c0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7c4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7c8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7cc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7d0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a7d4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe }, - { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 }, -}; - - -static const u32 ar9287Modes_rx_gain_9287_1_0[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, - { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, - { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 }, - { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c }, - { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 }, - { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 }, - { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 }, - { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c }, - { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 }, - { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 }, - { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 }, - { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c }, - { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 }, - { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 }, - { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 }, - { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 }, - { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 }, - { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac }, - { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 }, - { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 }, - { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 }, - { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 }, - { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 }, - { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c }, - { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 }, - { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 }, - { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 }, - { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c }, - { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 }, - { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 }, - { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 }, - { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c }, - { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 }, - { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 }, - { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 }, - { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 }, - { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 }, - { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 }, - { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 }, - { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c }, - { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 }, - { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 }, - { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 }, - { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c }, - { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 }, - { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 }, - { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 }, - { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 }, - { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 }, - { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 }, - { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c }, - { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 }, - { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 }, - { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 }, - { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 }, - { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 }, - { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac }, - { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 }, - { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 }, - { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 }, - { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 }, - { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 }, - { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 }, - { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 }, - { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 }, - { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 }, - { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 }, - { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c }, - { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 }, - { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 }, - { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c }, - { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 }, - { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 }, - { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 }, - { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 }, - { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 }, - { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac }, - { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 }, - { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 }, - { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 }, - { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 }, - { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 }, - { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad }, - { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 }, - { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 }, - { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 }, - { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 }, - { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 }, - { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd }, - { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 }, - { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 }, - { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 }, - { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 }, - { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca }, - { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce }, - { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 }, - { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 }, - { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda }, - { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 }, - { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb }, - { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf }, - { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 }, - { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 }, - { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, - { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, - { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 }, - { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c }, - { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 }, - { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 }, - { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 }, - { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c }, - { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 }, - { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 }, - { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 }, - { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c }, - { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 }, - { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 }, - { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 }, - { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 }, - { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 }, - { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac }, - { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 }, - { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 }, - { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 }, - { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 }, - { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 }, - { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c }, - { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 }, - { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 }, - { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 }, - { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c }, - { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 }, - { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 }, - { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 }, - { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c }, - { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 }, - { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 }, - { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 }, - { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 }, - { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 }, - { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 }, - { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 }, - { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c }, - { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 }, - { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 }, - { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 }, - { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c }, - { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 }, - { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 }, - { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 }, - { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 }, - { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 }, - { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 }, - { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c }, - { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 }, - { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 }, - { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 }, - { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 }, - { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 }, - { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac }, - { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 }, - { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 }, - { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 }, - { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 }, - { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 }, - { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 }, - { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 }, - { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 }, - { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 }, - { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 }, - { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c }, - { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 }, - { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 }, - { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c }, - { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 }, - { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 }, - { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 }, - { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 }, - { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 }, - { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac }, - { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 }, - { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 }, - { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 }, - { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 }, - { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 }, - { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad }, - { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 }, - { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 }, - { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 }, - { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 }, - { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 }, - { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd }, - { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 }, - { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 }, - { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 }, - { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 }, - { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca }, - { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce }, - { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 }, - { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 }, - { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda }, - { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 }, - { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb }, - { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf }, - { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 }, - { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 }, - { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, - { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, -}; - -static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffd }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, -}; - -static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffc }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, -}; - -/* AR9287 Revision 11 */ - static const u32 ar9287Modes_9287_1_1[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, - { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a }, - { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e }, - { 0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001 }, - { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 }, - { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 }, - { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e }, - { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 }, - { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, - { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 }, - { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 }, - { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 }, - { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce }, - { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c }, - { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 }, - { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, - { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001}, + {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0}, + {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, + {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e}, + {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18}, + {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881}, + {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar9287Common_9287_1_1[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020015 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00007010, 0x00000033 }, - { 0x00007020, 0x00000000 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x40000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x18487320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081c4, 0x00000000 }, - { 0x000081d4, 0x00000000 }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x000000ff }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000007 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x000107ff }, - { 0x00008344, 0x01c81043 }, - { 0x00008360, 0xffffffff }, - { 0x00008364, 0xffffffff }, - { 0x00008368, 0x00000000 }, - { 0x00008370, 0x00000000 }, - { 0x00008374, 0x000000ff }, - { 0x00008378, 0x00000000 }, - { 0x0000837c, 0x00000000 }, - { 0x00008380, 0xffffffff }, - { 0x00008384, 0xffffffff }, - { 0x00008390, 0x0fffffff }, - { 0x00008394, 0x0fffffff }, - { 0x00008398, 0x00000000 }, - { 0x0000839c, 0x00000000 }, - { 0x000083a0, 0x00000000 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafe68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x0000a84c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x00009910, 0x10002310 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x0000a920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009930, 0x00000000 }, - { 0x0000a930, 0x00000000 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x0108ecff }, - { 0x00009940, 0x14750604 }, - { 0x0000c95c, 0x004b6a8e }, - { 0x00009970, 0x990bb514 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x0c6f0000 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099c4, 0x06336f77 }, - { 0x000099c8, 0x6af6532f }, - { 0x000099cc, 0x08f186c8 }, - { 0x000099d0, 0x00046384 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x000099fc, 0x00001042 }, - { 0x0000a208, 0x803e4788 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x40206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x233f7180 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a23c, 0x13c889af }, - { 0x0000a240, 0x38490a20 }, - { 0x0000a244, 0x00000000 }, - { 0x0000a248, 0xfffffffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0cdbd380 }, - { 0x0000a25c, 0x0f0f0f01 }, - { 0x0000a260, 0xdfa91f01 }, - { 0x0000a264, 0x00418a11 }, - { 0x0000b264, 0x00418a11 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0e79e5c6 }, - { 0x0000b26c, 0x0e79e5c6 }, - { 0x0000d270, 0x00820820 }, - { 0x0000a278, 0x1ce739ce }, - { 0x0000a27c, 0x050701ce }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a394, 0x1ce739ce }, - { 0x0000a398, 0x000001ce }, - { 0x0000b398, 0x000001ce }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3c8, 0x00000246 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3dc, 0x1ce739ce }, - { 0x0000a3e0, 0x000001ce }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x0000a3f0, 0x01036a1e }, - { 0x0000a3f4, 0x00000000 }, - { 0x0000b3f4, 0x00000000 }, - { 0x0000a7d8, 0x000003f1 }, - { 0x00007800, 0x00000800 }, - { 0x00007804, 0x6c35ffd2 }, - { 0x00007808, 0x6db6c000 }, - { 0x0000780c, 0x6db6cb30 }, - { 0x00007810, 0x6db6cb6c }, - { 0x00007814, 0x0501e200 }, - { 0x00007818, 0x0094128d }, - { 0x0000781c, 0x976ee392 }, - { 0x00007820, 0xf75ff6fc }, - { 0x00007824, 0x00040000 }, - { 0x00007828, 0xdb003012 }, - { 0x0000782c, 0x04924914 }, - { 0x00007830, 0x21084210 }, - { 0x00007834, 0x00140000 }, - { 0x00007838, 0x0e4548d8 }, - { 0x0000783c, 0x54214514 }, - { 0x00007840, 0x02025830 }, - { 0x00007844, 0x71c0d388 }, - { 0x00007848, 0x934934a8 }, - { 0x00007850, 0x00000000 }, - { 0x00007854, 0x00000800 }, - { 0x00007858, 0x6c35ffd2 }, - { 0x0000785c, 0x6db6c000 }, - { 0x00007860, 0x6db6cb30 }, - { 0x00007864, 0x6db6cb6c }, - { 0x00007868, 0x0501e200 }, - { 0x0000786c, 0x0094128d }, - { 0x00007870, 0x976ee392 }, - { 0x00007874, 0xf75ff6fc }, - { 0x00007878, 0x00040000 }, - { 0x0000787c, 0xdb003012 }, - { 0x00007880, 0x04924914 }, - { 0x00007884, 0x21084210 }, - { 0x00007888, 0x001b6db0 }, - { 0x0000788c, 0x00376b63 }, - { 0x00007890, 0x06db6db6 }, - { 0x00007894, 0x006d8000 }, - { 0x00007898, 0x48100000 }, - { 0x0000789c, 0x00000000 }, - { 0x000078a0, 0x08000000 }, - { 0x000078a4, 0x0007ffd8 }, - { 0x000078a8, 0x0007ffd8 }, - { 0x000078ac, 0x001c0020 }, - { 0x000078b0, 0x00060aeb }, - { 0x000078b4, 0x40008080 }, - { 0x000078b8, 0x2a850160 }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020015}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00007010, 0x00000033}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x40000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18487320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0x01c81043}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0x0fffffff}, + {0x00008394, 0x0fffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x0000a84c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x00009910, 0x10002310}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x0000a920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009930, 0x00000000}, + {0x0000a930, 0x00000000}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x0108ecff}, + {0x00009940, 0x14750604}, + {0x0000c95c, 0x004b6a8e}, + {0x00009970, 0x990bb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x0c6f0000}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099c4, 0x06336f77}, + {0x000099c8, 0x6af6532f}, + {0x000099cc, 0x08f186c8}, + {0x000099d0, 0x00046384}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x000099fc, 0x00001042}, + {0x0000a208, 0x803e4788}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x40206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x233f7180}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a23c, 0x13c889af}, + {0x0000a240, 0x38490a20}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0cdbd380}, + {0x0000a25c, 0x0f0f0f01}, + {0x0000a260, 0xdfa91f01}, + {0x0000a264, 0x00418a11}, + {0x0000b264, 0x00418a11}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0e79e5c6}, + {0x0000b26c, 0x0e79e5c6}, + {0x0000d270, 0x00820820}, + {0x0000a278, 0x1ce739ce}, + {0x0000a27c, 0x050701ce}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a394, 0x1ce739ce}, + {0x0000a398, 0x000001ce}, + {0x0000b398, 0x000001ce}, + {0x0000a39c, 0x00000001}, + {0x0000a3c8, 0x00000246}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3dc, 0x1ce739ce}, + {0x0000a3e0, 0x000001ce}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x0000a3f0, 0x01036a1e}, + {0x0000a3f4, 0x00000000}, + {0x0000b3f4, 0x00000000}, + {0x0000a7d8, 0x000003f1}, + {0x00007800, 0x00000800}, + {0x00007804, 0x6c35ffd2}, + {0x00007808, 0x6db6c000}, + {0x0000780c, 0x6db6cb30}, + {0x00007810, 0x6db6cb6c}, + {0x00007814, 0x0501e200}, + {0x00007818, 0x0094128d}, + {0x0000781c, 0x976ee392}, + {0x00007820, 0xf75ff6fc}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb003012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x00140000}, + {0x00007838, 0x0e4548d8}, + {0x0000783c, 0x54214514}, + {0x00007840, 0x02025830}, + {0x00007844, 0x71c0d388}, + {0x00007848, 0x934934a8}, + {0x00007850, 0x00000000}, + {0x00007854, 0x00000800}, + {0x00007858, 0x6c35ffd2}, + {0x0000785c, 0x6db6c000}, + {0x00007860, 0x6db6cb30}, + {0x00007864, 0x6db6cb6c}, + {0x00007868, 0x0501e200}, + {0x0000786c, 0x0094128d}, + {0x00007870, 0x976ee392}, + {0x00007874, 0xf75ff6fc}, + {0x00007878, 0x00040000}, + {0x0000787c, 0xdb003012}, + {0x00007880, 0x04924914}, + {0x00007884, 0x21084210}, + {0x00007888, 0x001b6db0}, + {0x0000788c, 0x00376b63}, + {0x00007890, 0x06db6db6}, + {0x00007894, 0x006d8000}, + {0x00007898, 0x48100000}, + {0x0000789c, 0x00000000}, + {0x000078a0, 0x08000000}, + {0x000078a4, 0x0007ffd8}, + {0x000078a8, 0x0007ffd8}, + {0x000078ac, 0x001c0020}, + {0x000078b0, 0x00060aeb}, + {0x000078b4, 0x40008080}, + {0x000078b8, 0x2a850160}, }; -/* - * For Japanese regulatory requirements, 2484 MHz requires the following three - * registers be programmed differently from the channel between 2412 and - * 2472 MHz. - */ -static const u32 ar9287Common_normal_cck_fir_coeff_92871_1[][2] = { - { 0x0000a1f4, 0x00fffeff }, - { 0x0000a1f8, 0x00f5f9ff }, - { 0x0000a1fc, 0xb79f6427 }, +static const u32 ar9287Common_normal_cck_fir_coeff_9287_1_1[][2] = { + /* Addr allmodes */ + {0x0000a1f4, 0x00fffeff}, + {0x0000a1f8, 0x00f5f9ff}, + {0x0000a1fc, 0xb79f6427}, }; -static const u32 ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = { - { 0x0000a1f4, 0x00000000 }, - { 0x0000a1f8, 0xefff0301 }, - { 0x0000a1fc, 0xca9228ee }, +static const u32 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = { + /* Addr allmodes */ + {0x0000a1f4, 0x00000000}, + {0x0000a1f8, 0xefff0301}, + {0x0000a1fc, 0xca9228ee}, }; static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b }, - { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a }, - { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a }, - { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a }, - { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a }, - { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c }, - { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc }, - { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 }, - { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc }, - { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede }, - { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e }, - { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e }, - { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e }, - { 0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062 }, - { 0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064 }, - { 0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4 }, - { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa }, - { 0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac }, - { 0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4 }, - { 0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4 }, - { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134 }, - { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174 }, - { 0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c }, - { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e }, - { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be }, - { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe }, - { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b}, + {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, + {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a}, + {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a}, + {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c}, + {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc}, + {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4}, + {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc}, + {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede}, + {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, + {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e}, + {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e}, + {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062}, + {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064}, + {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4}, + {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa}, + {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac}, + {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4}, + {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4}, + {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134}, + {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174}, + {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c}, + {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e}, + {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be}, + {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, + {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000}, }; static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = { - /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ - { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, - { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, - { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 }, - { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c }, - { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 }, - { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 }, - { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 }, - { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c }, - { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 }, - { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 }, - { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 }, - { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c }, - { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 }, - { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 }, - { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 }, - { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 }, - { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 }, - { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac }, - { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 }, - { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 }, - { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 }, - { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 }, - { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 }, - { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c }, - { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 }, - { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 }, - { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 }, - { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c }, - { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 }, - { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 }, - { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 }, - { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c }, - { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 }, - { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 }, - { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 }, - { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 }, - { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 }, - { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 }, - { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 }, - { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c }, - { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 }, - { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 }, - { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 }, - { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c }, - { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 }, - { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 }, - { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 }, - { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 }, - { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 }, - { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 }, - { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c }, - { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 }, - { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 }, - { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 }, - { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 }, - { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 }, - { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac }, - { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 }, - { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 }, - { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 }, - { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 }, - { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 }, - { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 }, - { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 }, - { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 }, - { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 }, - { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 }, - { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c }, - { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 }, - { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 }, - { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c }, - { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 }, - { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 }, - { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 }, - { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 }, - { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 }, - { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac }, - { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 }, - { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 }, - { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 }, - { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 }, - { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 }, - { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad }, - { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 }, - { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 }, - { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 }, - { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 }, - { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 }, - { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd }, - { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 }, - { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 }, - { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 }, - { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 }, - { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca }, - { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce }, - { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 }, - { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 }, - { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda }, - { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 }, - { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb }, - { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf }, - { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 }, - { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 }, - { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, - { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, - { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 }, - { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c }, - { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 }, - { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 }, - { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 }, - { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c }, - { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 }, - { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 }, - { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 }, - { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c }, - { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 }, - { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 }, - { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 }, - { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 }, - { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 }, - { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac }, - { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 }, - { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 }, - { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 }, - { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 }, - { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 }, - { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c }, - { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 }, - { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 }, - { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 }, - { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c }, - { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 }, - { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 }, - { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 }, - { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c }, - { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 }, - { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 }, - { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 }, - { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 }, - { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 }, - { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 }, - { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 }, - { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c }, - { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 }, - { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 }, - { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 }, - { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c }, - { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 }, - { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 }, - { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 }, - { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 }, - { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 }, - { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 }, - { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c }, - { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 }, - { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 }, - { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 }, - { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 }, - { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 }, - { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac }, - { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 }, - { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 }, - { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 }, - { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 }, - { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 }, - { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 }, - { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 }, - { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 }, - { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 }, - { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 }, - { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c }, - { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 }, - { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 }, - { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c }, - { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 }, - { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 }, - { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 }, - { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 }, - { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 }, - { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac }, - { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 }, - { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 }, - { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 }, - { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 }, - { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 }, - { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad }, - { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 }, - { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 }, - { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 }, - { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 }, - { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 }, - { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd }, - { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 }, - { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 }, - { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 }, - { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 }, - { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca }, - { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce }, - { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 }, - { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 }, - { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda }, - { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 }, - { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb }, - { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf }, - { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 }, - { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 }, - { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb }, - { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, - { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, + {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, + {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, + {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, + {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, + {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, + {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, + {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, + {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, + {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, + {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, + {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, + {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, + {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, + {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, + {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, + {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, + {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, + {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, + {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, + {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, + {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, + {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, + {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, + {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, + {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, + {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, + {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, + {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, + {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, + {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, + {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, + {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, + {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, + {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, + {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, + {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, + {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, + {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, + {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, + {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, + {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, + {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, + {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, + {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, + {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, + {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, + {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, + {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, + {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, + {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, + {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, + {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, + {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, + {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, + {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, + {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, + {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, + {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, + {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, + {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, + {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, + {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, + {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, + {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, + {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, + {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, + {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, + {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, + {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, + {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, + {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, + {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, }; static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffd }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffd}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { - {0x00004040, 0x9248fd00 }, - {0x00004040, 0x24924924 }, - {0x00004040, 0xa8000019 }, - {0x00004040, 0x13160820 }, - {0x00004040, 0xe5980560 }, - {0x00004040, 0xc01dcffc }, - {0x00004040, 0x1aaabe41 }, - {0x00004040, 0xbe105554 }, - {0x00004040, 0x00043007 }, - {0x00004044, 0x00000000 }, + /* Addr allmodes */ + {0x00004040, 0x9248fd00}, + {0x00004040, 0x24924924}, + {0x00004040, 0xa8000019}, + {0x00004040, 0x13160820}, + {0x00004040, 0xe5980560}, + {0x00004040, 0xc01dcffc}, + {0x00004040, 0x1aaabe41}, + {0x00004040, 0xbe105554}, + {0x00004040, 0x00043007}, + {0x00004044, 0x00000000}, }; - -/* AR9271 initialization values automaticaly created: 06/04/09 */ static const u32 ar9271Modes_9271[][6] = { - { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, - { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, - { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, - { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, - { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, - { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, - { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, - { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, - { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, - { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e }, - { 0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001 }, - { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, - { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, - { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, - { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 }, - { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, - { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, - { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, - { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, - { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18 }, - { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, - { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310 }, - { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, - { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, - { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, - { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 }, - { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c }, - { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, - { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, - { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f }, - { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, - { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, - { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, - { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, - { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, - { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, - { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, - { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, - { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, - { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, - { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, - { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, - { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, - { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, - { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, - { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, - { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, - { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, - { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, - { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, - { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, - { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, - { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, - { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, - { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, - { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, - { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, - { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, - { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, - { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, - { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, - { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, - { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, - { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, - { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, - { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, - { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, - { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, - { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, - { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, - { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, - { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, - { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, - { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, - { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, - { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, - { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, - { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, - { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, - { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, - { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, - { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, - { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, - { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, - { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, - { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, - { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, - { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, - { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, - { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, - { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, - { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, - { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, - { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, - { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, - { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, - { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, - { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, - { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, - { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, - { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, - { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, - { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, - { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, - { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, - { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, - { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, - { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, - { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, - { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, - { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, - { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, - { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, - { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, - { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, - { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, - { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, - { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, - { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, - { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, - { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, - { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, - { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, - { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, - { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, - { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, - { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, - { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, - { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, - { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, - { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, - { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, - { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, - { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, - { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, - { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, - { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, - { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, - { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, - { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, - { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, - { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, - { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, - { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, - { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, - { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, - { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, - { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, - { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, - { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, - { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, - { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, - { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, - { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, - { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, - { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, - { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, - { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, - { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, - { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, - { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, - { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, - { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, - { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, - { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, - { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, - { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, - { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, - { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, - { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, - { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, - { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, - { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, - { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, - { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, - { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, - { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, - { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, - { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, - { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, - { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, - { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, - { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, - { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, - { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, - { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, - { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, - { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, - { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, - { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, - { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, - { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, - { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, - { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, - { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, - { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, - { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, - { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, - { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, - { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, - { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, - { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, - { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, - { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, - { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, - { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, - { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, - { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, - { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, - { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, - { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, - { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, - { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, - { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, - { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, - { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, - { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, - { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0}, + {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, + {0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, + {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, + {0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, + {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, + {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, + {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, + {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, + {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, + {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, + {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, + {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, + {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, + {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, + {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, + {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, + {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, + {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, + {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, + {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, + {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, + {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, + {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, + {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, + {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, + {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, + {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, + {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, + {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, + {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, + {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, + {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, + {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, + {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, + {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, + {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, + {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, + {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, + {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, + {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, + {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, + {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, + {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, + {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, + {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, + {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, + {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, + {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, + {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, + {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, + {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, + {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, + {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, + {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, + {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, + {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, + {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, + {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, + {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, + {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, + {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, + {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, + {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, + {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, + {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, + {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, + {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, + {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, + {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, + {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, + {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, + {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, + {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, + {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, + {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, + {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, + {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, + {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, + {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, + {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, + {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, + {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, + {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, + {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, + {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, + {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, + {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, + {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, + {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, + {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, + {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, + {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, + {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, + {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, + {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, + {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, + {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, + {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, + {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, + {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, + {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, + {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, + {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, + {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, + {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, + {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, + {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, + {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, + {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, + {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, + {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, + {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, + {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, + {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, + {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, + {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, + {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, + {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, + {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, + {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, + {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, + {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, + {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, + {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, + {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, + {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, + {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, + {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, + {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, + {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, + {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, + {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, + {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, + {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, + {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, + {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, + {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, + {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, + {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, + {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, + {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, + {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, + {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, + {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, + {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, + {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, + {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, + {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, + {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, + {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, + {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, + {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, + {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, + {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, + {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, + {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, + {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, }; static const u32 ar9271Common_9271[][2] = { - { 0x0000000c, 0x00000000 }, - { 0x00000030, 0x00020045 }, - { 0x00000034, 0x00000005 }, - { 0x00000040, 0x00000000 }, - { 0x00000044, 0x00000008 }, - { 0x00000048, 0x00000008 }, - { 0x0000004c, 0x00000010 }, - { 0x00000050, 0x00000000 }, - { 0x00000054, 0x0000001f }, - { 0x00000800, 0x00000000 }, - { 0x00000804, 0x00000000 }, - { 0x00000808, 0x00000000 }, - { 0x0000080c, 0x00000000 }, - { 0x00000810, 0x00000000 }, - { 0x00000814, 0x00000000 }, - { 0x00000818, 0x00000000 }, - { 0x0000081c, 0x00000000 }, - { 0x00000820, 0x00000000 }, - { 0x00000824, 0x00000000 }, - { 0x00001040, 0x002ffc0f }, - { 0x00001044, 0x002ffc0f }, - { 0x00001048, 0x002ffc0f }, - { 0x0000104c, 0x002ffc0f }, - { 0x00001050, 0x002ffc0f }, - { 0x00001054, 0x002ffc0f }, - { 0x00001058, 0x002ffc0f }, - { 0x0000105c, 0x002ffc0f }, - { 0x00001060, 0x002ffc0f }, - { 0x00001064, 0x002ffc0f }, - { 0x00001230, 0x00000000 }, - { 0x00001270, 0x00000000 }, - { 0x00001038, 0x00000000 }, - { 0x00001078, 0x00000000 }, - { 0x000010b8, 0x00000000 }, - { 0x000010f8, 0x00000000 }, - { 0x00001138, 0x00000000 }, - { 0x00001178, 0x00000000 }, - { 0x000011b8, 0x00000000 }, - { 0x000011f8, 0x00000000 }, - { 0x00001238, 0x00000000 }, - { 0x00001278, 0x00000000 }, - { 0x000012b8, 0x00000000 }, - { 0x000012f8, 0x00000000 }, - { 0x00001338, 0x00000000 }, - { 0x00001378, 0x00000000 }, - { 0x000013b8, 0x00000000 }, - { 0x000013f8, 0x00000000 }, - { 0x00001438, 0x00000000 }, - { 0x00001478, 0x00000000 }, - { 0x000014b8, 0x00000000 }, - { 0x000014f8, 0x00000000 }, - { 0x00001538, 0x00000000 }, - { 0x00001578, 0x00000000 }, - { 0x000015b8, 0x00000000 }, - { 0x000015f8, 0x00000000 }, - { 0x00001638, 0x00000000 }, - { 0x00001678, 0x00000000 }, - { 0x000016b8, 0x00000000 }, - { 0x000016f8, 0x00000000 }, - { 0x00001738, 0x00000000 }, - { 0x00001778, 0x00000000 }, - { 0x000017b8, 0x00000000 }, - { 0x000017f8, 0x00000000 }, - { 0x0000103c, 0x00000000 }, - { 0x0000107c, 0x00000000 }, - { 0x000010bc, 0x00000000 }, - { 0x000010fc, 0x00000000 }, - { 0x0000113c, 0x00000000 }, - { 0x0000117c, 0x00000000 }, - { 0x000011bc, 0x00000000 }, - { 0x000011fc, 0x00000000 }, - { 0x0000123c, 0x00000000 }, - { 0x0000127c, 0x00000000 }, - { 0x000012bc, 0x00000000 }, - { 0x000012fc, 0x00000000 }, - { 0x0000133c, 0x00000000 }, - { 0x0000137c, 0x00000000 }, - { 0x000013bc, 0x00000000 }, - { 0x000013fc, 0x00000000 }, - { 0x0000143c, 0x00000000 }, - { 0x0000147c, 0x00000000 }, - { 0x00004030, 0x00000002 }, - { 0x0000403c, 0x00000002 }, - { 0x00004024, 0x0000001f }, - { 0x00004060, 0x00000000 }, - { 0x00004064, 0x00000000 }, - { 0x00008004, 0x00000000 }, - { 0x00008008, 0x00000000 }, - { 0x0000800c, 0x00000000 }, - { 0x00008018, 0x00000700 }, - { 0x00008020, 0x00000000 }, - { 0x00008038, 0x00000000 }, - { 0x0000803c, 0x00000000 }, - { 0x00008048, 0x00000000 }, - { 0x00008054, 0x00000000 }, - { 0x00008058, 0x00000000 }, - { 0x0000805c, 0x000fc78f }, - { 0x00008060, 0x0000000f }, - { 0x00008064, 0x00000000 }, - { 0x00008070, 0x00000000 }, - { 0x000080b0, 0x00000000 }, - { 0x000080b4, 0x00000000 }, - { 0x000080b8, 0x00000000 }, - { 0x000080bc, 0x00000000 }, - { 0x000080c0, 0x2a80001a }, - { 0x000080c4, 0x05dc01e0 }, - { 0x000080c8, 0x1f402710 }, - { 0x000080cc, 0x01f40000 }, - { 0x000080d0, 0x00001e00 }, - { 0x000080d4, 0x00000000 }, - { 0x000080d8, 0x00400000 }, - { 0x000080e0, 0xffffffff }, - { 0x000080e4, 0x0000ffff }, - { 0x000080e8, 0x003f3f3f }, - { 0x000080ec, 0x00000000 }, - { 0x000080f0, 0x00000000 }, - { 0x000080f4, 0x00000000 }, - { 0x000080f8, 0x00000000 }, - { 0x000080fc, 0x00020000 }, - { 0x00008100, 0x00020000 }, - { 0x00008104, 0x00000001 }, - { 0x00008108, 0x00000052 }, - { 0x0000810c, 0x00000000 }, - { 0x00008110, 0x00000168 }, - { 0x00008118, 0x000100aa }, - { 0x0000811c, 0x00003210 }, - { 0x00008120, 0x08f04810 }, - { 0x00008124, 0x00000000 }, - { 0x00008128, 0x00000000 }, - { 0x0000812c, 0x00000000 }, - { 0x00008130, 0x00000000 }, - { 0x00008134, 0x00000000 }, - { 0x00008138, 0x00000000 }, - { 0x0000813c, 0x00000000 }, - { 0x00008144, 0xffffffff }, - { 0x00008168, 0x00000000 }, - { 0x0000816c, 0x00000000 }, - { 0x00008170, 0x32143320 }, - { 0x00008174, 0xfaa4fa50 }, - { 0x00008178, 0x00000100 }, - { 0x0000817c, 0x00000000 }, - { 0x000081c0, 0x00000000 }, - { 0x000081d0, 0x0000320a }, - { 0x000081ec, 0x00000000 }, - { 0x000081f0, 0x00000000 }, - { 0x000081f4, 0x00000000 }, - { 0x000081f8, 0x00000000 }, - { 0x000081fc, 0x00000000 }, - { 0x00008200, 0x00000000 }, - { 0x00008204, 0x00000000 }, - { 0x00008208, 0x00000000 }, - { 0x0000820c, 0x00000000 }, - { 0x00008210, 0x00000000 }, - { 0x00008214, 0x00000000 }, - { 0x00008218, 0x00000000 }, - { 0x0000821c, 0x00000000 }, - { 0x00008220, 0x00000000 }, - { 0x00008224, 0x00000000 }, - { 0x00008228, 0x00000000 }, - { 0x0000822c, 0x00000000 }, - { 0x00008230, 0x00000000 }, - { 0x00008234, 0x00000000 }, - { 0x00008238, 0x00000000 }, - { 0x0000823c, 0x00000000 }, - { 0x00008240, 0x00100000 }, - { 0x00008244, 0x0010f400 }, - { 0x00008248, 0x00000100 }, - { 0x0000824c, 0x0001e800 }, - { 0x00008250, 0x00000000 }, - { 0x00008254, 0x00000000 }, - { 0x00008258, 0x00000000 }, - { 0x0000825c, 0x400000ff }, - { 0x00008260, 0x00080922 }, - { 0x00008264, 0x88a00010 }, - { 0x00008270, 0x00000000 }, - { 0x00008274, 0x40000000 }, - { 0x00008278, 0x003e4180 }, - { 0x0000827c, 0x00000000 }, - { 0x00008284, 0x0000002c }, - { 0x00008288, 0x0000002c }, - { 0x0000828c, 0x00000000 }, - { 0x00008294, 0x00000000 }, - { 0x00008298, 0x00000000 }, - { 0x0000829c, 0x00000000 }, - { 0x00008300, 0x00000040 }, - { 0x00008314, 0x00000000 }, - { 0x00008328, 0x00000000 }, - { 0x0000832c, 0x00000001 }, - { 0x00008330, 0x00000302 }, - { 0x00008334, 0x00000e00 }, - { 0x00008338, 0x00ff0000 }, - { 0x0000833c, 0x00000000 }, - { 0x00008340, 0x00010380 }, - { 0x00008344, 0x00581043 }, - { 0x00007010, 0x00000030 }, - { 0x00007034, 0x00000002 }, - { 0x00007038, 0x000004c2 }, - { 0x00007800, 0x00140000 }, - { 0x00007804, 0x0e4548d8 }, - { 0x00007808, 0x54214514 }, - { 0x0000780c, 0x02025820 }, - { 0x00007810, 0x71c0d388 }, - { 0x00007814, 0x924934a8 }, - { 0x0000781c, 0x00000000 }, - { 0x00007828, 0x66964300 }, - { 0x0000782c, 0x8db6d961 }, - { 0x00007830, 0x8db6d96c }, - { 0x00007834, 0x6140008b }, - { 0x0000783c, 0x72ee0a72 }, - { 0x00007840, 0xbbfffffc }, - { 0x00007844, 0x000c0db6 }, - { 0x00007848, 0x6db61b6f }, - { 0x0000784c, 0x6d9b66db }, - { 0x00007850, 0x6d8c6dba }, - { 0x00007854, 0x00040000 }, - { 0x00007858, 0xdb003012 }, - { 0x0000785c, 0x04924914 }, - { 0x00007860, 0x21084210 }, - { 0x00007864, 0xf7d7ffde }, - { 0x00007868, 0xc2034080 }, - { 0x00007870, 0x10142c00 }, - { 0x00009808, 0x00000000 }, - { 0x0000980c, 0xafe68e30 }, - { 0x00009810, 0xfd14e000 }, - { 0x00009814, 0x9c0a9f6b }, - { 0x0000981c, 0x00000000 }, - { 0x0000982c, 0x0000a000 }, - { 0x00009830, 0x00000000 }, - { 0x0000983c, 0x00200400 }, - { 0x0000984c, 0x0040233c }, - { 0x00009854, 0x00000044 }, - { 0x00009900, 0x00000000 }, - { 0x00009904, 0x00000000 }, - { 0x00009908, 0x00000000 }, - { 0x0000990c, 0x00000000 }, - { 0x0000991c, 0x10000fff }, - { 0x00009920, 0x04900000 }, - { 0x00009928, 0x00000001 }, - { 0x0000992c, 0x00000004 }, - { 0x00009934, 0x1e1f2022 }, - { 0x00009938, 0x0a0b0c0d }, - { 0x0000993c, 0x00000000 }, - { 0x00009940, 0x14750604 }, - { 0x00009948, 0x9280c00a }, - { 0x0000994c, 0x00020028 }, - { 0x00009954, 0x5f3ca3de }, - { 0x00009958, 0x0108ecff }, - { 0x00009968, 0x000003ce }, - { 0x00009970, 0x192bb514 }, - { 0x00009974, 0x00000000 }, - { 0x00009978, 0x00000001 }, - { 0x0000997c, 0x00000000 }, - { 0x00009980, 0x00000000 }, - { 0x00009984, 0x00000000 }, - { 0x00009988, 0x00000000 }, - { 0x0000998c, 0x00000000 }, - { 0x00009990, 0x00000000 }, - { 0x00009994, 0x00000000 }, - { 0x00009998, 0x00000000 }, - { 0x0000999c, 0x00000000 }, - { 0x000099a0, 0x00000000 }, - { 0x000099a4, 0x00000001 }, - { 0x000099a8, 0x201fff00 }, - { 0x000099ac, 0x2def0400 }, - { 0x000099b0, 0x03051000 }, - { 0x000099b4, 0x00000820 }, - { 0x000099dc, 0x00000000 }, - { 0x000099e0, 0x00000000 }, - { 0x000099e4, 0xaaaaaaaa }, - { 0x000099e8, 0x3c466478 }, - { 0x000099ec, 0x0cc80caa }, - { 0x000099f0, 0x00000000 }, - { 0x0000a208, 0x803e68c8 }, - { 0x0000a210, 0x4080a333 }, - { 0x0000a214, 0x00206c10 }, - { 0x0000a218, 0x009c4060 }, - { 0x0000a220, 0x01834061 }, - { 0x0000a224, 0x00000400 }, - { 0x0000a228, 0x000003b5 }, - { 0x0000a22c, 0x00000000 }, - { 0x0000a234, 0x20202020 }, - { 0x0000a238, 0x20202020 }, - { 0x0000a244, 0x00000000 }, - { 0x0000a248, 0xfffffffc }, - { 0x0000a24c, 0x00000000 }, - { 0x0000a254, 0x00000000 }, - { 0x0000a258, 0x0ccb5380 }, - { 0x0000a25c, 0x15151501 }, - { 0x0000a260, 0xdfa90f01 }, - { 0x0000a268, 0x00000000 }, - { 0x0000a26c, 0x0ebae9e6 }, - { 0x0000a388, 0x0c000000 }, - { 0x0000a38c, 0x20202020 }, - { 0x0000a390, 0x20202020 }, - { 0x0000a39c, 0x00000001 }, - { 0x0000a3a0, 0x00000000 }, - { 0x0000a3a4, 0x00000000 }, - { 0x0000a3a8, 0x00000000 }, - { 0x0000a3ac, 0x00000000 }, - { 0x0000a3b0, 0x00000000 }, - { 0x0000a3b4, 0x00000000 }, - { 0x0000a3b8, 0x00000000 }, - { 0x0000a3bc, 0x00000000 }, - { 0x0000a3c0, 0x00000000 }, - { 0x0000a3c4, 0x00000000 }, - { 0x0000a3cc, 0x20202020 }, - { 0x0000a3d0, 0x20202020 }, - { 0x0000a3d4, 0x20202020 }, - { 0x0000a3e4, 0x00000000 }, - { 0x0000a3e8, 0x18c43433 }, - { 0x0000a3ec, 0x00f70081 }, - { 0x0000a3f0, 0x01036a2f }, - { 0x0000a3f4, 0x00000000 }, - { 0x0000d270, 0x0d820820 }, - { 0x0000d35c, 0x07ffffef }, - { 0x0000d360, 0x0fffffe7 }, - { 0x0000d364, 0x17ffffe5 }, - { 0x0000d368, 0x1fffffe4 }, - { 0x0000d36c, 0x37ffffe3 }, - { 0x0000d370, 0x3fffffe3 }, - { 0x0000d374, 0x57ffffe3 }, - { 0x0000d378, 0x5fffffe2 }, - { 0x0000d37c, 0x7fffffe2 }, - { 0x0000d380, 0x7f3c7bba }, - { 0x0000d384, 0xf3307ff0 }, + /* Addr allmodes */ + {0x0000000c, 0x00000000}, + {0x00000030, 0x00020045}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000008}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00000054, 0x0000001f}, + {0x00000800, 0x00000000}, + {0x00000804, 0x00000000}, + {0x00000808, 0x00000000}, + {0x0000080c, 0x00000000}, + {0x00000810, 0x00000000}, + {0x00000814, 0x00000000}, + {0x00000818, 0x00000000}, + {0x0000081c, 0x00000000}, + {0x00000820, 0x00000000}, + {0x00000824, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x00001230, 0x00000000}, + {0x00001270, 0x00000000}, + {0x00001038, 0x00000000}, + {0x00001078, 0x00000000}, + {0x000010b8, 0x00000000}, + {0x000010f8, 0x00000000}, + {0x00001138, 0x00000000}, + {0x00001178, 0x00000000}, + {0x000011b8, 0x00000000}, + {0x000011f8, 0x00000000}, + {0x00001238, 0x00000000}, + {0x00001278, 0x00000000}, + {0x000012b8, 0x00000000}, + {0x000012f8, 0x00000000}, + {0x00001338, 0x00000000}, + {0x00001378, 0x00000000}, + {0x000013b8, 0x00000000}, + {0x000013f8, 0x00000000}, + {0x00001438, 0x00000000}, + {0x00001478, 0x00000000}, + {0x000014b8, 0x00000000}, + {0x000014f8, 0x00000000}, + {0x00001538, 0x00000000}, + {0x00001578, 0x00000000}, + {0x000015b8, 0x00000000}, + {0x000015f8, 0x00000000}, + {0x00001638, 0x00000000}, + {0x00001678, 0x00000000}, + {0x000016b8, 0x00000000}, + {0x000016f8, 0x00000000}, + {0x00001738, 0x00000000}, + {0x00001778, 0x00000000}, + {0x000017b8, 0x00000000}, + {0x000017f8, 0x00000000}, + {0x0000103c, 0x00000000}, + {0x0000107c, 0x00000000}, + {0x000010bc, 0x00000000}, + {0x000010fc, 0x00000000}, + {0x0000113c, 0x00000000}, + {0x0000117c, 0x00000000}, + {0x000011bc, 0x00000000}, + {0x000011fc, 0x00000000}, + {0x0000123c, 0x00000000}, + {0x0000127c, 0x00000000}, + {0x000012bc, 0x00000000}, + {0x000012fc, 0x00000000}, + {0x0000133c, 0x00000000}, + {0x0000137c, 0x00000000}, + {0x000013bc, 0x00000000}, + {0x000013fc, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00004030, 0x00000002}, + {0x0000403c, 0x00000002}, + {0x00004024, 0x0000001f}, + {0x00004060, 0x00000000}, + {0x00004064, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000700}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008048, 0x00000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000000}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a80001a}, + {0x000080c4, 0x05dc01e0}, + {0x000080c8, 0x1f402710}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00001e00}, + {0x000080d4, 0x00000000}, + {0x000080d8, 0x00400000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x003f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080f8, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00020000}, + {0x00008104, 0x00000001}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000168}, + {0x00008118, 0x000100aa}, + {0x0000811c, 0x00003210}, + {0x00008120, 0x08f04810}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x00000000}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x32143320}, + {0x00008174, 0xfaa4fa50}, + {0x00008178, 0x00000100}, + {0x0000817c, 0x00000000}, + {0x000081c0, 0x00000000}, + {0x000081d0, 0x0000320a}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008200, 0x00000000}, + {0x00008204, 0x00000000}, + {0x00008208, 0x00000000}, + {0x0000820c, 0x00000000}, + {0x00008210, 0x00000000}, + {0x00008214, 0x00000000}, + {0x00008218, 0x00000000}, + {0x0000821c, 0x00000000}, + {0x00008220, 0x00000000}, + {0x00008224, 0x00000000}, + {0x00008228, 0x00000000}, + {0x0000822c, 0x00000000}, + {0x00008230, 0x00000000}, + {0x00008234, 0x00000000}, + {0x00008238, 0x00000000}, + {0x0000823c, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000100}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x400000ff}, + {0x00008260, 0x00080922}, + {0x00008264, 0x88a00010}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000000}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x00000000}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000040}, + {0x00008314, 0x00000000}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000001}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000e00}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x00000000}, + {0x00008340, 0x00010380}, + {0x00008344, 0x00581043}, + {0x00007010, 0x00000030}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00007800, 0x00140000}, + {0x00007804, 0x0e4548d8}, + {0x00007808, 0x54214514}, + {0x0000780c, 0x02025820}, + {0x00007810, 0x71c0d388}, + {0x00007814, 0x924934a8}, + {0x0000781c, 0x00000000}, + {0x00007828, 0x66964300}, + {0x0000782c, 0x8db6d961}, + {0x00007830, 0x8db6d96c}, + {0x00007834, 0x6140008b}, + {0x0000783c, 0x72ee0a72}, + {0x00007840, 0xbbfffffc}, + {0x00007844, 0x000c0db6}, + {0x00007848, 0x6db6246f}, + {0x0000784c, 0x6d9b66db}, + {0x00007850, 0x6d8c6dba}, + {0x00007854, 0x00040000}, + {0x00007858, 0xdb003012}, + {0x0000785c, 0x04924914}, + {0x00007860, 0x21084210}, + {0x00007864, 0xf7d7ffde}, + {0x00007868, 0xc2034080}, + {0x00007870, 0x10142c00}, + {0x00009808, 0x00000000}, + {0x0000980c, 0xafe68e30}, + {0x00009810, 0xfd14e000}, + {0x00009814, 0x9c0a9f6b}, + {0x0000981c, 0x00000000}, + {0x0000982c, 0x0000a000}, + {0x00009830, 0x00000000}, + {0x0000983c, 0x00200400}, + {0x0000984c, 0x0040233c}, + {0x00009854, 0x00000044}, + {0x00009900, 0x00000000}, + {0x00009904, 0x00000000}, + {0x00009908, 0x00000000}, + {0x0000990c, 0x00000000}, + {0x0000991c, 0x10000fff}, + {0x00009920, 0x04900000}, + {0x00009928, 0x00000001}, + {0x0000992c, 0x00000004}, + {0x00009934, 0x1e1f2022}, + {0x00009938, 0x0a0b0c0d}, + {0x0000993c, 0x00000000}, + {0x00009940, 0x14750604}, + {0x00009948, 0x9280c00a}, + {0x0000994c, 0x00020028}, + {0x00009954, 0x5f3ca3de}, + {0x00009958, 0x0108ecff}, + {0x00009968, 0x000003ce}, + {0x00009970, 0x192bb514}, + {0x00009974, 0x00000000}, + {0x00009978, 0x00000001}, + {0x0000997c, 0x00000000}, + {0x00009980, 0x00000000}, + {0x00009984, 0x00000000}, + {0x00009988, 0x00000000}, + {0x0000998c, 0x00000000}, + {0x00009990, 0x00000000}, + {0x00009994, 0x00000000}, + {0x00009998, 0x00000000}, + {0x0000999c, 0x00000000}, + {0x000099a0, 0x00000000}, + {0x000099a4, 0x00000001}, + {0x000099a8, 0x201fff00}, + {0x000099ac, 0x2def0400}, + {0x000099b0, 0x03051000}, + {0x000099b4, 0x00000820}, + {0x000099dc, 0x00000000}, + {0x000099e0, 0x00000000}, + {0x000099e4, 0xaaaaaaaa}, + {0x000099e8, 0x3c466478}, + {0x000099ec, 0x0cc80caa}, + {0x000099f0, 0x00000000}, + {0x0000a208, 0x803e68c8}, + {0x0000a210, 0x4080a333}, + {0x0000a214, 0x00206c10}, + {0x0000a218, 0x009c4060}, + {0x0000a220, 0x01834061}, + {0x0000a224, 0x00000400}, + {0x0000a228, 0x000003b5}, + {0x0000a22c, 0x00000000}, + {0x0000a234, 0x20202020}, + {0x0000a238, 0x20202020}, + {0x0000a244, 0x00000000}, + {0x0000a248, 0xfffffffc}, + {0x0000a24c, 0x00000000}, + {0x0000a254, 0x00000000}, + {0x0000a258, 0x0ccb5380}, + {0x0000a25c, 0x15151501}, + {0x0000a260, 0xdfa90f01}, + {0x0000a268, 0x00000000}, + {0x0000a26c, 0x0ebae9e6}, + {0x0000a388, 0x0c000000}, + {0x0000a38c, 0x20202020}, + {0x0000a390, 0x20202020}, + {0x0000a39c, 0x00000001}, + {0x0000a3a0, 0x00000000}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0x00000000}, + {0x0000a3ac, 0x00000000}, + {0x0000a3b0, 0x00000000}, + {0x0000a3b4, 0x00000000}, + {0x0000a3b8, 0x00000000}, + {0x0000a3bc, 0x00000000}, + {0x0000a3c0, 0x00000000}, + {0x0000a3c4, 0x00000000}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3e4, 0x00000000}, + {0x0000a3e8, 0x18c43433}, + {0x0000a3ec, 0x00f70081}, + {0x0000a3f0, 0x01036a2f}, + {0x0000a3f4, 0x00000000}, + {0x0000d270, 0x0d820820}, + {0x0000d35c, 0x07ffffef}, + {0x0000d360, 0x0fffffe7}, + {0x0000d364, 0x17ffffe5}, + {0x0000d368, 0x1fffffe4}, + {0x0000d36c, 0x37ffffe3}, + {0x0000d370, 0x3fffffe3}, + {0x0000d374, 0x57ffffe3}, + {0x0000d378, 0x5fffffe2}, + {0x0000d37c, 0x7fffffe2}, + {0x0000d380, 0x7f3c7bba}, + {0x0000d384, 0xf3307ff0}, }; static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = { - { 0x0000a1f4, 0x00fffeff }, - { 0x0000a1f8, 0x00f5f9ff }, - { 0x0000a1fc, 0xb79f6427 }, + /* Addr allmodes */ + {0x0000a1f4, 0x00fffeff}, + {0x0000a1f8, 0x00f5f9ff}, + {0x0000a1fc, 0xb79f6427}, }; static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = { - { 0x0000a1f4, 0x00000000 }, - { 0x0000a1f8, 0xefff0301 }, - { 0x0000a1fc, 0xca9228ee }, + /* Addr allmodes */ + {0x0000a1f4, 0x00000000}, + {0x0000a1f8, 0xefff0301}, + {0x0000a1fc, 0xca9228ee}, }; static const u32 ar9271Modes_9271_1_0_only[][6] = { - { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, - { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, + {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, }; static const u32 ar9271Modes_9271_ANI_reg[][6] = { - { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, - { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, - { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, - { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 }, - { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, - { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 }, - { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, - { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, }; static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = { - { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 }, - { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 }, - { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff }, - { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, - { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, - { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 }, - { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, - { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd }, - { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, - { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd }, - { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, - { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd }, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000}, + {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029}, + {0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652}, + {0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd}, + {0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, + {0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, }; static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = { - { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 }, - { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 }, - { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 }, - { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 }, - { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 }, - { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 }, - { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 }, - { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 }, - { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 }, - { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 }, - { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 }, - { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 }, - { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 }, - { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 }, - { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, - { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, - { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, - { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b }, - { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff }, - { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 }, - { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, - { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 }, - { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, - { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 }, - { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, - { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 }, - { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, - { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 }, + {0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000}, + {0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000}, + {0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000}, + {0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000}, + {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, + {0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b}, + {0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff}, + {0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652, 0x0a22a652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063}, + {0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, + {0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, + {0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, + {0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, }; -#endif /* INITVALS_9002_10_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 2be20d2070c..50dda394f8b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -287,6 +287,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); + ts->tid = MS(ads->ds_txstatus9, AR_TxTid); ts->ts_antenna = 0; return 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index ed314e89bfe..adbf031fbc5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -471,52 +471,47 @@ static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, static void ar9002_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { - struct ath_common *common = ath9k_hw_common(ah); int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); - - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 0] is %d\n", nf); - - if (AR_SREV_9271(ah) && (nf >= -114)) - nf = -116; - - nfarray[0] = nf; - - if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) { - nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), - AR9280_PHY_CH1_MINCCA_PWR); - - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 1] is %d\n", nf); - nfarray[1] = nf; - } + nfarray[0] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 0] is %d\n", nf); + if (IS_CHAN_HT40(ah->curchan)) + nfarray[3] = sign_extend(nf, 9); - if (AR_SREV_9271(ah) && (nf >= -114)) - nf = -116; + if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) + return; - nfarray[3] = nf; + nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); + nfarray[1] = sign_extend(nf, 9); - if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) { - nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), - AR9280_PHY_CH1_EXT_MINCCA_PWR); + nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR); + if (IS_CHAN_HT40(ah->curchan)) + nfarray[4] = sign_extend(nf, 9); +} - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 1] is %d\n", nf); - nfarray[4] = nf; +static void ar9002_hw_set_nf_limits(struct ath_hw *ah) +{ + if (AR_SREV_9285(ah)) { + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ; + } else if (AR_SREV_9287(ah)) { + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ; + } else if (AR_SREV_9271(ah)) { + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ; + } else { + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ; + ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ; + ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ; + ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ; } } @@ -532,4 +527,6 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->olc_init = ar9002_olc_init; priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; priv_ops->do_getnf = ar9002_hw_do_getnf; + + ar9002_hw_set_nf_limits(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 81bf6e5840e..c5151a4dd10 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -114,6 +114,10 @@ #define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 #define AR_PHY_FIND_SIG_FIRPWR_S 18 +#define AR_PHY_FIND_SIG_LOW 0x9840 +#define AR_PHY_FIND_SIG_FIRSTEP_LOW 0x00000FC0L +#define AR_PHY_FIND_SIG_FIRSTEP_LOW_S 6 + #define AR_PHY_AGC_CTL1 0x985C #define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 #define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 @@ -325,6 +329,9 @@ #define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 #define AR_PHY_EXT_CCA_THRESH62_S 16 +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1 0x0000FE00L +#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9 + #define AR_PHY_EXT_MINCCA_PWR 0xFF800000 #define AR_PHY_EXT_MINCCA_PWR_S 23 #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 @@ -569,4 +576,30 @@ #define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000 #define AR_PHY_CH2_EXT_MINCCA_PWR_S 23 +#define AR_PHY_CCA_NOM_VAL_5416_2GHZ -90 +#define AR_PHY_CCA_NOM_VAL_5416_5GHZ -100 +#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ -100 +#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ -110 +#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ -80 +#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ -90 + +#define AR_PHY_CCA_NOM_VAL_9280_2GHZ -112 +#define AR_PHY_CCA_NOM_VAL_9280_5GHZ -112 +#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ -127 +#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ -122 +#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ -97 +#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ -102 + +#define AR_PHY_CCA_NOM_VAL_9285_2GHZ -118 +#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ -127 +#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ -108 + +#define AR_PHY_CCA_NOM_VAL_9271_2GHZ -118 +#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ -127 +#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ -116 + +#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -120 +#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127 +#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -110 + #endif diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h index db019dd220b..d3375fc4ce8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h @@ -14,8 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef INITVALS_9003_H -#define INITVALS_9003_H +#ifndef INITVALS_9003_2P0_H +#define INITVALS_9003_2P0_H /* AR9003 2.0 */ @@ -835,71 +835,71 @@ static const u32 ar9300_2p0_baseband_core[][2] = { static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, - {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, - {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, @@ -913,71 +913,71 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, - {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, - {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, @@ -1781,4 +1781,4 @@ static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { {0x00004044, 0x00000000}, }; -#endif /* INITVALS_9003_H */ +#endif /* INITVALS_9003_2P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h new file mode 100644 index 00000000000..ec98ab50748 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -0,0 +1,1785 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9003_2P2_H +#define INITVALS_9003_2P2_H + +/* AR9003 2.2 */ + +static const u32 ar9300_2p2_radio_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, + {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, + {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, + {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +}; + +static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, + {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, + {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +}; + +static const u32 ar9300Modes_fast_clock_2p2[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000000b, 0x00000016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9300_2p2_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73f00000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x76d005b5}, + {0x00016050, 0x556cf031}, + {0x00016054, 0x13449440}, + {0x00016058, 0x0c51c92c}, + {0x0001605c, 0x3db7fffc}, + {0x00016060, 0xfffffffc}, + {0x00016064, 0x000f0278}, + {0x0001606c, 0x6db60000}, + {0x00016080, 0x00000000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x54214514}, + {0x0001608c, 0x119f481e}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd2888888}, + {0x000160a0, 0x0a108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92480080}, + {0x000160c0, 0x00adb6d0}, + {0x000160c4, 0x6db6db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x01e6c000}, + {0x00016100, 0x3fffbe01}, + {0x00016104, 0xfff80000}, + {0x00016108, 0x00080010}, + {0x00016144, 0x02084080}, + {0x00016148, 0x00000000}, + {0x00016280, 0x058a0001}, + {0x00016284, 0x3d840208}, + {0x00016288, 0x05a20408}, + {0x0001628c, 0x00038c07}, + {0x00016290, 0x00000004}, + {0x00016294, 0x458aa14f}, + {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}, + {0x00016400, 0x36db6db6}, + {0x00016404, 0x6db6db40}, + {0x00016408, 0x73f00000}, + {0x0001640c, 0x00000000}, + {0x00016440, 0x7f80fff8}, + {0x0001644c, 0x76d005b5}, + {0x00016450, 0x556cf031}, + {0x00016454, 0x13449440}, + {0x00016458, 0x0c51c92c}, + {0x0001645c, 0x3db7fffc}, + {0x00016460, 0xfffffffc}, + {0x00016464, 0x000f0278}, + {0x0001646c, 0x6db60000}, + {0x00016500, 0x3fffbe01}, + {0x00016504, 0xfff80000}, + {0x00016508, 0x00080010}, + {0x00016544, 0x02084080}, + {0x00016548, 0x00000000}, + {0x00016780, 0x00000000}, + {0x00016784, 0x00000000}, + {0x00016788, 0x00800700}, + {0x0001678c, 0x00800700}, + {0x00016790, 0x00800700}, + {0x00016794, 0x00000000}, + {0x00016798, 0x00000000}, + {0x0001679c, 0x00000000}, + {0x000167a0, 0x00000001}, + {0x000167a4, 0x00000001}, + {0x000167a8, 0x00000000}, + {0x000167ac, 0x00000000}, + {0x000167b0, 0x00000000}, + {0x000167b4, 0x00000000}, + {0x000167b8, 0x00000000}, + {0x000167bc, 0x00000000}, + {0x000167c0, 0x000000a0}, + {0x000167c4, 0x000c0000}, + {0x000167c8, 0x14021402}, + {0x000167cc, 0x00001402}, + {0x000167d0, 0x00000000}, + {0x000167d4, 0x00000000}, + {0x00016800, 0x36db6db6}, + {0x00016804, 0x6db6db40}, + {0x00016808, 0x73f00000}, + {0x0001680c, 0x00000000}, + {0x00016840, 0x7f80fff8}, + {0x0001684c, 0x76d005b5}, + {0x00016850, 0x556cf031}, + {0x00016854, 0x13449440}, + {0x00016858, 0x0c51c92c}, + {0x0001685c, 0x3db7fffc}, + {0x00016860, 0xfffffffc}, + {0x00016864, 0x000f0278}, + {0x0001686c, 0x6db60000}, + {0x00016900, 0x3fffbe01}, + {0x00016904, 0xfff80000}, + {0x00016908, 0x00080010}, + {0x00016944, 0x02084080}, + {0x00016948, 0x00000000}, + {0x00016b80, 0x00000000}, + {0x00016b84, 0x00000000}, + {0x00016b88, 0x00800700}, + {0x00016b8c, 0x00800700}, + {0x00016b90, 0x00800700}, + {0x00016b94, 0x00000000}, + {0x00016b98, 0x00000000}, + {0x00016b9c, 0x00000000}, + {0x00016ba0, 0x00000001}, + {0x00016ba4, 0x00000001}, + {0x00016ba8, 0x00000000}, + {0x00016bac, 0x00000000}, + {0x00016bb0, 0x00000000}, + {0x00016bb4, 0x00000000}, + {0x00016bb8, 0x00000000}, + {0x00016bbc, 0x00000000}, + {0x00016bc0, 0x000000a0}, + {0x00016bc4, 0x000c0000}, + {0x00016bc8, 0x14021402}, + {0x00016bcc, 0x00001402}, + {0x00016bd0, 0x00000000}, + {0x00016bd4, 0x00000000}, +}; + +static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x02000101}, + {0x0000a004, 0x02000102}, + {0x0000a008, 0x02000103}, + {0x0000a00c, 0x02000104}, + {0x0000a010, 0x02000200}, + {0x0000a014, 0x02000201}, + {0x0000a018, 0x02000202}, + {0x0000a01c, 0x02000203}, + {0x0000a020, 0x02000204}, + {0x0000a024, 0x02000205}, + {0x0000a028, 0x02000208}, + {0x0000a02c, 0x02000302}, + {0x0000a030, 0x02000303}, + {0x0000a034, 0x02000304}, + {0x0000a038, 0x02000400}, + {0x0000a03c, 0x02010300}, + {0x0000a040, 0x02010301}, + {0x0000a044, 0x02010302}, + {0x0000a048, 0x02000500}, + {0x0000a04c, 0x02010400}, + {0x0000a050, 0x02020300}, + {0x0000a054, 0x02020301}, + {0x0000a058, 0x02020302}, + {0x0000a05c, 0x02020303}, + {0x0000a060, 0x02020400}, + {0x0000a064, 0x02030300}, + {0x0000a068, 0x02030301}, + {0x0000a06c, 0x02030302}, + {0x0000a070, 0x02030303}, + {0x0000a074, 0x02030400}, + {0x0000a078, 0x02040300}, + {0x0000a07c, 0x02040301}, + {0x0000a080, 0x02040302}, + {0x0000a084, 0x02040303}, + {0x0000a088, 0x02030500}, + {0x0000a08c, 0x02040400}, + {0x0000a090, 0x02050203}, + {0x0000a094, 0x02050204}, + {0x0000a098, 0x02050205}, + {0x0000a09c, 0x02040500}, + {0x0000a0a0, 0x02050301}, + {0x0000a0a4, 0x02050302}, + {0x0000a0a8, 0x02050303}, + {0x0000a0ac, 0x02050400}, + {0x0000a0b0, 0x02050401}, + {0x0000a0b4, 0x02050402}, + {0x0000a0b8, 0x02050403}, + {0x0000a0bc, 0x02050500}, + {0x0000a0c0, 0x02050501}, + {0x0000a0c4, 0x02050502}, + {0x0000a0c8, 0x02050503}, + {0x0000a0cc, 0x02050504}, + {0x0000a0d0, 0x02050600}, + {0x0000a0d4, 0x02050601}, + {0x0000a0d8, 0x02050602}, + {0x0000a0dc, 0x02050603}, + {0x0000a0e0, 0x02050604}, + {0x0000a0e4, 0x02050700}, + {0x0000a0e8, 0x02050701}, + {0x0000a0ec, 0x02050702}, + {0x0000a0f0, 0x02050703}, + {0x0000a0f4, 0x02050704}, + {0x0000a0f8, 0x02050705}, + {0x0000a0fc, 0x02050708}, + {0x0000a100, 0x02050709}, + {0x0000a104, 0x0205070a}, + {0x0000a108, 0x0205070b}, + {0x0000a10c, 0x0205070c}, + {0x0000a110, 0x0205070d}, + {0x0000a114, 0x02050710}, + {0x0000a118, 0x02050711}, + {0x0000a11c, 0x02050712}, + {0x0000a120, 0x02050713}, + {0x0000a124, 0x02050714}, + {0x0000a128, 0x02050715}, + {0x0000a12c, 0x02050730}, + {0x0000a130, 0x02050731}, + {0x0000a134, 0x02050732}, + {0x0000a138, 0x02050733}, + {0x0000a13c, 0x02050734}, + {0x0000a140, 0x02050735}, + {0x0000a144, 0x02050750}, + {0x0000a148, 0x02050751}, + {0x0000a14c, 0x02050752}, + {0x0000a150, 0x02050753}, + {0x0000a154, 0x02050754}, + {0x0000a158, 0x02050755}, + {0x0000a15c, 0x02050770}, + {0x0000a160, 0x02050771}, + {0x0000a164, 0x02050772}, + {0x0000a168, 0x02050773}, + {0x0000a16c, 0x02050774}, + {0x0000a170, 0x02050775}, + {0x0000a174, 0x00000776}, + {0x0000a178, 0x00000776}, + {0x0000a17c, 0x00000776}, + {0x0000a180, 0x00000776}, + {0x0000a184, 0x00000776}, + {0x0000a188, 0x00000776}, + {0x0000a18c, 0x00000776}, + {0x0000a190, 0x00000776}, + {0x0000a194, 0x00000776}, + {0x0000a198, 0x00000776}, + {0x0000a19c, 0x00000776}, + {0x0000a1a0, 0x00000776}, + {0x0000a1a4, 0x00000776}, + {0x0000a1a8, 0x00000776}, + {0x0000a1ac, 0x00000776}, + {0x0000a1b0, 0x00000776}, + {0x0000a1b4, 0x00000776}, + {0x0000a1b8, 0x00000776}, + {0x0000a1bc, 0x00000776}, + {0x0000a1c0, 0x00000776}, + {0x0000a1c4, 0x00000776}, + {0x0000a1c8, 0x00000776}, + {0x0000a1cc, 0x00000776}, + {0x0000a1d0, 0x00000776}, + {0x0000a1d4, 0x00000776}, + {0x0000a1d8, 0x00000776}, + {0x0000a1dc, 0x00000776}, + {0x0000a1e0, 0x00000776}, + {0x0000a1e4, 0x00000776}, + {0x0000a1e8, 0x00000776}, + {0x0000a1ec, 0x00000776}, + {0x0000a1f0, 0x00000776}, + {0x0000a1f4, 0x00000776}, + {0x0000a1f8, 0x00000776}, + {0x0000a1fc, 0x00000776}, + {0x0000b000, 0x02000101}, + {0x0000b004, 0x02000102}, + {0x0000b008, 0x02000103}, + {0x0000b00c, 0x02000104}, + {0x0000b010, 0x02000200}, + {0x0000b014, 0x02000201}, + {0x0000b018, 0x02000202}, + {0x0000b01c, 0x02000203}, + {0x0000b020, 0x02000204}, + {0x0000b024, 0x02000205}, + {0x0000b028, 0x02000208}, + {0x0000b02c, 0x02000302}, + {0x0000b030, 0x02000303}, + {0x0000b034, 0x02000304}, + {0x0000b038, 0x02000400}, + {0x0000b03c, 0x02010300}, + {0x0000b040, 0x02010301}, + {0x0000b044, 0x02010302}, + {0x0000b048, 0x02000500}, + {0x0000b04c, 0x02010400}, + {0x0000b050, 0x02020300}, + {0x0000b054, 0x02020301}, + {0x0000b058, 0x02020302}, + {0x0000b05c, 0x02020303}, + {0x0000b060, 0x02020400}, + {0x0000b064, 0x02030300}, + {0x0000b068, 0x02030301}, + {0x0000b06c, 0x02030302}, + {0x0000b070, 0x02030303}, + {0x0000b074, 0x02030400}, + {0x0000b078, 0x02040300}, + {0x0000b07c, 0x02040301}, + {0x0000b080, 0x02040302}, + {0x0000b084, 0x02040303}, + {0x0000b088, 0x02030500}, + {0x0000b08c, 0x02040400}, + {0x0000b090, 0x02050203}, + {0x0000b094, 0x02050204}, + {0x0000b098, 0x02050205}, + {0x0000b09c, 0x02040500}, + {0x0000b0a0, 0x02050301}, + {0x0000b0a4, 0x02050302}, + {0x0000b0a8, 0x02050303}, + {0x0000b0ac, 0x02050400}, + {0x0000b0b0, 0x02050401}, + {0x0000b0b4, 0x02050402}, + {0x0000b0b8, 0x02050403}, + {0x0000b0bc, 0x02050500}, + {0x0000b0c0, 0x02050501}, + {0x0000b0c4, 0x02050502}, + {0x0000b0c8, 0x02050503}, + {0x0000b0cc, 0x02050504}, + {0x0000b0d0, 0x02050600}, + {0x0000b0d4, 0x02050601}, + {0x0000b0d8, 0x02050602}, + {0x0000b0dc, 0x02050603}, + {0x0000b0e0, 0x02050604}, + {0x0000b0e4, 0x02050700}, + {0x0000b0e8, 0x02050701}, + {0x0000b0ec, 0x02050702}, + {0x0000b0f0, 0x02050703}, + {0x0000b0f4, 0x02050704}, + {0x0000b0f8, 0x02050705}, + {0x0000b0fc, 0x02050708}, + {0x0000b100, 0x02050709}, + {0x0000b104, 0x0205070a}, + {0x0000b108, 0x0205070b}, + {0x0000b10c, 0x0205070c}, + {0x0000b110, 0x0205070d}, + {0x0000b114, 0x02050710}, + {0x0000b118, 0x02050711}, + {0x0000b11c, 0x02050712}, + {0x0000b120, 0x02050713}, + {0x0000b124, 0x02050714}, + {0x0000b128, 0x02050715}, + {0x0000b12c, 0x02050730}, + {0x0000b130, 0x02050731}, + {0x0000b134, 0x02050732}, + {0x0000b138, 0x02050733}, + {0x0000b13c, 0x02050734}, + {0x0000b140, 0x02050735}, + {0x0000b144, 0x02050750}, + {0x0000b148, 0x02050751}, + {0x0000b14c, 0x02050752}, + {0x0000b150, 0x02050753}, + {0x0000b154, 0x02050754}, + {0x0000b158, 0x02050755}, + {0x0000b15c, 0x02050770}, + {0x0000b160, 0x02050771}, + {0x0000b164, 0x02050772}, + {0x0000b168, 0x02050773}, + {0x0000b16c, 0x02050774}, + {0x0000b170, 0x02050775}, + {0x0000b174, 0x00000776}, + {0x0000b178, 0x00000776}, + {0x0000b17c, 0x00000776}, + {0x0000b180, 0x00000776}, + {0x0000b184, 0x00000776}, + {0x0000b188, 0x00000776}, + {0x0000b18c, 0x00000776}, + {0x0000b190, 0x00000776}, + {0x0000b194, 0x00000776}, + {0x0000b198, 0x00000776}, + {0x0000b19c, 0x00000776}, + {0x0000b1a0, 0x00000776}, + {0x0000b1a4, 0x00000776}, + {0x0000b1a8, 0x00000776}, + {0x0000b1ac, 0x00000776}, + {0x0000b1b0, 0x00000776}, + {0x0000b1b4, 0x00000776}, + {0x0000b1b8, 0x00000776}, + {0x0000b1bc, 0x00000776}, + {0x0000b1c0, 0x00000776}, + {0x0000b1c4, 0x00000776}, + {0x0000b1c8, 0x00000776}, + {0x0000b1cc, 0x00000776}, + {0x0000b1d0, 0x00000776}, + {0x0000b1d4, 0x00000776}, + {0x0000b1d8, 0x00000776}, + {0x0000b1dc, 0x00000776}, + {0x0000b1e0, 0x00000776}, + {0x0000b1e4, 0x00000776}, + {0x0000b1e8, 0x00000776}, + {0x0000b1ec, 0x00000776}, + {0x0000b1f0, 0x00000776}, + {0x0000b1f4, 0x00000776}, + {0x0000b1f8, 0x00000776}, + {0x0000b1fc, 0x00000776}, +}; + +static const u32 ar9300_2p2_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 ar9300_2p2_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, +}; + +static const u32 ar9200_merlin_2p2_radio_core[][2] = { + /* Addr allmodes */ + {0x00007800, 0x00040000}, + {0x00007804, 0xdb005012}, + {0x00007808, 0x04924914}, + {0x0000780c, 0x21084210}, + {0x00007810, 0x6d801300}, + {0x00007814, 0x0019beff}, + {0x00007818, 0x07e41000}, + {0x0000781c, 0x00392000}, + {0x00007820, 0x92592480}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb005012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x6d801300}, + {0x00007838, 0x0019beff}, + {0x0000783c, 0x07e40000}, + {0x00007840, 0x00392000}, + {0x00007844, 0x92592480}, + {0x00007848, 0x00100000}, + {0x0000784c, 0x773f0567}, + {0x00007850, 0x54214514}, + {0x00007854, 0x12035828}, + {0x00007858, 0x92592692}, + {0x0000785c, 0x00000000}, + {0x00007860, 0x56400000}, + {0x00007864, 0x0a8e370e}, + {0x00007868, 0xc0102850}, + {0x0000786c, 0x812d4000}, + {0x00007870, 0x807ec400}, + {0x00007874, 0x001b6db0}, + {0x00007878, 0x00376b63}, + {0x0000787c, 0x06db6db6}, + {0x00007880, 0x006d8000}, + {0x00007884, 0xffeffffe}, + {0x00007888, 0xffeffffe}, + {0x0000788c, 0x00010000}, + {0x00007890, 0x02060aeb}, + {0x00007894, 0x5a108000}, +}; + +static const u32 ar9300_2p2_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, + {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, + {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}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, + {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, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, + {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, +}; + +static const u32 ar9300_2p2_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a9f6b}, + {0x0000980c, 0x04900000}, + {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, 0xff55ff55}, + {0x00009c08, 0x0320ff55}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x9883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c0040b}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038230c}, + {0x00009e24, 0x990bb515}, + {0x00009e28, 0x0c6f0000}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e3c, 0xcf946222}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009e54, 0x00000000}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x00009fd0, 0x01193b93}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a22c, 0x01036a1e}, + {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, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {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, 0x00000246}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x06000080}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a600, 0x00000000}, + {0x0000a604, 0x00000000}, + {0x0000a608, 0x00000000}, + {0x0000a60c, 0x00000000}, + {0x0000a610, 0x00000000}, + {0x0000a614, 0x00000000}, + {0x0000a618, 0x00000000}, + {0x0000a61c, 0x00000000}, + {0x0000a620, 0x00000000}, + {0x0000a624, 0x00000000}, + {0x0000a628, 0x00000000}, + {0x0000a62c, 0x00000000}, + {0x0000a630, 0x00000000}, + {0x0000a634, 0x00000000}, + {0x0000a638, 0x00000000}, + {0x0000a63c, 0x00000000}, + {0x0000a640, 0x00000000}, + {0x0000a644, 0x3fad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00000637}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, + {0x0000a8d0, 0x004b6a8e}, + {0x0000a8d4, 0x00000820}, + {0x0000a8dc, 0x00000000}, + {0x0000a8f0, 0x00000000}, + {0x0000a8f4, 0x00000000}, + {0x0000b2d0, 0x00000080}, + {0x0000b2d4, 0x00000000}, + {0x0000b2dc, 0x00000000}, + {0x0000b2e0, 0x00000000}, + {0x0000b2e4, 0x00000000}, + {0x0000b2e8, 0x00000000}, + {0x0000b2ec, 0x00000000}, + {0x0000b2f0, 0x00000000}, + {0x0000b2f4, 0x00000000}, + {0x0000b2f8, 0x00000000}, + {0x0000b408, 0x0e79e5c0}, + {0x0000b40c, 0x00820820}, + {0x0000b420, 0x00000000}, + {0x0000b8d0, 0x004b6a8e}, + {0x0000b8d4, 0x00000820}, + {0x0000b8dc, 0x00000000}, + {0x0000b8f0, 0x00000000}, + {0x0000b8f4, 0x00000000}, + {0x0000c2d0, 0x00000080}, + {0x0000c2d4, 0x00000000}, + {0x0000c2dc, 0x00000000}, + {0x0000c2e0, 0x00000000}, + {0x0000c2e4, 0x00000000}, + {0x0000c2e8, 0x00000000}, + {0x0000c2ec, 0x00000000}, + {0x0000c2f0, 0x00000000}, + {0x0000c2f4, 0x00000000}, + {0x0000c2f8, 0x00000000}, + {0x0000c408, 0x0e79e5c0}, + {0x0000c40c, 0x00820820}, + {0x0000c420, 0x00000000}, +}; + +static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, + {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, + {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, + {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, + {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, + {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, + {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, + {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, + {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, +}; + +static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +}; + +static const u32 ar9300Common_rx_gain_table_2p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {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, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {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, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {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, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, + {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, + {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +}; + +static const u32 ar9300_2p2_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, 0x13881c20}, + {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}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f424}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e848}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9bc00010}, + {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, 0xaa48105b}, + {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 ar9300Common_wo_xlna_rx_gain_table_2p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {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, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {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, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {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, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9300_2p2_soc_preamble[][2] = { + /* Addr allmodes */ + {0x000040a4, 0x00a0c1c9}, + {0x00007008, 0x00000000}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00007048, 0x00000008}, +}; + +static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = { + /* Addr allmodes */ + {0x00004040, 0x08212e5e}, + {0x00004040, 0x0008003b}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = { + /* Addr allmodes */ + {0x00004040, 0x08253e5e}, + {0x00004040, 0x0008003b}, + {0x00004044, 0x00000000}, +}; + +static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = { + /* Addr allmodes */ + {0x00004040, 0x08213e5e}, + {0x00004040, 0x0008003b}, + {0x00004044, 0x00000000}, +}; + +#endif /* INITVALS_9003_2P2_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 56a9e5fa6d6..5a065039913 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -739,6 +739,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, */ ar9003_hw_set_chain_masks(ah, 0x7, 0x7); + /* Do Tx IQ Calibration */ + ar9003_hw_tx_iq_cal(ah); + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); + udelay(5); + REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); + /* Calibrate the AGC */ REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_READ(ah, AR_PHY_AGC_CONTROL) | @@ -753,10 +759,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, return false; } - /* Do Tx IQ Calibration */ - if (ah->config.tx_iq_calibration) - ar9003_hw_tx_iq_cal(ah); - /* Revert chainmasks to their original values before NF cal */ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 23eb60ea545..ace8d2678b1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -67,6 +67,7 @@ static const struct ar9300_eeprom ar9300_default = { * bit2 - enable fastClock - enabled * bit3 - enable doubling - enabled * bit4 - enable internal regulator - disabled + * bit5 - enable pa predistortion - disabled */ .miscConfiguration = 0, /* bit0 - turn down drivestrength */ .eepromWriteEnableGpio = 3, @@ -129,9 +130,11 @@ static const struct ar9300_eeprom ar9300_default = { .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, - .futureModal = { /* [32] */ + .papdRateMaskHt20 = LE32(0x80c080), + .papdRateMaskHt40 = LE32(0x80c080), + .futureModal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0 }, }, .calFreqPier2G = { @@ -326,9 +329,11 @@ static const struct ar9300_eeprom ar9300_default = { .txEndToRxOn = 0x2, .txFrameToXpaOn = 0xe, .thresh62 = 28, + .papdRateMaskHt20 = LE32(0xf0e0e0), + .papdRateMaskHt40 = LE32(0xf0e0e0), .futureModal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0 }, }, .calFreqPier5G = { @@ -644,6 +649,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, return (pBase->featureEnable & 0x10) >> 4; case EEP_SWREG: return le32_to_cpu(pBase->swreg); + case EEP_PAPRD: + return !!(pBase->featureEnable & BIT(5)); default: return 0; } @@ -944,7 +951,7 @@ static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, return 1; } -static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, +static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, struct ath9k_channel *chan) { return -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 23fb353c3bb..3c533bb983c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -234,7 +234,9 @@ struct ar9300_modal_eep_header { u8 txEndToRxOn; u8 txFrameToXpaOn; u8 thresh62; - u8 futureModal[32]; + __le32 papdRateMaskHt20; + __le32 papdRateMaskHt40; + u8 futureModal[24]; } __packed; struct ar9300_cal_data_per_freq_op_loop { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index b15309caf1d..06416890910 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -16,7 +16,8 @@ #include "hw.h" #include "ar9003_mac.h" -#include "ar9003_initvals.h" +#include "ar9003_2p0_initvals.h" +#include "ar9003_2p2_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -31,12 +32,8 @@ static bool ar9003_hw_macversion_supported(u32 macversion) return false; } -/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */ -/* - * XXX: move TX/RX gain INI to its own init_mode_gain_regs after - * ensuring it does not affect hardware bring up - */ -static void ar9003_hw_init_mode_regs(struct ath_hw *ah) +/* AR9003 2.0 */ +static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -106,27 +103,128 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 3); } +/* AR9003 2.2 */ +static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah) +{ + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9300_2p2_mac_core, + ARRAY_SIZE(ar9300_2p2_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9300_2p2_mac_postamble, + ARRAY_SIZE(ar9300_2p2_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9300_2p2_baseband_core, + ARRAY_SIZE(ar9300_2p2_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9300_2p2_baseband_postamble, + ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9300_2p2_radio_core, + ARRAY_SIZE(ar9300_2p2_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9300_2p2_radio_postamble, + ARRAY_SIZE(ar9300_2p2_radio_postamble), 5); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9300_2p2_soc_preamble, + ARRAY_SIZE(ar9300_2p2_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9300_2p2_soc_postamble, + ARRAY_SIZE(ar9300_2p2_soc_postamble), 5); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); + + /* Load PCIE SERDES settings from INI */ + + /* Awake Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, + ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), + 2); + + /* Sleep Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9300PciePhy_clkreq_enable_L1_2p2, + ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2), + 2); + + /* Fast clock modal settings */ + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9300Modes_fast_clock_2p2, + ARRAY_SIZE(ar9300Modes_fast_clock_2p2), + 3); +} + +/* + * The AR9003 family uses a new INI format (pre, core, post + * arrays per subsystem). + */ +static void ar9003_hw_init_mode_regs(struct ath_hw *ah) +{ + if (AR_SREV_9300_20(ah)) + ar9003_2p0_hw_init_mode_regs(ah); + else + ar9003_2p2_hw_init_mode_regs(ah); +} + static void ar9003_tx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), - 5); + if (AR_SREV_9300_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p0, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); break; case 1: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), - 5); + if (AR_SREV_9300_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p0, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), + 5); break; case 2: - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), - 5); + if (AR_SREV_9300_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p0, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), + 5); break; } } @@ -136,15 +234,28 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), - 2); + if (AR_SREV_9300_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p0, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), + 2); break; case 1: - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), - 2); + if (AR_SREV_9300_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p0, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), + 2); break; } } @@ -184,6 +295,26 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, /* Several PCIe massages to ensure proper behaviour */ if (ah->config.pcie_waen) REG_WRITE(ah, AR_WA, ah->config.pcie_waen); + else + REG_WRITE(ah, AR_WA, ah->WARegVal); + } + + /* + * Configire PCIE after Ini init. SERDES values now come from ini file + * This enables PCIe low power mode. + */ + if (ah->config.pcieSerDesWrite) { + unsigned int i; + struct ar5416IniArray *array; + + array = power_off ? &ah->iniPcieSerdes : + &ah->iniPcieSerdesLowPower; + + for (i = 0; i < array->ia_rows; i++) { + REG_WRITE(ah, + INI_RA(array, i, 0), + INI_RA(array, i, 1)); + } } } @@ -202,4 +333,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) ar9003_hw_attach_phy_ops(ah); ar9003_hw_attach_calib_ops(ah); ar9003_hw_attach_mac_ops(ah); + + ath9k_hw_attach_ani_ops_new(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 37ba37481a4..5b995bee70a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -90,6 +90,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) MAP_ISR_S2_CST); mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> MAP_ISR_S2_TSFOOR); + mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >> + MAP_ISR_S2_BB_WATCHDOG); if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { REG_WRITE(ah, AR_ISR_S2, isr2); @@ -167,6 +169,9 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) (void) REG_READ(ah, AR_ISR); } + + if (*masked & ATH9K_INT_BB_WATCHDOG) + ar9003_hw_bb_watchdog_read(ah); } if (sync_cause) { @@ -465,6 +470,14 @@ static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, ads->ctl11 &= ~AR_VirtMoreFrag; } +void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) +{ + struct ar9003_txc *ads = ds; + + ads->ctl12 |= SM(chains, AR_PAPRDChainMask); +} +EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc); + void ar9003_hw_attach_mac_ops(struct ath_hw *hw) { struct ath_hw_ops *ops = ath9k_hw_ops(hw); @@ -566,12 +579,39 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; if ((rxsp->status11 & AR_RxFrameOK) == 0) { + /* + * AR_CRCErr will bet set to true if we're on the last + * subframe and the AR_PostDelimCRCErr is caught. + * In a way this also gives us a guarantee that when + * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot + * possibly be reviewing the last subframe. AR_CRCErr + * is the CRC of the actual data. + */ if (rxsp->status11 & AR_CRCErr) { rxs->rs_status |= ATH9K_RXERR_CRC; } else if (rxsp->status11 & AR_PHYErr) { - rxs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(rxsp->status11, AR_PHYErrCode); - rxs->rs_phyerr = phyerr; + /* + * If we reach a point here where AR_PostDelimCRCErr is + * true it implies we're *not* on the last subframe. In + * in that case that we know already that the CRC of + * the frame was OK, and MAC would send an ACK for that + * subframe, even if we did get a phy error of type + * ATH9K_PHYERR_OFDM_RESTART. This is only applicable + * to frame that are prior to the last subframe. + * The AR_PostDelimCRCErr is the CRC for the MPDU + * delimiter, which contains the 4 reserved bits, + * the MPDU length (12 bits), and follows the MPDU + * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII). + */ + if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) && + (rxsp->status11 & AR_PostDelimCRCErr)) { + rxs->rs_phyerr = 0; + } else { + rxs->rs_status |= ATH9K_RXERR_PHY; + rxs->rs_phyerr = phyerr; + } + } else if (rxsp->status11 & AR_DecryptCRCErr) { rxs->rs_status |= ATH9K_RXERR_DECRYPT; } else if (rxsp->status11 & AR_MichaelErr) { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index f17558b1453..9f2cea70a84 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h @@ -33,13 +33,14 @@ #define AR_TxDescId_S 16 #define AR_TxPtrChkSum 0x0000ffff -#define AR_TxTid 0xf0000000 -#define AR_TxTid_S 28 - #define AR_LowRxChain 0x00004000 #define AR_Not_Sounding 0x20000000 +/* ctl 12 */ +#define AR_PAPRDChainMask 0x00000e00 +#define AR_PAPRDChainMask_S 9 + #define MAP_ISR_S2_CST 6 #define MAP_ISR_S2_GTT 6 #define MAP_ISR_S2_TIM 3 @@ -47,6 +48,7 @@ #define MAP_ISR_S2_DTIMSYNC 7 #define MAP_ISR_S2_DTIM 7 #define MAP_ISR_S2_TSFOOR 4 +#define MAP_ISR_S2_BB_WATCHDOG 6 #define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c new file mode 100644 index 00000000000..49e0c865ce5 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "hw.h" +#include "ar9003_phy.h" + +void ar9003_paprd_enable(struct ath_hw *ah, bool val) +{ + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); +} +EXPORT_SYMBOL(ar9003_paprd_enable); + +static void ar9003_paprd_setup_single_table(struct ath_hw *ah) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + struct ar9300_modal_eep_header *hdr; + const u32 ctrl0[3] = { + AR_PHY_PAPRD_CTRL0_B0, + AR_PHY_PAPRD_CTRL0_B1, + AR_PHY_PAPRD_CTRL0_B2 + }; + const u32 ctrl1[3] = { + AR_PHY_PAPRD_CTRL1_B0, + AR_PHY_PAPRD_CTRL1_B1, + AR_PHY_PAPRD_CTRL1_B2 + }; + u32 am_mask, ht40_mask; + int i; + + if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) + hdr = &eep->modalHeader5G; + else + hdr = &eep->modalHeader2G; + + am_mask = le32_to_cpu(hdr->papdRateMaskHt20); + ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40); + + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); + + for (i = 0; i < 3; i++) { + REG_RMW_FIELD(ah, ctrl0[i], + AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK, 181); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT, 361); + REG_RMW_FIELD(ah, ctrl1[i], + AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); + REG_RMW_FIELD(ah, ctrl0[i], + AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3); + } + + ar9003_paprd_enable(ah, false); + + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, + AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, + AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, + -15); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, + 100); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 261376); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 248079); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 233759); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 220464); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 208194); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 196949); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 185706); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, + AR_PHY_PAPRD_PRE_POST_SCALING, 175487); +} + +static void ar9003_paprd_get_gain_table(struct ath_hw *ah) +{ + u32 *entry = ah->paprd_gain_table_entries; + u8 *index = ah->paprd_gain_table_index; + u32 reg = AR_PHY_TXGAIN_TABLE; + int i; + + memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); + memset(index, 0, sizeof(ah->paprd_gain_table_index)); + + for (i = 0; i < 32; i++) { + entry[i] = REG_READ(ah, reg); + index[i] = (entry[i] >> 24) & 0xff; + reg += 4; + } +} + +static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, + int target_power) +{ + int olpc_gain_delta = 0; + int alpha_therm, alpha_volt; + int therm_cal_value, volt_cal_value; + int therm_value, volt_value; + int thermal_gain_corr, voltage_gain_corr; + int desired_scale, desired_gain = 0; + u32 reg; + + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); + desired_scale = REG_READ_FIELD(ah, AR_PHY_TPC_12, + AR_PHY_TPC_12_DESIRED_SCALE_HT40_5); + alpha_therm = REG_READ_FIELD(ah, AR_PHY_TPC_19, + AR_PHY_TPC_19_ALPHA_THERM); + alpha_volt = REG_READ_FIELD(ah, AR_PHY_TPC_19, + AR_PHY_TPC_19_ALPHA_VOLT); + therm_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, + AR_PHY_TPC_18_THERM_CAL_VALUE); + volt_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, + AR_PHY_TPC_18_VOLT_CAL_VALUE); + therm_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, + AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE); + volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, + AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE); + + if (chain == 0) + reg = AR_PHY_TPC_11_B0; + else if (chain == 1) + reg = AR_PHY_TPC_11_B1; + else + reg = AR_PHY_TPC_11_B2; + + olpc_gain_delta = REG_READ_FIELD(ah, reg, + AR_PHY_TPC_11_OLPC_GAIN_DELTA); + + if (olpc_gain_delta >= 128) + olpc_gain_delta = olpc_gain_delta - 256; + + thermal_gain_corr = (alpha_therm * (therm_value - therm_cal_value) + + (256 / 2)) / 256; + voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) + + (128 / 2)) / 128; + desired_gain = target_power - olpc_gain_delta - thermal_gain_corr - + voltage_gain_corr + desired_scale; + + return desired_gain; +} + +static void ar9003_tx_force_gain(struct ath_hw *ah, unsigned int gain_index) +{ + int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain; + int padrvgnA, padrvgnB, padrvgnC, padrvgnD; + u32 *gain_table_entries = ah->paprd_gain_table_entries; + + selected_gain_entry = gain_table_entries[gain_index]; + txbb1dbgain = selected_gain_entry & 0x7; + txbb6dbgain = (selected_gain_entry >> 3) & 0x3; + txmxrgain = (selected_gain_entry >> 5) & 0xf; + padrvgnA = (selected_gain_entry >> 9) & 0xf; + padrvgnB = (selected_gain_entry >> 13) & 0xf; + padrvgnC = (selected_gain_entry >> 17) & 0xf; + padrvgnD = (selected_gain_entry >> 21) & 0x3; + + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgnA); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgnB); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgnC); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgnD); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0); + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, + AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0); + REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0); + REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0); +} + +static inline int find_expn(int num) +{ + return fls(num) - 1; +} + +static inline int find_proper_scale(int expn, int N) +{ + return (expn > N) ? expn - 10 : 0; +} + +#define NUM_BIN 23 + +static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain) +{ + unsigned int thresh_accum_cnt; + int x_est[NUM_BIN + 1], Y[NUM_BIN + 1], theta[NUM_BIN + 1]; + int PA_in[NUM_BIN + 1]; + int B1_tmp[NUM_BIN + 1], B2_tmp[NUM_BIN + 1]; + unsigned int B1_abs_max, B2_abs_max; + int max_index, scale_factor; + int y_est[NUM_BIN + 1]; + int x_est_fxp1_nonlin, x_tilde[NUM_BIN + 1]; + unsigned int x_tilde_abs; + int G_fxp, Y_intercept, order_x_by_y, M, I, L, sum_y_sqr, sum_y_quad; + int Q_x, Q_B1, Q_B2, beta_raw, alpha_raw, scale_B; + int Q_scale_B, Q_beta, Q_alpha, alpha, beta, order_1, order_2; + int order1_5x, order2_3x, order1_5x_rem, order2_3x_rem; + int y5, y3, tmp; + int theta_low_bin = 0; + int i; + + /* disregard any bin that contains <= 16 samples */ + thresh_accum_cnt = 16; + scale_factor = 5; + max_index = 0; + memset(theta, 0, sizeof(theta)); + memset(x_est, 0, sizeof(x_est)); + memset(Y, 0, sizeof(Y)); + memset(y_est, 0, sizeof(y_est)); + memset(x_tilde, 0, sizeof(x_tilde)); + + for (i = 0; i < NUM_BIN; i++) { + s32 accum_cnt, accum_tx, accum_rx, accum_ang; + + /* number of samples */ + accum_cnt = data_L[i] & 0xffff; + + if (accum_cnt <= thresh_accum_cnt) + continue; + + /* sum(tx amplitude) */ + accum_tx = ((data_L[i] >> 16) & 0xffff) | + ((data_U[i] & 0x7ff) << 16); + + /* sum(rx amplitude distance to lower bin edge) */ + accum_rx = ((data_U[i] >> 11) & 0x1f) | + ((data_L[i + 23] & 0xffff) << 5); + + /* sum(angles) */ + accum_ang = ((data_L[i + 23] >> 16) & 0xffff) | + ((data_U[i + 23] & 0x7ff) << 16); + + accum_tx <<= scale_factor; + accum_rx <<= scale_factor; + x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >> + scale_factor; + + Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >> + scale_factor) + + (1 << scale_factor) * max_index + 16; + + if (accum_ang >= (1 << 26)) + accum_ang -= 1 << 27; + + theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) / + accum_cnt; + + max_index++; + } + + /* + * Find average theta of first 5 bin and all of those to same value. + * Curve is linear at that range. + */ + for (i = 1; i < 6; i++) + theta_low_bin += theta[i]; + + theta_low_bin = theta_low_bin / 5; + for (i = 1; i < 6; i++) + theta[i] = theta_low_bin; + + /* Set values at origin */ + theta[0] = theta_low_bin; + for (i = 0; i <= max_index; i++) + theta[i] -= theta_low_bin; + + x_est[0] = 0; + Y[0] = 0; + scale_factor = 8; + + /* low signal gain */ + if (x_est[6] == x_est[3]) + return false; + + G_fxp = + (((Y[6] - Y[3]) * 1 << scale_factor) + + (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]); + + Y_intercept = + (G_fxp * (x_est[0] - x_est[3]) + + (1 << scale_factor)) / (1 << scale_factor) + Y[3]; + + for (i = 0; i <= max_index; i++) + y_est[i] = Y[i] - Y_intercept; + + for (i = 0; i <= 3; i++) { + y_est[i] = i * 32; + + /* prevent division by zero */ + if (G_fxp == 0) + return false; + + x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp; + } + + x_est_fxp1_nonlin = + x_est[max_index] - ((1 << scale_factor) * y_est[max_index] + + G_fxp) / G_fxp; + + order_x_by_y = + (x_est_fxp1_nonlin + y_est[max_index]) / y_est[max_index]; + + if (order_x_by_y == 0) + M = 10; + else if (order_x_by_y == 1) + M = 9; + else + M = 8; + + I = (max_index > 15) ? 7 : max_index >> 1; + L = max_index - I; + scale_factor = 8; + sum_y_sqr = 0; + sum_y_quad = 0; + x_tilde_abs = 0; + + for (i = 0; i <= L; i++) { + unsigned int y_sqr; + unsigned int y_quad; + unsigned int tmp_abs; + + /* prevent division by zero */ + if (y_est[i + I] == 0) + return false; + + x_est_fxp1_nonlin = + x_est[i + I] - ((1 << scale_factor) * y_est[i + I] + + G_fxp) / G_fxp; + + x_tilde[i] = + (x_est_fxp1_nonlin * (1 << M) + y_est[i + I]) / y_est[i + + I]; + x_tilde[i] = + (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; + x_tilde[i] = + (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; + y_sqr = + (y_est[i + I] * y_est[i + I] + + (scale_factor * scale_factor)) / (scale_factor * + scale_factor); + tmp_abs = abs(x_tilde[i]); + if (tmp_abs > x_tilde_abs) + x_tilde_abs = tmp_abs; + + y_quad = y_sqr * y_sqr; + sum_y_sqr = sum_y_sqr + y_sqr; + sum_y_quad = sum_y_quad + y_quad; + B1_tmp[i] = y_sqr * (L + 1); + B2_tmp[i] = y_sqr; + } + + B1_abs_max = 0; + B2_abs_max = 0; + for (i = 0; i <= L; i++) { + int abs_val; + + B1_tmp[i] -= sum_y_sqr; + B2_tmp[i] = sum_y_quad - sum_y_sqr * B2_tmp[i]; + + abs_val = abs(B1_tmp[i]); + if (abs_val > B1_abs_max) + B1_abs_max = abs_val; + + abs_val = abs(B2_tmp[i]); + if (abs_val > B2_abs_max) + B2_abs_max = abs_val; + } + + Q_x = find_proper_scale(find_expn(x_tilde_abs), 10); + Q_B1 = find_proper_scale(find_expn(B1_abs_max), 10); + Q_B2 = find_proper_scale(find_expn(B2_abs_max), 10); + + beta_raw = 0; + alpha_raw = 0; + for (i = 0; i <= L; i++) { + x_tilde[i] = x_tilde[i] / (1 << Q_x); + B1_tmp[i] = B1_tmp[i] / (1 << Q_B1); + B2_tmp[i] = B2_tmp[i] / (1 << Q_B2); + beta_raw = beta_raw + B1_tmp[i] * x_tilde[i]; + alpha_raw = alpha_raw + B2_tmp[i] * x_tilde[i]; + } + + scale_B = + ((sum_y_quad / scale_factor) * (L + 1) - + (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor; + + Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10); + scale_B = scale_B / (1 << Q_scale_B); + Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); + Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); + beta_raw = beta_raw / (1 << Q_beta); + alpha_raw = alpha_raw / (1 << Q_alpha); + alpha = (alpha_raw << 10) / scale_B; + beta = (beta_raw << 10) / scale_B; + order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B; + order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B; + order1_5x = order_1 / 5; + order2_3x = order_2 / 3; + order1_5x_rem = order_1 - 5 * order1_5x; + order2_3x_rem = order_2 - 3 * order2_3x; + + for (i = 0; i < PAPRD_TABLE_SZ; i++) { + tmp = i * 32; + y5 = ((beta * tmp) >> 6) >> order1_5x; + y5 = (y5 * tmp) >> order1_5x; + y5 = (y5 * tmp) >> order1_5x; + y5 = (y5 * tmp) >> order1_5x; + y5 = (y5 * tmp) >> order1_5x; + y5 = y5 >> order1_5x_rem; + y3 = (alpha * tmp) >> order2_3x; + y3 = (y3 * tmp) >> order2_3x; + y3 = (y3 * tmp) >> order2_3x; + y3 = y3 >> order2_3x_rem; + PA_in[i] = y5 + y3 + (256 * tmp) / G_fxp; + + if (i >= 2) { + tmp = PA_in[i] - PA_in[i - 1]; + if (tmp < 0) + PA_in[i] = + PA_in[i - 1] + (PA_in[i - 1] - + PA_in[i - 2]); + } + + PA_in[i] = (PA_in[i] < 1400) ? PA_in[i] : 1400; + } + + beta_raw = 0; + alpha_raw = 0; + + for (i = 0; i <= L; i++) { + int theta_tilde = + ((theta[i + I] << M) + y_est[i + I]) / y_est[i + I]; + theta_tilde = + ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; + theta_tilde = + ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; + beta_raw = beta_raw + B1_tmp[i] * theta_tilde; + alpha_raw = alpha_raw + B2_tmp[i] * theta_tilde; + } + + Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); + Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); + beta_raw = beta_raw / (1 << Q_beta); + alpha_raw = alpha_raw / (1 << Q_alpha); + + alpha = (alpha_raw << 10) / scale_B; + beta = (beta_raw << 10) / scale_B; + order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B + 5; + order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B + 5; + order1_5x = order_1 / 5; + order2_3x = order_2 / 3; + order1_5x_rem = order_1 - 5 * order1_5x; + order2_3x_rem = order_2 - 3 * order2_3x; + + for (i = 0; i < PAPRD_TABLE_SZ; i++) { + int PA_angle; + + /* pa_table[4] is calculated from PA_angle for i=5 */ + if (i == 4) + continue; + + tmp = i * 32; + if (beta > 0) + y5 = (((beta * tmp - 64) >> 6) - + (1 << order1_5x)) / (1 << order1_5x); + else + y5 = ((((beta * tmp - 64) >> 6) + + (1 << order1_5x)) / (1 << order1_5x)); + + y5 = (y5 * tmp) / (1 << order1_5x); + y5 = (y5 * tmp) / (1 << order1_5x); + y5 = (y5 * tmp) / (1 << order1_5x); + y5 = (y5 * tmp) / (1 << order1_5x); + y5 = y5 / (1 << order1_5x_rem); + + if (beta > 0) + y3 = (alpha * tmp - + (1 << order2_3x)) / (1 << order2_3x); + else + y3 = (alpha * tmp + + (1 << order2_3x)) / (1 << order2_3x); + y3 = (y3 * tmp) / (1 << order2_3x); + y3 = (y3 * tmp) / (1 << order2_3x); + y3 = y3 / (1 << order2_3x_rem); + + if (i < 4) { + PA_angle = 0; + } else { + PA_angle = y5 + y3; + if (PA_angle < -150) + PA_angle = -150; + else if (PA_angle > 150) + PA_angle = 150; + } + + pa_table[i] = ((PA_in[i] & 0x7ff) << 11) + (PA_angle & 0x7ff); + if (i == 5) { + PA_angle = (PA_angle + 2) >> 1; + pa_table[i - 1] = ((PA_in[i - 1] & 0x7ff) << 11) + + (PA_angle & 0x7ff); + } + } + + *gain = G_fxp; + return true; +} + +void ar9003_paprd_populate_single_table(struct ath_hw *ah, + struct ath9k_channel *chan, int chain) +{ + u32 *paprd_table_val = chan->pa_table[chain]; + u32 small_signal_gain = chan->small_signal_gain[chain]; + u32 training_power; + u32 reg = 0; + int i; + + training_power = + REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, + AR_PHY_POWERTX_RATE5_POWERTXHT20_0); + training_power -= 4; + + if (chain == 0) + reg = AR_PHY_PAPRD_MEM_TAB_B0; + else if (chain == 1) + reg = AR_PHY_PAPRD_MEM_TAB_B1; + else if (chain == 2) + reg = AR_PHY_PAPRD_MEM_TAB_B2; + + for (i = 0; i < PAPRD_TABLE_SZ; i++) { + REG_WRITE(ah, reg, paprd_table_val[i]); + reg = reg + 4; + } + + if (chain == 0) + reg = AR_PHY_PA_GAIN123_B0; + else if (chain == 1) + reg = AR_PHY_PA_GAIN123_B1; + else + reg = AR_PHY_PA_GAIN123_B2; + + REG_RMW_FIELD(ah, reg, AR_PHY_PA_GAIN123_PA_GAIN1, small_signal_gain); + + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B0, + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, + training_power); + + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1, + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, + training_power); + + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, + training_power); +} +EXPORT_SYMBOL(ar9003_paprd_populate_single_table); + +int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) +{ + + unsigned int i, desired_gain, gain_index; + unsigned int train_power; + + train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, + AR_PHY_POWERTX_RATE5_POWERTXHT20_0); + + train_power = train_power - 4; + + desired_gain = ar9003_get_desired_gain(ah, chain, train_power); + + gain_index = 0; + for (i = 0; i < 32; i++) { + if (ah->paprd_gain_table_index[i] >= desired_gain) + break; + gain_index++; + } + + ar9003_tx_force_gain(ah, gain_index); + + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); + + return 0; +} +EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); + +int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, + int chain) +{ + u16 *small_signal_gain = &chan->small_signal_gain[chain]; + u32 *pa_table = chan->pa_table[chain]; + u32 *data_L, *data_U; + int i, status = 0; + u32 *buf; + u32 reg; + + memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain])); + + buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); + if (!buf) + return -ENOMEM; + + data_L = &buf[0]; + data_U = &buf[48]; + + REG_CLR_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); + + reg = AR_PHY_CHAN_INFO_TAB_0; + for (i = 0; i < 48; i++) + data_L[i] = REG_READ(ah, reg + (i << 2)); + + REG_SET_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, + AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); + + for (i = 0; i < 48; i++) + data_U[i] = REG_READ(ah, reg + (i << 2)); + + if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) + status = -2; + + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); + + kfree(buf); + + return status; +} +EXPORT_SYMBOL(ar9003_paprd_create_curve); + +int ar9003_paprd_init_table(struct ath_hw *ah) +{ + ar9003_paprd_setup_single_table(ah); + ar9003_paprd_get_gain_table(ah); + return 0; +} +EXPORT_SYMBOL(ar9003_paprd_init_table); + +bool ar9003_paprd_is_done(struct ath_hw *ah) +{ + return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); +} +EXPORT_SYMBOL(ar9003_paprd_is_done); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 80431a2f6dc..a753a431bb1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -17,6 +17,28 @@ #include "hw.h" #include "ar9003_phy.h" +static const int firstep_table[] = +/* level: 0 1 2 3 4 5 6 7 8 */ + { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ + +static const int cycpwrThr1_table[] = +/* level: 0 1 2 3 4 5 6 7 8 */ + { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ + +/* + * register values to turn OFDM weak signal detection OFF + */ +static const int m1ThreshLow_off = 127; +static const int m2ThreshLow_off = 127; +static const int m1Thresh_off = 127; +static const int m2Thresh_off = 127; +static const int m2CountThr_off = 31; +static const int m2CountThrLow_off = 63; +static const int m1ThreshLowExt_off = 127; +static const int m2ThreshLowExt_off = 127; +static const int m1ThreshExt_off = 127; +static const int m2ThreshExt_off = 127; + /** * ar9003_hw_set_channel - set channel on single-chip device * @ah: atheros hardware structure @@ -94,7 +116,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) } /** - * ar9003_hw_spur_mitigate - convert baseband spur frequency + * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency * @ah: atheros hardware structure * @chan: * @@ -521,15 +543,6 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah, u32 val = INI_RA(iniArr, i, column); REG_WRITE(ah, reg, val); - - /* - * Determine if this is a shift register value, and insert the - * configured delay if so. - */ - if (reg >= 0x16000 && reg < 0x17000 - && ah->config.analog_shiftreg) - udelay(100); - DO_DELAY(regWrites); } } @@ -732,71 +745,68 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, { struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; + s32 value, value2; switch (cmd & ah->ani_function) { - case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ - u32 level = param; - - if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { - ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", - level, - (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); - return false; - } - - REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, - AR_PHY_DESIRED_SZ_TOT_DES, - ah->totalSizeDesired[level]); - REG_RMW_FIELD(ah, AR_PHY_AGC, - AR_PHY_AGC_COARSE_LOW, - ah->coarse_low[level]); - REG_RMW_FIELD(ah, AR_PHY_AGC, - AR_PHY_AGC_COARSE_HIGH, - ah->coarse_high[level]); - REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, - AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]); - - if (level > aniState->noiseImmunityLevel) - ah->stats.ast_ani_niup++; - else if (level < aniState->noiseImmunityLevel) - ah->stats.ast_ani_nidown++; - aniState->noiseImmunityLevel = level; - break; - } case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ - const int m1ThreshLow[] = { 127, 50 }; - const int m2ThreshLow[] = { 127, 40 }; - const int m1Thresh[] = { 127, 0x4d }; - const int m2Thresh[] = { 127, 0x40 }; - const int m2CountThr[] = { 31, 16 }; - const int m2CountThrLow[] = { 63, 48 }; + /* + * on == 1 means ofdm weak signal detection is ON + * on == 1 is the default, for less noise immunity + * + * on == 0 means ofdm weak signal detection is OFF + * on == 0 means more noise imm + */ u32 on = param ? 1 : 0; + /* + * make register setting for default + * (weak sig detect ON) come from INI file + */ + int m1ThreshLow = on ? + aniState->iniDef.m1ThreshLow : m1ThreshLow_off; + int m2ThreshLow = on ? + aniState->iniDef.m2ThreshLow : m2ThreshLow_off; + int m1Thresh = on ? + aniState->iniDef.m1Thresh : m1Thresh_off; + int m2Thresh = on ? + aniState->iniDef.m2Thresh : m2Thresh_off; + int m2CountThr = on ? + aniState->iniDef.m2CountThr : m2CountThr_off; + int m2CountThrLow = on ? + aniState->iniDef.m2CountThrLow : m2CountThrLow_off; + int m1ThreshLowExt = on ? + aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; + int m2ThreshLowExt = on ? + aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; + int m1ThreshExt = on ? + aniState->iniDef.m1ThreshExt : m1ThreshExt_off; + int m2ThreshExt = on ? + aniState->iniDef.m2ThreshExt : m2ThreshExt_off; REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M1_THRESH_LOW, - m1ThreshLow[on]); + m1ThreshLow); REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2_THRESH_LOW, - m2ThreshLow[on]); + m2ThreshLow); REG_RMW_FIELD(ah, AR_PHY_SFCORR, - AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); + AR_PHY_SFCORR_M1_THRESH, m1Thresh); REG_RMW_FIELD(ah, AR_PHY_SFCORR, - AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); + AR_PHY_SFCORR_M2_THRESH, m2Thresh); REG_RMW_FIELD(ah, AR_PHY_SFCORR, - AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); + AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, - m2CountThrLow[on]); + m2CountThrLow); REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, - AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); + AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, - AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); + AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, - AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); + AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, - AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); + AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); if (on) REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, @@ -806,6 +816,12 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); if (!on != aniState->ofdmWeakSigDetectOff) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: ofdm weak signal: %s=>%s\n", + chan->channel, + !aniState->ofdmWeakSigDetectOff ? + "on" : "off", + on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else @@ -814,64 +830,167 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, } break; } - case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ - const int weakSigThrCck[] = { 8, 6 }; - u32 high = param ? 1 : 0; - - REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, - AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, - weakSigThrCck[high]); - if (high != aniState->cckWeakSigThreshold) { - if (high) - ah->stats.ast_ani_cckhigh++; - else - ah->stats.ast_ani_ccklow++; - aniState->cckWeakSigThreshold = high; - } - break; - } case ATH9K_ANI_FIRSTEP_LEVEL:{ - const int firstep[] = { 0, 4, 8 }; u32 level = param; - if (level >= ARRAY_SIZE(firstep)) { + if (level >= ARRAY_SIZE(firstep_table)) { ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", + "ATH9K_ANI_FIRSTEP_LEVEL: level " + "out of range (%u > %u)\n", level, - (unsigned) ARRAY_SIZE(firstep)); + (unsigned) ARRAY_SIZE(firstep_table)); return false; } + + /* + * make register setting relative to default + * from INI file & cap value + */ + value = firstep_table[level] - + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + aniState->iniDef.firstep; + if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) + value = ATH9K_SIG_FIRSTEP_SETTING_MIN; + if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) + value = ATH9K_SIG_FIRSTEP_SETTING_MAX; REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, - firstep[level]); - if (level > aniState->firstepLevel) - ah->stats.ast_ani_stepup++; - else if (level < aniState->firstepLevel) - ah->stats.ast_ani_stepdown++; - aniState->firstepLevel = level; + value); + /* + * we need to set first step low register too + * make register setting relative to default + * from INI file & cap value + */ + value2 = firstep_table[level] - + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + + aniState->iniDef.firstepLow; + if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) + value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; + if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) + value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; + + REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, + AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2); + + if (level != aniState->firstepLevel) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "firstep[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value, + aniState->iniDef.firstep); + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "firstep_low[level]=%d ini=%d\n", + chan->channel, + aniState->firstepLevel, + level, + ATH9K_ANI_FIRSTEP_LVL_NEW, + value2, + aniState->iniDef.firstepLow); + if (level > aniState->firstepLevel) + ah->stats.ast_ani_stepup++; + else if (level < aniState->firstepLevel) + ah->stats.ast_ani_stepdown++; + aniState->firstepLevel = level; + } break; } case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ - const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; u32 level = param; - if (level >= ARRAY_SIZE(cycpwrThr1)) { + if (level >= ARRAY_SIZE(cycpwrThr1_table)) { ath_print(common, ATH_DBG_ANI, - "level out of range (%u > %u)\n", + "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " + "out of range (%u > %u)\n", level, - (unsigned) ARRAY_SIZE(cycpwrThr1)); + (unsigned) ARRAY_SIZE(cycpwrThr1_table)); return false; } + /* + * make register setting relative to default + * from INI file & cap value + */ + value = cycpwrThr1_table[level] - + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + aniState->iniDef.cycpwrThr1; + if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) + value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; + if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) + value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, - cycpwrThr1[level]); - if (level > aniState->spurImmunityLevel) - ah->stats.ast_ani_spurup++; - else if (level < aniState->spurImmunityLevel) - ah->stats.ast_ani_spurdown++; - aniState->spurImmunityLevel = level; + value); + + /* + * set AR_PHY_EXT_CCA for extension channel + * make register setting relative to default + * from INI file & cap value + */ + value2 = cycpwrThr1_table[level] - + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + + aniState->iniDef.cycpwrThr1Ext; + if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) + value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; + if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) + value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; + REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, + AR_PHY_EXT_CYCPWR_THR1, value2); + + if (level != aniState->spurImmunityLevel) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "cycpwrThr1[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value, + aniState->iniDef.cycpwrThr1); + ath_print(common, ATH_DBG_ANI, + "** ch %d: level %d=>%d[def:%d] " + "cycpwrThr1Ext[level]=%d ini=%d\n", + chan->channel, + aniState->spurImmunityLevel, + level, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, + value2, + aniState->iniDef.cycpwrThr1Ext); + if (level > aniState->spurImmunityLevel) + ah->stats.ast_ani_spurup++; + else if (level < aniState->spurImmunityLevel) + ah->stats.ast_ani_spurdown++; + aniState->spurImmunityLevel = level; + } break; } + case ATH9K_ANI_MRC_CCK:{ + /* + * is_on == 1 means MRC CCK ON (default, less noise imm) + * is_on == 0 means MRC CCK is OFF (more noise imm) + */ + bool is_on = param ? 1 : 0; + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_ENABLE, is_on); + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_MUX_REG, is_on); + if (!is_on != aniState->mrcCCKOff) { + ath_print(common, ATH_DBG_ANI, + "** ch %d: MRC CCK: %s=>%s\n", + chan->channel, + !aniState->mrcCCKOff ? "on" : "off", + is_on ? "on" : "off"); + if (is_on) + ah->stats.ast_ani_ccklow++; + else + ah->stats.ast_ani_cckhigh++; + aniState->mrcCCKOff = !is_on; + } + break; + } case ATH9K_ANI_PRESENT: break; default: @@ -880,158 +999,126 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, return false; } - ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); ath_print(common, ATH_DBG_ANI, - "noiseImmunityLevel=%d, spurImmunityLevel=%d, " - "ofdmWeakSigDetectOff=%d\n", - aniState->noiseImmunityLevel, + "ANI parameters: SI=%d, ofdmWS=%s FS=%d " + "MRCcck=%s listenTime=%d CC=%d listen=%d " + "ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, - !aniState->ofdmWeakSigDetectOff); - ath_print(common, ATH_DBG_ANI, - "cckWeakSigThreshold=%d, " - "firstepLevel=%d, listenTime=%d\n", - aniState->cckWeakSigThreshold, + !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, - aniState->listenTime); - ath_print(common, ATH_DBG_ANI, - "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", - aniState->cycleCount, - aniState->ofdmPhyErrCount, - aniState->cckPhyErrCount); - + !aniState->mrcCCKOff ? "on" : "off", + aniState->listenTime, + aniState->cycleCount, + aniState->listenTime, + aniState->ofdmPhyErrCount, + aniState->cckPhyErrCount); return true; } -static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (*nf > ah->nf_2g_max) { - ath_print(common, ATH_DBG_CALIBRATE, - "2 GHz NF (%d) > MAX (%d), " - "correcting to MAX", - *nf, ah->nf_2g_max); - *nf = ah->nf_2g_max; - } else if (*nf < ah->nf_2g_min) { - ath_print(common, ATH_DBG_CALIBRATE, - "2 GHz NF (%d) < MIN (%d), " - "correcting to MIN", - *nf, ah->nf_2g_min); - *nf = ah->nf_2g_min; - } -} - -static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (*nf > ah->nf_5g_max) { - ath_print(common, ATH_DBG_CALIBRATE, - "5 GHz NF (%d) > MAX (%d), " - "correcting to MAX", - *nf, ah->nf_5g_max); - *nf = ah->nf_5g_max; - } else if (*nf < ah->nf_5g_min) { - ath_print(common, ATH_DBG_CALIBRATE, - "5 GHz NF (%d) < MIN (%d), " - "correcting to MIN", - *nf, ah->nf_5g_min); - *nf = ah->nf_5g_min; - } -} - -static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) -{ - if (IS_CHAN_2GHZ(ah->curchan)) - ar9003_hw_nf_sanitize_2g(ah, nf); - else - ar9003_hw_nf_sanitize_5g(ah, nf); -} - static void ar9003_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { - struct ath_common *common = ath9k_hw_common(ah); int16_t nf; nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 0] is %d\n", nf); - nfarray[0] = nf; + nfarray[0] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 1] is %d\n", nf); - nfarray[1] = nf; + nfarray[1] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ctl] [chain 2] is %d\n", nf); - nfarray[2] = nf; + nfarray[2] = sign_extend(nf, 9); + + if (!IS_CHAN_HT40(ah->curchan)) + return; nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 0] is %d\n", nf); - nfarray[3] = nf; + nfarray[3] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 1] is %d\n", nf); - nfarray[4] = nf; + nfarray[4] = sign_extend(nf, 9); nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); - if (nf & 0x100) - nf = 0 - ((nf ^ 0x1ff) + 1); - ar9003_hw_nf_sanitize(ah, &nf); - ath_print(common, ATH_DBG_CALIBRATE, - "NF calibrated [ext] [chain 2] is %d\n", nf); - nfarray[5] = nf; + nfarray[5] = sign_extend(nf, 9); } -void ar9003_hw_set_nf_limits(struct ath_hw *ah) +static void ar9003_hw_set_nf_limits(struct ath_hw *ah) { - ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; - ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; - ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; - ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; + ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; + ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; + ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; + ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; } /* - * Find out which of the RX chains are enabled + * Initialize the ANI register values with default (ini) values. + * This routine is called during a (full) hardware reset after + * all the registers are initialised from the INI. */ -static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah) +static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) { - u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK); - /* - * The bits [2:0] indicate the rx chain mask and are to be - * interpreted as follows: - * 00x => Only chain 0 is enabled - * 01x => Chain 1 and 0 enabled - * 1xx => Chain 2,1 and 0 enabled - */ - return chain & 0x7; + struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; + struct ath9k_ani_default *iniDef; + int index; + u32 val; + + index = ath9k_hw_get_ani_channel_idx(ah, chan); + aniState = &ah->ani[index]; + ah->curani = aniState; + iniDef = &aniState->iniDef; + + ath_print(common, ATH_DBG_ANI, + "ver %d.%d opmode %u chan %d Mhz/0x%x\n", + ah->hw_version.macVersion, + ah->hw_version.macRev, + ah->opmode, + chan->channel, + chan->channelFlags); + + val = REG_READ(ah, AR_PHY_SFCORR); + iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); + iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH); + iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR); + + val = REG_READ(ah, AR_PHY_SFCORR_LOW); + iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW); + iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW); + iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); + + val = REG_READ(ah, AR_PHY_SFCORR_EXT); + iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH); + iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH); + iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW); + iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW); + iniDef->firstep = REG_READ_FIELD(ah, + AR_PHY_FIND_SIG, + AR_PHY_FIND_SIG_FIRSTEP); + iniDef->firstepLow = REG_READ_FIELD(ah, + AR_PHY_FIND_SIG_LOW, + AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW); + iniDef->cycpwrThr1 = REG_READ_FIELD(ah, + AR_PHY_TIMING5, + AR_PHY_TIMING5_CYCPWR_THR1); + iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah, + AR_PHY_EXT_CCA, + AR_PHY_EXT_CYCPWR_THR1); + + /* these levels just got reset to defaults by the INI */ + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; + + aniState->cycleCount = 0; } -static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) +void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { - struct ath9k_nfcal_hist *h; - unsigned i, j; - int32_t val; + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); const u32 ar9300_cca_regs[6] = { AR_PHY_CCA_0, AR_PHY_CCA_1, @@ -1040,95 +1127,143 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) AR_PHY_EXT_CCA_1, AR_PHY_EXT_CCA_2, }; - u8 chainmask, rx_chain_status; - struct ath_common *common = ath9k_hw_common(ah); - rx_chain_status = ar9003_hw_get_rx_chainmask(ah); + priv_ops->rf_set_freq = ar9003_hw_set_channel; + priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; + priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; + priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; + priv_ops->init_bb = ar9003_hw_init_bb; + priv_ops->process_ini = ar9003_hw_process_ini; + priv_ops->set_rfmode = ar9003_hw_set_rfmode; + priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive; + priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; + priv_ops->rfbus_req = ar9003_hw_rfbus_req; + priv_ops->rfbus_done = ar9003_hw_rfbus_done; + priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; + priv_ops->set_diversity = ar9003_hw_set_diversity; + priv_ops->ani_control = ar9003_hw_ani_control; + priv_ops->do_getnf = ar9003_hw_do_getnf; + priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; - chainmask = 0x3F; - h = ah->nfCalHist; + ar9003_hw_set_nf_limits(ah); + memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); +} - for (i = 0; i < NUM_NF_READINGS; i++) { - if (chainmask & (1 << i)) { - val = REG_READ(ah, ar9300_cca_regs[i]); - val &= 0xFFFFFE00; - val |= (((u32) (h[i].privNF) << 1) & 0x1ff); - REG_WRITE(ah, ar9300_cca_regs[i], val); - } +void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + u32 idle_tmo_ms = ah->bb_watchdog_timeout_ms; + u32 val, idle_count; + + if (!idle_tmo_ms) { + /* disable IRQ, disable chip-reset for BB panic */ + REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2, + REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & + ~(AR_PHY_WATCHDOG_RST_ENABLE | + AR_PHY_WATCHDOG_IRQ_ENABLE)); + + /* disable watchdog in non-IDLE mode, disable in IDLE mode */ + REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1, + REG_READ(ah, AR_PHY_WATCHDOG_CTL_1) & + ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE | + AR_PHY_WATCHDOG_IDLE_ENABLE)); + + ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n"); + return; } + /* enable IRQ, disable chip-reset for BB watchdog */ + val = REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & AR_PHY_WATCHDOG_CNTL2_MASK; + REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2, + (val | AR_PHY_WATCHDOG_IRQ_ENABLE) & + ~AR_PHY_WATCHDOG_RST_ENABLE); + + /* bound limit to 10 secs */ + if (idle_tmo_ms > 10000) + idle_tmo_ms = 10000; + /* - * Load software filtered NF value into baseband internal minCCApwr - * variable. + * The time unit for watchdog event is 2^15 44/88MHz cycles. + * + * For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick + * For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick + * + * Given we use fast clock now in 5 GHz, these time units should + * be common for both 2 GHz and 5 GHz. */ - REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, - AR_PHY_AGC_CONTROL_ENABLE_NF); - REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, - AR_PHY_AGC_CONTROL_NO_UPDATE_NF); - REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + idle_count = (100 * idle_tmo_ms) / 74; + if (ah->curchan && IS_CHAN_HT40(ah->curchan)) + idle_count = (100 * idle_tmo_ms) / 37; /* - * Wait for load to complete, should be fast, a few 10s of us. - * The max delay was changed from an original 250us to 10000us - * since 250us often results in NF load timeout and causes deaf - * condition during stress testing 12/12/2009 + * enable watchdog in non-IDLE mode, disable in IDLE mode, + * set idle time-out. */ - for (j = 0; j < 1000; j++) { - if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & - AR_PHY_AGC_CONTROL_NF) == 0) - break; - udelay(10); - } + REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1, + AR_PHY_WATCHDOG_NON_IDLE_ENABLE | + AR_PHY_WATCHDOG_IDLE_MASK | + (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2))); + + ath_print(common, ATH_DBG_RESET, + "Enabled BB Watchdog timeout (%u ms)\n", + idle_tmo_ms); +} +void ar9003_hw_bb_watchdog_read(struct ath_hw *ah) +{ /* - * We timed out waiting for the noisefloor to load, probably due to an - * in-progress rx. Simply return here and allow the load plenty of time - * to complete before the next calibration interval. We need to avoid - * trying to load -50 (which happens below) while the previous load is - * still in progress as this can cause rx deafness. Instead by returning - * here, the baseband nf cal will just be capped by our present - * noisefloor until the next calibration timer. + * we want to avoid printing in ISR context so we save the + * watchdog status to be printed later in bottom half context. */ - if (j == 1000) { - ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " - "to load: AR_PHY_AGC_CONTROL=0x%x\n", - REG_READ(ah, AR_PHY_AGC_CONTROL)); - return; - } + ah->bb_watchdog_last_status = REG_READ(ah, AR_PHY_WATCHDOG_STATUS); /* - * Restore maxCCAPower register parameter again so that we're not capped - * by the median we just loaded. This will be initial (and max) value - * of next noise floor calibration the baseband does. + * the watchdog timer should reset on status read but to be sure + * sure we write 0 to the watchdog status bit. */ - for (i = 0; i < NUM_NF_READINGS; i++) { - if (chainmask & (1 << i)) { - val = REG_READ(ah, ar9300_cca_regs[i]); - val &= 0xFFFFFE00; - val |= (((u32) (-50) << 1) & 0x1ff); - REG_WRITE(ah, ar9300_cca_regs[i], val); - } - } + REG_WRITE(ah, AR_PHY_WATCHDOG_STATUS, + ah->bb_watchdog_last_status & ~AR_PHY_WATCHDOG_STATUS_CLR); } -void ar9003_hw_attach_phy_ops(struct ath_hw *ah) +void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) { - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + struct ath_common *common = ath9k_hw_common(ah); + u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status; - priv_ops->rf_set_freq = ar9003_hw_set_channel; - priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; - priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; - priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; - priv_ops->init_bb = ar9003_hw_init_bb; - priv_ops->process_ini = ar9003_hw_process_ini; - priv_ops->set_rfmode = ar9003_hw_set_rfmode; - priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive; - priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; - priv_ops->rfbus_req = ar9003_hw_rfbus_req; - priv_ops->rfbus_done = ar9003_hw_rfbus_done; - priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; - priv_ops->set_diversity = ar9003_hw_set_diversity; - priv_ops->ani_control = ar9003_hw_ani_control; - priv_ops->do_getnf = ar9003_hw_do_getnf; - priv_ops->loadnf = ar9003_hw_loadnf; + if (likely(!(common->debug_mask & ATH_DBG_RESET))) + return; + + status = ah->bb_watchdog_last_status; + ath_print(common, ATH_DBG_RESET, + "\n==== BB update: BB status=0x%08x ====\n", status); + ath_print(common, ATH_DBG_RESET, + "** BB state: wd=%u det=%u rdar=%u rOFDM=%d " + "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", + MS(status, AR_PHY_WATCHDOG_INFO), + MS(status, AR_PHY_WATCHDOG_DET_HANG), + MS(status, AR_PHY_WATCHDOG_RADAR_SM), + MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM), + MS(status, AR_PHY_WATCHDOG_RX_CCK_SM), + MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM), + MS(status, AR_PHY_WATCHDOG_TX_CCK_SM), + MS(status, AR_PHY_WATCHDOG_AGC_SM), + MS(status,AR_PHY_WATCHDOG_SRCH_SM)); + + ath_print(common, ATH_DBG_RESET, + "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", + REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), + REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); + ath_print(common, ATH_DBG_RESET, + "** BB mode: BB_gen_controls=0x%08x **\n", + REG_READ(ah, AR_PHY_GEN_CTRL)); + + if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt)) + ath_print(common, ATH_DBG_RESET, + "** BB busy times: rx_clear=%d%%, " + "rx_frame=%d%%, tx_frame=%d%% **\n", + rxc_pcnt, rxf_pcnt, txf_pcnt); + + ath_print(common, ATH_DBG_RESET, + "==== BB update: done ====\n\n"); } +EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index f08cc8bda00..3394dfe52b4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -149,6 +149,8 @@ #define AR_PHY_EXT_CCA_THRESH62_S 16 #define AR_PHY_EXT_MINCCA_PWR 0x01FF0000 #define AR_PHY_EXT_MINCCA_PWR_S 16 +#define AR_PHY_EXT_CYCPWR_THR1 0x0000FE00L +#define AR_PHY_EXT_CYCPWR_THR1_S 9 #define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE #define AR_PHY_TIMING5_CYCPWR_THR1_S 1 #define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001 @@ -283,6 +285,12 @@ #define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00 #define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9 +#define AR_PHY_MRC_CCK_CTRL (AR_AGC_BASE + 0x1d0) +#define AR_PHY_MRC_CCK_ENABLE 0x00000001 +#define AR_PHY_MRC_CCK_ENABLE_S 0 +#define AR_PHY_MRC_CCK_MUX_REG 0x00000002 +#define AR_PHY_MRC_CCK_MUX_REG_S 1 + #define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) #define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110 @@ -451,7 +459,11 @@ #define AR_PHY_TSTDAC (AR_SM_BASE + 0x168) #define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) -#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) + +#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) +#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008 +#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3 + #define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174) #define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178) #define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c) @@ -467,30 +479,86 @@ #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) -#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) -#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) -#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) -#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) -#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) -#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) +#define AR_PHY_TPC_1 (AR_SM_BASE + 0x1f8) +#define AR_PHY_TPC_1_FORCED_DAC_GAIN 0x0000003e +#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1 +#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001 +#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S 0 + +#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) +#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) +#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) + +#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) +#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) +#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) +#define AR_PHY_TPC_11_OLPC_GAIN_DELTA 0x00ff0000 +#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16 + +#define AR_PHY_TPC_12 (AR_SM_BASE + 0x224) +#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5 0x3e000000 +#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25 + +#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) +#define AR_PHY_TPC_18_THERM_CAL_VALUE 0x000000ff +#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 +#define AR_PHY_TPC_18_VOLT_CAL_VALUE 0x0000ff00 +#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S 8 + +#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) +#define AR_PHY_TPC_19_ALPHA_VOLT 0x001f0000 +#define AR_PHY_TPC_19_ALPHA_VOLT_S 16 +#define AR_PHY_TPC_19_ALPHA_THERM 0xff +#define AR_PHY_TPC_19_ALPHA_THERM_S 0 + +#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) +#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001 +#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S 0 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN 0x0000000e +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S 1 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN 0x00000030 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S 4 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN 0x000003c0 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S 6 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA 0x00003c00 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S 10 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB 0x0003c000 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S 14 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC 0x003c0000 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S 18 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND 0x00c00000 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S 22 +#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL 0x01000000 +#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S 24 -#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) #define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280) +#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) + #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) #define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450) -#define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0) -#define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4) -#define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8) -#define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc) +#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0) +#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4) +#define AR_PHY_WATCHDOG_CTL_2 (AR_SM_BASE + 0x5c8) +#define AR_PHY_WATCHDOG_CTL (AR_SM_BASE + 0x5cc) #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) -#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) + +#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) +#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff +#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 + +#define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254) +#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff +#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0 +#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00 +#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 + #define AR_PHY_65NM_CH0_SYNTH4 0x1608c #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 @@ -660,17 +728,9 @@ #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 -#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff -#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 -#define AR_PHY_TPC_19_ALPHA_THERM 0xff -#define AR_PHY_TPC_19_ALPHA_THERM_S 0 - #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 -#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff -#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 - /* * Channel 1 Register Map */ @@ -812,35 +872,173 @@ #define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) #define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) -#define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001 -#define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002 -#define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000 -#define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC - -#define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002 -#define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004 -#define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9 - -#define AR_PHY_BB_WD_STATUS 0x00000007 -#define AR_PHY_BB_WD_STATUS_S 0 -#define AR_PHY_BB_WD_DET_HANG 0x00000008 -#define AR_PHY_BB_WD_DET_HANG_S 3 -#define AR_PHY_BB_WD_RADAR_SM 0x000000F0 -#define AR_PHY_BB_WD_RADAR_SM_S 4 -#define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00 -#define AR_PHY_BB_WD_RX_OFDM_SM_S 8 -#define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000 -#define AR_PHY_BB_WD_RX_CCK_SM_S 12 -#define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000 -#define AR_PHY_BB_WD_TX_OFDM_SM_S 16 -#define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000 -#define AR_PHY_BB_WD_TX_CCK_SM_S 20 -#define AR_PHY_BB_WD_AGC_SM 0x0F000000 -#define AR_PHY_BB_WD_AGC_SM_S 24 -#define AR_PHY_BB_WD_SRCH_SM 0xF0000000 -#define AR_PHY_BB_WD_SRCH_SM_S 28 - -#define AR_PHY_BB_WD_STATUS_CLR 0x00000008 +#define AR_PHY_WATCHDOG_NON_IDLE_ENABLE 0x00000001 +#define AR_PHY_WATCHDOG_IDLE_ENABLE 0x00000002 +#define AR_PHY_WATCHDOG_IDLE_MASK 0xFFFF0000 +#define AR_PHY_WATCHDOG_NON_IDLE_MASK 0x0000FFFC + +#define AR_PHY_WATCHDOG_RST_ENABLE 0x00000002 +#define AR_PHY_WATCHDOG_IRQ_ENABLE 0x00000004 +#define AR_PHY_WATCHDOG_CNTL2_MASK 0xFFFFFFF9 + +#define AR_PHY_WATCHDOG_INFO 0x00000007 +#define AR_PHY_WATCHDOG_INFO_S 0 +#define AR_PHY_WATCHDOG_DET_HANG 0x00000008 +#define AR_PHY_WATCHDOG_DET_HANG_S 3 +#define AR_PHY_WATCHDOG_RADAR_SM 0x000000F0 +#define AR_PHY_WATCHDOG_RADAR_SM_S 4 +#define AR_PHY_WATCHDOG_RX_OFDM_SM 0x00000F00 +#define AR_PHY_WATCHDOG_RX_OFDM_SM_S 8 +#define AR_PHY_WATCHDOG_RX_CCK_SM 0x0000F000 +#define AR_PHY_WATCHDOG_RX_CCK_SM_S 12 +#define AR_PHY_WATCHDOG_TX_OFDM_SM 0x000F0000 +#define AR_PHY_WATCHDOG_TX_OFDM_SM_S 16 +#define AR_PHY_WATCHDOG_TX_CCK_SM 0x00F00000 +#define AR_PHY_WATCHDOG_TX_CCK_SM_S 20 +#define AR_PHY_WATCHDOG_AGC_SM 0x0F000000 +#define AR_PHY_WATCHDOG_AGC_SM_S 24 +#define AR_PHY_WATCHDOG_SRCH_SM 0xF0000000 +#define AR_PHY_WATCHDOG_SRCH_SM_S 28 + +#define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008 + +/* + * PAPRD registers + */ +#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64) + +#define AR_PHY_PAPRD_AM2AM (AR_CHAN_BASE + 0xe4) +#define AR_PHY_PAPRD_AM2AM_MASK 0x01ffffff +#define AR_PHY_PAPRD_AM2AM_MASK_S 0 + +#define AR_PHY_PAPRD_AM2PM (AR_CHAN_BASE + 0xe8) +#define AR_PHY_PAPRD_AM2PM_MASK 0x01ffffff +#define AR_PHY_PAPRD_AM2PM_MASK_S 0 + +#define AR_PHY_PAPRD_HT40 (AR_CHAN_BASE + 0xec) +#define AR_PHY_PAPRD_HT40_MASK 0x01ffffff +#define AR_PHY_PAPRD_HT40_MASK_S 0 + +#define AR_PHY_PAPRD_CTRL0_B0 (AR_CHAN_BASE + 0xf0) +#define AR_PHY_PAPRD_CTRL0_B1 (AR_CHAN1_BASE + 0xf0) +#define AR_PHY_PAPRD_CTRL0_B2 (AR_CHAN2_BASE + 0xf0) +#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001 +#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S 0 +#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK 0x00000002 +#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S 1 +#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH 0xf8000000 +#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27 + +#define AR_PHY_PAPRD_CTRL1_B0 (AR_CHAN_BASE + 0xf4) +#define AR_PHY_PAPRD_CTRL1_B1 (AR_CHAN1_BASE + 0xf4) +#define AR_PHY_PAPRD_CTRL1_B2 (AR_CHAN2_BASE + 0xf4) +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S 0 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE 0x00000002 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S 1 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE 0x00000004 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S 2 +#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL 0x000001f8 +#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S 3 +#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK 0x0001fe00 +#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S 9 +#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000 +#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17 + +#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490) +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S 1 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE 0x00000100 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S 8 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE 0x00000200 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE 0x00000400 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S 10 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE 0x00000800 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S 11 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12 + +#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494) +#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF +#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0 + +#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498) +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S 6 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL 0x0001f000 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES 0x000e0000 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S 17 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN 0x00f00000 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S 20 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN 0x0f000000 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S 24 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29 + +#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c) +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S 12 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR 0x00000fff +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S 0 + +#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0 (AR_CHAN_BASE + 0x100) +#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0 (AR_CHAN_BASE + 0x104) +#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0 (AR_CHAN_BASE + 0x108) +#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0 (AR_CHAN_BASE + 0x10c) +#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0 (AR_CHAN_BASE + 0x110) +#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0 (AR_CHAN_BASE + 0x114) +#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0 (AR_CHAN_BASE + 0x118) +#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0 (AR_CHAN_BASE + 0x11c) +#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF +#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0 + +#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0) +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S 1 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR 0x00000004 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S 2 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE 0x00000008 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S 3 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX 0x000001f0 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S 4 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9 + +#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4) +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S 16 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21 + +#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8) +#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff +#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0 + +#define AR_PHY_PAPRD_MEM_TAB_B0 (AR_CHAN_BASE + 0x120) +#define AR_PHY_PAPRD_MEM_TAB_B1 (AR_CHAN1_BASE + 0x120) +#define AR_PHY_PAPRD_MEM_TAB_B2 (AR_CHAN2_BASE + 0x120) + +#define AR_PHY_PA_GAIN123_B0 (AR_CHAN_BASE + 0xf8) +#define AR_PHY_PA_GAIN123_B1 (AR_CHAN1_BASE + 0xf8) +#define AR_PHY_PA_GAIN123_B2 (AR_CHAN2_BASE + 0xf8) +#define AR_PHY_PA_GAIN123_PA_GAIN1 0x3FF +#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0 + +#define AR_PHY_POWERTX_RATE5 (AR_SM_BASE + 0x1d0) +#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F +#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index fbb7dec6dde..998ae2c49ed 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -20,6 +20,7 @@ #include <linux/etherdevice.h> #include <linux/device.h> #include <linux/leds.h> +#include <linux/completion.h> #include "debug.h" #include "common.h" @@ -136,6 +137,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, #define ATH_MAX_ANTENNA 3 #define ATH_RXBUF 512 #define ATH_TXBUF 512 +#define ATH_TXBUF_RESERVE 5 +#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) #define ATH_TXMAXTRY 13 #define ATH_MGT_TXMAXTRY 4 @@ -192,6 +195,7 @@ enum ATH_AGGR_STATUS { #define ATH_TXFIFO_DEPTH 8 struct ath_txq { + int axq_class; u32 axq_qnum; u32 *axq_link; struct list_head axq_q; @@ -206,6 +210,71 @@ struct ath_txq { u8 txq_tailidx; }; +struct ath_atx_ac { + int sched; + int qnum; + struct list_head list; + struct list_head tid_q; +}; + +struct ath_buf_state { + int bfs_nframes; + u16 bfs_al; + u16 bfs_frmlen; + int bfs_seqno; + int bfs_tidno; + int bfs_retries; + u8 bf_type; + u8 bfs_paprd; + unsigned long bfs_paprd_timestamp; + u32 bfs_keyix; + enum ath9k_key_type bfs_keytype; +}; + +struct ath_buf { + struct list_head list; + struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or + an aggregate) */ + struct ath_buf *bf_next; /* next subframe in the aggregate */ + struct sk_buff *bf_mpdu; /* enclosing frame structure */ + void *bf_desc; /* virtual addr of desc */ + dma_addr_t bf_daddr; /* physical addr of desc */ + dma_addr_t bf_buf_addr; /* physical addr of data buffer */ + bool bf_stale; + bool bf_isnullfunc; + bool bf_tx_aborted; + u16 bf_flags; + struct ath_buf_state bf_state; + dma_addr_t bf_dmacontext; + struct ath_wiphy *aphy; +}; + +struct ath_atx_tid { + struct list_head list; + struct list_head buf_q; + struct ath_node *an; + struct ath_atx_ac *ac; + struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; + u16 seq_start; + u16 seq_next; + u16 baw_size; + int tidno; + int baw_head; /* first un-acked tx buffer */ + int baw_tail; /* next unused tx buffer slot */ + int sched; + int paused; + u8 state; +}; + +struct ath_node { + struct ath_common *common; + struct ath_atx_tid tid[WME_NUM_TID]; + struct ath_atx_ac ac[WME_NUM_AC]; + u16 maxampdu; + u8 mpdudensity; + int last_rssi; +}; + #define AGGR_CLEANUP BIT(1) #define AGGR_ADDBA_COMPLETE BIT(2) #define AGGR_ADDBA_PROGRESS BIT(3) @@ -214,6 +283,7 @@ struct ath_tx_control { struct ath_txq *txq; int if_id; enum ath9k_internal_frame_type frame_type; + u8 paprd; }; #define ATH_TX_ERROR 0x01 @@ -223,11 +293,12 @@ struct ath_tx_control { struct ath_tx { u16 seq_no; u32 txqsetup; - int hwq_map[ATH9K_WME_AC_VO+1]; + int hwq_map[WME_NUM_AC]; spinlock_t txbuflock; struct list_head txbuf; struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; struct ath_descdma txdma; + int pending_frames[WME_NUM_AC]; }; struct ath_rx_edma { @@ -267,7 +338,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_init(struct ath_softc *sc, int nbufs); void ath_tx_cleanup(struct ath_softc *sc); -struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_tx_queue_info *q); int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, @@ -351,10 +421,15 @@ int ath_beaconq_config(struct ath_softc *sc); #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ -#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ +#define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */ +#define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ +#define ATH_PAPRD_TIMEOUT 100 /* msecs */ + +void ath_hw_check(struct work_struct *work); +void ath_paprd_calibrate(struct work_struct *work); void ath_ani_calibrate(unsigned long data); /**********/ @@ -445,6 +520,7 @@ void ath_deinit_leds(struct ath_softc *sc); #define SC_OP_TSF_RESET BIT(11) #define SC_OP_BT_PRIORITY_DETECTED BIT(12) #define SC_OP_BT_SCAN BIT(13) +#define SC_OP_ANI_RUN BIT(14) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) @@ -486,6 +562,9 @@ struct ath_softc { spinlock_t sc_serial_rw; spinlock_t sc_pm_lock; struct mutex mutex; + struct work_struct paprd_work; + struct work_struct hw_check_work; + struct completion paprd_complete; u32 intrstatus; u32 sc_flags; /* SC_OP_* */ @@ -544,7 +623,6 @@ struct ath_wiphy { void ath9k_tasklet(unsigned long data); int ath_reset(struct ath_softc *sc, bool retry_tx); -int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); int ath_cabq_update(struct ath_softc *); @@ -555,13 +633,12 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) extern struct ieee80211_ops ath9k_ops; extern int modparam_nohwcrypt; +extern int led_blink; irqreturn_t ath_isr(int irq, void *dev); int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops); void ath9k_deinit_device(struct ath_softc *sc); -const char *ath_mac_bb_name(u32 mac_bb_version); -const char *ath_rf_name(u16 rf_version); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *ichan); @@ -610,9 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc); void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); -void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); - -int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); +bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index f43d85a302c..4d4b22d52df 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -38,8 +38,7 @@ int ath_beaconq_config(struct ath_softc *sc) qi.tqi_cwmax = 0; } else { /* Adhoc mode; important thing is to use 2x cwmin. */ - qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, - ATH9K_WME_AC_BE); + qnum = sc->tx.hwq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; qi.tqi_cwmin = 4*qi_be.tqi_cwmin; diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 07b8fa6fb62..139289e4e93 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -74,13 +74,8 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, h[i].currIndex = 0; if (h[i].invalidNFcount > 0) { - if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE || - nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) { - h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX; - } else { - h[i].invalidNFcount--; - h[i].privNF = nfarray[i]; - } + h[i].invalidNFcount--; + h[i].privNF = nfarray[i]; } else { h[i].privNF = ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); @@ -172,6 +167,116 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah) REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); } +void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) +{ + struct ath9k_nfcal_hist *h; + unsigned i, j; + int32_t val; + u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; + struct ath_common *common = ath9k_hw_common(ah); + + h = ah->nfCalHist; + + for (i = 0; i < NUM_NF_READINGS; i++) { + if (chainmask & (1 << i)) { + val = REG_READ(ah, ah->nf_regs[i]); + val &= 0xFFFFFE00; + val |= (((u32) (h[i].privNF) << 1) & 0x1ff); + REG_WRITE(ah, ah->nf_regs[i], val); + } + } + + /* + * Load software filtered NF value into baseband internal minCCApwr + * variable. + */ + REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, + AR_PHY_AGC_CONTROL_ENABLE_NF); + REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, + AR_PHY_AGC_CONTROL_NO_UPDATE_NF); + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); + + /* + * Wait for load to complete, should be fast, a few 10s of us. + * The max delay was changed from an original 250us to 10000us + * since 250us often results in NF load timeout and causes deaf + * condition during stress testing 12/12/2009 + */ + for (j = 0; j < 1000; j++) { + if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & + AR_PHY_AGC_CONTROL_NF) == 0) + break; + udelay(10); + } + + /* + * We timed out waiting for the noisefloor to load, probably due to an + * in-progress rx. Simply return here and allow the load plenty of time + * to complete before the next calibration interval. We need to avoid + * trying to load -50 (which happens below) while the previous load is + * still in progress as this can cause rx deafness. Instead by returning + * here, the baseband nf cal will just be capped by our present + * noisefloor until the next calibration timer. + */ + if (j == 1000) { + ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " + "to load: AR_PHY_AGC_CONTROL=0x%x\n", + REG_READ(ah, AR_PHY_AGC_CONTROL)); + return; + } + + /* + * Restore maxCCAPower register parameter again so that we're not capped + * by the median we just loaded. This will be initial (and max) value + * of next noise floor calibration the baseband does. + */ + ENABLE_REGWRITE_BUFFER(ah); + for (i = 0; i < NUM_NF_READINGS; i++) { + if (chainmask & (1 << i)) { + val = REG_READ(ah, ah->nf_regs[i]); + val &= 0xFFFFFE00; + val |= (((u32) (-50) << 1) & 0x1ff); + REG_WRITE(ah, ah->nf_regs[i], val); + } + } + REGWRITE_BUFFER_FLUSH(ah); + DISABLE_REGWRITE_BUFFER(ah); +} + + +static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath_nf_limits *limit; + int i; + + if (IS_CHAN_2GHZ(ah->curchan)) + limit = &ah->nf_2g; + else + limit = &ah->nf_5g; + + for (i = 0; i < NUM_NF_READINGS; i++) { + if (!nf[i]) + continue; + + ath_print(common, ATH_DBG_CALIBRATE, + "NF calibrated [%s] [chain %d] is %d\n", + (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); + + if (nf[i] > limit->max) { + ath_print(common, ATH_DBG_CALIBRATE, + "NF[%d] (%d) > MAX (%d), correcting to MAX", + i, nf[i], limit->max); + nf[i] = limit->max; + } else if (nf[i] < limit->min) { + ath_print(common, ATH_DBG_CALIBRATE, + "NF[%d] (%d) < MIN (%d), correcting to NOM", + i, nf[i], limit->min); + nf[i] = limit->nominal; + } + } +} + int16_t ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -190,6 +295,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, return chan->rawNoiseFloor; } else { ath9k_hw_do_getnf(ah, nfarray); + ath9k_hw_nf_sanitize(ah, nfarray); nf = nfarray[0]; if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) && nf > nfThresh) { @@ -211,25 +317,21 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) { + struct ath_nf_limits *limit; int i, j; - s16 noise_floor; - - if (AR_SREV_9280(ah)) - noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; - else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) - noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; - else if (AR_SREV_9287(ah)) - noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; + + if (!ah->curchan || IS_CHAN_2GHZ(ah->curchan)) + limit = &ah->nf_2g; else - noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE; + limit = &ah->nf_5g; for (i = 0; i < NUM_NF_READINGS; i++) { ah->nfCalHist[i].currIndex = 0; - ah->nfCalHist[i].privNF = noise_floor; + ah->nfCalHist[i].privNF = limit->nominal; ah->nfCalHist[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH; for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { - ah->nfCalHist[i].nfCalBuffer[j] = noise_floor; + ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal; } } } diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 24538bdb912..cd60d09cdda 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -19,12 +19,6 @@ #include "hw.h" -#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85 -#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112 -#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118 -#define AR_PHY_CCA_MAX_AR9287_GOOD_VALUE -118 -#define AR_PHY_CCA_MAX_HIGH_VALUE -62 -#define AR_PHY_CCA_MIN_BAD_VALUE -140 #define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 #define AR_PHY_CCA_FILTERWINDOW_LENGTH 5 @@ -115,6 +109,7 @@ struct ath9k_pacal_info{ bool ath9k_hw_reset_calvalid(struct ath_hw *ah); void ath9k_hw_start_nfcal(struct ath_hw *ah); +void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); int16_t ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 7707341cd0d..c86f7d3593a 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -27,270 +27,6 @@ MODULE_AUTHOR("Atheros Communications"); MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); MODULE_LICENSE("Dual BSD/GPL"); -/* Common RX processing */ - -/* Assumes you've already done the endian to CPU conversion */ -static bool ath9k_rx_accept(struct ath_common *common, - struct sk_buff *skb, - struct ieee80211_rx_status *rxs, - struct ath_rx_status *rx_stats, - bool *decrypt_error) -{ - struct ath_hw *ah = common->ah; - struct ieee80211_hdr *hdr; - __le16 fc; - - hdr = (struct ieee80211_hdr *) skb->data; - fc = hdr->frame_control; - - if (!rx_stats->rs_datalen) - return false; - /* - * rs_status follows rs_datalen so if rs_datalen is too large - * we can take a hint that hardware corrupted it, so ignore - * those frames. - */ - if (rx_stats->rs_datalen > common->rx_bufsize) - return false; - - /* - * rs_more indicates chained descriptors which can be used - * to link buffers together for a sort of scatter-gather - * operation. - * reject the frame, we don't support scatter-gather yet and - * the frame is probably corrupt anyway - */ - if (rx_stats->rs_more) - return false; - - /* - * The rx_stats->rs_status will not be set until the end of the - * chained descriptors so it can be ignored if rs_more is set. The - * rs_more will be false at the last element of the chained - * descriptors. - */ - if (rx_stats->rs_status != 0) { - if (rx_stats->rs_status & ATH9K_RXERR_CRC) - rxs->flag |= RX_FLAG_FAILED_FCS_CRC; - if (rx_stats->rs_status & ATH9K_RXERR_PHY) - return false; - - if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { - *decrypt_error = true; - } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { - if (ieee80211_is_ctl(fc)) - /* - * Sometimes, we get invalid - * MIC failures on valid control frames. - * Remove these mic errors. - */ - rx_stats->rs_status &= ~ATH9K_RXERR_MIC; - else - rxs->flag |= RX_FLAG_MMIC_ERROR; - } - /* - * Reject error frames with the exception of - * decryption and MIC failures. For monitor mode, - * we also ignore the CRC error. - */ - if (ah->opmode == NL80211_IFTYPE_MONITOR) { - if (rx_stats->rs_status & - ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | - ATH9K_RXERR_CRC)) - return false; - } else { - if (rx_stats->rs_status & - ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { - return false; - } - } - } - return true; -} - -static int ath9k_process_rate(struct ath_common *common, - struct ieee80211_hw *hw, - struct ath_rx_status *rx_stats, - struct ieee80211_rx_status *rxs, - struct sk_buff *skb) -{ - struct ieee80211_supported_band *sband; - enum ieee80211_band band; - unsigned int i = 0; - - band = hw->conf.channel->band; - sband = hw->wiphy->bands[band]; - - if (rx_stats->rs_rate & 0x80) { - /* HT rate */ - rxs->flag |= RX_FLAG_HT; - if (rx_stats->rs_flags & ATH9K_RX_2040) - rxs->flag |= RX_FLAG_40MHZ; - if (rx_stats->rs_flags & ATH9K_RX_GI) - rxs->flag |= RX_FLAG_SHORT_GI; - rxs->rate_idx = rx_stats->rs_rate & 0x7f; - return 0; - } - - for (i = 0; i < sband->n_bitrates; i++) { - if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { - rxs->rate_idx = i; - return 0; - } - if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { - rxs->flag |= RX_FLAG_SHORTPRE; - rxs->rate_idx = i; - return 0; - } - } - - /* - * No valid hardware bitrate found -- we should not get here - * because hardware has already validated this frame as OK. - */ - ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " - "0x%02x using 1 Mbit\n", rx_stats->rs_rate); - if ((common->debug_mask & ATH_DBG_XMIT)) - print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); - - return -EINVAL; -} - -static void ath9k_process_rssi(struct ath_common *common, - struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ath_rx_status *rx_stats) -{ - struct ath_hw *ah = common->ah; - struct ieee80211_sta *sta; - struct ieee80211_hdr *hdr; - struct ath_node *an; - int last_rssi = ATH_RSSI_DUMMY_MARKER; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - rcu_read_lock(); - /* - * XXX: use ieee80211_find_sta! This requires quite a bit of work - * under the current ath9k virtual wiphy implementation as we have - * no way of tying a vif to wiphy. Typically vifs are attached to - * at least one sdata of a wiphy on mac80211 but with ath9k virtual - * wiphy you'd have to iterate over every wiphy and each sdata. - */ - sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); - if (sta) { - an = (struct ath_node *) sta->drv_priv; - if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && - !rx_stats->rs_moreaggr) - ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); - last_rssi = an->last_rssi; - } - rcu_read_unlock(); - - if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rx_stats->rs_rssi = ATH_EP_RND(last_rssi, - ATH_RSSI_EP_MULTIPLIER); - if (rx_stats->rs_rssi < 0) - rx_stats->rs_rssi = 0; - - /* Update Beacon RSSI, this is used by ANI. */ - if (ieee80211_is_beacon(fc)) - ah->stats.avgbrssi = rx_stats->rs_rssi; -} - -/* - * For Decrypt or Demic errors, we only mark packet status here and always push - * up the frame up to let mac80211 handle the actual error case, be it no - * decryption key or real decryption error. This let us keep statistics there. - */ -int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, - struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ath_rx_status *rx_stats, - struct ieee80211_rx_status *rx_status, - bool *decrypt_error) -{ - struct ath_hw *ah = common->ah; - - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - - /* - * everything but the rate is checked here, the rate check is done - * separately to avoid doing two lookups for a rate for each frame. - */ - if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) - return -EINVAL; - - ath9k_process_rssi(common, hw, skb, rx_stats); - - if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb)) - return -EINVAL; - - rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); - rx_status->band = hw->conf.channel->band; - rx_status->freq = hw->conf.channel->center_freq; - rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; - rx_status->antenna = rx_stats->rs_antenna; - rx_status->flag |= RX_FLAG_TSFT; - - return 0; -} -EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess); - -void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, - struct sk_buff *skb, - struct ath_rx_status *rx_stats, - struct ieee80211_rx_status *rxs, - bool decrypt_error) -{ - struct ath_hw *ah = common->ah; - struct ieee80211_hdr *hdr; - int hdrlen, padpos, padsize; - u8 keyix; - __le16 fc; - - /* see if any padding is done by the hw and remove it */ - hdr = (struct ieee80211_hdr *) skb->data; - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - fc = hdr->frame_control; - padpos = ath9k_cmn_padpos(hdr->frame_control); - - /* The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = (4 - padpos % 4) % 4; However, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. In addition, we must - * not try to remove padding from short control frames that do - * not have payload. */ - padsize = padpos & 3; - if (padsize && skb->len>=padpos+padsize+FCS_LEN) { - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); - } - - keyix = rx_stats->rs_keyix; - - if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && - ieee80211_has_protected(fc)) { - rxs->flag |= RX_FLAG_DECRYPTED; - } else if (ieee80211_has_protected(fc) - && !decrypt_error && skb->len >= hdrlen + 4) { - keyix = skb->data[hdrlen + 3] >> 6; - - if (test_bit(keyix, common->keymap)) - rxs->flag |= RX_FLAG_DECRYPTED; - } - if (ah->sw_mgmt_crypto && - (rxs->flag & RX_FLAG_DECRYPTED) && - ieee80211_is_mgmt(fc)) - /* Use software decrypt for management frames. */ - rxs->flag &= ~RX_FLAG_DECRYPTED; -} -EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); - int ath9k_cmn_padpos(__le16 frame_control) { int padpos = 24; @@ -475,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) return -1; } -static int ath_reserve_key_cache_slot(struct ath_common *common) +static int ath_reserve_key_cache_slot(struct ath_common *common, + enum ieee80211_key_alg alg) { int i; + if (alg == ALG_TKIP) + return ath_reserve_key_cache_slot_tkip(common); + /* First, try to find slots that would not be available for TKIP. */ if (common->splitmic) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { @@ -547,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common, struct ath_hw *ah = common->ah; struct ath9k_keyval hk; const u8 *mac = NULL; + u8 gmac[ETH_ALEN]; int ret = 0; int idx; @@ -570,9 +311,27 @@ int ath9k_cmn_key_config(struct ath_common *common, memcpy(hk.kv_val, key->key, key->keylen); if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - /* For now, use the default keys for broadcast keys. This may - * need to change with virtual interfaces. */ - idx = key->keyidx; + switch (vif->type) { + case NL80211_IFTYPE_AP: + memcpy(gmac, vif->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->alg); + break; + case NL80211_IFTYPE_ADHOC: + if (!sta) { + idx = key->keyidx; + break; + } + memcpy(gmac, sta->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->alg); + break; + default: + idx = key->keyidx; + break; + } } else if (key->keyidx) { if (WARN_ON(!sta)) return -EOPNOTSUPP; @@ -589,14 +348,12 @@ int ath9k_cmn_key_config(struct ath_common *common, return -EOPNOTSUPP; mac = sta->addr; - if (key->alg == ALG_TKIP) - idx = ath_reserve_key_cache_slot_tkip(common); - else - idx = ath_reserve_key_cache_slot(common); - if (idx < 0) - return -ENOSPC; /* no free key cache entries */ + idx = ath_reserve_key_cache_slot(common, key->alg); } + if (idx < 0) + return -ENOSPC; /* no free key cache entries */ + if (key->alg == ALG_TKIP) ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, vif->type == NL80211_IFTYPE_AP); @@ -644,6 +401,19 @@ void ath9k_cmn_key_delete(struct ath_common *common, } EXPORT_SYMBOL(ath9k_cmn_key_delete); +int ath9k_cmn_count_streams(unsigned int chainmask, int max) +{ + int streams = 0; + + do { + if (++streams == max) + break; + } while ((chainmask = chainmask & (chainmask - 1))); + + return streams; +} +EXPORT_SYMBOL(ath9k_cmn_count_streams); + static int __init ath9k_cmn_init(void) { return 0; diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index e08f7e5a26e..97809d39c73 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -52,82 +52,6 @@ #define ATH_EP_RND(x, mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) -struct ath_atx_ac { - int sched; - int qnum; - struct list_head list; - struct list_head tid_q; -}; - -struct ath_buf_state { - int bfs_nframes; - u16 bfs_al; - u16 bfs_frmlen; - int bfs_seqno; - int bfs_tidno; - int bfs_retries; - u8 bf_type; - u32 bfs_keyix; - enum ath9k_key_type bfs_keytype; -}; - -struct ath_buf { - struct list_head list; - struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or - an aggregate) */ - struct ath_buf *bf_next; /* next subframe in the aggregate */ - struct sk_buff *bf_mpdu; /* enclosing frame structure */ - void *bf_desc; /* virtual addr of desc */ - dma_addr_t bf_daddr; /* physical addr of desc */ - dma_addr_t bf_buf_addr; /* physical addr of data buffer */ - bool bf_stale; - bool bf_isnullfunc; - bool bf_tx_aborted; - u16 bf_flags; - struct ath_buf_state bf_state; - dma_addr_t bf_dmacontext; - struct ath_wiphy *aphy; -}; - -struct ath_atx_tid { - struct list_head list; - struct list_head buf_q; - struct ath_node *an; - struct ath_atx_ac *ac; - struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; - u16 seq_start; - u16 seq_next; - u16 baw_size; - int tidno; - int baw_head; /* first un-acked tx buffer */ - int baw_tail; /* next unused tx buffer slot */ - int sched; - int paused; - u8 state; -}; - -struct ath_node { - struct ath_common *common; - struct ath_atx_tid tid[WME_NUM_TID]; - struct ath_atx_ac ac[WME_NUM_AC]; - u16 maxampdu; - u8 mpdudensity; - int last_rssi; -}; - -int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, - struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ath_rx_status *rx_stats, - struct ieee80211_rx_status *rx_status, - bool *decrypt_error); - -void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, - struct sk_buff *skb, - struct ath_rx_status *rx_stats, - struct ieee80211_rx_status *rxs, - bool decrypt_error); - int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, @@ -140,3 +64,4 @@ int ath9k_cmn_key_config(struct ath_common *common, struct ieee80211_key_conf *key); void ath9k_cmn_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +int ath9k_cmn_count_streams(unsigned int chainmask, int max); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 29898f8d189..54aae931424 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -42,7 +42,7 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf, char buf[32]; unsigned int len; - len = snprintf(buf, sizeof(buf), "0x%08x\n", common->debug_mask); + len = sprintf(buf, "0x%08x\n", common->debug_mask); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -57,7 +57,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) - return -EINVAL; + return -EFAULT; buf[len] = '\0'; if (strict_strtoul(buf, 0, &mask)) @@ -86,7 +86,7 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, char buf[32]; unsigned int len; - len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); + len = sprintf(buf, "0x%08x\n", common->tx_chainmask); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -101,7 +101,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) - return -EINVAL; + return -EFAULT; buf[len] = '\0'; if (strict_strtoul(buf, 0, &mask)) @@ -128,7 +128,7 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, char buf[32]; unsigned int len; - len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); + len = sprintf(buf, "0x%08x\n", common->rx_chainmask); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -143,7 +143,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) - return -EINVAL; + return -EFAULT; buf[len] = '\0'; if (strict_strtoul(buf, 0, &mask)) @@ -176,7 +176,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); if (!buf) - return 0; + return -ENOMEM; ath9k_ps_wakeup(sc); @@ -248,6 +248,9 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, ath9k_ps_restore(sc); + if (len > DMA_BUF_LEN) + len = DMA_BUF_LEN; + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); return retval; @@ -269,6 +272,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) sc->debug.stats.istats.rxlp++; if (status & ATH9K_INT_RXHP) sc->debug.stats.istats.rxhp++; + if (status & ATH9K_INT_BB_WATCHDOG) + sc->debug.stats.istats.bb_watchdog++; } else { if (status & ATH9K_INT_RX) sc->debug.stats.istats.rxok++; @@ -319,6 +324,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); len += snprintf(buf + len, sizeof(buf) - len, "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp); + len += snprintf(buf + len, sizeof(buf) - len, + "%8s: %10u\n", "WATCHDOG", + sc->debug.stats.istats.bb_watchdog); } else { len += snprintf(buf + len, sizeof(buf) - len, "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); @@ -358,6 +366,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -397,11 +408,10 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, if (sc->cur_rate_table == NULL) return 0; - max = 80 + sc->cur_rate_table->rate_cnt * 1024; - buf = kmalloc(max + 1, GFP_KERNEL); + max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1; + buf = kmalloc(max, GFP_KERNEL); if (buf == NULL) - return 0; - buf[max] = 0; + return -ENOMEM; len += sprintf(buf, "%6s %6s %6s " "%10s %10s %10s %10s\n", @@ -443,6 +453,9 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, stats->per); } + if (len > max) + len = max; + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); return retval; @@ -505,6 +518,9 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "addrmask: %pM\n", addr); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -614,10 +630,10 @@ static const struct file_operations fops_wiphy = { do { \ len += snprintf(buf + len, size - len, \ "%s%13u%11u%10u%10u\n", str, \ - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \ - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \ + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \ + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \ + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \ + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \ } while(0) static ssize_t read_file_xmit(struct file *file, char __user *user_buf, @@ -630,7 +646,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) - return 0; + return -ENOMEM; len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); @@ -648,6 +664,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DATA Underrun: ", data_underrun); PR("DELIM Underrun: ", delim_underrun); + if (len > size) + len = size; + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); @@ -700,7 +719,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) - return 0; + return -ENOMEM; len += snprintf(buf + len, size - len, "%18s : %10u\n", "CRC ERR", @@ -751,6 +770,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); + if (len > size) + len = size; + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); @@ -802,7 +824,7 @@ static ssize_t read_file_regidx(struct file *file, char __user *user_buf, char buf[32]; unsigned int len; - len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); + len = sprintf(buf, "0x%08x\n", sc->debug.regidx); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -816,7 +838,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) - return -EINVAL; + return -EFAULT; buf[len] = '\0'; if (strict_strtoul(buf, 0, ®idx)) @@ -843,7 +865,7 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf, u32 regval; regval = REG_READ_D(ah, sc->debug.regidx); - len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); + len = sprintf(buf, "0x%08x\n", regval); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -858,7 +880,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) - return -EINVAL; + return -EFAULT; buf[len] = '\0'; if (strict_strtoul(buf, 0, ®val)) @@ -934,6 +956,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, sc, &fops_regval)) goto err; + if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) + goto err; + sc->debug.regidx = 0; return 0; err: diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 5147b8709e1..5d21704e87f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -53,6 +53,7 @@ struct ath_buf; * @cabend: RX End of CAB traffic * @dtimsync: DTIM sync lossage * @dtim: RX Beacon with DTIM + * @bb_watchdog: Baseband watchdog */ struct ath_interrupt_stats { u32 total; @@ -76,6 +77,7 @@ struct ath_interrupt_stats { u32 cabend; u32 dtimsync; u32 dtim; + u32 bb_watchdog; }; struct ath_rc_stats { diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index ca8704a9d7a..1266333f586 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -24,6 +24,14 @@ static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); } +void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val) +{ + REG_WRITE(ah, reg, val); + + if (ah->config.analog_shiftreg) + udelay(100); +} + void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, u32 shift, u32 val) { @@ -250,6 +258,27 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, return twiceMaxEdgePower; } +void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); + + switch (ar5416_get_ntxchains(ah->txchainmask)) { + case 1: + break; + case 2: + regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; + break; + case 3: + regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; + break; + default: + ath_print(common, ATH_DBG_EEPROM, + "Invalid chainmask configuration\n"); + break; + } +} + int ath9k_hw_eeprom_init(struct ath_hw *ah) { int status; diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 21354c15a9a..8750c558c22 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -263,7 +263,8 @@ enum eeprom_param { EEP_PWR_TABLE_OFFSET, EEP_DRIVE_STRENGTH, EEP_INTERNAL_REGULATOR, - EEP_SWREG + EEP_SWREG, + EEP_PAPRD, }; enum ar5416_rates { @@ -669,7 +670,7 @@ struct eeprom_ops { int (*get_eeprom_ver)(struct ath_hw *hw); int (*get_eeprom_rev)(struct ath_hw *hw); u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band); - u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, + u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); @@ -679,6 +680,7 @@ struct eeprom_ops { u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); }; +void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val); void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, u32 shift, u32 val); int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, @@ -704,6 +706,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah, u16 numRates, bool isHt40Target); u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, bool is2GHz, int num_band_edges); +void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); int ath9k_hw_eeprom_init(struct ath_hw *ah); #define ar5416_get_ntxchains(_txchainmask) \ diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 41a77d1bd43..9cccd12e8f2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -222,7 +222,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_per_freq_4k *pRawDataSet, u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, int16_t *pMinCalPower, + u16 tPdGainOverlap, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) { @@ -249,6 +249,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, struct chan_centers centers; #define PD_GAIN_BOUNDARY_DEFAULT 58; + memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { @@ -307,8 +308,6 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, } } - *pMinCalPower = (int16_t)(minPwrT4[0] / 2); - k = 0; for (i = 0; i < numXpdGains; i++) { @@ -398,7 +397,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; u16 numPiers, i, j; - int16_t tMinCalPower; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; u32 reg32, regOffset, regChainOffset; @@ -451,7 +449,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, - &tMinCalPower, gainBoundaries, + gainBoundaries, pdadcValues, numXpdGain); ENABLE_REGWRITE_BUFFER(ah); @@ -1149,13 +1147,13 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, } } -static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, +static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; struct modal_eep_4k_header *pModal = &eep->modalHeader; - return pModal->antCtrlCommon & 0xFFFF; + return pModal->antCtrlCommon; } static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b471db5fb82..4a52cf03808 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -17,17 +17,19 @@ #include "hw.h" #include "ar9002_phy.h" -static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) +#define NUM_EEP_WORDS (sizeof(struct ar9287_eeprom) / sizeof(u16)) + +static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) { return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; } -static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah) +static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) { return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; } -static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) +static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct ath_common *common = ath9k_hw_common(ah); @@ -40,20 +42,20 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) "Reading from EEPROM, not flash\n"); } - for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16); - addr++) { - if (!ath9k_hw_nvram_read(common, - addr + eep_start_loc, eep_data)) { + for (addr = 0; addr < NUM_EEP_WORDS; addr++) { + if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, + eep_data)) { ath_print(common, ATH_DBG_EEPROM, "Unable to read eeprom region\n"); return false; } eep_data++; } + return true; } -static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) +static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) { u32 sum = 0, el, integer; u16 temp, word, magic, magic2, *eepdata; @@ -63,8 +65,8 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); if (!ath9k_hw_use_flash(ah)) { - if (!ath9k_hw_nvram_read(common, - AR5416_EEPROM_MAGIC_OFFSET, &magic)) { + if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, + &magic)) { ath_print(common, ATH_DBG_FATAL, "Reading Magic # failed\n"); return false; @@ -72,6 +74,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) ath_print(common, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic); + if (magic != AR5416_EEPROM_MAGIC) { magic2 = swab16(magic); @@ -79,9 +82,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) need_swap = true; eepdata = (u16 *)(&ah->eeprom); - for (addr = 0; - addr < sizeof(struct ar9287_eeprom) / sizeof(u16); - addr++) { + for (addr = 0; addr < NUM_EEP_WORDS; addr++) { temp = swab16(*eepdata); *eepdata = temp; eepdata++; @@ -89,13 +90,14 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) } else { ath_print(common, ATH_DBG_FATAL, "Invalid EEPROM Magic. " - "endianness mismatch.\n"); + "Endianness mismatch.\n"); return -EINVAL; } } } - ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ? - "True" : "False"); + + ath_print(common, ATH_DBG_EEPROM, "need_swap = %s.\n", + need_swap ? "True" : "False"); if (need_swap) el = swab16(ah->eeprom.map9287.baseEepHeader.length); @@ -108,6 +110,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) el = el / sizeof(u16); eepdata = (u16 *)(&ah->eeprom); + for (i = 0; i < el; i++) sum ^= *eepdata++; @@ -161,7 +164,7 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) return 0; } -static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, +static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah, enum eeprom_param param) { struct ar9287_eeprom *eep = &ah->eeprom.map9287; @@ -170,6 +173,7 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, u16 ver_minor; ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK; + switch (param) { case EEP_NFTHRESH_2: return pModal->noiseFloorThreshCh[0]; @@ -214,29 +218,29 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, } } - -static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, - struct ath9k_channel *chan, - struct cal_data_per_freq_ar9287 *pRawDataSet, - u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, int16_t *pMinCalPower, - u16 *pPdGainBoundaries, u8 *pPDADCValues, - u16 numXpdGains) +static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, + struct ath9k_channel *chan, + struct cal_data_per_freq_ar9287 *pRawDataSet, + u8 *bChans, u16 availPiers, + u16 tPdGainOverlap, + u16 *pPdGainBoundaries, + u8 *pPDADCValues, + u16 numXpdGains) { -#define TMP_VAL_VPD_TABLE \ +#define TMP_VAL_VPD_TABLE \ ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep)); - int i, j, k; - int16_t ss; - u16 idxL = 0, idxR = 0, numPiers; - u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; - u8 minPwrT4[AR9287_NUM_PD_GAINS]; - u8 maxPwrT4[AR9287_NUM_PD_GAINS]; - int16_t vpdStep; - int16_t tmpVal; - u16 sizeCurrVpdTable, maxIndex, tgtIndex; - bool match; - int16_t minDelta = 0; + int i, j, k; + int16_t ss; + u16 idxL = 0, idxR = 0, numPiers; + u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR; + u8 minPwrT4[AR9287_NUM_PD_GAINS]; + u8 maxPwrT4[AR9287_NUM_PD_GAINS]; + int16_t vpdStep; + int16_t tmpVal; + u16 sizeCurrVpdTable, maxIndex, tgtIndex; + bool match; + int16_t minDelta = 0; struct chan_centers centers; static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; @@ -245,6 +249,7 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS] [AR5416_MAX_PWR_RANGE_IN_HALF_DB]; + memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { @@ -253,18 +258,18 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, } match = ath9k_hw_get_lower_upper_index( - (u8)FREQ2FBIN(centers.synth_center, - IS_CHAN_2GHZ(chan)), bChans, numPiers, - &idxL, &idxR); + (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), + bChans, numPiers, &idxL, &idxR); if (match) { for (i = 0; i < numXpdGains; i++) { minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pRawDataSet[idxL].pwrPdg[i], - pRawDataSet[idxL].vpdPdg[i], - AR9287_PD_GAIN_ICEPTS, vpdTableI[i]); + pRawDataSet[idxL].pwrPdg[i], + pRawDataSet[idxL].vpdPdg[i], + AR9287_PD_GAIN_ICEPTS, + vpdTableI[i]); } } else { for (i = 0; i < numXpdGains; i++) { @@ -275,61 +280,58 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, minPwrT4[i] = max(pPwrL[0], pPwrR[0]); - maxPwrT4[i] = - min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], - pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); + maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1], + pPwrR[AR9287_PD_GAIN_ICEPTS - 1]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrL, pVpdL, - AR9287_PD_GAIN_ICEPTS, - vpdTableL[i]); + pPwrL, pVpdL, + AR9287_PD_GAIN_ICEPTS, + vpdTableL[i]); ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], - pPwrR, pVpdR, - AR9287_PD_GAIN_ICEPTS, - vpdTableR[i]); + pPwrR, pVpdR, + AR9287_PD_GAIN_ICEPTS, + vpdTableR[i]); for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { - vpdTableI[i][j] = - (u8)(ath9k_hw_interpolate((u16) - FREQ2FBIN(centers. synth_center, - IS_CHAN_2GHZ(chan)), - bChans[idxL], bChans[idxR], - vpdTableL[i][j], vpdTableR[i][j])); + vpdTableI[i][j] = (u8)(ath9k_hw_interpolate( + (u16)FREQ2FBIN(centers. synth_center, + IS_CHAN_2GHZ(chan)), + bChans[idxL], bChans[idxR], + vpdTableL[i][j], vpdTableR[i][j])); } } } - *pMinCalPower = (int16_t)(minPwrT4[0] / 2); k = 0; + for (i = 0; i < numXpdGains; i++) { if (i == (numXpdGains - 1)) - pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2); + pPdGainBoundaries[i] = + (u16)(maxPwrT4[i] / 2); else - pPdGainBoundaries[i] = (u16)((maxPwrT4[i] + - minPwrT4[i+1]) / 4); + pPdGainBoundaries[i] = + (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4); pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER, - pPdGainBoundaries[i]); + pPdGainBoundaries[i]); - if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { - minDelta = pPdGainBoundaries[0] - 23; - pPdGainBoundaries[0] = 23; - } else - minDelta = 0; + minDelta = 0; if (i == 0) { if (AR_SREV_9280_10_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; - } else + } else { ss = (int16_t)((pPdGainBoundaries[i-1] - - (minPwrT4[i] / 2)) - + (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); + } vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); + while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal); @@ -348,12 +350,13 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); + if (tgtIndex > maxIndex) { while ((ss <= tgtIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t) TMP_VAL_VPD_TABLE; - pPDADCValues[k++] = (u8)((tmpVal > 255) ? - 255 : tmpVal); + pPDADCValues[k++] = + (u8)((tmpVal > 255) ? 255 : tmpVal); ss++; } } @@ -375,10 +378,9 @@ static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah, static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, - u8 *pCalChans, u16 availPiers, - int8_t *pPwr) + u8 *pCalChans, u16 availPiers, int8_t *pPwr) { - u16 idxL = 0, idxR = 0, numPiers; + u16 idxL = 0, idxR = 0, numPiers; bool match; struct chan_centers centers; @@ -390,15 +392,14 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, } match = ath9k_hw_get_lower_upper_index( - (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), - pCalChans, numPiers, - &idxL, &idxR); + (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), + pCalChans, numPiers, &idxL, &idxR); if (match) { *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0]; } else { *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] + - (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; + (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2; } } @@ -409,16 +410,22 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, u32 tmpVal; u32 a; + /* Enable OLPC for chain 0 */ + tmpVal = REG_READ(ah, 0xa270); tmpVal = tmpVal & 0xFCFFFFFF; tmpVal = tmpVal | (0x3 << 24); REG_WRITE(ah, 0xa270, tmpVal); + /* Enable OLPC for chain 1 */ + tmpVal = REG_READ(ah, 0xb270); tmpVal = tmpVal & 0xFCFFFFFF; tmpVal = tmpVal | (0x3 << 24); REG_WRITE(ah, 0xb270, tmpVal); + /* Write the OLPC ref power for chain 0 */ + if (chain == 0) { tmpVal = REG_READ(ah, 0xa398); tmpVal = tmpVal & 0xff00ffff; @@ -427,6 +434,8 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, REG_WRITE(ah, 0xa398, tmpVal); } + /* Write the OLPC ref power for chain 1 */ + if (chain == 1) { tmpVal = REG_READ(ah, 0xb398); tmpVal = tmpVal & 0xff00ffff; @@ -436,28 +445,28 @@ static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, } } -static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, +static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) { - struct ath_common *common = ath9k_hw_common(ah); struct cal_data_per_freq_ar9287 *pRawDataset; struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; - u8 *pCalBChans = NULL; + u8 *pCalBChans = NULL; u16 pdGainOverlap_t2; - u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; + u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; u16 numPiers = 0, i, j; - int16_t tMinCalPower; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; - u32 reg32, regOffset, regChainOffset; - int16_t modalIdx, diff = 0; + u32 reg32, regOffset, regChainOffset, regval; + int16_t modalIdx, diff = 0; struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; + modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; xpdMask = pEepData->modalHeader.xpdGain; + if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= - AR9287_EEP_MINOR_VER_2) + AR9287_EEP_MINOR_VER_2) pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap; else pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5), @@ -466,15 +475,16 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, if (IS_CHAN_2GHZ(chan)) { pCalBChans = pEepData->calFreqPier2G; numPiers = AR9287_NUM_2G_CAL_PIERS; - if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { + if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { pRawDatasetOpenLoop = - (struct cal_data_op_loop_ar9287 *) - pEepData->calPierData2G[0]; + (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[0]; ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0]; } } numXpdGain = 0; + + /* Calculate the value of xpdgains from the xpdGain Mask */ for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { if (numXpdGain >= AR9287_NUM_PD_GAINS) @@ -496,99 +506,79 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, for (i = 0; i < AR9287_MAX_CHAINS; i++) { regChainOffset = i * 0x1000; + if (pEepData->baseEepHeader.txMask & (1 << i)) { - pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *) - pEepData->calPierData2G[i]; - if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { + pRawDatasetOpenLoop = + (struct cal_data_op_loop_ar9287 *)pEepData->calPierData2G[i]; + + if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { int8_t txPower; ar9287_eeprom_get_tx_gain_index(ah, chan, - pRawDatasetOpenLoop, - pCalBChans, numPiers, - &txPower); + pRawDatasetOpenLoop, + pCalBChans, numPiers, + &txPower); ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i); } else { pRawDataset = (struct cal_data_per_freq_ar9287 *) pEepData->calPierData2G[i]; - ath9k_hw_get_AR9287_gain_boundaries_pdadcs( - ah, chan, pRawDataset, - pCalBChans, numPiers, - pdGainOverlap_t2, - &tMinCalPower, gainBoundaries, - pdadcValues, numXpdGain); + + ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan, + pRawDataset, + pCalBChans, numPiers, + pdGainOverlap_t2, + gainBoundaries, + pdadcValues, + numXpdGain); } if (i == 0) { - if (!ath9k_hw_AR9287_get_eeprom( - ah, EEP_OL_PWRCTRL)) { - REG_WRITE(ah, AR_PHY_TPCRG5 + - regChainOffset, - SM(pdGainOverlap_t2, - AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | - SM(gainBoundaries[0], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) - | SM(gainBoundaries[1], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) - | SM(gainBoundaries[2], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) - | SM(gainBoundaries[3], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); + if (!ath9k_hw_ar9287_get_eeprom(ah, + EEP_OL_PWRCTRL)) { + + regval = SM(pdGainOverlap_t2, + AR_PHY_TPCRG5_PD_GAIN_OVERLAP) + | SM(gainBoundaries[0], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) + | SM(gainBoundaries[1], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) + | SM(gainBoundaries[2], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) + | SM(gainBoundaries[3], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4); + + REG_WRITE(ah, + AR_PHY_TPCRG5 + regChainOffset, + regval); } } if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB != - pEepData->baseEepHeader.pwrTableOffset) { - diff = (u16) - (pEepData->baseEepHeader.pwrTableOffset - - (int32_t)AR9287_PWR_TABLE_OFFSET_DB); + pEepData->baseEepHeader.pwrTableOffset) { + diff = (u16)(pEepData->baseEepHeader.pwrTableOffset - + (int32_t)AR9287_PWR_TABLE_OFFSET_DB); diff *= 2; - for (j = 0; - j < ((u16)AR9287_NUM_PDADC_VALUES-diff); - j++) + for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++) pdadcValues[j] = pdadcValues[j+diff]; for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); j < AR9287_NUM_PDADC_VALUES; j++) pdadcValues[j] = - pdadcValues[ - AR9287_NUM_PDADC_VALUES-diff]; + pdadcValues[AR9287_NUM_PDADC_VALUES-diff]; } - if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { - regOffset = AR_PHY_BASE + (672 << 2) + - regChainOffset; - for (j = 0; j < 32; j++) { - reg32 = ((pdadcValues[4*j + 0] - & 0xFF) << 0) | - ((pdadcValues[4*j + 1] - & 0xFF) << 8) | - ((pdadcValues[4*j + 2] - & 0xFF) << 16) | - ((pdadcValues[4*j + 3] - & 0xFF) << 24) ; - REG_WRITE(ah, regOffset, reg32); + if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { + regOffset = AR_PHY_BASE + + (672 << 2) + regChainOffset; - ath_print(common, ATH_DBG_EEPROM, - "PDADC (%d,%4x): %4.4x " - "%8.8x\n", - i, regChainOffset, regOffset, - reg32); - - ath_print(common, ATH_DBG_EEPROM, - "PDADC: Chain %d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d | " - "PDADC %3d Value %3d |\n", - i, 4 * j, pdadcValues[4 * j], - 4 * j + 1, - pdadcValues[4 * j + 1], - 4 * j + 2, - pdadcValues[4 * j + 2], - 4 * j + 3, - pdadcValues[4 * j + 3]); + for (j = 0; j < 32; j++) { + reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) + | ((pdadcValues[4*j + 1] & 0xFF) << 8) + | ((pdadcValues[4*j + 2] & 0xFF) << 16) + | ((pdadcValues[4*j + 3] & 0xFF) << 24); + REG_WRITE(ah, regOffset, reg32); regOffset += 4; } } @@ -598,30 +588,45 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah, *pTxPowerIndexOffset = 0; } -static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, - struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl, - u16 AntennaReduction, u16 twiceMaxRegulatoryPower, - u16 powerLimit) +static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, + struct ath9k_channel *chan, + int16_t *ratesArray, + u16 cfgCtl, + u16 AntennaReduction, + u16 twiceMaxRegulatoryPower, + u16 powerLimit) { +#define CMP_CTL \ + (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ + pEepData->ctlIndex[i]) + +#define CMP_NO_CTL \ + (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ + ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) + #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 + struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; static const u16 tpScaleReductionTable[5] = { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; int i; - int16_t twiceLargestAntenna; + int16_t twiceLargestAntenna; struct cal_ctl_data_ar9287 *rep; struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, targetPowerCck = {0, {0, 0, 0, 0} }; struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} }, targetPowerCckExt = {0, {0, 0, 0, 0} }; - struct cal_target_power_ht targetPowerHt20, + struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0} }; u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; - u16 ctlModesFor11g[] = - {CTL_11B, CTL_11G, CTL_2GHT20, - CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40}; + u16 ctlModesFor11g[] = {CTL_11B, + CTL_11G, + CTL_2GHT20, + CTL_11B_EXT, + CTL_11G_EXT, + CTL_2GHT40}; u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq; struct chan_centers centers; int tx_chainmask; @@ -631,19 +636,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, ath9k_hw_get_channel_centers(ah, chan, ¢ers); + /* Compute TxPower reduction due to Antenna Gain */ twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0], pEepData->modalHeader.antennaGainCh[1]); + twiceLargestAntenna = (int16_t)min((AntennaReduction) - + twiceLargestAntenna, 0); - twiceLargestAntenna = (int16_t)min((AntennaReduction) - - twiceLargestAntenna, 0); - + /* + * scaledPower is the minimum of the user input power level + * and the regulatory allowed power level. + */ maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; + if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) maxRegAllowedPower -= (tpScaleReductionTable[(regulatory->tp_scale)] * 2); scaledPower = min(powerLimit, maxRegAllowedPower); + /* + * Reduce scaled Power by number of chains active + * to get the per chain tx power level. + */ switch (ar5416_get_ntxchains(tx_chainmask)) { case 1: break; @@ -656,9 +670,14 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, } scaledPower = max((u16)0, scaledPower); + /* + * Get TX power from EEPROM. + */ if (IS_CHAN_2GHZ(chan)) { + /* CTL_11B, CTL_11G, CTL_2GHT20 */ numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; + pCtlMode = ctlModesFor11g; ath9k_hw_get_legacy_target_powers(ah, chan, @@ -675,6 +694,7 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, &targetPowerHt20, 8, false); if (IS_CHAN_HT40(chan)) { + /* All 2G CTLs */ numCtlModes = ARRAY_SIZE(ctlModesFor11g); ath9k_hw_get_target_powers(ah, chan, pEepData->calTargetPower2GHT40, @@ -692,8 +712,9 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, } for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { - bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || - (pCtlMode[ctlMode] == CTL_2GHT40); + bool isHt40CtlMode = + (pCtlMode[ctlMode] == CTL_2GHT40) ? true : false; + if (isHt40CtlMode) freq = centers.synth_center; else if (pCtlMode[ctlMode] & EXT_ADDITIVE) @@ -701,31 +722,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, else freq = centers.ctl_center; - if (ah->eep_ops->get_eeprom_ver(ah) == 14 && - ah->eep_ops->get_eeprom_rev(ah) <= 2) - twiceMaxEdgePower = AR5416_MAX_RATE_POWER; - + /* Walk through the CTL indices stored in EEPROM */ for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { - if ((((cfgCtl & ~CTL_MODE_M) | - (pCtlMode[ctlMode] & CTL_MODE_M)) == - pEepData->ctlIndex[i]) || - (((cfgCtl & ~CTL_MODE_M) | - (pCtlMode[ctlMode] & CTL_MODE_M)) == - ((pEepData->ctlIndex[i] & - CTL_MODE_M) | SD_NO_CTL))) { + struct cal_ctl_edges *pRdEdgesPower; + /* + * Compare test group from regulatory channel list + * with test mode from pCtlMode list + */ + if (CMP_CTL || CMP_NO_CTL) { rep = &(pEepData->ctlData[i]); - twiceMinEdgePower = ath9k_hw_get_max_edge_power( - freq, - rep->ctlEdges[ar5416_get_ntxchains( - tx_chainmask) - 1], - IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); - - if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) - twiceMaxEdgePower = min( - twiceMaxEdgePower, - twiceMinEdgePower); - else { + pRdEdgesPower = + rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1]; + + twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq, + pRdEdgesPower, + IS_CHAN_2GHZ(chan), + AR5416_NUM_BAND_EDGES); + + if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { + twiceMaxEdgePower = min(twiceMaxEdgePower, + twiceMinEdgePower); + } else { twiceMaxEdgePower = twiceMinEdgePower; break; } @@ -734,55 +752,48 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); + /* Apply ctl mode to correct target power set */ switch (pCtlMode[ctlMode]) { case CTL_11B: - for (i = 0; - i < ARRAY_SIZE(targetPowerCck.tPow2x); - i++) { - targetPowerCck.tPow2x[i] = (u8)min( - (u16)targetPowerCck.tPow2x[i], - minCtlPower); + for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) { + targetPowerCck.tPow2x[i] = + (u8)min((u16)targetPowerCck.tPow2x[i], + minCtlPower); } break; case CTL_11A: case CTL_11G: - for (i = 0; - i < ARRAY_SIZE(targetPowerOfdm.tPow2x); - i++) { - targetPowerOfdm.tPow2x[i] = (u8)min( - (u16)targetPowerOfdm.tPow2x[i], - minCtlPower); + for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) { + targetPowerOfdm.tPow2x[i] = + (u8)min((u16)targetPowerOfdm.tPow2x[i], + minCtlPower); } break; case CTL_5GHT20: case CTL_2GHT20: - for (i = 0; - i < ARRAY_SIZE(targetPowerHt20.tPow2x); - i++) { - targetPowerHt20.tPow2x[i] = (u8)min( - (u16)targetPowerHt20.tPow2x[i], - minCtlPower); + for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) { + targetPowerHt20.tPow2x[i] = + (u8)min((u16)targetPowerHt20.tPow2x[i], + minCtlPower); } break; case CTL_11B_EXT: - targetPowerCckExt.tPow2x[0] = (u8)min( - (u16)targetPowerCckExt.tPow2x[0], - minCtlPower); + targetPowerCckExt.tPow2x[0] = + (u8)min((u16)targetPowerCckExt.tPow2x[0], + minCtlPower); break; case CTL_11A_EXT: case CTL_11G_EXT: - targetPowerOfdmExt.tPow2x[0] = (u8)min( - (u16)targetPowerOfdmExt.tPow2x[0], - minCtlPower); + targetPowerOfdmExt.tPow2x[0] = + (u8)min((u16)targetPowerOfdmExt.tPow2x[0], + minCtlPower); break; case CTL_5GHT40: case CTL_2GHT40: - for (i = 0; - i < ARRAY_SIZE(targetPowerHt40.tPow2x); - i++) { - targetPowerHt40.tPow2x[i] = (u8)min( - (u16)targetPowerHt40.tPow2x[i], - minCtlPower); + for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) { + targetPowerHt40.tPow2x[i] = + (u8)min((u16)targetPowerHt40.tPow2x[i], + minCtlPower); } break; default: @@ -790,12 +801,13 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, } } + /* Now set the rates array */ + ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = - ratesArray[rate24mb] = - targetPowerOfdm.tPow2x[0]; + ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; @@ -807,12 +819,12 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, if (IS_CHAN_2GHZ(chan)) { ratesArray[rate1l] = targetPowerCck.tPow2x[0]; - ratesArray[rate2s] = ratesArray[rate2l] = - targetPowerCck.tPow2x[1]; - ratesArray[rate5_5s] = ratesArray[rate5_5l] = - targetPowerCck.tPow2x[2]; - ratesArray[rate11s] = ratesArray[rate11l] = - targetPowerCck.tPow2x[3]; + ratesArray[rate2s] = + ratesArray[rate2l] = targetPowerCck.tPow2x[1]; + ratesArray[rate5_5s] = + ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; + ratesArray[rate11s] = + ratesArray[rate11l] = targetPowerCck.tPow2x[3]; } if (IS_CHAN_HT40(chan)) { for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) @@ -821,28 +833,28 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah, ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; + if (IS_CHAN_2GHZ(chan)) ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; } +#undef CMP_CTL +#undef CMP_NO_CTL #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN } -static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, +static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, struct ath9k_channel *chan, u16 cfgCtl, u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower, u8 powerLimit) { -#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 -#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 - struct ath_common *common = ath9k_hw_common(ah); struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; int16_t ratesArray[Ar5416RateSize]; - int16_t txPowerIndexOffset = 0; + int16_t txPowerIndexOffset = 0; u8 ht40PowerIncForPdadc = 2; int i; @@ -852,13 +864,13 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, AR9287_EEP_MINOR_VER_2) ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; - ath9k_hw_set_AR9287_power_per_rate_table(ah, chan, + ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, &ratesArray[0], cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit); - ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset); + ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset); for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); @@ -871,6 +883,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; } + /* OFDM power per rate */ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, ATH9K_POW_SM(ratesArray[rate18mb], 24) | ATH9K_POW_SM(ratesArray[rate12mb], 16) @@ -883,6 +896,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate36mb], 8) | ATH9K_POW_SM(ratesArray[rate24mb], 0)); + /* CCK power per rate */ if (IS_CHAN_2GHZ(chan)) { REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, ATH9K_POW_SM(ratesArray[rate2s], 24) @@ -896,6 +910,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); } + /* HT20 power per rate */ REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, ATH9K_POW_SM(ratesArray[rateHt20_3], 24) | ATH9K_POW_SM(ratesArray[rateHt20_2], 16) @@ -908,8 +923,9 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rateHt20_5], 8) | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)); + /* HT40 power per rate */ if (IS_CHAN_HT40(chan)) { - if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { + if (ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, ATH9K_POW_SM(ratesArray[rateHt40_3], 24) | ATH9K_POW_SM(ratesArray[rateHt40_2], 16) @@ -943,6 +959,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, ht40PowerIncForPdadc, 0)); } + /* Dup/Ext power per rate */ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ATH9K_POW_SM(ratesArray[rateExtCck], 16) @@ -960,37 +977,20 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah, ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; else regulatory->max_power_level = ratesArray[i]; - - switch (ar5416_get_ntxchains(ah->txchainmask)) { - case 1: - break; - case 2: - regulatory->max_power_level += - INCREASE_MAXPOW_BY_TWO_CHAIN; - break; - case 3: - regulatory->max_power_level += - INCREASE_MAXPOW_BY_THREE_CHAIN; - break; - default: - ath_print(common, ATH_DBG_EEPROM, - "Invalid chainmask configuration\n"); - break; - } } -static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah, +static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, struct ath9k_channel *chan) { } -static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, +static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct modal_eep_ar9287_header *pModal = &eep->modalHeader; u16 antWrites[AR9287_ANT_16S]; - u32 regChainOffset; + u32 regChainOffset, regval; u8 txRxAttenLocal; int i, j, offset_num; @@ -1077,42 +1077,37 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1, - AR9287_AN_RF2G3_DB1_S, pModal->db1); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2, - AR9287_AN_RF2G3_DB2_S, pModal->db2); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, - AR9287_AN_RF2G3_OB_CCK, - AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, - AR9287_AN_RF2G3_OB_PSK, - AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, - AR9287_AN_RF2G3_OB_QAM, - AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, - AR9287_AN_RF2G3_OB_PAL_OFF, - AR9287_AN_RF2G3_OB_PAL_OFF_S, - pModal->ob_pal_off); - - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, - AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S, - pModal->db1); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2, - AR9287_AN_RF2G3_DB2_S, pModal->db2); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, - AR9287_AN_RF2G3_OB_CCK, - AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, - AR9287_AN_RF2G3_OB_PSK, - AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, - AR9287_AN_RF2G3_OB_QAM, - AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam); - ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, - AR9287_AN_RF2G3_OB_PAL_OFF, - AR9287_AN_RF2G3_OB_PAL_OFF_S, - pModal->ob_pal_off); + regval = REG_READ(ah, AR9287_AN_RF2G3_CH0); + regval &= ~(AR9287_AN_RF2G3_DB1 | + AR9287_AN_RF2G3_DB2 | + AR9287_AN_RF2G3_OB_CCK | + AR9287_AN_RF2G3_OB_PSK | + AR9287_AN_RF2G3_OB_QAM | + AR9287_AN_RF2G3_OB_PAL_OFF); + regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | + SM(pModal->db2, AR9287_AN_RF2G3_DB2) | + SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | + SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | + SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | + SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); + + ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH0, regval); + + regval = REG_READ(ah, AR9287_AN_RF2G3_CH1); + regval &= ~(AR9287_AN_RF2G3_DB1 | + AR9287_AN_RF2G3_DB2 | + AR9287_AN_RF2G3_OB_CCK | + AR9287_AN_RF2G3_OB_PSK | + AR9287_AN_RF2G3_OB_QAM | + AR9287_AN_RF2G3_OB_PAL_OFF); + regval |= (SM(pModal->db1, AR9287_AN_RF2G3_DB1) | + SM(pModal->db2, AR9287_AN_RF2G3_DB2) | + SM(pModal->ob_cck, AR9287_AN_RF2G3_OB_CCK) | + SM(pModal->ob_psk, AR9287_AN_RF2G3_OB_PSK) | + SM(pModal->ob_qam, AR9287_AN_RF2G3_OB_QAM) | + SM(pModal->ob_pal_off, AR9287_AN_RF2G3_OB_PAL_OFF)); + + ath9k_hw_analog_shift_regwrite(ah, AR9287_AN_RF2G3_CH1, regval); REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart); @@ -1125,26 +1120,27 @@ static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, pModal->xpaBiasLvl); } -static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah, +static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah, enum ieee80211_band freq_band) { return 1; } -static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, +static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct modal_eep_ar9287_header *pModal = &eep->modalHeader; - return pModal->antCtrlCommon & 0xFFFF; + return pModal->antCtrlCommon; } -static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, +static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) { #define EEP_MAP9287_SPURCHAN \ (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan) + struct ath_common *common = ath9k_hw_common(ah); u16 spur_val = AR_NO_SPUR; @@ -1171,15 +1167,15 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, } const struct eeprom_ops eep_ar9287_ops = { - .check_eeprom = ath9k_hw_AR9287_check_eeprom, - .get_eeprom = ath9k_hw_AR9287_get_eeprom, - .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, - .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver, - .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev, - .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config, - .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg, - .set_board_values = ath9k_hw_AR9287_set_board_values, - .set_addac = ath9k_hw_AR9287_set_addac, - .set_txpower = ath9k_hw_AR9287_set_txpower, - .get_spur_channel = ath9k_hw_AR9287_get_spur_channel + .check_eeprom = ath9k_hw_ar9287_check_eeprom, + .get_eeprom = ath9k_hw_ar9287_get_eeprom, + .fill_eeprom = ath9k_hw_ar9287_fill_eeprom, + .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, + .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, + .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config, + .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg, + .set_board_values = ath9k_hw_ar9287_set_board_values, + .set_addac = ath9k_hw_ar9287_set_addac, + .set_txpower = ath9k_hw_ar9287_set_txpower, + .get_spur_channel = ath9k_hw_ar9287_get_spur_channel }; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 7e1ed78d0e6..afa2b73ddbd 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -593,7 +593,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_data_per_freq *pRawDataSet, u8 *bChans, u16 availPiers, - u16 tPdGainOverlap, int16_t *pMinCalPower, + u16 tPdGainOverlap, u16 *pPdGainBoundaries, u8 *pPDADCValues, u16 numXpdGains) { @@ -617,6 +617,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, int16_t minDelta = 0; struct chan_centers centers; + memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS); ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) { @@ -674,8 +675,6 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, } } - *pMinCalPower = (int16_t)(minPwrT4[0] / 2); - k = 0; for (i = 0; i < numXpdGains; i++) { @@ -729,7 +728,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, vpdTableI[i][sizeCurrVpdTable - 2]); vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); - if (tgtIndex > maxIndex) { + if (tgtIndex >= maxIndex) { while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + @@ -837,7 +836,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK]; u16 numPiers, i, j; - int16_t tMinCalPower, diff = 0; + int16_t diff = 0; u16 numXpdGain, xpdMask; u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 }; u32 reg32, regOffset, regChainOffset; @@ -922,7 +921,6 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, - &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); @@ -1437,14 +1435,14 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, return num_ant_config; } -static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, +static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar5416_eeprom_def *eep = &ah->eeprom.def; struct modal_eep_header *pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); - return pModal->antCtrlCommon & 0xFFFF; + return pModal->antCtrlCommon; } static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 0ee75e79fe3..3a8ee999da5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -76,7 +76,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev, case LED_FULL: if (led->led_type == ATH_LED_ASSOC) { sc->sc_flags |= SC_OP_LED_ASSOCIATED; - ieee80211_queue_delayed_work(sc->hw, + if (led_blink) + ieee80211_queue_delayed_work(sc->hw, &sc->ath_led_blink_work, 0); } else if (led->led_type == ATH_LED_RADIO) { ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); @@ -143,7 +144,8 @@ void ath_init_leds(struct ath_softc *sc) /* LED off, active low */ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); - INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); + if (led_blink) + INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); trigger = ieee80211_get_radio_led_name(sc->hw); snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), @@ -180,7 +182,8 @@ void ath_init_leds(struct ath_softc *sc) return; fail: - cancel_delayed_work_sync(&sc->ath_led_blink_work); + if (led_blink) + cancel_delayed_work_sync(&sc->ath_led_blink_work); ath_deinit_leds(sc); } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 77b359162d6..61c1bee3f26 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -16,12 +16,27 @@ #include "htc.h" -#define ATH9K_FW_USB_DEV(devid, fw) \ - { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw } +/* identify firmware images */ +#define FIRMWARE_AR7010 "ar7010.fw" +#define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" +#define FIRMWARE_AR9271 "ar9271.fw" + +MODULE_FIRMWARE(FIRMWARE_AR7010); +MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); +MODULE_FIRMWARE(FIRMWARE_AR9271); static struct usb_device_id ath9k_hif_usb_ids[] = { - ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"), - ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"), + { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ + { USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */ + { USB_DEVICE(0x0cf3, 0x7010) }, /* Atheros */ + { USB_DEVICE(0x0cf3, 0x7015) }, /* Atheros */ + { USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */ + { USB_DEVICE(0x0846, 0x9018) }, /* Netgear WNDA3200 */ + { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ + { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ + { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ + { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ + { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ { }, }; @@ -730,13 +745,17 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) /* RX */ if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0) - goto err; + goto err_rx; /* Register Read */ if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) - goto err; + goto err_reg; return 0; +err_reg: + ath9k_hif_usb_dealloc_rx_urbs(hif_dev); +err_rx: + ath9k_hif_usb_dealloc_tx_urbs(hif_dev); err: return -ENOMEM; } @@ -756,6 +775,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) size_t len = hif_dev->firmware->size; u32 addr = AR9271_FIRMWARE; u8 *buf = kzalloc(4096, GFP_KERNEL); + u32 firm_offset; if (!buf) return -ENOMEM; @@ -779,32 +799,37 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) } kfree(buf); + if (hif_dev->device_id == 0x7010) + firm_offset = AR7010_FIRMWARE_TEXT; + else + firm_offset = AR9271_FIRMWARE_TEXT; + /* * Issue FW download complete command to firmware. */ err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0), FIRMWARE_DOWNLOAD_COMP, 0x40 | USB_DIR_OUT, - AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ); + firm_offset >> 8, 0, NULL, 0, HZ); if (err) return -EIO; dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n", - "ar9271.fw", (unsigned long) hif_dev->firmware->size); + hif_dev->fw_name, (unsigned long) hif_dev->firmware->size); return 0; } -static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, - const char *fw_name) +static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { int ret; /* Request firmware */ - ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev); + ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, + &hif_dev->udev->dev); if (ret) { dev_err(&hif_dev->udev->dev, - "ath9k_htc: Firmware - %s not found\n", fw_name); + "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); goto err_fw_req; } @@ -820,7 +845,8 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, - "ath9k_htc: Firmware - %s download failed\n", fw_name); + "ath9k_htc: Firmware - %s download failed\n", + hif_dev->fw_name); goto err_fw_download; } @@ -847,7 +873,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, { struct usb_device *udev = interface_to_usbdev(interface); struct hif_device_usb *hif_dev; - const char *fw_name = (const char *) id->driver_info; int ret = 0; hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); @@ -872,7 +897,27 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, goto err_htc_hw_alloc; } - ret = ath9k_hif_usb_dev_init(hif_dev, fw_name); + /* Find out which firmware to load */ + + switch(hif_dev->device_id) { + case 0x7010: + case 0x9018: + if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) + hif_dev->fw_name = FIRMWARE_AR7010_1_1; + else + hif_dev->fw_name = FIRMWARE_AR7010; + break; + default: + hif_dev->fw_name = FIRMWARE_AR9271; + break; + } + + if (!hif_dev->fw_name) { + dev_err(&udev->dev, "Can't determine firmware !\n"); + goto err_htc_hw_alloc; + } + + ret = ath9k_hif_usb_dev_init(hif_dev); if (ret) { ret = -EINVAL; goto err_hif_init_usb; @@ -907,12 +952,10 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) void *buf; int ret; - buf = kmalloc(4, GFP_KERNEL); + buf = kmemdup(&reboot_cmd, 4, GFP_KERNEL); if (!buf) return; - memcpy(buf, &reboot_cmd, 4); - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), buf, 4, NULL, HZ); if (ret) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 0aca49b6fcb..2daf97b11c0 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -19,6 +19,7 @@ #define AR9271_FIRMWARE 0x501000 #define AR9271_FIRMWARE_TEXT 0x903000 +#define AR7010_FIRMWARE_TEXT 0x906000 #define FIRMWARE_DOWNLOAD 0x30 #define FIRMWARE_DOWNLOAD_COMP 0x31 @@ -90,6 +91,7 @@ struct hif_device_usb { struct usb_anchor regout_submitted; struct usb_anchor rx_submitted; struct sk_buff *remain_skb; + const char *fw_name; int rx_remain_len; int rx_pkt_len; int rx_transfer_len; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index c251603ab03..3756400e6bf 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -223,15 +223,6 @@ struct ath9k_htc_sta { enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; }; -struct ath9k_htc_aggr_work { - u16 tid; - u8 sta_addr[ETH_ALEN]; - struct ieee80211_hw *hw; - struct ieee80211_vif *vif; - enum ieee80211_ampdu_mlme_action action; - struct mutex mutex; -}; - #define ATH9K_HTC_RXBUF 256 #define HTC_RX_FRAME_HEADER_SIZE 40 @@ -257,12 +248,15 @@ struct ath9k_htc_tx_ctl { #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) +#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) + struct ath_tx_stats { u32 buf_queued; u32 buf_completed; u32 skb_queued; u32 skb_completed; u32 skb_dropped; + u32 queue_stats[WME_NUM_AC]; }; struct ath_rx_stats { @@ -286,11 +280,14 @@ struct ath9k_debug { #define TX_STAT_INC(c) do { } while (0) #define RX_STAT_INC(c) do { } while (0) +#define TX_QSTAT_INC(c) do { } while (0) + #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ #define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_9287 8 #define ATH_LED_PIN_9271 15 +#define ATH_LED_PIN_7010 12 #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ @@ -326,11 +323,10 @@ struct htc_beacon_config { #define OP_LED_ON BIT(4) #define OP_PREAMBLE_SHORT BIT(5) #define OP_PROTECT_ENABLE BIT(6) -#define OP_TXAGGR BIT(7) -#define OP_ASSOCIATED BIT(8) -#define OP_ENABLE_BEACON BIT(9) -#define OP_LED_DEINIT BIT(10) -#define OP_UNPLUGGED BIT(11) +#define OP_ASSOCIATED BIT(7) +#define OP_ENABLE_BEACON BIT(8) +#define OP_LED_DEINIT BIT(9) +#define OP_UNPLUGGED BIT(10) struct ath9k_htc_priv { struct device *dev; @@ -371,8 +367,6 @@ struct ath9k_htc_priv { struct ath9k_htc_rx rx; struct tasklet_struct tx_tasklet; struct sk_buff_head tx_queue; - struct ath9k_htc_aggr_work aggr_work; - struct delayed_work ath9k_aggr_work; struct delayed_work ath9k_ani_work; struct work_struct ps_work; @@ -390,13 +384,14 @@ struct ath9k_htc_priv { int led_off_duration; int led_on_cnt; int led_off_cnt; - int hwq_map[ATH9K_WME_AC_VO+1]; + + int beaconq; + int cabq; + int hwq_map[WME_NUM_AC]; #ifdef CONFIG_ATH9K_HTC_DEBUGFS struct ath9k_debug debug; #endif - struct ath9k_htc_target_rate tgt_rate; - struct mutex mutex; }; @@ -405,6 +400,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) common->bus_ops->read_cachesize(common, csz); } +void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); @@ -424,8 +420,8 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); -bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, - enum ath9k_tx_queue_subtype qtype); +bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); +int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv); int get_hw_qnum(u16 queue, int *hwq_map); int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, struct ath9k_tx_queue_info *qinfo); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index c10c7d002eb..bd1506e6910 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -222,6 +222,29 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) spin_unlock_bh(&priv->beacon_lock); } +/* Currently, only for IBSS */ +void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + struct ath9k_tx_queue_info qi, qi_be; + int qnum = priv->hwq_map[WME_AC_BE]; + + memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); + memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); + + ath9k_hw_get_txq_props(ah, qnum, &qi_be); + + qi.tqi_aifs = qi_be.tqi_aifs; + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + qi.tqi_cwmax = qi_be.tqi_cwmax; + + if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { + ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, + "Unable to update beacon queue %u!\n", qnum); + } else { + ath9k_hw_resettxqueue(ah, priv->beaconq); + } +} void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index dc015077a8d..148b43317fd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -34,6 +34,13 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); .max_power = 20, \ } +#define CHAN5G(_freq, _idx) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 20, \ +} + static struct ieee80211_channel ath9k_2ghz_channels[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ @@ -51,6 +58,37 @@ static struct ieee80211_channel ath9k_2ghz_channels[] = { CHAN2G(2484, 13), /* Channel 14 */ }; +static struct ieee80211_channel ath9k_5ghz_channels[] = { + /* _We_ call this UNII 1 */ + CHAN5G(5180, 14), /* Channel 36 */ + CHAN5G(5200, 15), /* Channel 40 */ + CHAN5G(5220, 16), /* Channel 44 */ + CHAN5G(5240, 17), /* Channel 48 */ + /* _We_ call this UNII 2 */ + CHAN5G(5260, 18), /* Channel 52 */ + CHAN5G(5280, 19), /* Channel 56 */ + CHAN5G(5300, 20), /* Channel 60 */ + CHAN5G(5320, 21), /* Channel 64 */ + /* _We_ call this "Middle band" */ + CHAN5G(5500, 22), /* Channel 100 */ + CHAN5G(5520, 23), /* Channel 104 */ + CHAN5G(5540, 24), /* Channel 108 */ + CHAN5G(5560, 25), /* Channel 112 */ + CHAN5G(5580, 26), /* Channel 116 */ + CHAN5G(5600, 27), /* Channel 120 */ + CHAN5G(5620, 28), /* Channel 124 */ + CHAN5G(5640, 29), /* Channel 128 */ + CHAN5G(5660, 30), /* Channel 132 */ + CHAN5G(5680, 31), /* Channel 136 */ + CHAN5G(5700, 32), /* Channel 140 */ + /* _We_ call this UNII 3 */ + CHAN5G(5745, 33), /* Channel 149 */ + CHAN5G(5765, 34), /* Channel 153 */ + CHAN5G(5785, 35), /* Channel 157 */ + CHAN5G(5805, 36), /* Channel 161 */ + CHAN5G(5825, 37), /* Channel 165 */ +}; + /* Atheros hardware rate code addition for short premble */ #define SHPCHECK(__hw_rate, __flags) \ ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0) @@ -141,7 +179,7 @@ static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv, return htc_connect_service(priv->htc, &req, ep_id); } -static int ath9k_init_htc_services(struct ath9k_htc_priv *priv) +static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) { int ret; @@ -199,10 +237,28 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv) if (ret) goto err; + /* + * Setup required credits before initializing HTC. + * This is a bit hacky, but, since queuing is done in + * the HIF layer, shouldn't matter much. + */ + + switch(devid) { + case 0x7010: + case 0x9018: + priv->htc->credits = 45; + break; + default: + priv->htc->credits = 33; + } + ret = htc_init(priv->htc); if (ret) goto err; + dev_info(priv->dev, "ath9k_htc: HTC initialized with %d credits\n", + priv->htc->credits); + return 0; err: @@ -398,17 +454,43 @@ static const struct ath_bus_ops ath9k_usb_bus_ops = { static void setup_ht_cap(struct ath9k_htc_priv *priv, struct ieee80211_sta_ht_cap *ht_info) { + struct ath_common *common = ath9k_hw_common(priv->ah); + u8 tx_streams, rx_streams; + int i; + ht_info->ht_supported = true; ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SM_PS | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_DSSSCCK40; + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) + ht_info->cap |= IEEE80211_HT_CAP_SGI_20; + + ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - ht_info->mcs.rx_mask[0] = 0xff; + + /* ath9k_htc supports only 1 or 2 stream devices */ + tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2); + rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2); + + ath_print(common, ATH_DBG_CONFIG, + "TX streams %d, RX streams: %d\n", + tx_streams, rx_streams); + + if (tx_streams != rx_streams) { + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; + ht_info->mcs.tx_params |= ((tx_streams - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + } + + for (i = 0; i < rx_streams; i++) + ht_info->mcs.rx_mask[i] = 0xff; + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; } @@ -420,23 +502,37 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++) priv->hwq_map[i] = -1; - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) { + priv->beaconq = ath9k_hw_beaconq_setup(priv->ah); + if (priv->beaconq == -1) { + ath_print(common, ATH_DBG_FATAL, + "Unable to setup BEACON xmit queue\n"); + goto err; + } + + priv->cabq = ath9k_htc_cabq_setup(priv); + if (priv->cabq == -1) { + ath_print(common, ATH_DBG_FATAL, + "Unable to setup CAB xmit queue\n"); + goto err; + } + + if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for BE traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for BK traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for VI traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for VO traffic\n"); goto err; @@ -468,36 +564,6 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) */ for (i = 0; i < common->keymax; i++) ath9k_hw_keyreset(priv->ah, (u16) i); - - if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL)) { - /* - * Whether we should enable h/w TKIP MIC. - * XXX: if we don't support WME TKIP MIC, then we wouldn't - * report WMM capable, so it's always safe to turn on - * TKIP MIC in this case. - */ - ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); - } - - /* - * Check whether the separate key cache entries - * are required to handle both tx+rx MIC keys. - * With split mic keys the number of stations is limited - * to 27 otherwise 59. - */ - if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL) - && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_MIC, NULL) - && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT, - 0, NULL)) - common->splitmic = 1; - - /* turn on mcast key search if possible */ - if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) - (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, - 1, 1, NULL); } static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) @@ -512,6 +578,17 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates = ARRAY_SIZE(ath9k_legacy_rates); } + + if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) { + priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels; + priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; + priv->sbands[IEEE80211_BAND_5GHZ].n_channels = + ARRAY_SIZE(ath9k_5ghz_channels); + priv->sbands[IEEE80211_BAND_5GHZ].bitrates = + ath9k_legacy_rates + 4; + priv->sbands[IEEE80211_BAND_5GHZ].n_bitrates = + ARRAY_SIZE(ath9k_legacy_rates) - 4; + } } static void ath9k_init_misc(struct ath9k_htc_priv *priv) @@ -524,7 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); - priv->op_flags |= OP_TXAGGR; priv->ah->opmode = NL80211_IFTYPE_STATION; } @@ -556,14 +632,12 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) spin_lock_init(&priv->beacon_lock); spin_lock_init(&priv->tx_lock); mutex_init(&priv->mutex); - mutex_init(&priv->aggr_work.mutex); mutex_init(&priv->htc_pm_lock); tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet, (unsigned long)priv); tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, (unsigned long)priv); tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); - INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work); INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); @@ -643,11 +717,17 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->sbands[IEEE80211_BAND_2GHZ]; + if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &priv->sbands[IEEE80211_BAND_5GHZ]; if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) setup_ht_cap(priv, &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); + if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + setup_ht_cap(priv, + &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); } SET_IEEE80211_PERM_ADDR(hw, common->macaddr); @@ -747,7 +827,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, goto err_free; } - ret = ath9k_init_htc_services(priv); + ret = ath9k_init_htc_services(priv, devid); if (ret) goto err_init; @@ -790,7 +870,8 @@ int ath9k_htc_resume(struct htc_target *htc_handle) if (ret) return ret; - ret = ath9k_init_htc_services(htc_handle->drv_priv); + ret = ath9k_init_htc_services(htc_handle->drv_priv, + htc_handle->drv_priv->ah->hw_version.devid); return ret; } #endif diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9d371c18eb4..cf9bcc67ade 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -27,13 +27,11 @@ static struct dentry *ath9k_debugfs_root; static void ath_update_txpow(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; - u32 txpow; if (priv->curtxpow != priv->txpowlimit) { ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit); /* read back in case value is clamped */ - ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); - priv->curtxpow = txpow; + priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit; } } @@ -325,142 +323,129 @@ static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) tcap.flags_ext = 0x80601000; tcap.ampdu_limit = 0xffff0000; tcap.ampdu_subframes = 20; - tcap.tx_chainmask_legacy = 1; + tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask; tcap.protmode = 1; - tcap.tx_chainmask = 1; + tcap.tx_chainmask = priv->ah->caps.tx_chainmask; WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); return ret; } -static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, + struct ieee80211_sta *sta, + struct ath9k_htc_target_rate *trate) { - struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; struct ieee80211_supported_band *sband; - struct ath9k_htc_target_rate trate; u32 caps = 0; - u8 cmd_rsp; - int i, j, ret; + int i, j; - memset(&trate, 0, sizeof(trate)); - - /* Only 2GHz is supported */ - sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; + sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band]; for (i = 0, j = 0; i < sband->n_bitrates; i++) { if (sta->supp_rates[sband->band] & BIT(i)) { - priv->tgt_rate.rates.legacy_rates.rs_rates[j] + trate->rates.legacy_rates.rs_rates[j] = (sband->bitrates[i].bitrate * 2) / 10; j++; } } - priv->tgt_rate.rates.legacy_rates.rs_nrates = j; + trate->rates.legacy_rates.rs_nrates = j; if (sta->ht_cap.ht_supported) { for (i = 0, j = 0; i < 77; i++) { if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) - priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i; + trate->rates.ht_rates.rs_rates[j++] = i; if (j == ATH_HTC_RATE_MAX) break; } - priv->tgt_rate.rates.ht_rates.rs_nrates = j; + trate->rates.ht_rates.rs_nrates = j; caps = WLAN_RC_HT_FLAG; + if (sta->ht_cap.mcs.rx_mask[1]) + caps |= WLAN_RC_DS_FLAG; if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) caps |= WLAN_RC_40_FLAG; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) + if (conf_is_ht40(&priv->hw->conf) && + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) + caps |= WLAN_RC_SGI_FLAG; + else if (conf_is_ht20(&priv->hw->conf) && + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)) caps |= WLAN_RC_SGI_FLAG; - } - priv->tgt_rate.sta_index = ista->index; - priv->tgt_rate.isnew = 1; - trate = priv->tgt_rate; - priv->tgt_rate.capflags = cpu_to_be32(caps); - trate.capflags = cpu_to_be32(caps); + trate->sta_index = ista->index; + trate->isnew = 1; + trate->capflags = cpu_to_be32(caps); +} - WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); +static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv, + struct ath9k_htc_target_rate *trate) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + int ret; + u8 cmd_rsp; + + WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate); if (ret) { ath_print(common, ATH_DBG_FATAL, "Unable to initialize Rate information on target\n"); - return ret; } - ath_print(common, ATH_DBG_CONFIG, - "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps); - return 0; + return ret; } -static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40) +static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv, + struct ieee80211_sta *sta) { - struct ath9k_htc_priv *priv = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (!conf_is_ht(conf)) - return false; - - if (!(priv->op_flags & OP_ASSOCIATED) || - (priv->op_flags & OP_SCANNING)) - return false; + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_rate trate; + int ret; - if (conf_is_ht40(conf)) { - if (priv->ah->curchan->chanmode & - (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) { - return false; - } else { - *cw40 = true; - return true; - } - } else { /* ht20 */ - if (priv->ah->curchan->chanmode & CHANNEL_HT20) - return false; - else - return true; - } + memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); + ath9k_htc_setup_rate(priv, sta, &trate); + ret = ath9k_htc_send_rate_cmd(priv, &trate); + if (!ret) + ath_print(common, ATH_DBG_CONFIG, + "Updated target sta: %pM, rate caps: 0x%X\n", + sta->addr, be32_to_cpu(trate.capflags)); } -static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40) +static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) { - struct ath9k_htc_target_rate trate; struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_rate trate; + struct ieee80211_sta *sta; int ret; - u32 caps = be32_to_cpu(priv->tgt_rate.capflags); - u8 cmd_rsp; - - memset(&trate, 0, sizeof(trate)); - - trate = priv->tgt_rate; - - if (is_cw40) - caps |= WLAN_RC_40_FLAG; - else - caps &= ~WLAN_RC_40_FLAG; - priv->tgt_rate.capflags = cpu_to_be32(caps); - trate.capflags = cpu_to_be32(caps); + memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); - WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); - if (ret) { - ath_print(common, ATH_DBG_FATAL, - "Unable to update Rate information on target\n"); + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (!sta) { + rcu_read_unlock(); return; } + ath9k_htc_setup_rate(priv, sta, &trate); + rcu_read_unlock(); - ath_print(common, ATH_DBG_CONFIG, "Rate control updated with " - "caps:0x%x on target\n", priv->tgt_rate.capflags); + ret = ath9k_htc_send_rate_cmd(priv, &trate); + if (!ret) + ath_print(common, ATH_DBG_CONFIG, + "Updated target sta: %pM, rate caps: 0x%X\n", + bss_conf->bssid, be32_to_cpu(trate.capflags)); } -static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, - struct ieee80211_vif *vif, - u8 *sta_addr, u8 tid, bool oper) +static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_ampdu_mlme_action action, + u16 tid) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_target_aggr aggr; - struct ieee80211_sta *sta = NULL; struct ath9k_htc_sta *ista; int ret = 0; u8 cmd_rsp; @@ -469,72 +454,28 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, return -EINVAL; memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); - - rcu_read_lock(); - - /* Check if we are able to retrieve the station */ - sta = ieee80211_find_sta(vif, sta_addr); - if (!sta) { - rcu_read_unlock(); - return -EINVAL; - } - ista = (struct ath9k_htc_sta *) sta->drv_priv; - if (oper) - ista->tid_state[tid] = AGGR_START; - else - ista->tid_state[tid] = AGGR_STOP; - aggr.sta_index = ista->index; - - rcu_read_unlock(); - - aggr.tidno = tid; - aggr.aggr_enable = oper; + aggr.tidno = tid & 0xf; + aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false; WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); if (ret) ath_print(common, ATH_DBG_CONFIG, "Unable to %s TX aggregation for (%pM, %d)\n", - (oper) ? "start" : "stop", sta->addr, tid); + (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid); else ath_print(common, ATH_DBG_CONFIG, - "%s aggregation for (%pM, %d)\n", - (oper) ? "Starting" : "Stopping", sta->addr, tid); - - return ret; -} + "%s TX aggregation for (%pM, %d)\n", + (aggr.aggr_enable) ? "Starting" : "Stopping", + sta->addr, tid); -void ath9k_htc_aggr_work(struct work_struct *work) -{ - int ret = 0; - struct ath9k_htc_priv *priv = - container_of(work, struct ath9k_htc_priv, - ath9k_aggr_work.work); - struct ath9k_htc_aggr_work *wk = &priv->aggr_work; - - mutex_lock(&wk->mutex); - - switch (wk->action) { - case IEEE80211_AMPDU_TX_START: - ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr, - wk->tid, true); - if (!ret) - ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr, - wk->tid); - break; - case IEEE80211_AMPDU_TX_STOP: - ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr, - wk->tid, false); - ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid); - break; - default: - ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, - "Unknown AMPDU action\n"); - } + spin_lock_bh(&priv->tx_lock); + ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP; + spin_unlock_bh(&priv->tx_lock); - mutex_unlock(&wk->mutex); + return ret; } /*********/ @@ -552,8 +493,7 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = - (struct ath9k_htc_priv *) file->private_data; + struct ath9k_htc_priv *priv = file->private_data; struct ath9k_htc_target_stats cmd_rsp; char buf[512]; unsigned int len = 0; @@ -584,6 +524,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%19s : %10u\n", "TX Rate", priv->debug.txrate); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -596,8 +539,7 @@ static const struct file_operations fops_tgt_stats = { static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = - (struct ath9k_htc_priv *) file->private_data; + struct ath9k_htc_priv *priv = file->private_data; char buf[512]; unsigned int len = 0; @@ -617,6 +559,22 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, "%20s : %10u\n", "SKBs dropped", priv->debug.tx_stats.skb_dropped); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BE queued", + priv->debug.tx_stats.queue_stats[WME_AC_BE]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BK queued", + priv->debug.tx_stats.queue_stats[WME_AC_BK]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VI queued", + priv->debug.tx_stats.queue_stats[WME_AC_VI]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VO queued", + priv->debug.tx_stats.queue_stats[WME_AC_VO]); + + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -629,8 +587,7 @@ static const struct file_operations fops_xmit = { static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct ath9k_htc_priv *priv = - (struct ath9k_htc_priv *) file->private_data; + struct ath9k_htc_priv *priv = file->private_data; char buf[512]; unsigned int len = 0; @@ -644,6 +601,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, "%20s : %10u\n", "SKBs Dropped", priv->debug.rx_stats.skb_dropped); + if (len > sizeof(buf)) + len = sizeof(buf); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -978,6 +938,8 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) priv->ah->led_pin = ATH_LED_PIN_9287; else if (AR_SREV_9271(priv->ah)) priv->ah->led_pin = ATH_LED_PIN_9271; + else if (AR_DEVID_7010(priv->ah)) + priv->ah->led_pin = ATH_LED_PIN_7010; else priv->ah->led_pin = ATH_LED_PIN_DEF; @@ -1054,6 +1016,95 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) wiphy_rfkill_start_polling(priv->hw->wiphy); } +static void ath9k_htc_radio_enable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, false); + if (ret) { + ath_print(common, ATH_DBG_FATAL, + "Unable to reset hardware; reset status %d " + "(freq %u MHz)\n", ret, ah->curchan->channel); + } + + ath_update_txpow(priv); + + /* Start RX */ + WMI_CMD(WMI_START_RECV_CMDID); + ath9k_host_rx_init(priv); + + /* Start TX */ + htc_start(priv->htc); + spin_lock_bh(&priv->tx_lock); + priv->tx_queues_stop = false; + spin_unlock_bh(&priv->tx_lock); + ieee80211_wake_queues(hw); + + WMI_CMD(WMI_ENABLE_INTR_CMDID); + + /* Enable LED */ + ath9k_hw_cfg_output(ah, ah->led_pin, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath9k_hw_set_gpio(ah, ah->led_pin, 0); +} + +static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + ath9k_htc_ps_wakeup(priv); + + /* Disable LED */ + ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_cfg_gpio_input(ah, ah->led_pin); + + WMI_CMD(WMI_DISABLE_INTR_CMDID); + + /* Stop TX */ + ieee80211_stop_queues(hw); + htc_stop(priv->htc); + WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); + skb_queue_purge(&priv->tx_queue); + + /* Stop RX */ + WMI_CMD(WMI_STOP_RECV_CMDID); + + /* + * The MIB counters have to be disabled here, + * since the target doesn't do it. + */ + ath9k_hw_disable_mib_counters(ah); + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, false); + if (ret) { + ath_print(common, ATH_DBG_FATAL, + "Unable to reset hardware; reset status %d " + "(freq %u MHz)\n", ret, ah->curchan->channel); + } + + /* Disable the PHY */ + ath9k_hw_phy_disable(ah); + + ath9k_htc_ps_restore(priv); + ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); +} + /**********************/ /* mac80211 Callbacks */ /**********************/ @@ -1099,7 +1150,7 @@ fail_tx: return 0; } -static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) +static int ath9k_htc_start(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; @@ -1111,10 +1162,16 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) __be16 htc_mode; u8 cmd_rsp; + mutex_lock(&priv->mutex); + ath_print(common, ATH_DBG_CONFIG, "Starting driver with initial channel: %d MHz\n", curchan->center_freq); + /* Ensure that HW is awake before flushing RX */ + ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); + WMI_CMD(WMI_FLUSH_RECV_CMDID); + /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); @@ -1127,6 +1184,7 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) ath_print(common, ATH_DBG_FATAL, "Unable to reset hardware; reset status %d " "(freq %u MHz)\n", ret, curchan->center_freq); + mutex_unlock(&priv->mutex); return ret; } @@ -1147,31 +1205,14 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) priv->tx_queues_stop = false; spin_unlock_bh(&priv->tx_lock); - if (led) { - /* Enable LED */ - ath9k_hw_cfg_output(ah, ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - ath9k_hw_set_gpio(ah, ah->led_pin, 0); - } - ieee80211_wake_queues(hw); - return ret; -} - -static int ath9k_htc_start(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - int ret = 0; - - mutex_lock(&priv->mutex); - ret = ath9k_htc_radio_enable(hw, false); mutex_unlock(&priv->mutex); return ret; } -static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) +static void ath9k_htc_stop(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; @@ -1179,21 +1220,17 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) int ret = 0; u8 cmd_rsp; + mutex_lock(&priv->mutex); + if (priv->op_flags & OP_INVALID) { ath_print(common, ATH_DBG_ANY, "Device not present\n"); + mutex_unlock(&priv->mutex); return; } - if (led) { - /* Disable LED */ - ath9k_hw_set_gpio(ah, ah->led_pin, 1); - ath9k_hw_cfg_gpio_input(ah, ah->led_pin); - } - /* Cancel all the running timers/work .. */ cancel_work_sync(&priv->ps_work); cancel_delayed_work_sync(&priv->ath9k_ani_work); - cancel_delayed_work_sync(&priv->ath9k_aggr_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); ath9k_led_stop_brightness(priv); @@ -1202,12 +1239,6 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); - ath9k_hw_phy_disable(ah); - ath9k_hw_disable(ah); - ath9k_hw_configpcipowersave(ah, 1, 1); - ath9k_htc_ps_restore(priv); - ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); - skb_queue_purge(&priv->tx_queue); /* Remove monitor interface here */ @@ -1220,21 +1251,18 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) "Monitor interface removed\n"); } + ath9k_hw_phy_disable(ah); + ath9k_hw_disable(ah); + ath9k_hw_configpcipowersave(ah, 1, 1); + ath9k_htc_ps_restore(priv); + ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); + priv->op_flags |= OP_INVALID; ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); -} - -static void ath9k_htc_stop(struct ieee80211_hw *hw) -{ - struct ath9k_htc_priv *priv = hw->priv; - - mutex_lock(&priv->mutex); - ath9k_htc_radio_disable(hw, false); mutex_unlock(&priv->mutex); } - static int ath9k_htc_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { @@ -1302,6 +1330,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, out: ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); + return ret; } @@ -1318,6 +1347,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); @@ -1328,6 +1358,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, ath9k_htc_remove_station(priv, vif, NULL); priv->vif = NULL; + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -1343,30 +1374,27 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) bool enable_radio = false; bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); + mutex_lock(&priv->htc_pm_lock); if (!idle && priv->ps_idle) enable_radio = true; - priv->ps_idle = idle; + mutex_unlock(&priv->htc_pm_lock); if (enable_radio) { - ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); - ath9k_htc_radio_enable(hw, true); ath_print(common, ATH_DBG_CONFIG, "not-idle: enabling radio\n"); + ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); + ath9k_htc_radio_enable(hw); } } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; - bool is_cw40 = false; ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", curchan->center_freq); - if (check_rc_update(hw, &is_cw40)) - ath9k_htc_rc_update(priv, is_cw40); - ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { @@ -1399,14 +1427,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) } } - if (priv->ps_idle) { + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + mutex_lock(&priv->htc_pm_lock); + if (!priv->ps_idle) { + mutex_unlock(&priv->htc_pm_lock); + goto out; + } + mutex_unlock(&priv->htc_pm_lock); + ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); - ath9k_htc_radio_disable(hw, true); + ath9k_htc_radio_disable(hw); } +out: mutex_unlock(&priv->mutex); - return 0; } @@ -1428,8 +1463,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, u32 rfilt; mutex_lock(&priv->mutex); - ath9k_htc_ps_wakeup(priv); + changed_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS; @@ -1444,30 +1479,38 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); } -static void ath9k_htc_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta) +static int ath9k_htc_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { struct ath9k_htc_priv *priv = hw->priv; int ret; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); + ret = ath9k_htc_add_station(priv, vif, sta); + if (!ret) + ath9k_htc_init_rate(priv, sta); + ath9k_htc_ps_restore(priv); + mutex_unlock(&priv->mutex); - switch (cmd) { - case STA_NOTIFY_ADD: - ret = ath9k_htc_add_station(priv, vif, sta); - if (!ret) - ath9k_htc_init_rate(priv, vif, sta); - break; - case STA_NOTIFY_REMOVE: - ath9k_htc_remove_station(priv, vif, sta); - break; - default: - break; - } + return ret; +} + +static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct ath9k_htc_priv *priv = hw->priv; + int ret; + mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); + ret = ath9k_htc_remove_station(priv, vif, sta); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); + + return ret; } static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, @@ -1482,6 +1525,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, return 0; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); @@ -1499,9 +1543,16 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, params->cw_max, params->txop); ret = ath_htc_txq_update(priv, qnum, &qi); - if (ret) + if (ret) { ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); + goto out; + } + if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && + (qnum == priv->hwq_map[WME_AC_BE])) + ath9k_htc_beaconq_config(priv); +out: + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); return ret; @@ -1574,7 +1625,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_start_ani(priv); } else { priv->op_flags &= ~OP_ASSOCIATED; - cancel_work_sync(&priv->ps_work); cancel_delayed_work_sync(&priv->ath9k_ani_work); } } @@ -1631,6 +1681,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath9k_hw_init_global_settings(ah); } + if (changed & BSS_CHANGED_HT) + ath9k_htc_update_rate(priv, vif, bss_conf); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -1641,7 +1694,9 @@ static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw) u64 tsf; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); tsf = ath9k_hw_gettsf64(priv->ah); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); return tsf; @@ -1652,7 +1707,9 @@ static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf) struct ath9k_htc_priv *priv = hw->priv; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); ath9k_hw_settsf64(priv->ah, tsf); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -1660,11 +1717,11 @@ static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; - ath9k_htc_ps_wakeup(priv); mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); ath9k_hw_reset_tsf(priv->ah); - mutex_unlock(&priv->mutex); ath9k_htc_ps_restore(priv); + mutex_unlock(&priv->mutex); } static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, @@ -1674,8 +1731,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, u16 tid, u16 *ssn) { struct ath9k_htc_priv *priv = hw->priv; - struct ath9k_htc_aggr_work *work = &priv->aggr_work; struct ath9k_htc_sta *ista; + int ret = 0; switch (action) { case IEEE80211_AMPDU_RX_START: @@ -1683,26 +1740,26 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: + ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); + if (!ret) + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; case IEEE80211_AMPDU_TX_STOP: - if (!(priv->op_flags & OP_TXAGGR)) - return -ENOTSUPP; - memcpy(work->sta_addr, sta->addr, ETH_ALEN); - work->hw = hw; - work->vif = vif; - work->action = action; - work->tid = tid; - ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0); + ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: ista = (struct ath9k_htc_sta *) sta->drv_priv; + spin_lock_bh(&priv->tx_lock); ista->tid_state[tid] = AGGR_OPERATIONAL; + spin_unlock_bh(&priv->tx_lock); break; default: ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, "Unknown AMPDU action\n"); } - return 0; + return ret; } static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) @@ -1722,8 +1779,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) { struct ath9k_htc_priv *priv = hw->priv; - ath9k_htc_ps_wakeup(priv); mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); spin_lock_bh(&priv->beacon_lock); priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); @@ -1731,8 +1788,8 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) if (priv->op_flags & OP_ASSOCIATED) ath9k_htc_beacon_config(priv, priv->vif); ath_start_ani(priv); - mutex_unlock(&priv->mutex); ath9k_htc_ps_restore(priv); + mutex_unlock(&priv->mutex); } static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) @@ -1746,8 +1803,10 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, struct ath9k_htc_priv *priv = hw->priv; mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); priv->ah->coverage_class = coverage_class; ath9k_hw_init_global_settings(priv->ah); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -1759,7 +1818,8 @@ struct ieee80211_ops ath9k_htc_ops = { .remove_interface = ath9k_htc_remove_interface, .config = ath9k_htc_config, .configure_filter = ath9k_htc_configure_filter, - .sta_notify = ath9k_htc_sta_notify, + .sta_add = ath9k_htc_sta_add, + .sta_remove = ath9k_htc_sta_remove, .conf_tx = ath9k_htc_conf_tx, .bss_info_changed = ath9k_htc_bss_info_changed, .set_key = ath9k_htc_set_key, diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2571b443ac8..bd0b4acc3ec 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -20,19 +20,29 @@ /* TX */ /******/ +#define ATH9K_HTC_INIT_TXQ(subtype) do { \ + qi.tqi_subtype = subtype; \ + qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; \ + qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; \ + qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; \ + qi.tqi_physCompBuf = 0; \ + qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | \ + TXQ_FLAG_TXDESCINT_ENABLE; \ + } while (0) + int get_hw_qnum(u16 queue, int *hwq_map) { switch (queue) { case 0: - return hwq_map[ATH9K_WME_AC_VO]; + return hwq_map[WME_AC_VO]; case 1: - return hwq_map[ATH9K_WME_AC_VI]; + return hwq_map[WME_AC_VI]; case 2: - return hwq_map[ATH9K_WME_AC_BE]; + return hwq_map[WME_AC_BE]; case 3: - return hwq_map[ATH9K_WME_AC_BK]; + return hwq_map[WME_AC_BK]; default: - return hwq_map[ATH9K_WME_AC_BE]; + return hwq_map[WME_AC_BE]; } } @@ -71,7 +81,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) struct ath9k_htc_vif *avp; struct ath9k_htc_tx_ctl tx_ctl; enum htc_endpoint_id epid; - u16 qnum, hw_qnum; + u16 qnum; __le16 fc; u8 *tx_fhdr; u8 sta_idx; @@ -131,20 +141,23 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); qnum = skb_get_queue_mapping(skb); - hw_qnum = get_hw_qnum(qnum, priv->hwq_map); - switch (hw_qnum) { + switch (qnum) { case 0: - epid = priv->data_be_ep; + TX_QSTAT_INC(WME_AC_VO); + epid = priv->data_vo_ep; break; - case 2: + case 1: + TX_QSTAT_INC(WME_AC_VI); epid = priv->data_vi_ep; break; - case 3: - epid = priv->data_vo_ep; + case 2: + TX_QSTAT_INC(WME_AC_BE); + epid = priv->data_be_ep; break; - case 1: + case 3: default: + TX_QSTAT_INC(WME_AC_BK); epid = priv->data_bk_ep; break; } @@ -174,6 +187,19 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) return htc_send(priv->htc, skb, epid, &tx_ctl); } +static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, + struct ath9k_htc_sta *ista, u8 tid) +{ + bool ret = false; + + spin_lock_bh(&priv->tx_lock); + if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) + ret = true; + spin_unlock_bh(&priv->tx_lock); + + return ret; +} + void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; @@ -203,8 +229,7 @@ void ath9k_tx_tasklet(unsigned long data) /* Check if we need to start aggregation */ if (sta && conf_is_ht(&priv->hw->conf) && - (priv->op_flags & OP_TXAGGR) - && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { if (ieee80211_is_data_qos(fc)) { u8 *qc, tid; struct ath9k_htc_sta *ista; @@ -213,10 +238,11 @@ void ath9k_tx_tasklet(unsigned long data) tid = qc[0] & 0xf; ista = (struct ath9k_htc_sta *)sta->drv_priv; - if ((tid < ATH9K_HTC_MAX_TID) && - ista->tid_state[tid] == AGGR_STOP) { + if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { ieee80211_start_tx_ba_session(sta, tid); + spin_lock_bh(&priv->tx_lock); ista->tid_state[tid] = AGGR_PROGRESS; + spin_unlock_bh(&priv->tx_lock); } } } @@ -284,8 +310,7 @@ void ath9k_tx_cleanup(struct ath9k_htc_priv *priv) } -bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, - enum ath9k_tx_queue_subtype subtype) +bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype) { struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); @@ -293,13 +318,7 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int qnum; memset(&qi, 0, sizeof(qi)); - - qi.tqi_subtype = subtype; - qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; - qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; - qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; - qi.tqi_physCompBuf = 0; - qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE; + ATH9K_HTC_INIT_TXQ(subtype); qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi); if (qnum == -1) @@ -317,6 +336,16 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, return true; } +int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv) +{ + struct ath9k_tx_queue_info qi; + + memset(&qi, 0, sizeof(qi)); + ATH9K_HTC_INIT_TXQ(0); + + return ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_CAB, &qi); +} + /******/ /* RX */ /******/ @@ -387,9 +416,6 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) /* configure operational mode */ ath9k_hw_setopmode(ah); - /* Handle any link-level address change. */ - ath9k_hw_setmac(ah, common->macaddr); - /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); @@ -399,7 +425,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv) { ath9k_hw_rxena(priv->ah); ath9k_htc_opmode_init(priv); - ath9k_hw_startpcureceive(priv->ah); + ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING)); priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 064397fd738..705c0f342e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -89,7 +89,6 @@ static void htc_process_target_rdy(struct htc_target *target, struct htc_endpoint *endpoint; struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf; - target->credits = be16_to_cpu(htc_ready_msg->credits); target->credit_size = be16_to_cpu(htc_ready_msg->credit_size); endpoint = &target->endpoint[ENDPOINT0]; @@ -159,7 +158,7 @@ static int htc_config_pipe_credits(struct htc_target *target) cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID); cp_msg->pipe_id = USB_WLAN_TX_PIPE; - cp_msg->credits = 28; + cp_msg->credits = target->credits; target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 624422a8169..ffecbadaea4 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -128,6 +128,17 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); } +static inline void ath9k_hw_procmibevent(struct ath_hw *ah) +{ + ath9k_hw_ops(ah)->ani_proc_mib_event(ah); +} + +static inline void ath9k_hw_ani_monitor(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + ath9k_hw_ops(ah)->ani_monitor(ah, chan); +} + /* Private hardware call ops */ /* PHY ops */ @@ -253,12 +264,6 @@ static inline void ath9k_hw_do_getnf(struct ath_hw *ah, ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray); } -static inline void ath9k_hw_loadnf(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - ath9k_hw_private_ops(ah)->loadnf(ah, chan); -} - static inline bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -277,4 +282,9 @@ static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah, return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType); } +static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) +{ + ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning); +} + #endif /* ATH9K_HW_OPS_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c33f17dbe6f..8d291ccf5c8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -23,11 +23,6 @@ #include "rc.h" #include "ar9003_mac.h" -#define ATH9K_CLOCK_RATE_CCK 22 -#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 -#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 -#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44 - static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); MODULE_AUTHOR("Atheros Communications"); @@ -80,6 +75,15 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); } +static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) +{ + /* You will not have this callback if using the old ANI */ + if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs) + return; + + ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah); +} + /********************/ /* Helper Functions */ /********************/ @@ -371,13 +375,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.ofdm_trig_high = 500; ah->config.cck_trig_high = 200; ah->config.cck_trig_low = 100; - - /* - * For now ANI is disabled for AR9003, it is still - * being tested. - */ - if (!AR_SREV_9300_20_OR_LATER(ah)) - ah->config.enable_ani = 1; + ah->config.enable_ani = true; for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { ah->config.spurchans[i][0] = AR_NO_SPUR; @@ -390,12 +388,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.ht_enable = 0; ah->config.rx_intr_mitigation = true; - - /* - * Tx IQ Calibration (ah->config.tx_iq_calibration) is only - * used by AR9003, but it is showing reliability issues. - * It will take a while to fix so this is currently disabled. - */ + ah->config.pcieSerDesWrite = true; /* * We need this for PCI devices only (Cardbus, PCI, miniPCI) @@ -433,7 +426,9 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->ah_flags = AH_USE_EEPROM; ah->atim_window = 0; - ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; + ah->sta_id1_defaults = + AR_STA_ID1_CRPT_MIC_ENABLE | + AR_STA_ID1_MCAST_KSRCH; ah->beacon_interval = 100; ah->enable_32kHz_clock = DONT_USE_32KHZ; ah->slottime = (u32) -1; @@ -537,7 +532,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - (AR_SREV_9280(ah) && !ah->is_pciexpress)) { + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && + !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; } else { @@ -571,28 +567,19 @@ static int __ath9k_hw_init(struct ath_hw *ah) ah->ani_function = ATH9K_ANI_ALL; if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; + if (!AR_SREV_9300_20_OR_LATER(ah)) + ah->ani_function &= ~ATH9K_ANI_MRC_CCK; ath9k_hw_init_mode_regs(ah); /* - * Configire PCIE after Ini init. SERDES values now come from ini file - * This enables PCIe low power mode. + * Read back AR_WA into a permanent copy and set bits 14 and 17. + * We need to do this to avoid RMW of this register. We cannot + * read the reg when chip is asleep. */ - if (AR_SREV_9300_20_OR_LATER(ah)) { - u32 regval; - unsigned int i; - - /* Set Bits 16 and 17 in the AR_WA register. */ - regval = REG_READ(ah, AR_WA); - regval |= 0x00030000; - REG_WRITE(ah, AR_WA, regval); - - for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { - REG_WRITE(ah, - INI_RA(&ah->iniPcieSerdesLowPower, i, 0), - INI_RA(&ah->iniPcieSerdesLowPower, i, 1)); - } - } + ah->WARegVal = REG_READ(ah, AR_WA); + ah->WARegVal |= (AR_WA_D3_L1_DISABLE | + AR_WA_ASPM_TIMER_BASED_DISABLE); if (ah->is_pciexpress) ath9k_hw_configpcipowersave(ah, 0, 0); @@ -623,10 +610,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) else ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); - if (AR_SREV_9300_20_OR_LATER(ah)) - ar9003_hw_set_nf_limits(ah); - ath9k_init_nfcal_hist_buffer(ah); + ah->bb_watchdog_timeout_ms = 25; common->state = ATH_HW_INITIALIZED; @@ -1012,6 +997,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) ENABLE_REGWRITE_BUFFER(ah); + if (AR_SREV_9300_20_OR_LATER(ah)) { + REG_WRITE(ah, AR_WA, ah->WARegVal); + udelay(10); + } + REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); @@ -1066,6 +1056,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) { ENABLE_REGWRITE_BUFFER(ah); + if (AR_SREV_9300_20_OR_LATER(ah)) { + REG_WRITE(ah, AR_WA, ah->WARegVal); + udelay(10); + } + REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); @@ -1073,6 +1068,7 @@ 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); DISABLE_REGWRITE_BUFFER(ah); @@ -1102,6 +1098,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) { + if (AR_SREV_9300_20_OR_LATER(ah)) { + REG_WRITE(ah, AR_WA, ah->WARegVal); + udelay(10); + } + REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); @@ -1232,9 +1233,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ah->chip_fullsleep) { ath9k_hw_abortpcurecv(ah); - if (!ath9k_hw_stopdmarecv(ah)) + if (!ath9k_hw_stopdmarecv(ah)) { ath_print(common, ATH_DBG_XMIT, "Failed to stop receive dma\n"); + bChannelChange = false; + } } if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) @@ -1265,7 +1268,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; /* For chips on which RTC reset is done, save TSF before it gets cleared */ - if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + if (AR_SREV_9100(ah) || + (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) tsf = ath9k_hw_gettsf64(ah); saveLedState = REG_READ(ah, AR_CFG_LED) & @@ -1297,16 +1301,30 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } /* Restore TSF */ - if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + if (tsf) ath9k_hw_settsf64(ah, tsf); if (AR_SREV_9280_10_OR_LATER(ah)) REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); + if (!AR_SREV_9300_20_OR_LATER(ah)) + ar9002_hw_enable_async_fifo(ah); + r = ath9k_hw_process_ini(ah, chan); if (r) return r; + /* + * Some AR91xx SoC devices frequently fail to accept TSF writes + * right after the chip reset. When that happens, write a new + * value after the initvals have been applied, with an offset + * based on measured time difference + */ + if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { + tsf += 1500; + ath9k_hw_settsf64(ah, tsf); + } + /* Setup MFP options for CCMP */ if (AR_SREV_9280_20_OR_LATER(ah)) { /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt @@ -1367,6 +1385,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_resettxqueue(ah, i); ath9k_hw_init_interrupt_masks(ah, ah->opmode); + ath9k_hw_ani_cache_ini_regs(ah); ath9k_hw_init_qos(ah); if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) @@ -1375,7 +1394,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_init_global_settings(ah); if (!AR_SREV_9300_20_OR_LATER(ah)) { - ar9002_hw_enable_async_fifo(ah); + ar9002_hw_update_async_fifo(ah); ar9002_hw_enable_wep_aggregation(ah); } @@ -1426,9 +1445,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); } } else { - /* Configure AR9271 target WLAN */ - if (AR_SREV_9271(ah)) - REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); + if (common->bus_ops->ath_bus_type == ATH_USB) { + /* Configure AR9271 target WLAN */ + if (AR_SREV_9271(ah)) + REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); + else + REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); + } #ifdef __BIG_ENDIAN else REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); @@ -1441,6 +1464,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (AR_SREV_9300_20_OR_LATER(ah)) { ath9k_hw_loadnf(ah, curchan); ath9k_hw_start_nfcal(ah); + ar9003_hw_bb_watchdog_config(ah); } return 0; @@ -1486,9 +1510,10 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) } EXPORT_SYMBOL(ath9k_hw_keyreset); -bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) +static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) { u32 macHi, macLo; + u32 unicast_flag = AR_KEYTABLE_VALID; if (entry >= ah->caps.keycache_size) { ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, @@ -1497,6 +1522,16 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) } if (mac != NULL) { + /* + * AR_KEYTABLE_VALID indicates that the address is a unicast + * address, which must match the transmitter address for + * decrypting frames. + * Not setting this bit allows the hardware to use the key + * for multicast frame decryption. + */ + if (mac[0] & 0x01) + unicast_flag = 0; + macHi = (mac[5] << 8) | mac[4]; macLo = (mac[3] << 24) | (mac[2] << 16) | @@ -1509,11 +1544,10 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) macLo = macHi = 0; } REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); - REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID); + REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); return true; } -EXPORT_SYMBOL(ath9k_hw_keysetmac); bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, const struct ath9k_keyval *k, @@ -1714,17 +1748,6 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, } EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); -bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry) -{ - if (entry < ah->caps.keycache_size) { - u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry)); - if (val & AR_KEYTABLE_VALID) - return true; - } - return false; -} -EXPORT_SYMBOL(ath9k_hw_keyisvalid); - /******************************/ /* Power Management (Chipset) */ /******************************/ @@ -1751,6 +1774,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) REG_CLR_BIT(ah, (AR_RTC_RESET), AR_RTC_RESET_EN); } + + /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ + if (AR_SREV_9300_20_OR_LATER(ah)) + REG_WRITE(ah, AR_WA, + ah->WARegVal & ~AR_WA_D3_L1_DISABLE); } /* @@ -1777,6 +1805,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) AR_RTC_FORCE_WAKE_EN); } } + + /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ + if (AR_SREV_9300_20_OR_LATER(ah)) + REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); } static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) @@ -1784,6 +1816,12 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) u32 val; int i; + /* Set Bits 14 and 17 of AR_WA before powering on the chip. */ + if (AR_SREV_9300_20_OR_LATER(ah)) { + REG_WRITE(ah, AR_WA, ah->WARegVal); + udelay(10); + } + if (setChip) { if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { @@ -2138,6 +2176,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9271(ah)) pCap->num_gpio_pins = AR9271_NUM_GPIO; + else if (AR_DEVID_7010(ah)) + pCap->num_gpio_pins = AR7010_NUM_GPIO; else if (AR_SREV_9285_10_OR_LATER(ah)) pCap->num_gpio_pins = AR9285_NUM_GPIO; else if (AR_SREV_9280_10_OR_LATER(ah)) @@ -2165,7 +2205,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; } #endif - if (AR_SREV_9271(ah)) + if (AR_SREV_9271(ah) || AR_SREV_9300_20_OR_LATER(ah)) pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; else pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; @@ -2220,6 +2260,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->rx_status_len = sizeof(struct ar9003_rxs); pCap->tx_desc_len = sizeof(struct ar9003_txc); pCap->txs_len = sizeof(struct ar9003_txs); + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) + pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; } else { pCap->tx_desc_len = sizeof(struct ath_desc); if (AR_SREV_9280_20(ah) && @@ -2232,100 +2274,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; - return 0; -} - -bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, - u32 capability, u32 *result) -{ - struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); - switch (type) { - case ATH9K_CAP_CIPHER: - switch (capability) { - case ATH9K_CIPHER_AES_CCM: - case ATH9K_CIPHER_AES_OCB: - case ATH9K_CIPHER_TKIP: - case ATH9K_CIPHER_WEP: - case ATH9K_CIPHER_MIC: - case ATH9K_CIPHER_CLR: - return true; - default: - return false; - } - case ATH9K_CAP_TKIP_MIC: - switch (capability) { - case 0: - return true; - case 1: - return (ah->sta_id1_defaults & - AR_STA_ID1_CRPT_MIC_ENABLE) ? true : - false; - } - case ATH9K_CAP_TKIP_SPLIT: - return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ? - false : true; - case ATH9K_CAP_MCAST_KEYSRCH: - switch (capability) { - case 0: - return true; - case 1: - if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) { - return false; - } else { - return (ah->sta_id1_defaults & - AR_STA_ID1_MCAST_KSRCH) ? true : - false; - } - } - return false; - case ATH9K_CAP_TXPOW: - switch (capability) { - case 0: - return 0; - case 1: - *result = regulatory->power_limit; - return 0; - case 2: - *result = regulatory->max_power_level; - return 0; - case 3: - *result = regulatory->tp_scale; - return 0; - } - return false; - case ATH9K_CAP_DS: - return (AR_SREV_9280_20_OR_LATER(ah) && - (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1)) - ? false : true; - default: - return false; - } -} -EXPORT_SYMBOL(ath9k_hw_getcapability); + if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; -bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, - u32 capability, u32 setting, int *status) -{ - switch (type) { - case ATH9K_CAP_TKIP_MIC: - if (setting) - ah->sta_id1_defaults |= - AR_STA_ID1_CRPT_MIC_ENABLE; - else - ah->sta_id1_defaults &= - ~AR_STA_ID1_CRPT_MIC_ENABLE; - return true; - case ATH9K_CAP_MCAST_KEYSRCH: - if (setting) - ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH; - else - ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH; - return true; - default: - return false; - } + return 0; } -EXPORT_SYMBOL(ath9k_hw_setcapability); /****************************/ /* GPIO / RFKILL / Antennae */ @@ -2365,8 +2318,15 @@ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio) BUG_ON(gpio >= ah->caps.num_gpio_pins); - gpio_shift = gpio << 1; + if (AR_DEVID_7010(ah)) { + gpio_shift = gpio; + REG_RMW(ah, AR7010_GPIO_OE, + (AR7010_GPIO_OE_AS_INPUT << gpio_shift), + (AR7010_GPIO_OE_MASK << gpio_shift)); + return; + } + gpio_shift = gpio << 1; REG_RMW(ah, AR_GPIO_OE_OUT, (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), @@ -2382,7 +2342,11 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) if (gpio >= ah->caps.num_gpio_pins) return 0xffffffff; - if (AR_SREV_9300_20_OR_LATER(ah)) + if (AR_DEVID_7010(ah)) { + u32 val; + val = REG_READ(ah, AR7010_GPIO_IN); + return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; + } else if (AR_SREV_9300_20_OR_LATER(ah)) return MS_REG_READ(AR9300, gpio) != 0; else if (AR_SREV_9271(ah)) return MS_REG_READ(AR9271, gpio) != 0; @@ -2402,10 +2366,16 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, { u32 gpio_shift; - ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); + if (AR_DEVID_7010(ah)) { + gpio_shift = gpio; + REG_RMW(ah, AR7010_GPIO_OE, + (AR7010_GPIO_OE_AS_OUTPUT << gpio_shift), + (AR7010_GPIO_OE_MASK << gpio_shift)); + return; + } + ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); gpio_shift = 2 * gpio; - REG_RMW(ah, AR_GPIO_OE_OUT, (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), @@ -2415,6 +2385,13 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output); void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) { + if (AR_DEVID_7010(ah)) { + val = val ? 0 : 1; + REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio), + AR_GPIO_BIT(gpio)); + return; + } + if (AR_SREV_9271(ah)) val = ~val; @@ -2520,12 +2497,6 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) } EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); -void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) -{ - memcpy(ath9k_hw_common(ah)->macaddr, mac, ETH_ALEN); -} -EXPORT_SYMBOL(ath9k_hw_setmac); - void ath9k_hw_setopmode(struct ath_hw *ah) { ath9k_hw_set_operating_mode(ah, ah->opmode); @@ -2598,21 +2569,6 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) } EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); -/* - * Extend 15-bit time stamp from rx descriptor to - * a full 64-bit TSF using the current h/w TSF. -*/ -u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) -{ - u64 tsf; - - tsf = ath9k_hw_gettsf64(ah); - if ((tsf & 0x7fff) < rstamp) - tsf -= 0x8000; - return (tsf & ~0x7fff) | rstamp; -} -EXPORT_SYMBOL(ath9k_hw_extend_tsf); - void ath9k_hw_set11nmac2040(struct ath_hw *ah) { struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 77245dff599..2d30efc0b94 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -158,6 +158,9 @@ #define ATH9K_HW_RX_HP_QDEPTH 16 #define ATH9K_HW_RX_LP_QDEPTH 128 +#define PAPRD_GAIN_TABLE_ENTRIES 32 +#define PAPRD_TABLE_SZ 24 + enum ath_ini_subsys { ATH_INI_PRE = 0, ATH_INI_CORE, @@ -199,15 +202,8 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), ATH9K_HW_CAP_LDPC = BIT(19), ATH9K_HW_CAP_FASTCLOCK = BIT(20), -}; - -enum ath9k_capability_type { - ATH9K_CAP_CIPHER = 0, - ATH9K_CAP_TKIP_MIC, - ATH9K_CAP_TKIP_SPLIT, - ATH9K_CAP_TXPOW, - ATH9K_CAP_MCAST_KEYSRCH, - ATH9K_CAP_DS + ATH9K_HW_CAP_SGI_20 = BIT(21), + ATH9K_HW_CAP_PAPRD = BIT(22), }; struct ath9k_hw_capabilities { @@ -237,8 +233,9 @@ struct ath9k_ops_config { int sw_beacon_response_time; int additional_swba_backoff; int ack_6mb; - int cwm_ignore_extcca; + u32 cwm_ignore_extcca; u8 pcie_powersave_enable; + bool pcieSerDesWrite; u8 pcie_clock_req; u32 pcie_waen; u8 analog_shiftreg; @@ -262,10 +259,10 @@ struct ath9k_ops_config { #define AR_BASE_FREQ_5GHZ 4900 #define AR_SPUR_FEEQ_BOUND_HT40 19 #define AR_SPUR_FEEQ_BOUND_HT20 10 - bool tx_iq_calibration; /* Only available for >= AR9003 */ int spurmode; u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; u8 max_txtrig_level; + u16 ani_poll_interval; /* ANI poll interval in ms */ }; enum ath9k_int { @@ -279,6 +276,7 @@ enum ath9k_int { ATH9K_INT_TX = 0x00000040, ATH9K_INT_TXDESC = 0x00000080, ATH9K_INT_TIM_TIMER = 0x00000100, + ATH9K_INT_BB_WATCHDOG = 0x00000400, ATH9K_INT_TXURN = 0x00000800, ATH9K_INT_MIB = 0x00001000, ATH9K_INT_RXPHY = 0x00004000, @@ -358,6 +356,9 @@ struct ath9k_channel { int8_t iCoff; int8_t qCoff; int16_t rawNoiseFloor; + bool paprd_done; + u16 small_signal_gain[AR9300_MAX_CHAINS]; + u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; }; #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ @@ -459,7 +460,7 @@ struct ath9k_hw_version { #define AR_GENTMR_BIT(_index) (1 << (_index)) /* - * Using de Bruijin sequence to to look up 1's index in a 32 bit number + * Using de Bruijin sequence to look up 1's index in a 32 bit number * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001 */ #define debruijn32 0x077CB531U @@ -509,7 +510,17 @@ struct ath_gen_timer_table { * AR_RTC_PLL_CONTROL for a given channel * @setup_calibration: set up calibration * @iscal_supported: used to query if a type of calibration is supported - * @loadnf: load noise floor read from each chain on the CCA registers + * + * @ani_reset: reset ANI parameters to default values + * @ani_lower_immunity: lower the noise immunity level. The level controls + * the power-based packet detection on hardware. If a power jump is + * detected the adapter takes it as an indication that a packet has + * arrived. The level ranges from 0-5. Each level corresponds to a + * few dB more of noise immunity. If you have a strong time-varying + * interference that is causing false detections (OFDM timing errors or + * CCK timing errors) the level can be increased. + * @ani_cache_ini_regs: cache the values for ANI from the initial + * register settings through the register initialization. */ struct ath_hw_private_ops { /* Calibration ops */ @@ -552,7 +563,11 @@ struct ath_hw_private_ops { bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param); void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); - void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan); + + /* ANI */ + void (*ani_reset)(struct ath_hw *ah, bool is_scanning); + void (*ani_lower_immunity)(struct ath_hw *ah); + void (*ani_cache_ini_regs)(struct ath_hw *ah); }; /** @@ -563,6 +578,11 @@ struct ath_hw_private_ops { * * @config_pci_powersave: * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC + * + * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI + * thresholds being reached or having overflowed. + * @ani_monitor: called periodically by the core driver to collect + * MIB stats and adjust ANI if specific thresholds have been reached. */ struct ath_hw_ops { void (*config_pci_powersave)(struct ath_hw *ah, @@ -603,6 +623,15 @@ struct ath_hw_ops { u32 burstDuration); void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, u32 vmf); + + void (*ani_proc_mib_event)(struct ath_hw *ah); + void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan); +}; + +struct ath_nf_limits { + s16 max; + s16 min; + s16 nominal; }; struct ath_hw { @@ -626,10 +655,10 @@ struct ath_hw { bool is_pciexpress; bool need_an_top2_fixup; u16 tx_trig_level; - s16 nf_2g_max; - s16 nf_2g_min; - s16 nf_5g_max; - s16 nf_5g_min; + + u32 nf_regs[6]; + struct ath_nf_limits nf_2g; + struct ath_nf_limits nf_5g; u16 rfsilent; u32 rfkill_gpio; u32 rfkill_polarity; @@ -789,6 +818,18 @@ struct ath_hw { u32 ts_paddr_end; u16 ts_tail; u8 ts_size; + + u32 bb_watchdog_last_status; + u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ + + u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; + u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; + /* + * Store the permanent value of Reg 0x4004in WARegVal + * so we dont have to R/M/W. We should not be reading + * this register when in sleep states. + */ + u32 WARegVal; }; static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) @@ -811,6 +852,12 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah) return &ah->ops; } +static inline int sign_extend(int val, const int nbits) +{ + int order = BIT(nbits-1); + return (val ^ order) - order; +} + /* Initialization, Detach, Reset */ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); @@ -818,19 +865,13 @@ int ath9k_hw_init(struct ath_hw *ah); int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, bool bChannelChange); int ath9k_hw_fill_cap_info(struct ath_hw *ah); -bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, - u32 capability, u32 *result); -bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, - u32 capability, u32 setting, int *status); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); /* Key Cache Management */ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); -bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac); bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, const struct ath9k_keyval *k, const u8 *mac); -bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry); /* GPIO / RFKILL / Antennae */ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); @@ -856,7 +897,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); bool ath9k_hw_phy_disable(struct ath_hw *ah); bool ath9k_hw_disable(struct ath_hw *ah); void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); -void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac); void ath9k_hw_setopmode(struct ath_hw *ah); void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); void ath9k_hw_setbssidmask(struct ath_hw *ah); @@ -865,7 +905,6 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah); void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); void ath9k_hw_reset_tsf(struct ath_hw *ah); void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); -u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); void ath9k_hw_init_global_settings(struct ath_hw *ah); void ath9k_hw_set11nmac2040(struct ath_hw *ah); void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); @@ -907,13 +946,25 @@ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); int ar9002_hw_rf_claim(struct ath_hw *ah); void ar9002_hw_enable_async_fifo(struct ath_hw *ah); +void ar9002_hw_update_async_fifo(struct ath_hw *ah); void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); /* - * Code specifric to AR9003, we stuff these here to avoid callbacks + * Code specific to AR9003, we stuff these here to avoid callbacks * for older families */ -void ar9003_hw_set_nf_limits(struct ath_hw *ah); +void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); +void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); +void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); +void ar9003_paprd_enable(struct ath_hw *ah, bool val); +void ar9003_paprd_populate_single_table(struct ath_hw *ah, + struct ath9k_channel *chan, int chain); +int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, + int chain); +int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); +int ar9003_paprd_init_table(struct ath_hw *ah); +bool ar9003_paprd_is_done(struct ath_hw *ah); +void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains); /* Hardware family op attach helpers */ void ar5008_hw_attach_phy_ops(struct ath_hw *ah); @@ -926,8 +977,24 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah); void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); +/* + * ANI work can be shared between all families but a next + * generation implementation of ANI will be used only for AR9003 only + * for now as the other families still need to be tested with the same + * next generation ANI. Feel free to start testing it though for the + * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. + */ +extern int modparam_force_new_ani; +void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); +void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); + #define ATH_PCIE_CAP_LINK_CTRL 0x70 #define ATH_PCIE_CAP_LINK_L0S 1 #define ATH_PCIE_CAP_LINK_L1 2 +#define ATH9K_CLOCK_RATE_CCK 22 +#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 +#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 +#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44 + #endif diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d457cb3bd77..243c1775f34 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -33,6 +33,10 @@ int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); +int led_blink = 1; +module_param_named(blink, led_blink, int, 0444); +MODULE_PARM_DESC(blink, "Enable LED blink on activity"); + /* We use the hw_value as an index into our private channel structure */ #define CHAN2G(_freq, _idx) { \ @@ -175,18 +179,6 @@ static const struct ath_ops ath9k_common_ops = { .write = ath9k_iowrite32, }; -static int count_streams(unsigned int chainmask, int max) -{ - int streams = 0; - - do { - if (++streams == max) - break; - } while ((chainmask = chainmask & (chainmask - 1))); - - return streams; -} - /**************************/ /* Initialization */ /**************************/ @@ -208,6 +200,9 @@ static void setup_ht_cap(struct ath_softc *sc, if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) + ht_info->cap |= IEEE80211_HT_CAP_SGI_20; + ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; @@ -224,8 +219,8 @@ static void setup_ht_cap(struct ath_softc *sc, /* set up supported mcs set */ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - tx_streams = count_streams(common->tx_chainmask, max_streams); - rx_streams = count_streams(common->rx_chainmask, max_streams); + tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); + rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); ath_print(common, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", @@ -388,36 +383,14 @@ static void ath9k_init_crypto(struct ath_softc *sc) for (i = 0; i < common->keymax; i++) ath9k_hw_keyreset(sc->sc_ah, (u16) i); - if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL)) { - /* - * Whether we should enable h/w TKIP MIC. - * XXX: if we don't support WME TKIP MIC, then we wouldn't - * report WMM capable, so it's always safe to turn on - * TKIP MIC in this case. - */ - ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); - } - /* * Check whether the separate key cache entries * are required to handle both tx+rx MIC keys. * With split mic keys the number of stations is limited * to 27 otherwise 59. */ - if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_TKIP, NULL) - && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER, - ATH9K_CIPHER_MIC, NULL) - && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT, - 0, NULL)) + if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)) common->splitmic = 1; - - /* turn on mcast key search if possible */ - if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) - (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, - 1, 1, NULL); - } static int ath9k_init_btcoex(struct ath_softc *sc) @@ -435,7 +408,7 @@ static int ath9k_init_btcoex(struct ath_softc *sc) r = ath_init_btcoex_timer(sc); if (r) return -1; - qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); + qnum = sc->tx.hwq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; break; @@ -472,23 +445,23 @@ static int ath9k_init_queues(struct ath_softc *sc) sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { + if (!ath_tx_setup(sc, WME_AC_BK)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for BK traffic\n"); goto err; } - if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { + if (!ath_tx_setup(sc, WME_AC_BE)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for BE traffic\n"); goto err; } - if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { + if (!ath_tx_setup(sc, WME_AC_VI)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for VI traffic\n"); goto err; } - if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { + if (!ath_tx_setup(sc, WME_AC_VO)) { ath_print(common, ATH_DBG_FATAL, "Unable to setup xmit queue for VO traffic\n"); goto err; @@ -745,6 +718,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, goto error_world; } + INIT_WORK(&sc->hw_check_work, ath_hw_check); + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); sc->wiphy_scheduler_int = msecs_to_jiffies(500); @@ -812,12 +787,12 @@ void ath9k_deinit_device(struct ath_softc *sc) ieee80211_unregister_hw(aphy->hw); ieee80211_free_hw(aphy->hw); } - kfree(sc->sec_wiphy); ieee80211_unregister_hw(hw); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); + kfree(sc->sec_wiphy); } void ath_descdma_cleanup(struct ath_softc *sc, diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 0e425cb4bbb..e955bb9d98c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -15,6 +15,7 @@ */ #include "hw.h" +#include "hw-ops.h" static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, struct ath9k_tx_queue_info *qi) @@ -554,8 +555,13 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REGWRITE_BUFFER_FLUSH(ah); DISABLE_REGWRITE_BUFFER(ah); - /* cwmin and cwmax should be 0 for beacon queue */ - if (AR_SREV_9300_20_OR_LATER(ah)) { + /* + * cwmin and cwmax should be 0 for beacon queue + * but not for IBSS as we would create an imbalance + * on beaconing fairness for participating nodes. + */ + if (AR_SREV_9300_20_OR_LATER(ah) && + ah->opmode != NL80211_IFTYPE_ADHOC) { REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN) | SM(0, AR_D_LCL_IFS_CWMAX) | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); @@ -756,11 +762,11 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp) } EXPORT_SYMBOL(ath9k_hw_putrxbuf); -void ath9k_hw_startpcureceive(struct ath_hw *ah) +void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning) { ath9k_enable_mib_counters(ah); - ath9k_ani_reset(ah); + ath9k_ani_reset(ah, is_scanning); REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); } diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 00f3e0c7528..2633896d399 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -485,6 +485,9 @@ struct ar5416_desc { #define AR_TxRSSICombined 0xff000000 #define AR_TxRSSICombined_S 24 +#define AR_TxTid 0xf0000000 +#define AR_TxTid_S 28 + #define AR_TxEVM0 ds_txstatus5 #define AR_TxEVM1 ds_txstatus6 #define AR_TxEVM2 ds_txstatus7 @@ -577,13 +580,8 @@ enum ath9k_tx_queue { #define ATH9K_NUM_TX_QUEUES 10 -enum ath9k_tx_queue_subtype { - ATH9K_WME_AC_BK = 0, - ATH9K_WME_AC_BE, - ATH9K_WME_AC_VI, - ATH9K_WME_AC_VO, - ATH9K_WME_UPSD -}; +/* Used as a queue subtype instead of a WMM AC */ +#define ATH9K_WME_UPSD 4 enum ath9k_tx_queue_flags { TXQ_FLAG_TXOKINT_ENABLE = 0x0001, @@ -617,7 +615,7 @@ enum ath9k_pkt_type { struct ath9k_tx_queue_info { u32 tqi_ver; enum ath9k_tx_queue tqi_type; - enum ath9k_tx_queue_subtype tqi_subtype; + int tqi_subtype; enum ath9k_tx_queue_flags tqi_qflags; u32 tqi_priority; u32 tqi_aifs; @@ -715,7 +713,7 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags); bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); -void ath9k_hw_startpcureceive(struct ath_hw *ah); +void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning); void ath9k_hw_stoppcurecv(struct ath_hw *ah); void ath9k_hw_abortpcurecv(struct ath_hw *ah); bool ath9k_hw_stopdmarecv(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index abfa0493236..0429dda0961 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -51,13 +51,11 @@ static void ath_cache_conf_rate(struct ath_softc *sc, static void ath_update_txpow(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - u32 txpow; if (sc->curtxpow != sc->config.txpowlimit) { ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit); /* read back in case value is clamped */ - ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); - sc->curtxpow = txpow; + sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; } } @@ -232,6 +230,114 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, return r; } +static void ath_paprd_activate(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + int chain; + + if (!ah->curchan->paprd_done) + return; + + ath9k_ps_wakeup(sc); + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { + if (!(ah->caps.tx_chainmask & BIT(chain))) + continue; + + ar9003_paprd_populate_single_table(ah, ah->curchan, chain); + } + + ar9003_paprd_enable(ah, true); + ath9k_ps_restore(sc); +} + +void ath_paprd_calibrate(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); + struct ieee80211_hw *hw = sc->hw; + struct ath_hw *ah = sc->sc_ah; + struct ieee80211_hdr *hdr; + struct sk_buff *skb = NULL; + struct ieee80211_tx_info *tx_info; + int band = hw->conf.channel->band; + struct ieee80211_supported_band *sband = &sc->sbands[band]; + struct ath_tx_control txctl; + int qnum, ftype; + int chain_ok = 0; + int chain; + int len = 1800; + int time_left; + int i; + + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) + return; + + tx_info = IEEE80211_SKB_CB(skb); + + skb_put(skb, len); + memset(skb->data, 0, len); + hdr = (struct ieee80211_hdr *)skb->data; + ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; + hdr->frame_control = cpu_to_le16(ftype); + hdr->duration_id = cpu_to_le16(10); + memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); + + memset(&txctl, 0, sizeof(txctl)); + qnum = sc->tx.hwq_map[WME_AC_BE]; + txctl.txq = &sc->tx.txq[qnum]; + + ath9k_ps_wakeup(sc); + ar9003_paprd_init_table(ah); + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { + if (!(ah->caps.tx_chainmask & BIT(chain))) + continue; + + chain_ok = 0; + memset(tx_info, 0, sizeof(*tx_info)); + tx_info->band = band; + + for (i = 0; i < 4; i++) { + tx_info->control.rates[i].idx = sband->n_bitrates - 1; + tx_info->control.rates[i].count = 6; + } + + init_completion(&sc->paprd_complete); + ar9003_paprd_setup_gain_table(ah, chain); + txctl.paprd = BIT(chain); + if (ath_tx_start(hw, skb, &txctl) != 0) + break; + + time_left = wait_for_completion_timeout(&sc->paprd_complete, + msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); + if (!time_left) { + ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, + "Timeout waiting for paprd training on " + "TX chain %d\n", + chain); + goto fail_paprd; + } + + if (!ar9003_paprd_is_done(ah)) + break; + + if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0) + break; + + chain_ok = 1; + } + kfree_skb(skb); + + if (chain_ok) { + ah->curchan->paprd_done = true; + ath_paprd_activate(sc); + } + +fail_paprd: + ath9k_ps_restore(sc); +} + /* * This routine performs the periodic noise floor calibration function * that is used to adjust and optimize the chip performance. This @@ -285,7 +391,8 @@ void ath_ani_calibrate(unsigned long data) } /* Verify whether we must check ANI */ - if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { + if ((timestamp - common->ani.checkani_timer) >= + ah->config.ani_poll_interval) { aniflag = true; common->ani.checkani_timer = timestamp; } @@ -326,23 +433,37 @@ set_timer: */ cal_interval = ATH_LONG_CALINTERVAL; if (sc->sc_ah->config.enable_ani) - cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); + cal_interval = min(cal_interval, + (u32)ah->config.ani_poll_interval); if (!common->ani.caldone) cal_interval = min(cal_interval, (u32)short_cal_interval); mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && + !(sc->sc_flags & SC_OP_SCANNING)) { + if (!sc->sc_ah->curchan->paprd_done) + ieee80211_queue_work(sc->hw, &sc->paprd_work); + else + ath_paprd_activate(sc); + } } static void ath_start_ani(struct ath_common *common) { + struct ath_hw *ah = common->ah; unsigned long timestamp = jiffies_to_msecs(jiffies); + struct ath_softc *sc = (struct ath_softc *) common->priv; + + if (!(sc->sc_flags & SC_OP_ANI_RUN)) + return; common->ani.longcal_timer = timestamp; common->ani.shortcal_timer = timestamp; common->ani.checkani_timer = timestamp; mod_timer(&common->ani.timer, - jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); + jiffies + + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); } /* @@ -394,6 +515,25 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) ath_tx_node_cleanup(sc, an); } +void ath_hw_check(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); + int i; + + ath9k_ps_wakeup(sc); + + for (i = 0; i < 3; i++) { + if (ath9k_hw_check_alive(sc->sc_ah)) + goto out; + + msleep(1); + } + ath_reset(sc, false); + +out: + ath9k_ps_restore(sc); +} + void ath9k_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -405,13 +545,15 @@ void ath9k_tasklet(unsigned long data) ath9k_ps_wakeup(sc); - if ((status & ATH9K_INT_FATAL) || - !ath9k_hw_check_alive(ah)) { + if (status & ATH9K_INT_FATAL) { ath_reset(sc, false); ath9k_ps_restore(sc); return; } + if (!ath9k_hw_check_alive(ah)) + ieee80211_queue_work(sc->hw, &sc->hw_check_work); + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); @@ -520,6 +662,12 @@ irqreturn_t ath_isr(int irq, void *dev) !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) goto chip_reset; + if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && + (status & ATH9K_INT_BB_WATCHDOG)) { + ar9003_hw_bb_watchdog_dbg_info(ah); + goto chip_reset; + } + if (status & ATH9K_INT_SWBA) tasklet_schedule(&sc->bcon_tasklet); @@ -615,234 +763,6 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, return chanmode; } -static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, - struct ath9k_keyval *hk, const u8 *addr, - bool authenticator) -{ - struct ath_hw *ah = common->ah; - const u8 *key_rxmic; - const u8 *key_txmic; - - key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; - key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; - - if (addr == NULL) { - /* - * Group key installation - only two key cache entries are used - * regardless of splitmic capability since group key is only - * used either for TX or RX. - */ - if (authenticator) { - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); - } else { - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); - } - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - if (!common->splitmic) { - /* TX and RX keys share the same key cache entry. */ - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - - /* Separate key cache entries for TX and RX */ - - /* TX key goes at first index, RX key at +32. */ - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { - /* TX MIC entry failed. No need to proceed further */ - ath_print(common, ATH_DBG_FATAL, - "Setting TX MIC Key Failed\n"); - return 0; - } - - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - /* XXX delete tx key on failure? */ - return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); -} - -static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) -{ - int i; - - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap)) - continue; /* At least one part of TKIP key allocated */ - if (common->splitmic && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - continue; /* At least one part of TKIP key allocated */ - - /* Found a free slot for a TKIP key */ - return i; - } - return -1; -} - -static int ath_reserve_key_cache_slot(struct ath_common *common) -{ - int i; - - /* First, try to find slots that would not be available for TKIP. */ - if (common->splitmic) { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { - if (!test_bit(i, common->keymap) && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i; - if (!test_bit(i + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 32; - if (!test_bit(i + 64, common->keymap) && - (test_bit(i , common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 64; - if (!test_bit(i + 64 + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap))) - return i + 64 + 32; - } - } else { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (!test_bit(i, common->keymap) && - test_bit(i + 64, common->keymap)) - return i; - if (test_bit(i, common->keymap) && - !test_bit(i + 64, common->keymap)) - return i + 64; - } - } - - /* No partially used TKIP slots, pick any available slot */ - for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { - /* Do not allow slots that could be needed for TKIP group keys - * to be used. This limitation could be removed if we know that - * TKIP will not be used. */ - if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) - continue; - if (common->splitmic) { - if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) - continue; - if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) - continue; - } - - if (!test_bit(i, common->keymap)) - return i; /* Found a free slot for a key */ - } - - /* No free slot found */ - return -1; -} - -static int ath_key_config(struct ath_common *common, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct ath_hw *ah = common->ah; - struct ath9k_keyval hk; - const u8 *mac = NULL; - int ret = 0; - int idx; - - memset(&hk, 0, sizeof(hk)); - - switch (key->alg) { - case ALG_WEP: - hk.kv_type = ATH9K_CIPHER_WEP; - break; - case ALG_TKIP: - hk.kv_type = ATH9K_CIPHER_TKIP; - break; - case ALG_CCMP: - hk.kv_type = ATH9K_CIPHER_AES_CCM; - break; - default: - return -EOPNOTSUPP; - } - - hk.kv_len = key->keylen; - memcpy(hk.kv_val, key->key, key->keylen); - - if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - /* For now, use the default keys for broadcast keys. This may - * need to change with virtual interfaces. */ - idx = key->keyidx; - } else if (key->keyidx) { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - if (vif->type != NL80211_IFTYPE_AP) { - /* Only keyidx 0 should be used with unicast key, but - * allow this for client mode for now. */ - idx = key->keyidx; - } else - return -EIO; - } else { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - if (key->alg == ALG_TKIP) - idx = ath_reserve_key_cache_slot_tkip(common); - else - idx = ath_reserve_key_cache_slot(common); - if (idx < 0) - return -ENOSPC; /* no free key cache entries */ - } - - if (key->alg == ALG_TKIP) - ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, - vif->type == NL80211_IFTYPE_AP); - else - ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); - - if (!ret) - return -EIO; - - set_bit(idx, common->keymap); - if (key->alg == ALG_TKIP) { - set_bit(idx + 64, common->keymap); - if (common->splitmic) { - set_bit(idx + 32, common->keymap); - set_bit(idx + 64 + 32, common->keymap); - } - } - - return idx; -} - -static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) -{ - struct ath_hw *ah = common->ah; - - ath9k_hw_keyreset(ah, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) - return; - - clear_bit(key->hw_key_idx, common->keymap); - if (key->alg != ALG_TKIP) - return; - - clear_bit(key->hw_key_idx + 64, common->keymap); - if (common->splitmic) { - ath9k_hw_keyreset(ah, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); - } -} - static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) @@ -872,11 +792,13 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, /* Reset rssi stats */ sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; + sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); } else { ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); common->curaid = 0; /* Stop ANI */ + sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); } } @@ -935,9 +857,14 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_ps_wakeup(sc); ieee80211_stop_queues(hw); - /* Disable LED */ - ath9k_hw_set_gpio(ah, ah->led_pin, 1); - ath9k_hw_cfg_gpio_input(ah, ah->led_pin); + /* + * Keep the LED on when the radio is disabled + * during idle unassociated state. + */ + if (!sc->ps_idle) { + ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_cfg_gpio_input(ah, ah->led_pin); + } /* Disable interrupts */ ath9k_hw_set_interrupts(ah, 0); @@ -1026,25 +953,25 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } -int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) +static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) { int qnum; switch (queue) { case 0: - qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; + qnum = sc->tx.hwq_map[WME_AC_VO]; break; case 1: - qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; + qnum = sc->tx.hwq_map[WME_AC_VI]; break; case 2: - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; + qnum = sc->tx.hwq_map[WME_AC_BE]; break; case 3: - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; + qnum = sc->tx.hwq_map[WME_AC_BK]; break; default: - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; + qnum = sc->tx.hwq_map[WME_AC_BE]; break; } @@ -1056,16 +983,16 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) int qnum; switch (queue) { - case ATH9K_WME_AC_VO: + case WME_AC_VO: qnum = 0; break; - case ATH9K_WME_AC_VI: + case WME_AC_VI: qnum = 1; break; - case ATH9K_WME_AC_BE: + case WME_AC_BE: qnum = 2; break; - case ATH9K_WME_AC_BK: + case WME_AC_BK: qnum = 3; break; default: @@ -1195,7 +1122,9 @@ static int ath9k_start(struct ieee80211_hw *hw) ATH9K_INT_GLOBAL; if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP; + ah->imask |= ATH9K_INT_RXHP | + ATH9K_INT_RXLP | + ATH9K_INT_BB_WATCHDOG; else ah->imask |= ATH9K_INT_RX; @@ -1245,6 +1174,7 @@ static int ath9k_tx(struct ieee80211_hw *hw, struct ath_tx_control txctl; int padpos, padsize; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + int qnum; if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { ath_print(common, ATH_DBG_XMIT, @@ -1274,7 +1204,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, * completed and if needed, also for RX of buffered frames. */ ath9k_ps_wakeup(sc); - ath9k_hw_setrxabort(sc->sc_ah, 0); + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) + ath9k_hw_setrxabort(sc->sc_ah, 0); if (ieee80211_is_pspoll(hdr->frame_control)) { ath_print(common, ATH_DBG_PS, "Sending PS-Poll to pick a buffered frame\n"); @@ -1316,11 +1247,8 @@ static int ath9k_tx(struct ieee80211_hw *hw, memmove(skb->data, skb->data + padsize, padpos); } - /* Check if a tx queue is available */ - - txctl.txq = ath_test_get_txq(sc, skb); - if (!txctl.txq) - goto exit; + qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); + txctl.txq = &sc->tx.txq[qnum]; ath_print(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); @@ -1341,15 +1269,25 @@ static void ath9k_stop(struct ieee80211_hw *hw) struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); + int i; mutex_lock(&sc->mutex); aphy->state = ATH_WIPHY_INACTIVE; - cancel_delayed_work_sync(&sc->ath_led_blink_work); + if (led_blink) + cancel_delayed_work_sync(&sc->ath_led_blink_work); + cancel_delayed_work_sync(&sc->tx_complete_work); + cancel_work_sync(&sc->paprd_work); + cancel_work_sync(&sc->hw_check_work); - if (!sc->num_sec_wiphy) { + for (i = 0; i < sc->num_sec_wiphy; i++) { + if (sc->sec_wiphy[i]) + break; + } + + if (i == sc->num_sec_wiphy) { cancel_delayed_work_sync(&sc->wiphy_work); cancel_work_sync(&sc->chan_work); } @@ -1478,8 +1416,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MONITOR) + vif->type == NL80211_IFTYPE_MONITOR) { + sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); + } out: mutex_unlock(&sc->mutex); @@ -1500,6 +1440,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); /* Stop ANI */ + sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); /* Reclaim beacon resources */ @@ -1538,8 +1479,8 @@ void ath9k_enable_ps(struct ath_softc *sc) ah->imask |= ATH9K_INT_TIM_TIMER; ath9k_hw_set_interrupts(ah, ah->imask); } + ath9k_hw_setrxabort(ah, 1); } - ath9k_hw_setrxabort(ah, 1); } static int ath9k_config(struct ieee80211_hw *hw, u32 changed) @@ -1776,7 +1717,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) - if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) + if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) ath_beaconq_config(sc); mutex_unlock(&sc->mutex); @@ -1804,7 +1745,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - ret = ath_key_config(common, vif, sta, key); + ret = ath9k_cmn_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ @@ -1817,7 +1758,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath9k_cmn_key_delete(common, key); break; default: ret = -EINVAL; @@ -1990,6 +1931,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, struct ath_softc *sc = aphy->sc; int ret = 0; + local_bh_disable(); + switch (action) { case IEEE80211_AMPDU_RX_START: if (!(sc->sc_flags & SC_OP_RXAGGR)) @@ -2019,6 +1962,8 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, "Unknown AMPDU action\n"); } + local_bh_enable(); + return ret; } @@ -2049,11 +1994,12 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); if (ath9k_wiphy_scanning(sc)) { - printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the " - "same time\n"); /* - * Do not allow the concurrent scanning state for now. This - * could be improved with scanning control moved into ath9k. + * There is a race here in mac80211 but fixing it requires + * we revisit how we handle the scan complete callback. + * After mac80211 fixes we will not have configured hardware + * to the home channel nor would we have configured the RX + * filter yet. */ mutex_unlock(&sc->mutex); return; @@ -2063,10 +2009,16 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) ath9k_wiphy_pause_all_forced(sc, aphy); sc->sc_flags |= SC_OP_SCANNING; del_timer_sync(&common->ani.timer); + cancel_work_sync(&sc->paprd_work); + cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); mutex_unlock(&sc->mutex); } +/* + * XXX: this requires a revisit after the driver + * scan_complete gets moved to another place/removed in mac80211. + */ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) { struct ath_wiphy *aphy = hw->priv; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 1ec836cf1c0..b5b651413e7 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ + { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ { 0 } }; @@ -208,11 +209,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); - printk(KERN_INFO - "%s: %s mem=0x%lx, irq=%d\n", - wiphy_name(hw->wiphy), - hw_name, - (unsigned long)mem, pdev->irq); + wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", + hw_name, (unsigned long)mem, pdev->irq); return 0; diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 8519452c95f..e49be733d54 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -20,93 +20,145 @@ #include "ath9k.h" static const struct ath_rate_table ar5416_11na_ratetable = { - 42, + 68, 8, /* MCS start */ { - { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 0, 12, 0, 0, 0, 0, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 1, 18, 0, 1, 1, 1, 1 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10000, 2, 24, 2, 2, 2, 2, 2 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 13900, 3, 36, 2, 3, 3, 3, 3 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17300, 4, 48, 4, 4, 4, 4, 4 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23000, 5, 72, 4, 5, 5, 5, 5 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 6, 96, 4, 6, 6, 6, 6 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 29300, 7, 108, 4, 7, 7, 7, 7 }, - { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ - 6400, 0, 0, 0, 8, 24, 8, 24 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ - 12700, 1, 1, 2, 9, 25, 9, 25 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ - 18800, 2, 2, 2, 10, 26, 10, 26 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ - 25000, 3, 3, 4, 11, 27, 11, 27 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ - 36700, 4, 4, 4, 12, 28, 12, 28 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ - 48100, 5, 5, 4, 13, 29, 13, 29 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ - 53500, 6, 6, 4, 14, 30, 14, 30 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ - 59000, 7, 7, 4, 15, 31, 15, 32 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ - 12700, 8, 8, 3, 16, 33, 16, 33 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ - 24800, 9, 9, 2, 17, 34, 17, 34 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ - 36600, 10, 10, 2, 18, 35, 18, 35 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ - 48100, 11, 11, 4, 19, 36, 19, 36 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ - 69500, 12, 12, 4, 20, 37, 20, 37 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ - 89500, 13, 13, 4, 21, 38, 21, 38 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ - 98900, 14, 14, 4, 22, 39, 22, 39 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ - 108300, 15, 15, 4, 23, 40, 23, 41 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ - 13200, 0, 0, 0, 8, 24, 24, 24 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ - 25900, 1, 1, 2, 9, 25, 25, 25 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ - 38600, 2, 2, 2, 10, 26, 26, 26 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ - 49800, 3, 3, 4, 11, 27, 27, 27 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ - 72200, 4, 4, 4, 12, 28, 28, 28 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ - 92900, 5, 5, 4, 13, 29, 29, 29 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ - 102700, 6, 6, 4, 14, 30, 30, 30 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ - 112000, 7, 7, 4, 15, 31, 32, 32 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ - 122000, 7, 7, 4, 15, 31, 32, 32 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ - 25800, 8, 8, 0, 16, 33, 33, 33 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ - 49800, 9, 9, 2, 17, 34, 34, 34 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ - 71900, 10, 10, 2, 18, 35, 35, 35 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ - 92500, 11, 11, 4, 19, 36, 36, 36 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ - 130300, 12, 12, 4, 20, 37, 37, 37 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ - 162800, 13, 13, 4, 21, 38, 38, 38 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ - 178200, 14, 14, 4, 22, 39, 39, 39 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ - 192100, 15, 15, 4, 23, 40, 41, 41 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ - 207000, 15, 15, 4, 23, 40, 41, 41 }, + [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, + 5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */ + [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, + 7800, 1, 18, 0, 1, 1, 1 }, /* 9 Mb */ + [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, + 10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */ + [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, + 13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */ + [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, + 17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */ + [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, + 23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */ + [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, + 27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */ + [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, + 29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */ + [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500, + 6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */ + [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, + 12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */ + [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, + 18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */ + [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, + 25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */ + [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, + 36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */ + [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, + 48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */ + [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, + 53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */ + [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, + 59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */ + [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, + 65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */ + [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, + 12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */ + [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, + 24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */ + [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, + 36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */ + [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, + 48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */ + [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, + 69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */ + [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, + 89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */ + [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, + 98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */ + [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, + 108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */ + [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, + 120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */ + [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, + 17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */ + [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, + 35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */ + [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, + 52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */ + [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, + 70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */ + [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, + 104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */ + [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, + 115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/ + [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, + 137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */ + [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, + 151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */ + [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, + 152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */ + [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, + 168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/ + [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, + 168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */ + [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, + 185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */ + [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, + 13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/ + [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, + 25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/ + [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, + 38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/ + [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, + 49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */ + [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, + 72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */ + [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, + 92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */ + [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, + 102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/ + [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, + 112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */ + [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, + 122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */ + [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, + 25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */ + [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, + 49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */ + [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, + 71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */ + [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, + 92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */ + [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, + 130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */ + [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, + 162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */ + [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, + 178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */ + [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, + 192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */ + [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, + 207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */ + [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, + 36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */ + [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, + 72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */ + [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, + 108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */ + [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, + 142000, 19, 19, 4, 59, 59, 59 }, /* 162 Mb */ + [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, + 205100, 20, 20, 4, 60, 61, 61 }, /* 243 Mb */ + [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, + 224700, 20, 20, 4, 60, 61, 61 }, /* 270 Mb */ + [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, + 263100, 21, 21, 4, 62, 63, 63 }, /* 324 Mb */ + [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, + 288000, 21, 21, 4, 62, 63, 63 }, /* 360 Mb */ + [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, + 290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */ + [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, + 317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */ + [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, + 317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */ + [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, + 346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */ }, 50, /* probe interval */ WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ @@ -116,101 +168,153 @@ static const struct ath_rate_table ar5416_11na_ratetable = { * for HT are the 64K max aggregate limit */ static const struct ath_rate_table ar5416_11ng_ratetable = { - 46, + 72, 12, /* MCS start */ { - { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ - 900, 0, 2, 0, 0, 0, 0, 0 }, - { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ - 1900, 1, 4, 1, 1, 1, 1, 1 }, - { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ - 4900, 2, 11, 2, 2, 2, 2, 2 }, - { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ - 8100, 3, 22, 3, 3, 3, 3, 3 }, - { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 4, 12, 4, 4, 4, 4, 4 }, - { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 5, 18, 4, 5, 5, 5, 5 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10100, 6, 24, 6, 6, 6, 6, 6 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 14100, 7, 36, 6, 7, 7, 7, 7 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17700, 8, 48, 8, 8, 8, 8, 8 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23700, 9, 72, 8, 9, 9, 9, 9 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 10, 96, 8, 10, 10, 10, 10 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 30900, 11, 108, 8, 11, 11, 11, 11 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ - 6400, 0, 0, 4, 12, 28, 12, 28 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ - 12700, 1, 1, 6, 13, 29, 13, 29 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ - 18800, 2, 2, 6, 14, 30, 14, 30 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ - 25000, 3, 3, 8, 15, 31, 15, 31 }, - { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ - 36700, 4, 4, 8, 16, 32, 16, 32 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ - 48100, 5, 5, 8, 17, 33, 17, 33 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ - 53500, 6, 6, 8, 18, 34, 18, 34 }, - { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ - 59000, 7, 7, 8, 19, 35, 19, 36 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ - 12700, 8, 8, 4, 20, 37, 20, 37 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ - 24800, 9, 9, 6, 21, 38, 21, 38 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ - 36600, 10, 10, 6, 22, 39, 22, 39 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ - 48100, 11, 11, 8, 23, 40, 23, 40 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ - 69500, 12, 12, 8, 24, 41, 24, 41 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ - 89500, 13, 13, 8, 25, 42, 25, 42 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ - 98900, 14, 14, 8, 26, 43, 26, 44 }, - { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ - 108300, 15, 15, 8, 27, 44, 27, 45 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ - 13200, 0, 0, 8, 12, 28, 28, 28 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ - 25900, 1, 1, 8, 13, 29, 29, 29 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ - 38600, 2, 2, 8, 14, 30, 30, 30 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ - 49800, 3, 3, 8, 15, 31, 31, 31 }, - { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ - 72200, 4, 4, 8, 16, 32, 32, 32 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ - 92900, 5, 5, 8, 17, 33, 33, 33 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ - 102700, 6, 6, 8, 18, 34, 34, 34 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ - 112000, 7, 7, 8, 19, 35, 36, 36 }, - { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ - 122000, 7, 7, 8, 19, 35, 36, 36 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ - 25800, 8, 8, 8, 20, 37, 37, 37 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ - 49800, 9, 9, 8, 21, 38, 38, 38 }, - { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ - 71900, 10, 10, 8, 22, 39, 39, 39 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ - 92500, 11, 11, 8, 23, 40, 40, 40 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ - 130300, 12, 12, 8, 24, 41, 41, 41 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ - 162800, 13, 13, 8, 25, 42, 42, 42 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ - 178200, 14, 14, 8, 26, 43, 43, 43 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ - 192100, 15, 15, 8, 27, 44, 45, 45 }, - { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ - 207000, 15, 15, 8, 27, 44, 45, 45 }, + [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000, + 900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */ + [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000, + 1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */ + [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500, + 4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */ + [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000, + 8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */ + [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, + 5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */ + [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, + 7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */ + [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, + 10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */ + [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, + 14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */ + [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, + 17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */ + [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, + 23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */ + [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, + 27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */ + [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, + 30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */ + [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, + 6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */ + [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000, + 12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */ + [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500, + 18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/ + [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, + 25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */ + [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, + 36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */ + [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, + 48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */ + [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, + 53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */ + [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, + 59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */ + [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200, + 65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/ + [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, + 12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */ + [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000, + 24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */ + [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000, + 36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */ + [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000, + 48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */ + [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000, + 69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */ + [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000, + 89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */ + [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000, + 98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */ + [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000, + 108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */ + [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, + 120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */ + [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500, + 17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */ + [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000, + 35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */ + [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500, + 52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */ + [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000, + 70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */ + [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000, + 104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */ + [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000, + 115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */ + [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000, + 137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */ + [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300, + 151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */ + [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500, + 152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */ + [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000, + 168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */ + [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000, + 168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */ + [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700, + 185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */ + [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500, + 13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */ + [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500, + 25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */ + [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500, + 38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */ + [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, + 49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */ + [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, + 72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */ + [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, + 92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */ + [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, + 102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */ + [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, + 112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */ + [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, + 122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */ + [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, + 25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */ + [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000, + 49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */ + [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000, + 71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */ + [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000, + 92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */ + [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000, + 130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */ + [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000, + 162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */ + [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000, + 178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */ + [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000, + 192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */ + [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, + 207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */ + [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500, + 36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */ + [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000, + 72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */ + [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500, + 108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */ + [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000, + 142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */ + [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, + 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ + [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, + 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ + [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, + 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ + [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, + 288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */ + [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500, + 290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */ + [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000, + 317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */ + [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000, + 317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */ + [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000, + 346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */ }, 50, /* probe interval */ WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ @@ -220,22 +324,22 @@ static const struct ath_rate_table ar5416_11a_ratetable = { 8, 0, { - { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 0, 12, 0, 0, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 1, 18, 0, 1, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10000, 2, 24, 2, 2, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 13900, 3, 36, 2, 3, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17300, 4, 48, 4, 4, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23000, 5, 72, 4, 5, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 6, 96, 4, 6, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 29300, 7, 108, 4, 7, 0 }, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 0, 12, 0}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 1, 18, 0}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10000, 2, 24, 2}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 13900, 3, 36, 2}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17300, 4, 48, 4}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23000, 5, 72, 4}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 6, 96, 4}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 29300, 7, 108, 4}, }, 50, /* probe interval */ 0, /* Phy rates allowed initially */ @@ -245,30 +349,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = { 12, 0, { - { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ - 900, 0, 2, 0, 0, 0 }, - { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ - 1900, 1, 4, 1, 1, 0 }, - { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ - 4900, 2, 11, 2, 2, 0 }, - { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ - 8100, 3, 22, 3, 3, 0 }, - { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ - 5400, 4, 12, 4, 4, 0 }, - { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ - 7800, 5, 18, 4, 5, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ - 10000, 6, 24, 6, 6, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ - 13900, 7, 36, 6, 7, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ - 17300, 8, 48, 8, 8, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ - 23000, 9, 72, 8, 9, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ - 27400, 10, 96, 8, 10, 0 }, - { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ - 29300, 11, 108, 8, 11, 0 }, + { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ + 900, 0, 2, 0}, + { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ + 1900, 1, 4, 1}, + { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ + 4900, 2, 11, 2}, + { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ + 8100, 3, 22, 3}, + { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ + 5400, 4, 12, 4}, + { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ + 7800, 5, 18, 4}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ + 10000, 6, 24, 6}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ + 13900, 7, 36, 6}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ + 17300, 8, 48, 8}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ + 23000, 9, 72, 8}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ + 27400, 10, 96, 8}, + { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ + 29300, 11, 108, 8}, }, 50, /* probe interval */ 0, /* Phy rates allowed initially */ @@ -338,7 +442,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, u8 index, int valid_tx_rate) { BUG_ON(index > ath_rc_priv->rate_table_size); - ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; + ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate; } static inline @@ -370,6 +474,8 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) return 0; if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) return 0; + if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG)) + return 0; if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) return 0; if (!ignore_cw && WLAN_RC_PHY_HT(phy)) @@ -400,13 +506,9 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, u32 capflag) { u8 i, hi = 0; - u32 valid; for (i = 0; i < rate_table->rate_cnt; i++) { - valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? - rate_table->info[i].valid_single_stream : - rate_table->info[i].valid); - if (valid == 1) { + if (rate_table->info[i].rate_flags & RC_LEGACY) { u32 phy = rate_table->info[i].phy; u8 valid_rate_count = 0; @@ -418,7 +520,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; ath_rc_priv->valid_phy_ratecnt[phy] += 1; ath_rc_set_valid_txmask(ath_rc_priv, i, 1); - hi = A_MAX(hi, i); + hi = i; } } @@ -436,9 +538,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? - rate_table->info[j].valid_single_stream : - rate_table->info[j].valid); + u16 rate_flags = rate_table->info[i].rate_flags; u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; @@ -447,8 +547,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, * (VALID/VALID_20/VALID_40) flags */ if ((rate == dot11rate) && - ((valid & WLAN_RC_CAP_MODE(capflag)) == - WLAN_RC_CAP_MODE(capflag)) && + (rate_flags & WLAN_RC_CAP_MODE(capflag)) == + WLAN_RC_CAP_MODE(capflag) && + (rate_flags & WLAN_RC_CAP_STREAM(capflag)) && !WLAN_RC_PHY_HT(phy)) { u8 valid_rate_count = 0; @@ -482,14 +583,13 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? - rate_table->info[j].valid_single_stream : - rate_table->info[j].valid); + u16 rate_flags = rate_table->info[j].rate_flags; u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) || - !WLAN_RC_PHY_HT_VALID(valid, capflag)) + !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) || + !WLAN_RC_PHY_HT_VALID(rate_flags, capflag)) continue; if (!ath_rc_valid_phyrate(phy, capflag, 0)) @@ -585,12 +685,15 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, if (rate > (ath_rc_priv->rate_table_size - 1)) rate = ath_rc_priv->rate_table_size - 1; - if (rate_table->info[rate].valid && - (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) + if (RC_TS_ONLY(rate_table->info[rate].rate_flags) && + (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG)) + return rate; + + if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) && + (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG))) return rate; - if (rate_table->info[rate].valid_single_stream && - !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) + if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags)) return rate; /* This should not happen */ @@ -1003,12 +1106,19 @@ static void ath_rc_update_ht(struct ath_softc *sc, static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate) { - int rix; + int rix = 0, i = 0; + int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 }; if (!(rate->flags & IEEE80211_TX_RC_MCS)) return rate->idx; - rix = rate->idx + rate_table->mcs_start; + while (rate->idx > mcs_rix_off[i] && + i < sizeof(mcs_rix_off)/sizeof(int)) { + rix++; i++; + } + + rix += rate->idx + rate_table->mcs_start; + if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (rate->flags & IEEE80211_TX_RC_SHORT_GI)) rix = rate_table->info[rix].ht_index; @@ -1016,8 +1126,6 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, rix = rate_table->info[rix].sgi_index; else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) rix = rate_table->info[rix].cw40index; - else - rix = rate_table->info[rix].base_index; return rix; } @@ -1193,20 +1301,19 @@ static void ath_rc_init(struct ath_softc *sc, } static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, - bool is_cw40, bool is_sgi40) + bool is_cw40, bool is_sgi) { u8 caps = 0; if (sta->ht_cap.ht_supported) { caps = WLAN_RC_HT_FLAG; - if (sc->sc_ah->caps.tx_chainmask != 1 && - ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) { - if (sta->ht_cap.mcs.rx_mask[1]) - caps |= WLAN_RC_DS_FLAG; - } + if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2]) + caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; + else if (sta->ht_cap.mcs.rx_mask[1]) + caps |= WLAN_RC_DS_FLAG; if (is_cw40) caps |= WLAN_RC_40_FLAG; - if (is_sgi40) + if (is_sgi) caps |= WLAN_RC_SGI_FLAG; } @@ -1300,7 +1407,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, struct ath_softc *sc = priv; struct ath_rate_priv *ath_rc_priv = priv_sta; const struct ath_rate_table *rate_table; - bool is_cw40, is_sgi40; + bool is_cw40, is_sgi = false; int i, j = 0; for (i = 0; i < sband->n_bitrates; i++) { @@ -1323,7 +1430,11 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, } is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; - is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + + if (is_cw40) + is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) + is_sgi = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; /* Choose rate table first */ @@ -1336,7 +1447,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, rate_table = hw_rate_table[sc->cur_rate_mode]; } - ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); + ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); } @@ -1347,10 +1458,10 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, struct ath_softc *sc = priv; struct ath_rate_priv *ath_rc_priv = priv_sta; const struct ath_rate_table *rate_table = NULL; - bool oper_cw40 = false, oper_sgi40; + bool oper_cw40 = false, oper_sgi; bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ? true : false; - bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? + bool local_sgi = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ? true : false; /* FIXME: Handle AP mode later when we support CWM */ @@ -1363,15 +1474,21 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, oper_chan_type == NL80211_CHAN_HT40PLUS) oper_cw40 = true; - oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? - true : false; + if (oper_cw40) + oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? + true : false; + else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20) + oper_sgi = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? + true : false; + else + oper_sgi = false; - if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { + if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) { rate_table = ath_choose_rate_table(sc, sband->band, sta->ht_cap.ht_supported, oper_cw40); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, - oper_cw40, oper_sgi40); + oper_cw40, oper_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 3d8d40cdc99..dc108265450 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -24,32 +24,63 @@ struct ath_softc; #define ATH_RATE_MAX 30 -#define RATE_TABLE_SIZE 64 +#define RATE_TABLE_SIZE 72 #define MAX_TX_RATE_PHY 48 -/* VALID_ALL - valid for 20/40/Legacy, - * VALID - Legacy only, - * VALID_20 - HT 20 only, - * VALID_40 - HT 40 only */ -#define INVALID 0x0 -#define VALID 0x1 -#define VALID_20 0x2 -#define VALID_40 0x4 -#define VALID_2040 (VALID_20|VALID_40) -#define VALID_ALL (VALID_2040|VALID) +#define RC_INVALID 0x0000 +#define RC_LEGACY 0x0001 +#define RC_SS 0x0002 +#define RC_DS 0x0004 +#define RC_TS 0x0008 +#define RC_HT_20 0x0010 +#define RC_HT_40 0x0020 + +#define RC_STREAM_MASK 0xe +#define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \ + (((f) & RC_STREAM_MASK) == (RC_DS | RC_TS))) +#define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS) +#define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY)) + +#define RC_HT_2040 (RC_HT_20 | RC_HT_40) +#define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS) +#define RC_L_SD (RC_LEGACY | RC_SS | RC_DS) +#define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS) +#define RC_HT_S_20 (RC_HT_20 | RC_SS) +#define RC_HT_D_20 (RC_HT_20 | RC_DS) +#define RC_HT_T_20 (RC_HT_20 | RC_TS) +#define RC_HT_S_40 (RC_HT_40 | RC_SS) +#define RC_HT_D_40 (RC_HT_40 | RC_DS) +#define RC_HT_T_40 (RC_HT_40 | RC_TS) + +#define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS) +#define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS) +#define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS) +#define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS) + +#define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS) +#define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS) + +#define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS) +#define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS) + +#define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM) enum { WLAN_RC_PHY_OFDM, WLAN_RC_PHY_CCK, WLAN_RC_PHY_HT_20_SS, WLAN_RC_PHY_HT_20_DS, + WLAN_RC_PHY_HT_20_TS, WLAN_RC_PHY_HT_40_SS, WLAN_RC_PHY_HT_40_DS, + WLAN_RC_PHY_HT_40_TS, WLAN_RC_PHY_HT_20_SS_HGI, WLAN_RC_PHY_HT_20_DS_HGI, + WLAN_RC_PHY_HT_20_TS_HGI, WLAN_RC_PHY_HT_40_SS_HGI, WLAN_RC_PHY_HT_40_DS_HGI, + WLAN_RC_PHY_HT_40_TS_HGI, WLAN_RC_PHY_MAX }; @@ -57,36 +88,50 @@ enum { || (_phy == WLAN_RC_PHY_HT_40_DS) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) +#define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \ + || (_phy == WLAN_RC_PHY_HT_40_TS) \ + || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) #define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \ || (_phy == WLAN_RC_PHY_HT_20_DS) \ + || (_phy == WLAN_RC_PHY_HT_20_TS) \ || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)) + || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_20_TS_HGI)) #define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ || (_phy == WLAN_RC_PHY_HT_40_DS) \ + || (_phy == WLAN_RC_PHY_HT_40_TS) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) #define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \ || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ - || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) + || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \ + || (_phy == WLAN_RC_PHY_HT_40_TS_HGI)) #define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) #define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \ - (capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID)) + ((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY)) + +#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \ + (RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS))) /* Return TRUE if flag supports HT20 && client supports HT20 or * return TRUE if flag supports HT40 && client supports HT40. * This is used becos some rates overlap between HT20/HT40. */ #define WLAN_RC_PHY_HT_VALID(flag, capflag) \ - (((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \ - ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG))) + (((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \ + ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG))) #define WLAN_RC_DS_FLAG (0x01) -#define WLAN_RC_40_FLAG (0x02) -#define WLAN_RC_SGI_FLAG (0x04) -#define WLAN_RC_HT_FLAG (0x08) +#define WLAN_RC_TS_FLAG (0x02) +#define WLAN_RC_40_FLAG (0x04) +#define WLAN_RC_SGI_FLAG (0x08) +#define WLAN_RC_HT_FLAG (0x10) /** * struct ath_rate_table - Rate Control table @@ -110,15 +155,13 @@ struct ath_rate_table { int rate_cnt; int mcs_start; struct { - u8 valid; - u8 valid_single_stream; + u16 rate_flags; u8 phy; u32 ratekbps; u32 user_ratekbps; u8 ratecode; u8 dot11rate; u8 ctrl_rate; - u8 base_index; u8 cw40index; u8 sgi_index; u8 ht_index; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ca6065b71b4..da0cfe90c38 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -116,9 +116,6 @@ static void ath_opmode_init(struct ath_softc *sc) /* configure operational mode */ ath9k_hw_setopmode(ah); - /* Handle any link-level address change. */ - ath9k_hw_setmac(ah, common->macaddr); - /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); @@ -295,7 +292,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) ath_opmode_init(sc); - ath9k_hw_startpcureceive(sc->sc_ah); + ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING)); } static void ath_edma_stop_recv(struct ath_softc *sc) @@ -501,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc) start_recv: spin_unlock_bh(&sc->rx.rxbuflock); ath_opmode_init(sc); - ath9k_hw_startpcureceive(ah); + ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING)); return 0; } @@ -700,12 +697,16 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, bf = SKB_CB_ATHBUF(skb); BUG_ON(!bf); - dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); - if (ret == -EINPROGRESS) + if (ret == -EINPROGRESS) { + /*let device gain the buffer again*/ + dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + common->rx_bufsize, DMA_FROM_DEVICE); return false; + } __skb_unlink(skb, &rx_edma->rx_fifo); if (ret == -EINVAL) { @@ -814,13 +815,263 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, * 1. accessing the frame * 2. requeueing the same buffer to h/w */ - dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); return bf; } +/* Assumes you've already done the endian to CPU conversion */ +static bool ath9k_rx_accept(struct ath_common *common, + struct ieee80211_hdr *hdr, + struct ieee80211_rx_status *rxs, + struct ath_rx_status *rx_stats, + bool *decrypt_error) +{ + struct ath_hw *ah = common->ah; + __le16 fc; + u8 rx_status_len = ah->caps.rx_status_len; + + fc = hdr->frame_control; + + if (!rx_stats->rs_datalen) + return false; + /* + * rs_status follows rs_datalen so if rs_datalen is too large + * we can take a hint that hardware corrupted it, so ignore + * those frames. + */ + if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) + return false; + + /* + * rs_more indicates chained descriptors which can be used + * to link buffers together for a sort of scatter-gather + * operation. + * reject the frame, we don't support scatter-gather yet and + * the frame is probably corrupt anyway + */ + if (rx_stats->rs_more) + return false; + + /* + * The rx_stats->rs_status will not be set until the end of the + * chained descriptors so it can be ignored if rs_more is set. The + * rs_more will be false at the last element of the chained + * descriptors. + */ + if (rx_stats->rs_status != 0) { + if (rx_stats->rs_status & ATH9K_RXERR_CRC) + rxs->flag |= RX_FLAG_FAILED_FCS_CRC; + if (rx_stats->rs_status & ATH9K_RXERR_PHY) + return false; + + if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { + *decrypt_error = true; + } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { + if (ieee80211_is_ctl(fc)) + /* + * Sometimes, we get invalid + * MIC failures on valid control frames. + * Remove these mic errors. + */ + rx_stats->rs_status &= ~ATH9K_RXERR_MIC; + else + rxs->flag |= RX_FLAG_MMIC_ERROR; + } + /* + * Reject error frames with the exception of + * decryption and MIC failures. For monitor mode, + * we also ignore the CRC error. + */ + if (ah->opmode == NL80211_IFTYPE_MONITOR) { + if (rx_stats->rs_status & + ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | + ATH9K_RXERR_CRC)) + return false; + } else { + if (rx_stats->rs_status & + ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { + return false; + } + } + } + return true; +} + +static int ath9k_process_rate(struct ath_common *common, + struct ieee80211_hw *hw, + struct ath_rx_status *rx_stats, + struct ieee80211_rx_status *rxs) +{ + struct ieee80211_supported_band *sband; + enum ieee80211_band band; + unsigned int i = 0; + + band = hw->conf.channel->band; + sband = hw->wiphy->bands[band]; + + if (rx_stats->rs_rate & 0x80) { + /* HT rate */ + rxs->flag |= RX_FLAG_HT; + if (rx_stats->rs_flags & ATH9K_RX_2040) + rxs->flag |= RX_FLAG_40MHZ; + if (rx_stats->rs_flags & ATH9K_RX_GI) + rxs->flag |= RX_FLAG_SHORT_GI; + rxs->rate_idx = rx_stats->rs_rate & 0x7f; + return 0; + } + + for (i = 0; i < sband->n_bitrates; i++) { + if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { + rxs->rate_idx = i; + return 0; + } + if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { + rxs->flag |= RX_FLAG_SHORTPRE; + rxs->rate_idx = i; + return 0; + } + } + + /* + * No valid hardware bitrate found -- we should not get here + * because hardware has already validated this frame as OK. + */ + ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " + "0x%02x using 1 Mbit\n", rx_stats->rs_rate); + + return -EINVAL; +} + +static void ath9k_process_rssi(struct ath_common *common, + struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + struct ath_rx_status *rx_stats) +{ + struct ath_hw *ah = common->ah; + struct ieee80211_sta *sta; + struct ath_node *an; + int last_rssi = ATH_RSSI_DUMMY_MARKER; + __le16 fc; + + fc = hdr->frame_control; + + rcu_read_lock(); + /* + * XXX: use ieee80211_find_sta! This requires quite a bit of work + * under the current ath9k virtual wiphy implementation as we have + * no way of tying a vif to wiphy. Typically vifs are attached to + * at least one sdata of a wiphy on mac80211 but with ath9k virtual + * wiphy you'd have to iterate over every wiphy and each sdata. + */ + sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); + if (sta) { + an = (struct ath_node *) sta->drv_priv; + if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && + !rx_stats->rs_moreaggr) + ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); + last_rssi = an->last_rssi; + } + rcu_read_unlock(); + + if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) + rx_stats->rs_rssi = ATH_EP_RND(last_rssi, + ATH_RSSI_EP_MULTIPLIER); + if (rx_stats->rs_rssi < 0) + rx_stats->rs_rssi = 0; + + /* Update Beacon RSSI, this is used by ANI. */ + if (ieee80211_is_beacon(fc)) + ah->stats.avgbrssi = rx_stats->rs_rssi; +} + +/* + * For Decrypt or Demic errors, we only mark packet status here and always push + * up the frame up to let mac80211 handle the actual error case, be it no + * decryption key or real decryption error. This let us keep statistics there. + */ +static int ath9k_rx_skb_preprocess(struct ath_common *common, + struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, + struct ath_rx_status *rx_stats, + struct ieee80211_rx_status *rx_status, + bool *decrypt_error) +{ + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + + /* + * everything but the rate is checked here, the rate check is done + * separately to avoid doing two lookups for a rate for each frame. + */ + if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) + return -EINVAL; + + ath9k_process_rssi(common, hw, hdr, rx_stats); + + if (ath9k_process_rate(common, hw, rx_stats, rx_status)) + return -EINVAL; + + rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.channel->center_freq; + rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; + rx_status->antenna = rx_stats->rs_antenna; + rx_status->flag |= RX_FLAG_TSFT; + + return 0; +} + +static void ath9k_rx_skb_postprocess(struct ath_common *common, + struct sk_buff *skb, + struct ath_rx_status *rx_stats, + struct ieee80211_rx_status *rxs, + bool decrypt_error) +{ + struct ath_hw *ah = common->ah; + struct ieee80211_hdr *hdr; + int hdrlen, padpos, padsize; + u8 keyix; + __le16 fc; + + /* see if any padding is done by the hw and remove it */ + hdr = (struct ieee80211_hdr *) skb->data; + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + fc = hdr->frame_control; + padpos = ath9k_cmn_padpos(hdr->frame_control); + + /* The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = (4 - padpos % 4) % 4; However, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. In addition, we must + * not try to remove padding from short control frames that do + * not have payload. */ + padsize = padpos & 3; + if (padsize && skb->len>=padpos+padsize+FCS_LEN) { + memmove(skb->data + padsize, skb->data, padpos); + skb_pull(skb, padsize); + } + + keyix = rx_stats->rs_keyix; + + if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && + ieee80211_has_protected(fc)) { + rxs->flag |= RX_FLAG_DECRYPTED; + } else if (ieee80211_has_protected(fc) + && !decrypt_error && skb->len >= hdrlen + 4) { + keyix = skb->data[hdrlen + 3] >> 6; + + if (test_bit(keyix, common->keymap)) + rxs->flag |= RX_FLAG_DECRYPTED; + } + if (ah->sw_mgmt_crypto && + (rxs->flag & RX_FLAG_DECRYPTED) && + ieee80211_is_mgmt(fc)) + /* Use software decrypt for management frames. */ + rxs->flag &= ~RX_FLAG_DECRYPTED; +} int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { @@ -842,15 +1093,21 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) enum ath9k_rx_qtype qtype; bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int dma_type; + u8 rx_status_len = ah->caps.rx_status_len; + u64 tsf = 0; + u32 tsf_lower = 0; if (edma) - dma_type = DMA_FROM_DEVICE; - else dma_type = DMA_BIDIRECTIONAL; + else + dma_type = DMA_FROM_DEVICE; qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; spin_lock_bh(&sc->rx.rxbuflock); + tsf = ath9k_hw_gettsf64(ah); + tsf_lower = tsf & 0xffffffff; + do { /* If handling rx interrupt and flush is in progress => exit */ if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) @@ -869,7 +1126,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (!skb) continue; - hdr = (struct ieee80211_hdr *) skb->data; + hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len); rxs = IEEE80211_SKB_RXCB(skb); hw = ath_get_virt_hw(sc, hdr); @@ -883,8 +1140,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (flush) goto requeue; - retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs, - rxs, &decrypt_error); + rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; + if (rs.rs_tstamp > tsf_lower && + unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) + rxs->mactime -= 0x100000000ULL; + + if (rs.rs_tstamp < tsf_lower && + unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) + rxs->mactime += 0x100000000ULL; + + retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, + rxs, &decrypt_error); if (retval) goto requeue; @@ -908,8 +1174,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (ah->caps.rx_status_len) skb_pull(skb, ah->caps.rx_status_len); - ath9k_cmn_rx_skb_postprocess(common, skb, &rs, - rxs, decrypt_error); + ath9k_rx_skb_postprocess(common, skb, &rs, + rxs, decrypt_error); /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index d4371a43bda..633e3d949ec 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -222,6 +222,7 @@ #define AR_ISR_S2 0x008c #define AR_ISR_S2_QCU_TXURN 0x000003FF +#define AR_ISR_S2_BB_WATCHDOG 0x00010000 #define AR_ISR_S2_CST 0x00400000 #define AR_ISR_S2_GTT 0x00800000 #define AR_ISR_S2_TIM 0x01000000 @@ -699,7 +700,15 @@ #define AR_RC_HOSTIF 0x00000100 #define AR_WA 0x4004 +#define AR_WA_BIT6 (1 << 6) +#define AR_WA_BIT7 (1 << 7) +#define AR_WA_BIT23 (1 << 23) #define AR_WA_D3_L1_DISABLE (1 << 14) +#define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16) +#define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17) +#define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ +#define AR_WA_ANALOG_SHIFT (1 << 20) +#define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ #define AR9285_WA_DEFAULT 0x004a050b #define AR9280_WA_DEFAULT 0x0040073b #define AR_WA_DEFAULT 0x0000073f @@ -756,32 +765,33 @@ #define AR_SREV_REVISION2 0x00000F00 #define AR_SREV_REVISION2_S 8 -#define AR_SREV_VERSION_5416_PCI 0xD -#define AR_SREV_VERSION_5416_PCIE 0xC -#define AR_SREV_REVISION_5416_10 0 -#define AR_SREV_REVISION_5416_20 1 -#define AR_SREV_REVISION_5416_22 2 -#define AR_SREV_VERSION_9100 0x14 -#define AR_SREV_VERSION_9160 0x40 -#define AR_SREV_REVISION_9160_10 0 -#define AR_SREV_REVISION_9160_11 1 -#define AR_SREV_VERSION_9280 0x80 -#define AR_SREV_REVISION_9280_10 0 -#define AR_SREV_REVISION_9280_20 1 -#define AR_SREV_REVISION_9280_21 2 -#define AR_SREV_VERSION_9285 0xC0 -#define AR_SREV_REVISION_9285_10 0 -#define AR_SREV_REVISION_9285_11 1 -#define AR_SREV_REVISION_9285_12 2 -#define AR_SREV_VERSION_9287 0x180 -#define AR_SREV_REVISION_9287_10 0 -#define AR_SREV_REVISION_9287_11 1 -#define AR_SREV_REVISION_9287_12 2 -#define AR_SREV_VERSION_9271 0x140 -#define AR_SREV_REVISION_9271_10 0 -#define AR_SREV_REVISION_9271_11 1 -#define AR_SREV_VERSION_9300 0x1c0 -#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ +#define AR_SREV_VERSION_5416_PCI 0xD +#define AR_SREV_VERSION_5416_PCIE 0xC +#define AR_SREV_REVISION_5416_10 0 +#define AR_SREV_REVISION_5416_20 1 +#define AR_SREV_REVISION_5416_22 2 +#define AR_SREV_VERSION_9100 0x14 +#define AR_SREV_VERSION_9160 0x40 +#define AR_SREV_REVISION_9160_10 0 +#define AR_SREV_REVISION_9160_11 1 +#define AR_SREV_VERSION_9280 0x80 +#define AR_SREV_REVISION_9280_10 0 +#define AR_SREV_REVISION_9280_20 1 +#define AR_SREV_REVISION_9280_21 2 +#define AR_SREV_VERSION_9285 0xC0 +#define AR_SREV_REVISION_9285_10 0 +#define AR_SREV_REVISION_9285_11 1 +#define AR_SREV_REVISION_9285_12 2 +#define AR_SREV_VERSION_9287 0x180 +#define AR_SREV_REVISION_9287_10 0 +#define AR_SREV_REVISION_9287_11 1 +#define AR_SREV_REVISION_9287_12 2 +#define AR_SREV_REVISION_9287_13 3 +#define AR_SREV_VERSION_9271 0x140 +#define AR_SREV_REVISION_9271_10 0 +#define AR_SREV_REVISION_9271_11 1 +#define AR_SREV_VERSION_9300 0x1c0 +#define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ #define AR_SREV_5416(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ @@ -859,6 +869,11 @@ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12))) +#define AR_SREV_9287_13_OR_LATER(_ah) \ + (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ + ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_13))) + #define AR_SREV_9271(_ah) \ (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271) #define AR_SREV_9271_10(_ah) \ @@ -867,6 +882,7 @@ #define AR_SREV_9271_11(_ah) \ (AR_SREV_9271(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) + #define AR_SREV_9300(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) #define AR_SREV_9300_20(_ah) \ @@ -881,6 +897,10 @@ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) +#define AR_DEVID_7010(_ah) \ + (((_ah)->hw_version.devid == 0x7010) || \ + ((_ah)->hw_version.devid == 0x9018)) + #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 #define AR_RAD2133_SREV_MAJOR 0xd0 @@ -978,6 +998,7 @@ enum { #define AR9287_NUM_GPIO 11 #define AR9271_NUM_GPIO 16 #define AR9300_NUM_GPIO 17 +#define AR7010_NUM_GPIO 16 #define AR_GPIO_IN_OUT 0x4048 #define AR_GPIO_IN_VAL 0x0FFFC000 @@ -992,6 +1013,8 @@ enum { #define AR9271_GPIO_IN_VAL_S 16 #define AR9300_GPIO_IN_VAL 0x0001FFFF #define AR9300_GPIO_IN_VAL_S 0 +#define AR7010_GPIO_IN_VAL 0x0000FFFF +#define AR7010_GPIO_IN_VAL_S 0 #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) #define AR_GPIO_OE_OUT_DRV 0x3 @@ -1000,6 +1023,21 @@ enum { #define AR_GPIO_OE_OUT_DRV_HI 0x2 #define AR_GPIO_OE_OUT_DRV_ALL 0x3 +#define AR7010_GPIO_OE 0x52000 +#define AR7010_GPIO_OE_MASK 0x1 +#define AR7010_GPIO_OE_AS_OUTPUT 0x0 +#define AR7010_GPIO_OE_AS_INPUT 0x1 +#define AR7010_GPIO_IN 0x52004 +#define AR7010_GPIO_OUT 0x52008 +#define AR7010_GPIO_SET 0x5200C +#define AR7010_GPIO_CLEAR 0x52010 +#define AR7010_GPIO_INT 0x52014 +#define AR7010_GPIO_INT_TYPE 0x52018 +#define AR7010_GPIO_INT_POLARITY 0x5201C +#define AR7010_GPIO_PENDING 0x52020 +#define AR7010_GPIO_INT_MASK 0x52024 +#define AR7010_GPIO_FUNCTION 0x52028 + #define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) #define AR_GPIO_INTR_POL_VAL 0x0001FFFF #define AR_GPIO_INTR_POL_VAL_S 0 diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 105ad40968f..fd20241f57d 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -219,7 +219,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy, info->control.rates[1].idx = -1; memset(&txctl, 0, sizeof(struct ath_tx_control)); - txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; + txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]]; txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; if (ath_tx_start(aphy->hw, skb, &txctl) != 0) @@ -695,16 +695,18 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) idle ? "idle" : "not-idle"); } /* Only bother starting a queue on an active virtual wiphy */ -void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) +bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) { struct ieee80211_hw *hw = sc->pri_wiphy->hw; unsigned int i; + bool txq_started = false; spin_lock_bh(&sc->wiphy_lock); /* Start the primary wiphy */ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { ieee80211_wake_queue(hw, skb_queue); + txq_started = true; goto unlock; } @@ -718,11 +720,13 @@ void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) hw = aphy->hw; ieee80211_wake_queue(hw, skb_queue); + txq_started = true; break; } unlock: spin_unlock_bh(&sc->wiphy_lock); + return txq_started; } /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index e23172c9caa..6260faa658a 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -279,9 +279,6 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, if (wmi->drv_priv->op_flags & OP_UNPLUGGED) return 0; - if (!wmi) - return -EINVAL; - skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); if (!skb) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 859aa4ab076..501b72821b4 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -328,6 +328,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; + struct ieee80211_tx_rate rates[4]; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -335,18 +336,44 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tx_info = IEEE80211_SKB_CB(skb); hw = bf->aphy->hw; + memcpy(rates, tx_info->control.rates, sizeof(rates)); + rcu_read_lock(); /* XXX: use ieee80211_find_sta! */ sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); if (!sta) { rcu_read_unlock(); + + INIT_LIST_HEAD(&bf_head); + while (bf) { + bf_next = bf->bf_next; + + bf->bf_state.bf_type |= BUF_XRETRY; + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || + !bf->bf_stale || bf_next != NULL) + list_move_tail(&bf->list, &bf_head); + + ath_tx_rc_status(bf, ts, 0, 0, false); + ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, + 0, 0); + + bf = bf_next; + } return; } an = (struct ath_node *)sta->drv_priv; tid = ATH_AN_2_TID(an, bf->bf_tidno); + /* + * The hardware occasionally sends a tx status for the wrong TID. + * In this case, the BA status cannot be considered valid and all + * subframes need to be retransmitted + */ + if (bf->bf_tidno != ts->tid) + txok = false; + isaggr = bf_isaggr(bf); memset(ba, 0, WME_BA_BMP_SIZE >> 3); @@ -375,6 +402,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, txfail = txpending = 0; bf_next = bf->bf_next; + skb = bf->bf_mpdu; + tx_info = IEEE80211_SKB_CB(skb); + if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { /* transmit completion, subframe is * acked by block ack */ @@ -428,6 +458,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, spin_unlock_bh(&txq->axq_lock); if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { + memcpy(tx_info->control.rates, rates, sizeof(rates)); ath_tx_rc_status(bf, ts, nbad, txok, true); rc_update = false; } else { @@ -487,6 +518,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf = bf_next; } + /* prepend un-acked frames to the beginning of the pending frame queue */ + if (!list_empty(&bf_pending)) { + spin_lock_bh(&txq->axq_lock); + list_splice(&bf_pending, &tid->buf_q); + ath_tx_queue_tid(txq, tid); + spin_unlock_bh(&txq->axq_lock); + } + if (tid->state & AGGR_CLEANUP) { if (tid->baw_head == tid->baw_tail) { tid->state &= ~AGGR_ADDBA_COMPLETE; @@ -499,14 +538,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, return; } - /* prepend un-acked frames to the beginning of the pending frame queue */ - if (!list_empty(&bf_pending)) { - spin_lock_bh(&txq->axq_lock); - list_splice(&bf_pending, &tid->buf_q); - ath_tx_queue_tid(txq, tid); - spin_unlock_bh(&txq->axq_lock); - } - rcu_read_unlock(); if (needreset) @@ -941,6 +972,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) if (!ATH_TXQ_SETUP(sc, qnum)) { struct ath_txq *txq = &sc->tx.txq[qnum]; + txq->axq_class = subtype; txq->axq_qnum = qnum; txq->axq_link = NULL; INIT_LIST_HEAD(&txq->axq_q); @@ -958,58 +990,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) return &sc->tx.txq[qnum]; } -int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) -{ - int qnum; - - switch (qtype) { - case ATH9K_TX_QUEUE_DATA: - if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "HAL AC %u out of range, max %zu!\n", - haltype, ARRAY_SIZE(sc->tx.hwq_map)); - return -1; - } - qnum = sc->tx.hwq_map[haltype]; - break; - case ATH9K_TX_QUEUE_BEACON: - qnum = sc->beacon.beaconq; - break; - case ATH9K_TX_QUEUE_CAB: - qnum = sc->beacon.cabq->axq_qnum; - break; - default: - qnum = -1; - } - return qnum; -} - -struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) -{ - struct ath_txq *txq = NULL; - u16 skb_queue = skb_get_queue_mapping(skb); - int qnum; - - qnum = ath_get_hal_qnum(skb_queue, sc); - txq = &sc->tx.txq[qnum]; - - spin_lock_bh(&txq->axq_lock); - - if (txq->axq_depth >= (ATH_TXBUF - 20)) { - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT, - "TX queue: %d is full, depth: %d\n", - qnum, txq->axq_depth); - ath_mac80211_stop_queue(sc, skb_queue); - txq->stopped = 1; - spin_unlock_bh(&txq->axq_lock); - return NULL; - } - - spin_unlock_bh(&txq->axq_lock); - - return txq; -} - int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_tx_queue_info *qinfo) { @@ -1688,12 +1668,15 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_frmlen -= padsize; } - if (conf_is_ht(&hw->conf)) { + if (!txctl->paprd && conf_is_ht(&hw->conf)) { bf->bf_state.bf_type |= BUF_HT; if (tx_info->flags & IEEE80211_TX_CTL_LDPC) use_ldpc = true; } + bf->bf_state.bfs_paprd = txctl->paprd; + if (txctl->paprd) + bf->bf_state.bfs_paprd_timestamp = jiffies; bf->bf_flags = setup_tx_flags(skb, use_ldpc); bf->bf_keytype = get_hw_crypto_keytype(skb); @@ -1768,6 +1751,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, bf->bf_buf_addr, txctl->txq->axq_qnum); + if (bf->bf_state.bfs_paprd) + ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); + spin_lock_bh(&txctl->txq->axq_lock); if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && @@ -1809,8 +1795,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_txq *txq = txctl->txq; struct ath_buf *bf; - int r; + int q, r; bf = ath_tx_get_buffer(sc); if (!bf) { @@ -1820,8 +1807,6 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, r = ath_tx_setup_buffer(hw, bf, skb, txctl); if (unlikely(r)) { - struct ath_txq *txq = txctl->txq; - ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); /* upon ath_tx_processq() this TX queue will be resumed, we @@ -1829,7 +1814,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, * we will at least have to run TX completionon one buffer * on the queue */ spin_lock_bh(&txq->axq_lock); - if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { + if (!txq->stopped && txq->axq_depth > 1) { ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); txq->stopped = 1; } @@ -1840,6 +1825,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, return r; } + q = skb_get_queue_mapping(skb); + if (q >= 4) + q = 0; + + spin_lock_bh(&txq->axq_lock); + if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { + ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); + txq->stopped = 1; + } + spin_unlock_bh(&txq->axq_lock); + ath_tx_start_dma(sc, bf, txctl); return 0; @@ -1909,7 +1905,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; - int padpos, padsize; + int q, padpos, padsize; ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); @@ -1948,8 +1944,16 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) ath9k_tx_status(hw, skb); - else + else { + q = skb_get_queue_mapping(skb); + if (q >= 4) + q = 0; + + if (--sc->tx.pending_frames[q] < 0) + sc->tx.pending_frames[q] = 0; + ieee80211_tx_status(hw, skb); + } } static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, @@ -1971,8 +1975,18 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, } dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); - ath_tx_complete(sc, skb, bf->aphy, tx_flags); - ath_debug_stat_tx(sc, txq, bf, ts); + + if (bf->bf_state.bfs_paprd) { + if (time_after(jiffies, + bf->bf_state.bfs_paprd_timestamp + + msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) + dev_kfree_skb_any(skb); + else + complete(&sc->paprd_complete); + } else { + ath_tx_complete(sc, skb, bf->aphy, tx_flags); + ath_debug_stat_tx(sc, txq, bf, ts); + } /* * Return the list of ath_buf of this mpdu to free queue @@ -2050,21 +2064,21 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, tx_info->status.rates[i].idx = -1; } - tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; + tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; } static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) { int qnum; + qnum = ath_get_mac80211_qnum(txq->axq_class, sc); + if (qnum == -1) + return; + spin_lock_bh(&txq->axq_lock); - if (txq->stopped && - sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { - qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); - if (qnum != -1) { - ath_mac80211_start_queue(sc, qnum); + if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { + if (ath_mac80211_start_queue(sc, qnum)) txq->stopped = 0; - } } spin_unlock_bh(&txq->axq_lock); } @@ -2161,7 +2175,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) * This frame is sent out as a single frame. * Use hardware retry status for this frame. */ - bf->bf_retries = ts.ts_longretry; if (ts.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; ath_tx_rc_status(bf, &ts, 0, txok, true); @@ -2279,8 +2292,18 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) txok = !(txs.ts_status & ATH9K_TXERR_MASK); + /* + * Make sure null func frame is acked before configuring + * hw into ps mode. + */ + if (bf->bf_isnullfunc && txok) { + if ((sc->ps_flags & PS_ENABLED)) + ath9k_enable_ps(sc); + else + sc->ps_flags |= PS_NULLFUNC_COMPLETED; + } + if (!bf_isampdu(bf)) { - bf->bf_retries = txs.ts_longretry; if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; ath_tx_rc_status(bf, &txs, 0, txok, true); @@ -2424,62 +2447,44 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) for (acno = 0, ac = &an->ac[acno]; acno < WME_NUM_AC; acno++, ac++) { ac->sched = false; + ac->qnum = sc->tx.hwq_map[acno]; INIT_LIST_HEAD(&ac->tid_q); - - switch (acno) { - case WME_AC_BE: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); - break; - case WME_AC_BK: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); - break; - case WME_AC_VI: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); - break; - case WME_AC_VO: - ac->qnum = ath_tx_get_qnum(sc, - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); - break; - } } } void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) { - int i; - struct ath_atx_ac *ac, *ac_tmp; - struct ath_atx_tid *tid, *tid_tmp; + struct ath_atx_ac *ac; + struct ath_atx_tid *tid; struct ath_txq *txq; + int i, tidno; - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (ATH_TXQ_SETUP(sc, i)) { - txq = &sc->tx.txq[i]; + for (tidno = 0, tid = &an->tid[tidno]; + tidno < WME_NUM_TID; tidno++, tid++) { + i = tid->ac->qnum; - spin_lock_bh(&txq->axq_lock); + if (!ATH_TXQ_SETUP(sc, i)) + continue; - list_for_each_entry_safe(ac, - ac_tmp, &txq->axq_acq, list) { - tid = list_first_entry(&ac->tid_q, - struct ath_atx_tid, list); - if (tid && tid->an != an) - continue; - list_del(&ac->list); - ac->sched = false; - - list_for_each_entry_safe(tid, - tid_tmp, &ac->tid_q, list) { - list_del(&tid->list); - tid->sched = false; - ath_tid_drain(sc, txq, tid); - tid->state &= ~AGGR_ADDBA_COMPLETE; - tid->state &= ~AGGR_CLEANUP; - } - } + txq = &sc->tx.txq[i]; + ac = tid->ac; - spin_unlock_bh(&txq->axq_lock); + spin_lock_bh(&txq->axq_lock); + + if (tid->sched) { + list_del(&tid->list); + tid->sched = false; } + + if (ac->sched) { + list_del(&ac->list); + tid->ac->sched = false; + } + + ath_tid_drain(sc, txq, tid); + tid->state &= ~AGGR_ADDBA_COMPLETE; + tid->state &= ~AGGR_CLEANUP; + + spin_unlock_bh(&txq->axq_lock); } } diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 3a003e6803a..8674a99356a 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -530,7 +530,7 @@ struct b43_fw_header { /* Size of the data. For ucode and PCM this is in bytes. * For IV this is number-of-ivs. */ __be32 size; -} __attribute__((__packed__)); +} __packed; /* Initial Value file format */ #define B43_IV_OFFSET_MASK 0x7FFF @@ -540,8 +540,8 @@ struct b43_iv { union { __be16 d16; __be32 d32; - } data __attribute__((__packed__)); -} __attribute__((__packed__)); + } data __packed; +} __packed; /* Data structures for DMA transmission, per 80211 core. */ diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index fa40fdfea71..10d0aaf754c 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -333,11 +333,11 @@ static inline dma_addr_t dmaaddr; if (tx) { - dmaaddr = ssb_dma_map_single(ring->dev->dev, - buf, len, DMA_TO_DEVICE); + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, + buf, len, DMA_TO_DEVICE); } else { - dmaaddr = ssb_dma_map_single(ring->dev->dev, - buf, len, DMA_FROM_DEVICE); + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, + buf, len, DMA_FROM_DEVICE); } return dmaaddr; @@ -348,11 +348,11 @@ static inline dma_addr_t addr, size_t len, int tx) { if (tx) { - ssb_dma_unmap_single(ring->dev->dev, - addr, len, DMA_TO_DEVICE); + dma_unmap_single(ring->dev->dev->dma_dev, + addr, len, DMA_TO_DEVICE); } else { - ssb_dma_unmap_single(ring->dev->dev, - addr, len, DMA_FROM_DEVICE); + dma_unmap_single(ring->dev->dev->dma_dev, + addr, len, DMA_FROM_DEVICE); } } @@ -361,7 +361,7 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - ssb_dma_sync_single_for_cpu(ring->dev->dev, + dma_sync_single_for_cpu(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -370,8 +370,8 @@ static inline dma_addr_t addr, size_t len) { B43_WARN_ON(ring->tx); - ssb_dma_sync_single_for_device(ring->dev->dev, - addr, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(ring->dev->dev->dma_dev, + addr, len, DMA_FROM_DEVICE); } static inline @@ -401,9 +401,9 @@ static int alloc_ringmemory(struct b43_dmaring *ring) */ if (ring->type == B43_DMA_64BIT) flags |= GFP_DMA; - ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, - B43_DMA_RINGMEMSIZE, - &(ring->dmabase), flags); + ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, + B43_DMA_RINGMEMSIZE, + &(ring->dmabase), flags); if (!ring->descbase) { b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); return -ENOMEM; @@ -420,8 +420,8 @@ static void free_ringmemory(struct b43_dmaring *ring) if (ring->type == B43_DMA_64BIT) flags |= GFP_DMA; - ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, - ring->descbase, ring->dmabase, flags); + dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, + ring->descbase, ring->dmabase); } /* Reset the RX DMA channel */ @@ -528,7 +528,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, dma_addr_t addr, size_t buffersize, bool dma_to_device) { - if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) + if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) return 1; switch (ring->type) { @@ -874,10 +874,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = ssb_dma_map_single(dev->dev, - ring->txhdr_cache, - b43_txhdr_size(dev), - DMA_TO_DEVICE); + dma_test = dma_map_single(dev->dev->dma_dev, + ring->txhdr_cache, + b43_txhdr_size(dev), + DMA_TO_DEVICE); if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev), 1)) { @@ -889,10 +889,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = ssb_dma_map_single(dev->dev, - ring->txhdr_cache, - b43_txhdr_size(dev), - DMA_TO_DEVICE); + dma_test = dma_map_single(dev->dev->dma_dev, + ring->txhdr_cache, + b43_txhdr_size(dev), + DMA_TO_DEVICE); if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev), 1)) { @@ -903,9 +903,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, } } - ssb_dma_unmap_single(dev->dev, - dma_test, b43_txhdr_size(dev), - DMA_TO_DEVICE); + dma_unmap_single(dev->dev->dma_dev, + dma_test, b43_txhdr_size(dev), + DMA_TO_DEVICE); } err = alloc_ringmemory(ring); @@ -1018,9 +1018,12 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = ssb_dma_set_mask(dev->dev, mask); - if (!err) - break; + err = dma_set_mask(dev->dev->dma_dev, mask); + if (!err) { + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); + if (!err) + break; + } if (mask == DMA_BIT_MASK(64)) { mask = DMA_BIT_MASK(32); fallback = 1; @@ -1221,14 +1224,14 @@ static int dma_tx_fragment(struct b43_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { - priv_info->bouncebuffer = kmalloc(skb->len, GFP_ATOMIC | GFP_DMA); + priv_info->bouncebuffer = kmemdup(skb->data, skb->len, + GFP_ATOMIC | GFP_DMA); if (!priv_info->bouncebuffer) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; err = -ENOMEM; goto out_unmap_hdr; } - memcpy(priv_info->bouncebuffer, skb->data, skb->len); meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1); if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index dc91944d602..a01c2100f16 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -67,7 +67,7 @@ struct b43_dmadesc32 { __le32 control; __le32 address; -} __attribute__ ((__packed__)); +} __packed; #define B43_DMA32_DCTL_BYTECNT 0x00001FFF #define B43_DMA32_DCTL_ADDREXT_MASK 0x00030000 #define B43_DMA32_DCTL_ADDREXT_SHIFT 16 @@ -140,7 +140,7 @@ struct b43_dmadesc64 { __le32 control1; __le32 address_low; __le32 address_high; -} __attribute__ ((__packed__)); +} __packed; #define B43_DMA64_DCTL0_DTABLEEND 0x10000000 #define B43_DMA64_DCTL0_IRQ 0x20000000 #define B43_DMA64_DCTL0_FRAMEEND 0x40000000 @@ -153,8 +153,8 @@ struct b43_dmadesc_generic { union { struct b43_dmadesc32 dma32; struct b43_dmadesc64 dma64; - } __attribute__ ((__packed__)); -} __attribute__ ((__packed__)); + } __packed; +} __packed; /* Misc DMA constants */ #define B43_DMA_RINGMEMSIZE PAGE_SIZE diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7965b70efba..20631ae2ddd 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -108,7 +108,7 @@ int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; module_param_named(verbose, b43_modparam_verbose, int, 0644); MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); -int b43_modparam_pio = B43_PIO_DEFAULT; +static int b43_modparam_pio = B43_PIO_DEFAULT; module_param_named(pio, b43_modparam_pio, int, 0644); MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); @@ -1804,7 +1804,7 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) dma_reason[2], dma_reason[3], dma_reason[4], dma_reason[5]); b43err(dev->wl, "This device does not support DMA " - "on your system. Please use PIO instead.\n"); + "on your system. It will now be switched to PIO.\n"); /* Fall back to PIO transfers if we get fatal DMA errors! */ dev->use_pio = 1; b43_controller_restart(dev, "DMA error"); diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 29bf34ced86..0dc33b65e86 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -972,7 +972,7 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode) b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B); if (phy->rev >= 3) { - b43_phy_mask(dev, 0x048A, (u16)~0x8000); + b43_phy_mask(dev, 0x048A, 0x7FFF); b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8); b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8); b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D); diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index c6afe9d9459..fd50eb11624 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -1145,7 +1145,7 @@ static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev) B43_WARN_ON(1); } b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl); + ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, ctl); } static void lpphy_set_tx_power_control(struct b43_wldev *dev, @@ -1522,11 +1522,11 @@ static void lpphy_tx_pctl_init_hw(struct b43_wldev *dev) b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xFF); b43_phy_write(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xA); b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, + ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF); b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xF8FF); b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD, - (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, + ~B43_LPPHY_TX_PWR_CTL_CMD_MODE & 0xFFFF, B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW); if (dev->phy.rev < 2) { @@ -2698,7 +2698,7 @@ static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev, return B43_TXPWR_RES_DONE; } -void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on) +static void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on) { if (on) { b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xfff8); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 3d6b3377596..5a725703770 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -509,7 +509,8 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); - b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS, + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, + ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF, ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT)); @@ -762,7 +763,7 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) if (tmp & 0x1) b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); else if (tmp & 0x2) - b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000); + b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); @@ -1009,7 +1010,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) b43_nphy_set_rf_sequence(dev, 5, rfseq_events, rfseq_delays, 3); b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, - (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, + ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -1116,7 +1117,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); b43_phy_mask(dev, B43_NPHY_PIL_DW1, - (u16)~B43_NPHY_PIL_DW_64QAM); + ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); @@ -2455,7 +2456,8 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); - b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX); + b43_phy_mask(dev, B43_NPHY_BBCFG, + ~B43_NPHY_BBCFG_RSTRX & 0xFFFF); tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); regs[5] = tmp; @@ -2930,7 +2932,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, tmp[5] = b43_phy_read(dev, rfctl[1]); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, - (u16)~B43_NPHY_RFSEQCA_RXDIS, + ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF, ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, (1 - i)); @@ -3291,7 +3293,7 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); - b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000); + b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); } diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 4e56b7bbceb..45933cf8e8c 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -182,6 +182,7 @@ static void b43_sdio_remove(struct sdio_func *func) static const struct sdio_device_id b43_sdio_ids[] = { { SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */ + { SDIO_DEVICE(0x0092, 0x0004) }, /* C-guys, Inc. EW-CG1102GC */ { }, }; diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 97c79161c20..9a335da65b4 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c @@ -382,7 +382,7 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); } - b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700); + b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80); b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300); @@ -400,9 +400,9 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020); b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200); b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E); - b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00); + b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00); b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028); - b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00); + b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00); if (phy->rev == 1) { b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002); @@ -412,7 +412,7 @@ static void b43_wa_altagc(struct b43_wldev *dev) b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004); if (phy->rev >= 6) { b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); - b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000); + b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000); } } b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874); diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index d23ff9fe0c9..d4cf9b390af 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -10,8 +10,8 @@ union { \ __le32 data; \ __u8 raw[size]; \ - } __attribute__((__packed__)); \ - } __attribute__((__packed__)) + } __packed; \ + } __packed /* struct b43_plcp_hdr4 */ _b43_declare_plcp_hdr(4); @@ -57,7 +57,7 @@ struct b43_txhdr { __u8 rts_frame[16]; /* The RTS frame (if used) */ PAD_BYTES(2); struct b43_plcp_hdr6 plcp; /* Main PLCP header */ - } new_format __attribute__ ((__packed__)); + } new_format __packed; /* The old r351 format. */ struct { @@ -68,10 +68,10 @@ struct b43_txhdr { __u8 rts_frame[16]; /* The RTS frame (if used) */ PAD_BYTES(2); struct b43_plcp_hdr6 plcp; /* Main PLCP header */ - } old_format __attribute__ ((__packed__)); + } old_format __packed; - } __attribute__ ((__packed__)); -} __attribute__ ((__packed__)); + } __packed; +} __packed; /* MAC TX control */ #define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ @@ -218,20 +218,20 @@ struct b43_rxhdr_fw4 { struct { __u8 jssi; /* PHY RX Status 1: JSSI */ __u8 sig_qual; /* PHY RX Status 1: Signal Quality */ - } __attribute__ ((__packed__)); + } __packed; /* RSSI for N-PHYs */ struct { __s8 power0; /* PHY RX Status 1: Power 0 */ __s8 power1; /* PHY RX Status 1: Power 1 */ - } __attribute__ ((__packed__)); - } __attribute__ ((__packed__)); + } __packed; + } __packed; __le16 phy_status2; /* PHY RX Status 2 */ __le16 phy_status3; /* PHY RX Status 3 */ __le32 mac_status; /* MAC RX status */ __le16 mac_time; __le16 channel; -} __attribute__ ((__packed__)); +} __packed; /* PHY RX Status 0 */ #define B43_RX_PHYST0_GAINCTL 0x4000 /* Gain Control */ diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 89fe2f972c7..c81b2f53b0c 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -372,7 +372,7 @@ struct b43legacy_fw_header { /* Size of the data. For ucode and PCM this is in bytes. * For IV this is number-of-ivs. */ __be32 size; -} __attribute__((__packed__)); +} __packed; /* Initial Value file format */ #define B43legacy_IV_OFFSET_MASK 0x7FFF @@ -382,8 +382,8 @@ struct b43legacy_iv { union { __be16 d16; __be32 d32; - } data __attribute__((__packed__)); -} __attribute__((__packed__)); + } data __packed; +} __packed; #define B43legacy_PHYMODE(phytype) (1 << (phytype)) #define B43legacy_PHYMODE_B B43legacy_PHYMODE \ diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index e91520d0312..e03e01d0bc3 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -394,11 +394,11 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring, dma_addr_t dmaaddr; if (tx) - dmaaddr = ssb_dma_map_single(ring->dev->dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_TO_DEVICE); else - dmaaddr = ssb_dma_map_single(ring->dev->dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_FROM_DEVICE); @@ -412,11 +412,11 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring, int tx) { if (tx) - ssb_dma_unmap_single(ring->dev->dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_TO_DEVICE); else - ssb_dma_unmap_single(ring->dev->dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -428,8 +428,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring, { B43legacy_WARN_ON(ring->tx); - ssb_dma_sync_single_for_cpu(ring->dev->dev, - addr, len, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(ring->dev->dev->dma_dev, + addr, len, DMA_FROM_DEVICE); } static inline @@ -439,8 +439,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring, { B43legacy_WARN_ON(ring->tx); - ssb_dma_sync_single_for_device(ring->dev->dev, - addr, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(ring->dev->dev->dma_dev, + addr, len, DMA_FROM_DEVICE); } static inline @@ -460,10 +460,10 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, static int alloc_ringmemory(struct b43legacy_dmaring *ring) { /* GFP flags must match the flags in free_ringmemory()! */ - ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, - B43legacy_DMA_RINGMEMSIZE, - &(ring->dmabase), - GFP_KERNEL); + ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, + B43legacy_DMA_RINGMEMSIZE, + &(ring->dmabase), + GFP_KERNEL); if (!ring->descbase) { b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" " failed\n"); @@ -476,8 +476,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) static void free_ringmemory(struct b43legacy_dmaring *ring) { - ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE, - ring->descbase, ring->dmabase, GFP_KERNEL); + dma_free_coherent(ring->dev->dev->dma_dev, B43legacy_DMA_RINGMEMSIZE, + ring->descbase, ring->dmabase); } /* Reset the RX DMA channel */ @@ -589,7 +589,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, size_t buffersize, bool dma_to_device) { - if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) + if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) return 1; switch (ring->type) { @@ -906,7 +906,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); @@ -920,7 +920,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = ssb_dma_map_single(dev->dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); @@ -930,9 +930,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, goto err_kfree_txhdr_cache; } - ssb_dma_unmap_single(dev->dev, dma_test, - sizeof(struct b43legacy_txhdr_fw3), - DMA_TO_DEVICE); + dma_unmap_single(dev->dev->dma_dev, dma_test, + sizeof(struct b43legacy_txhdr_fw3), + DMA_TO_DEVICE); } ring->nr_slots = nr_slots; @@ -1040,9 +1040,12 @@ static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = ssb_dma_set_mask(dev->dev, mask); - if (!err) - break; + err = dma_set_mask(dev->dev->dma_dev, mask); + if (!err) { + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); + if (!err) + break; + } if (mask == DMA_BIT_MASK(64)) { mask = DMA_BIT_MASK(32); fallback = 1; diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h index f9681041c2d..f89c3422628 100644 --- a/drivers/net/wireless/b43legacy/dma.h +++ b/drivers/net/wireless/b43legacy/dma.h @@ -72,7 +72,7 @@ struct b43legacy_dmadesc32 { __le32 control; __le32 address; -} __attribute__((__packed__)); +} __packed; #define B43legacy_DMA32_DCTL_BYTECNT 0x00001FFF #define B43legacy_DMA32_DCTL_ADDREXT_MASK 0x00030000 #define B43legacy_DMA32_DCTL_ADDREXT_SHIFT 16 @@ -147,7 +147,7 @@ struct b43legacy_dmadesc64 { __le32 control1; __le32 address_low; __le32 address_high; -} __attribute__((__packed__)); +} __packed; #define B43legacy_DMA64_DCTL0_DTABLEEND 0x10000000 #define B43legacy_DMA64_DCTL0_IRQ 0x20000000 #define B43legacy_DMA64_DCTL0_FRAMEEND 0x40000000 @@ -162,8 +162,8 @@ struct b43legacy_dmadesc_generic { union { struct b43legacy_dmadesc32 dma32; struct b43legacy_dmadesc64 dma64; - } __attribute__((__packed__)); -} __attribute__((__packed__)); + } __packed; +} __packed; /* Misc DMA constants */ diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index 91633087a20..289db00a4a7 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h @@ -9,8 +9,8 @@ union { \ __le32 data; \ __u8 raw[size]; \ - } __attribute__((__packed__)); \ - } __attribute__((__packed__)) + } __packed; \ + } __packed /* struct b43legacy_plcp_hdr4 */ _b43legacy_declare_plcp_hdr(4); @@ -39,7 +39,7 @@ struct b43legacy_txhdr_fw3 { struct b43legacy_plcp_hdr6 rts_plcp; /* RTS PLCP */ __u8 rts_frame[18]; /* The RTS frame (if used) */ struct b43legacy_plcp_hdr6 plcp; -} __attribute__((__packed__)); +} __packed; /* MAC TX control */ #define B43legacy_TX4_MAC_KEYIDX 0x0FF00000 /* Security key index */ @@ -123,7 +123,7 @@ struct b43legacy_hwtxstatus { __le16 seq; u8 phy_stat; PAD_BYTES(1); -} __attribute__((__packed__)); +} __packed; /* Receive header for v3 firmware. */ @@ -138,7 +138,7 @@ struct b43legacy_rxhdr_fw3 { __le16 mac_status; /* MAC RX status */ __le16 mac_time; __le16 channel; -} __attribute__((__packed__)); +} __packed; /* PHY RX Status 0 */ diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h index 7f9d8d976aa..ed98ce7c8f6 100644 --- a/drivers/net/wireless/hostap/hostap_80211.h +++ b/drivers/net/wireless/hostap/hostap_80211.h @@ -19,35 +19,35 @@ struct hostap_ieee80211_mgmt { __le16 status_code; /* possibly followed by Challenge text */ u8 variable[0]; - } __attribute__ ((packed)) auth; + } __packed auth; struct { __le16 reason_code; - } __attribute__ ((packed)) deauth; + } __packed deauth; struct { __le16 capab_info; __le16 listen_interval; /* followed by SSID and Supported rates */ u8 variable[0]; - } __attribute__ ((packed)) assoc_req; + } __packed assoc_req; struct { __le16 capab_info; __le16 status_code; __le16 aid; /* followed by Supported rates */ u8 variable[0]; - } __attribute__ ((packed)) assoc_resp, reassoc_resp; + } __packed assoc_resp, reassoc_resp; struct { __le16 capab_info; __le16 listen_interval; u8 current_ap[6]; /* followed by SSID and Supported rates */ u8 variable[0]; - } __attribute__ ((packed)) reassoc_req; + } __packed reassoc_req; struct { __le16 reason_code; - } __attribute__ ((packed)) disassoc; + } __packed disassoc; struct { - } __attribute__ ((packed)) probe_req; + } __packed probe_req; struct { u8 timestamp[8]; __le16 beacon_int; @@ -55,9 +55,9 @@ struct hostap_ieee80211_mgmt { /* followed by some of SSID, Supported rates, * FH Params, DS Params, CF Params, IBSS Params, TIM */ u8 variable[0]; - } __attribute__ ((packed)) beacon, probe_resp; + } __packed beacon, probe_resp; } u; -} __attribute__ ((packed)); +} __packed; #define IEEE80211_MGMT_HDR_LEN 24 diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 231dbd77f5f..dbb986946e1 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -688,7 +688,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) struct ap_data *ap = data; struct net_device *dev = ap->local->dev; struct ieee80211_hdr *hdr; - u16 fc, status; + u16 status; __le16 *pos; struct sta_info *sta = NULL; char *txt = NULL; @@ -699,7 +699,6 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) } hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); if ((!ieee80211_is_assoc_resp(hdr->frame_control) && !ieee80211_is_reassoc_resp(hdr->frame_control)) || skb->len < IEEE80211_MGMT_HDR_LEN + 4) { @@ -1225,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap) /* Generate challenge data for shared key authentication. IEEE 802.11 specifies - * that WEP algorithm is used for generating challange. This should be unique, + * that WEP algorithm is used for generating challenge. This should be unique, * but otherwise there is not really need for randomness etc. Initialize WEP * with pseudo random key and then use increasing IV to get unique challenge * streams. diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h index 90b64b09200..4230102ac9e 100644 --- a/drivers/net/wireless/hostap/hostap_common.h +++ b/drivers/net/wireless/hostap/hostap_common.h @@ -179,7 +179,7 @@ struct hfa384x_comp_ident __le16 variant; __le16 major; __le16 minor; -} __attribute__ ((packed)); +} __packed; #define HFA384X_COMP_ID_PRI 0x15 #define HFA384X_COMP_ID_STA 0x1f @@ -192,14 +192,14 @@ struct hfa384x_sup_range __le16 variant; __le16 bottom; __le16 top; -} __attribute__ ((packed)); +} __packed; struct hfa384x_build_id { __le16 pri_seq; __le16 sec_seq; -} __attribute__ ((packed)); +} __packed; /* FD01 - Download Buffer */ struct hfa384x_rid_download_buffer @@ -207,14 +207,14 @@ struct hfa384x_rid_download_buffer __le16 page; __le16 offset; __le16 length; -} __attribute__ ((packed)); +} __packed; /* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */ struct hfa384x_comms_quality { __le16 comm_qual; /* 0 .. 92 */ __le16 signal_level; /* 27 .. 154 */ __le16 noise_level; /* 27 .. 154 */ -} __attribute__ ((packed)); +} __packed; /* netdevice private ioctls (used, e.g., with iwpriv from user space) */ diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 2f999fc94f6..e9d9d622a9b 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -1896,7 +1896,7 @@ fail: /* Some SMP systems have reported number of odd errors with hostap_pci. fid * register has changed values between consecutive reads for an unknown reason. * This should really not happen, so more debugging is needed. This test - * version is a big slower, but it will detect most of such register changes + * version is a bit slower, but it will detect most of such register changes * and will try to get the correct fid eventually. */ #define EXTRA_FID_READ_TESTS diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index eb57d1ea361..25a2722c8a9 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -186,7 +186,7 @@ int prism2_wds_add(local_info_t *local, u8 *remote_addr, return -ENOBUFS; /* verify that there is room for wds# postfix in the interface name */ - if (strlen(local->dev->name) > IFNAMSIZ - 5) { + if (strlen(local->dev->name) >= IFNAMSIZ - 5) { printk(KERN_DEBUG "'%s' too long base device name\n", local->dev->name); return -EINVAL; @@ -741,9 +741,7 @@ void hostap_set_multicast_list_queue(struct work_struct *work) local_info_t *local = container_of(work, local_info_t, set_multicast_list_queue); struct net_device *dev = local->dev; - struct hostap_interface *iface; - iface = netdev_priv(dev); if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, local->is_promisc)) { printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index d24dc7dc072..972a9c3af39 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -330,6 +330,7 @@ static int prism2_pci_probe(struct pci_dev *pdev, dev->irq = pdev->irq; hw_priv->mem_start = mem; + dev->base_addr = (unsigned long) mem; prism2_pci_cor_sreset(local); diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 1ba33be98b2..1c66b3c1030 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -31,14 +31,14 @@ struct linux_wlan_ng_val { u32 did; u16 status, len; u32 data; -} __attribute__ ((packed)); +} __packed; struct linux_wlan_ng_prism_hdr { u32 msgcode, msglen; char devname[16]; struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal, noise, rate, istx, frmlen; -} __attribute__ ((packed)); +} __packed; struct linux_wlan_ng_cap_hdr { __be32 version; @@ -55,7 +55,7 @@ struct linux_wlan_ng_cap_hdr { __be32 ssi_noise; __be32 preamble; __be32 encoding; -} __attribute__ ((packed)); +} __packed; struct hostap_radiotap_rx { struct ieee80211_radiotap_header hdr; @@ -66,7 +66,7 @@ struct hostap_radiotap_rx { __le16 chan_flags; s8 dbm_antsignal; s8 dbm_antnoise; -} __attribute__ ((packed)); +} __packed; #define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */ #define LWNG_CAPHDR_VERSION 0x80211001 @@ -97,7 +97,7 @@ struct hfa384x_rx_frame { __be16 len; /* followed by frame data; max 2304 bytes */ -} __attribute__ ((packed)); +} __packed; struct hfa384x_tx_frame { @@ -126,14 +126,14 @@ struct hfa384x_tx_frame { __be16 len; /* followed by frame data; max 2304 bytes */ -} __attribute__ ((packed)); +} __packed; struct hfa384x_rid_hdr { __le16 len; __le16 rid; -} __attribute__ ((packed)); +} __packed; /* Macro for converting signal levels (range 27 .. 154) to wireless ext @@ -145,24 +145,24 @@ struct hfa384x_rid_hdr struct hfa384x_scan_request { __le16 channel_list; __le16 txrate; /* HFA384X_RATES_* */ -} __attribute__ ((packed)); +} __packed; struct hfa384x_hostscan_request { __le16 channel_list; __le16 txrate; __le16 target_ssid_len; u8 target_ssid[32]; -} __attribute__ ((packed)); +} __packed; struct hfa384x_join_request { u8 bssid[6]; __le16 channel; -} __attribute__ ((packed)); +} __packed; struct hfa384x_info_frame { __le16 len; __le16 type; -} __attribute__ ((packed)); +} __packed; struct hfa384x_comm_tallies { __le16 tx_unicast_frames; @@ -186,7 +186,7 @@ struct hfa384x_comm_tallies { __le16 rx_discards_wep_undecryptable; __le16 rx_message_in_msg_fragments; __le16 rx_message_in_bad_msg_fragments; -} __attribute__ ((packed)); +} __packed; struct hfa384x_comm_tallies32 { __le32 tx_unicast_frames; @@ -210,7 +210,7 @@ struct hfa384x_comm_tallies32 { __le32 rx_discards_wep_undecryptable; __le32 rx_message_in_msg_fragments; __le32 rx_message_in_bad_msg_fragments; -} __attribute__ ((packed)); +} __packed; struct hfa384x_scan_result_hdr { __le16 reserved; @@ -219,7 +219,7 @@ struct hfa384x_scan_result_hdr { #define HFA384X_SCAN_HOST_INITIATED 1 #define HFA384X_SCAN_FIRMWARE_INITIATED 2 #define HFA384X_SCAN_INQUIRY_FROM_HOST 3 -} __attribute__ ((packed)); +} __packed; #define HFA384X_SCAN_MAX_RESULTS 32 @@ -234,7 +234,7 @@ struct hfa384x_scan_result { u8 ssid[32]; u8 sup_rates[10]; __le16 rate; -} __attribute__ ((packed)); +} __packed; struct hfa384x_hostscan_result { __le16 chid; @@ -248,7 +248,7 @@ struct hfa384x_hostscan_result { u8 sup_rates[10]; __le16 rate; __le16 atim; -} __attribute__ ((packed)); +} __packed; struct comm_tallies_sums { unsigned int tx_unicast_frames; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 0bd4dfa59a8..c24c5efeae1 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -174,7 +174,7 @@ that only one external action is invoked at a time. #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" -struct pm_qos_request_list *ipw2100_pm_qos_req; +static struct pm_qos_request_list ipw2100_pm_qos_req; /* Debugging stuff */ #ifdef CONFIG_IPW2100_DEBUG @@ -1741,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) /* the ipw2100 hardware really doesn't want power management delays * longer than 175usec */ - pm_qos_update_request(ipw2100_pm_qos_req, 175); + pm_qos_update_request(&ipw2100_pm_qos_req, 175); /* If the interrupt is enabled, turn it off... */ spin_lock_irqsave(&priv->low_lock, flags); @@ -1889,7 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv) ipw2100_disable_interrupts(priv); spin_unlock_irqrestore(&priv->low_lock, flags); - pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); + pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); /* We have to signal any supplicant if we are disassociating */ if (associated) @@ -3467,10 +3467,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) dma_addr_t p; priv->msg_buffers = - (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE * - sizeof(struct - ipw2100_tx_packet), - GFP_KERNEL); + kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), + GFP_KERNEL); if (!priv->msg_buffers) { printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " "buffers.\n", priv->net_dev->name); @@ -4499,10 +4497,8 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv) } priv->tx_buffers = - (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH * - sizeof(struct - ipw2100_tx_packet), - GFP_ATOMIC); + kmalloc(TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet), + GFP_ATOMIC); if (!priv->tx_buffers) { printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n", @@ -4651,9 +4647,9 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv) /* * allocate packets */ - priv->rx_buffers = (struct ipw2100_rx_packet *) - kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet), - GFP_KERNEL); + priv->rx_buffers = kmalloc(RX_QUEUE_LENGTH * + sizeof(struct ipw2100_rx_packet), + GFP_KERNEL); if (!priv->rx_buffers) { IPW_DEBUG_INFO("can't allocate rx packet buffer table\n"); @@ -5233,7 +5229,7 @@ struct security_info_params { u8 auth_mode; u8 replay_counters_number; u8 unicast_using_group; -} __attribute__ ((packed)); +} __packed; static int ipw2100_set_security_information(struct ipw2100_priv *priv, int auth_mode, @@ -6669,8 +6665,8 @@ static int __init ipw2100_init(void) if (ret) goto out; - ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); + pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); #ifdef CONFIG_IPW2100_DEBUG ipw2100_debug_level = debug; ret = driver_create_file(&ipw2100_pci_driver.driver, @@ -6692,7 +6688,7 @@ static void __exit ipw2100_exit(void) &driver_attr_debug_level); #endif pci_unregister_driver(&ipw2100_pci_driver); - pm_qos_remove_request(ipw2100_pm_qos_req); + pm_qos_remove_request(&ipw2100_pm_qos_req); } module_init(ipw2100_init); @@ -8475,7 +8471,7 @@ struct ipw2100_fw_header { short mode; unsigned int fw_size; unsigned int uc_size; -} __attribute__ ((packed)); +} __packed; static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw) { diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h index 1eab0d698f4..838002b4881 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.h +++ b/drivers/net/wireless/ipw2x00/ipw2100.h @@ -164,7 +164,7 @@ struct bd_status { } fields; u8 field; } info; -} __attribute__ ((packed)); +} __packed; struct ipw2100_bd { u32 host_addr; @@ -174,7 +174,7 @@ struct ipw2100_bd { * 1st TBD) */ u8 num_fragments; u8 reserved[6]; -} __attribute__ ((packed)); +} __packed; #define IPW_BD_QUEUE_LENGTH(n) (1<<n) #define IPW_BD_ALIGNMENT(L) (L*sizeof(struct ipw2100_bd)) @@ -232,7 +232,7 @@ struct ipw2100_status { #define IPW_STATUS_FLAG_WEP_ENCRYPTED (1<<1) #define IPW_STATUS_FLAG_CRC_ERROR (1<<2) u8 rssi; -} __attribute__ ((packed)); +} __packed; struct ipw2100_status_queue { /* driver (virtual) pointer to queue */ @@ -293,7 +293,7 @@ struct ipw2100_cmd_header { u32 reserved1[3]; u32 *ordinal1_ptr; u32 *ordinal2_ptr; -} __attribute__ ((packed)); +} __packed; struct ipw2100_data_header { u32 host_command_reg; @@ -307,7 +307,7 @@ struct ipw2100_data_header { u8 src_addr[ETH_ALEN]; u8 dst_addr[ETH_ALEN]; u16 fragment_size; -} __attribute__ ((packed)); +} __packed; /* Host command data structure */ struct host_command { @@ -316,7 +316,7 @@ struct host_command { u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) u32 host_command_length; // LENGTH u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS -} __attribute__ ((packed)); +} __packed; typedef enum { POWER_ON_RESET, @@ -382,7 +382,7 @@ struct ipw2100_notification { u32 hnhdr_size; /* size in bytes of data or number of entries, if table. Does NOT include header */ -} __attribute__ ((packed)); +} __packed; #define MAX_KEY_SIZE 16 #define MAX_KEYS 8 @@ -814,7 +814,7 @@ struct ipw2100_rx { struct ipw2100_notification notification; struct ipw2100_cmd_header command; } rx_data; -} __attribute__ ((packed)); +} __packed; /* Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved */ #define TX_RATE_1_MBIT 0x0001 diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 3aa3bb18f61..cb2552a6777 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -96,7 +96,7 @@ static int network_mode = 0; static u32 ipw_debug_level; static int associate; static int auto_create = 1; -static int led_support = 0; +static int led_support = 1; static int disable = 0; static int bt_coexist = 0; static int hwcrypto = 0; @@ -6624,13 +6624,12 @@ static int ipw_wx_set_genie(struct net_device *dev, return -EINVAL; if (wrqu->data.length) { - buf = kmalloc(wrqu->data.length, GFP_KERNEL); + buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL); if (buf == NULL) { err = -ENOMEM; goto out; } - memcpy(buf, extra, wrqu->data.length); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = wrqu->data.length; @@ -12083,7 +12082,7 @@ module_param(auto_create, int, 0444); MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); module_param_named(led, led_support, int, 0444); -MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)"); +MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)"); module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index bf0eeb2e873..d7d049c7a4f 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -388,7 +388,7 @@ struct clx2_queue { dma_addr_t dma_addr; /**< physical addr for BD's */ int low_mark; /**< low watermark, resume queue if free space more than this */ int high_mark; /**< high watermark, stop queue if free space less than this */ -} __attribute__ ((packed)); /* XXX */ +} __packed; /* XXX */ struct machdr32 { __le16 frame_ctl; @@ -399,7 +399,7 @@ struct machdr32 { __le16 seq_ctrl; // more endians! u8 addr4[MACADRR_BYTE_LEN]; __le16 qos_ctrl; -} __attribute__ ((packed)); +} __packed; struct machdr30 { __le16 frame_ctl; @@ -409,7 +409,7 @@ struct machdr30 { u8 addr3[MACADRR_BYTE_LEN]; __le16 seq_ctrl; // more endians! u8 addr4[MACADRR_BYTE_LEN]; -} __attribute__ ((packed)); +} __packed; struct machdr26 { __le16 frame_ctl; @@ -419,7 +419,7 @@ struct machdr26 { u8 addr3[MACADRR_BYTE_LEN]; __le16 seq_ctrl; // more endians! __le16 qos_ctrl; -} __attribute__ ((packed)); +} __packed; struct machdr24 { __le16 frame_ctl; @@ -428,20 +428,20 @@ struct machdr24 { u8 addr2[MACADRR_BYTE_LEN]; u8 addr3[MACADRR_BYTE_LEN]; __le16 seq_ctrl; // more endians! -} __attribute__ ((packed)); +} __packed; // TX TFD with 32 byte MAC Header struct tx_tfd_32 { struct machdr32 mchdr; // 32 __le32 uivplaceholder[2]; // 8 -} __attribute__ ((packed)); +} __packed; // TX TFD with 30 byte MAC Header struct tx_tfd_30 { struct machdr30 mchdr; // 30 u8 reserved[2]; // 2 __le32 uivplaceholder[2]; // 8 -} __attribute__ ((packed)); +} __packed; // tx tfd with 26 byte mac header struct tx_tfd_26 { @@ -449,14 +449,14 @@ struct tx_tfd_26 { u8 reserved1[2]; // 2 __le32 uivplaceholder[2]; // 8 u8 reserved2[4]; // 4 -} __attribute__ ((packed)); +} __packed; // tx tfd with 24 byte mac header struct tx_tfd_24 { struct machdr24 mchdr; // 24 __le32 uivplaceholder[2]; // 8 u8 reserved[8]; // 8 -} __attribute__ ((packed)); +} __packed; #define DCT_WEP_KEY_FIELD_LENGTH 16 @@ -465,7 +465,7 @@ struct tfd_command { u8 length; __le16 reserved; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct tfd_data { /* Header */ @@ -504,14 +504,14 @@ struct tfd_data { __le32 num_chunks; __le32 chunk_ptr[NUM_TFD_CHUNKS]; __le16 chunk_len[NUM_TFD_CHUNKS]; -} __attribute__ ((packed)); +} __packed; struct txrx_control_flags { u8 message_type; u8 rx_seq_num; u8 control_bits; u8 reserved; -} __attribute__ ((packed)); +} __packed; #define TFD_SIZE 128 #define TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH (TFD_SIZE - sizeof(struct txrx_control_flags)) @@ -523,7 +523,7 @@ struct tfd_frame { struct tfd_command cmd; u8 raw[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; } u; -} __attribute__ ((packed)); +} __packed; typedef void destructor_func(const void *); @@ -559,7 +559,7 @@ struct rate_histogram { __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; } failed; -} __attribute__ ((packed)); +} __packed; /* statistics command response */ struct ipw_cmd_stats { @@ -586,13 +586,13 @@ struct ipw_cmd_stats { __le16 rx_autodetec_no_ofdm; __le16 rx_autodetec_no_barker; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct notif_channel_result { u8 channel_num; struct ipw_cmd_stats stats; u8 uReserved; -} __attribute__ ((packed)); +} __packed; #define SCAN_COMPLETED_STATUS_COMPLETE 1 #define SCAN_COMPLETED_STATUS_ABORTED 2 @@ -602,24 +602,24 @@ struct notif_scan_complete { u8 num_channels; u8 status; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct notif_frag_length { __le16 frag_length; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct notif_beacon_state { __le32 state; __le32 number; -} __attribute__ ((packed)); +} __packed; struct notif_tgi_tx_key { u8 key_state; u8 security_type; u8 station_index; u8 reserved; -} __attribute__ ((packed)); +} __packed; #define SILENCE_OVER_THRESH (1) #define SILENCE_UNDER_THRESH (2) @@ -631,25 +631,25 @@ struct notif_link_deterioration { struct rate_histogram histogram; u8 silence_notification_type; /* SILENCE_OVER/UNDER_THRESH */ __le16 silence_count; -} __attribute__ ((packed)); +} __packed; struct notif_association { u8 state; -} __attribute__ ((packed)); +} __packed; struct notif_authenticate { u8 state; struct machdr24 addr; __le16 status; -} __attribute__ ((packed)); +} __packed; struct notif_calibration { u8 data[104]; -} __attribute__ ((packed)); +} __packed; struct notif_noise { __le32 value; -} __attribute__ ((packed)); +} __packed; struct ipw_rx_notification { u8 reserved[8]; @@ -669,7 +669,7 @@ struct ipw_rx_notification { struct notif_noise noise; u8 raw[0]; } u; -} __attribute__ ((packed)); +} __packed; struct ipw_rx_frame { __le32 reserved1; @@ -692,14 +692,14 @@ struct ipw_rx_frame { u8 rtscts_seen; // 0x1 RTS seen ; 0x2 CTS seen __le16 length; u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct ipw_rx_header { u8 message_type; u8 rx_seq_num; u8 control_bits; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_rx_packet { struct ipw_rx_header header; @@ -707,7 +707,7 @@ struct ipw_rx_packet { struct ipw_rx_frame frame; struct ipw_rx_notification notification; } u; -} __attribute__ ((packed)); +} __packed; #define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12 #define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \ @@ -717,7 +717,7 @@ struct ipw_rx_mem_buffer { dma_addr_t dma_addr; struct sk_buff *skb; struct list_head list; -}; /* Not transferred over network, so not __attribute__ ((packed)) */ +}; /* Not transferred over network, so not __packed */ struct ipw_rx_queue { struct ipw_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; @@ -730,7 +730,7 @@ struct ipw_rx_queue { struct list_head rx_free; /* Own an SKBs */ struct list_head rx_used; /* No SKB allocated */ spinlock_t lock; -}; /* Not transferred over network, so not __attribute__ ((packed)) */ +}; /* Not transferred over network, so not __packed */ struct alive_command_responce { u8 alive_command; @@ -745,21 +745,21 @@ struct alive_command_responce { __le16 reserved4; u8 time_stamp[5]; /* month, day, year, hours, minutes */ u8 ucode_valid; -} __attribute__ ((packed)); +} __packed; #define IPW_MAX_RATES 12 struct ipw_rates { u8 num_rates; u8 rates[IPW_MAX_RATES]; -} __attribute__ ((packed)); +} __packed; struct command_block { unsigned int control; u32 source_addr; u32 dest_addr; unsigned int status; -} __attribute__ ((packed)); +} __packed; #define CB_NUMBER_OF_ELEMENTS_SMALL 64 struct fw_image_desc { @@ -792,7 +792,7 @@ struct ipw_sys_config { u8 accept_all_mgmt_frames; u8 pass_noise_stats_to_host; u8 reserved3; -} __attribute__ ((packed)); +} __packed; struct ipw_multicast_addr { u8 num_of_multicast_addresses; @@ -801,7 +801,7 @@ struct ipw_multicast_addr { u8 mac2[6]; u8 mac3[6]; u8 mac4[6]; -} __attribute__ ((packed)); +} __packed; #define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */ #define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */ @@ -822,7 +822,7 @@ struct ipw_wep_key { u8 key_index; u8 key_size; u8 key[16]; -} __attribute__ ((packed)); +} __packed; struct ipw_tgi_tx_key { u8 key_id; @@ -831,7 +831,7 @@ struct ipw_tgi_tx_key { u8 flags; u8 key[16]; __le32 tx_counter[2]; -} __attribute__ ((packed)); +} __packed; #define IPW_SCAN_CHANNELS 54 @@ -840,7 +840,7 @@ struct ipw_scan_request { __le16 dwell_time; u8 channels_list[IPW_SCAN_CHANNELS]; u8 channels_reserved[3]; -} __attribute__ ((packed)); +} __packed; enum { IPW_SCAN_PASSIVE_TILL_FIRST_BEACON_SCAN = 0, @@ -857,7 +857,7 @@ struct ipw_scan_request_ext { u8 scan_type[IPW_SCAN_CHANNELS / 2]; u8 reserved; __le16 dwell_time[IPW_SCAN_TYPES]; -} __attribute__ ((packed)); +} __packed; static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index) { @@ -902,7 +902,7 @@ struct ipw_associate { u8 smr; u8 reserved1; __le16 reserved2; -} __attribute__ ((packed)); +} __packed; struct ipw_supported_rates { u8 ieee_mode; @@ -910,36 +910,36 @@ struct ipw_supported_rates { u8 purpose; u8 reserved; u8 supported_rates[IPW_MAX_RATES]; -} __attribute__ ((packed)); +} __packed; struct ipw_rts_threshold { __le16 rts_threshold; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_frag_threshold { __le16 frag_threshold; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_retry_limit { u8 short_retry_limit; u8 long_retry_limit; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_dino_config { __le32 dino_config_addr; __le16 dino_config_size; u8 dino_response; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_aironet_info { u8 id; u8 length; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_rx_key { u8 station_index; @@ -950,25 +950,25 @@ struct ipw_rx_key { u8 station_address[6]; u8 key_index; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct ipw_country_channel_info { u8 first_channel; u8 no_channels; s8 max_tx_power; -} __attribute__ ((packed)); +} __packed; struct ipw_country_info { u8 id; u8 length; u8 country_str[3]; struct ipw_country_channel_info groups[7]; -} __attribute__ ((packed)); +} __packed; struct ipw_channel_tx_power { u8 channel_number; s8 tx_power; -} __attribute__ ((packed)); +} __packed; #define SCAN_ASSOCIATED_INTERVAL (HZ) #define SCAN_INTERVAL (HZ / 10) @@ -979,18 +979,18 @@ struct ipw_tx_power { u8 num_channels; u8 ieee_mode; struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; -} __attribute__ ((packed)); +} __packed; struct ipw_rsn_capabilities { u8 id; u8 length; __le16 version; -} __attribute__ ((packed)); +} __packed; struct ipw_sensitivity_calib { __le16 beacon_rssi_raw; __le16 reserved; -} __attribute__ ((packed)); +} __packed; /** * Host command structure. @@ -1019,7 +1019,7 @@ struct ipw_cmd { /* XXX */ * nParams=(len+3)/4+status_len */ u32 param[0]; -} __attribute__ ((packed)); +} __packed; #define STATUS_HCMD_ACTIVE (1<<0) /**< host command in progress */ @@ -1114,7 +1114,7 @@ struct ipw_event { /* XXX */ u32 event; u32 time; u32 data; -} __attribute__ ((packed)); +} __packed; struct ipw_fw_error { /* XXX */ unsigned long jiffies; @@ -1125,7 +1125,7 @@ struct ipw_fw_error { /* XXX */ struct ipw_error_elem *elem; struct ipw_event *log; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; #ifdef CONFIG_IPW2200_PROMISCUOUS @@ -1170,7 +1170,7 @@ struct ipw_rt_hdr { s8 rt_dbmnoise; u8 rt_antenna; /* antenna number */ u8 payload[0]; /* payload... */ -} __attribute__ ((packed)); +} __packed; #endif struct ipw_priv { @@ -1957,7 +1957,7 @@ enum { struct ipw_fixed_rate { __le16 tx_rates; __le16 reserved; -} __attribute__ ((packed)); +} __packed; #define IPW_INDIRECT_ADDR_MASK (~0x3ul) @@ -1966,14 +1966,14 @@ struct host_cmd { u8 len; u16 reserved; u32 *param; -} __attribute__ ((packed)); /* XXX */ +} __packed; /* XXX */ struct cmdlog_host_cmd { u8 cmd; u8 len; __le16 reserved; char param[124]; -} __attribute__ ((packed)); +} __packed; struct ipw_cmd_log { unsigned long jiffies; diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 284b0e4cb81..70f5586d96b 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -154,7 +154,7 @@ struct libipw_snap_hdr { u8 ctrl; /* always 0x03 */ u8 oui[P80211_OUI_LEN]; /* organizational universal id */ -} __attribute__ ((packed)); +} __packed; #define SNAP_SIZE sizeof(struct libipw_snap_hdr) @@ -323,7 +323,7 @@ struct libipw_security { u8 keys[WEP_KEYS][SCM_KEY_LEN]; u8 level; u16 flags; -} __attribute__ ((packed)); +} __packed; /* @@ -347,7 +347,7 @@ struct libipw_hdr_1addr { __le16 duration_id; u8 addr1[ETH_ALEN]; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_hdr_2addr { __le16 frame_ctl; @@ -355,7 +355,7 @@ struct libipw_hdr_2addr { u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_hdr_3addr { __le16 frame_ctl; @@ -365,7 +365,7 @@ struct libipw_hdr_3addr { u8 addr3[ETH_ALEN]; __le16 seq_ctl; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_hdr_4addr { __le16 frame_ctl; @@ -376,7 +376,7 @@ struct libipw_hdr_4addr { __le16 seq_ctl; u8 addr4[ETH_ALEN]; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_hdr_3addrqos { __le16 frame_ctl; @@ -387,13 +387,13 @@ struct libipw_hdr_3addrqos { __le16 seq_ctl; u8 payload[0]; __le16 qos_ctl; -} __attribute__ ((packed)); +} __packed; struct libipw_info_element { u8 id; u8 len; u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* * These are the data types that can make up management packets @@ -406,7 +406,7 @@ struct libipw_info_element { u16 listen_interval; struct { u16 association_id:14, reserved:2; - } __attribute__ ((packed)); + } __packed; u32 time_stamp[2]; u16 reason; u16 status; @@ -419,7 +419,7 @@ struct libipw_auth { __le16 status; /* challenge */ struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_channel_switch { u8 id; @@ -427,7 +427,7 @@ struct libipw_channel_switch { u8 mode; u8 channel; u8 count; -} __attribute__ ((packed)); +} __packed; struct libipw_action { struct libipw_hdr_3addr header; @@ -441,12 +441,12 @@ struct libipw_action { struct libipw_channel_switch channel_switch; } format; -} __attribute__ ((packed)); +} __packed; struct libipw_disassoc { struct libipw_hdr_3addr header; __le16 reason; -} __attribute__ ((packed)); +} __packed; /* Alias deauth for disassoc */ #define libipw_deauth libipw_disassoc @@ -455,7 +455,7 @@ struct libipw_probe_request { struct libipw_hdr_3addr header; /* SSID, supported rates */ struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_probe_response { struct libipw_hdr_3addr header; @@ -465,7 +465,7 @@ struct libipw_probe_response { /* SSID, supported rates, FH params, DS params, * CF params, IBSS params, TIM (if beacon), RSN */ struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; /* Alias beacon for probe_response */ #define libipw_beacon libipw_probe_response @@ -476,7 +476,7 @@ struct libipw_assoc_request { __le16 listen_interval; /* SSID, supported rates, RSN */ struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_reassoc_request { struct libipw_hdr_3addr header; @@ -484,7 +484,7 @@ struct libipw_reassoc_request { __le16 listen_interval; u8 current_ap[ETH_ALEN]; struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_assoc_response { struct libipw_hdr_3addr header; @@ -493,7 +493,7 @@ struct libipw_assoc_response { __le16 aid; /* supported rates */ struct libipw_info_element info_element[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_txb { u8 nr_frags; @@ -555,19 +555,19 @@ struct libipw_qos_information_element { u8 qui_subtype; u8 version; u8 ac_info; -} __attribute__ ((packed)); +} __packed; struct libipw_qos_ac_parameter { u8 aci_aifsn; u8 ecw_min_max; __le16 tx_op_limit; -} __attribute__ ((packed)); +} __packed; struct libipw_qos_parameter_info { struct libipw_qos_information_element info_element; u8 reserved; struct libipw_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); +} __packed; struct libipw_qos_parameters { __le16 cw_min[QOS_QUEUE_NUM]; @@ -575,7 +575,7 @@ struct libipw_qos_parameters { u8 aifs[QOS_QUEUE_NUM]; u8 flag[QOS_QUEUE_NUM]; __le16 tx_op_limit[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); +} __packed; struct libipw_qos_data { struct libipw_qos_parameters parameters; @@ -588,7 +588,7 @@ struct libipw_qos_data { struct libipw_tim_parameters { u8 tim_count; u8 tim_period; -} __attribute__ ((packed)); +} __packed; /*******************************************************/ @@ -606,7 +606,7 @@ struct libipw_basic_report { __le64 start_time; __le16 duration; u8 map; -} __attribute__ ((packed)); +} __packed; enum { /* libipw_measurement_request.mode */ /* Bit 0 is reserved */ @@ -627,7 +627,7 @@ struct libipw_measurement_params { u8 channel; __le64 start_time; __le16 duration; -} __attribute__ ((packed)); +} __packed; struct libipw_measurement_request { struct libipw_info_element ie; @@ -635,7 +635,7 @@ struct libipw_measurement_request { u8 mode; u8 type; struct libipw_measurement_params params[0]; -} __attribute__ ((packed)); +} __packed; struct libipw_measurement_report { struct libipw_info_element ie; @@ -645,17 +645,17 @@ struct libipw_measurement_report { union { struct libipw_basic_report basic[0]; } u; -} __attribute__ ((packed)); +} __packed; struct libipw_tpc_report { u8 transmit_power; u8 link_margin; -} __attribute__ ((packed)); +} __packed; struct libipw_channel_map { u8 channel; u8 map; -} __attribute__ ((packed)); +} __packed; struct libipw_ibss_dfs { struct libipw_info_element ie; @@ -668,14 +668,14 @@ struct libipw_csa { u8 mode; u8 channel; u8 count; -} __attribute__ ((packed)); +} __packed; struct libipw_quiet { u8 count; u8 period; u8 duration; u8 offset; -} __attribute__ ((packed)); +} __packed; struct libipw_network { /* These entries are used to identify a unique network */ @@ -828,7 +828,6 @@ struct libipw_device { int host_strip_iv_icv; int host_open_frag; - int host_build_iv; int ieee802_1x; /* is IEEE 802.1X used */ /* WPA data */ diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 55965408ff3..32dee2ce5d3 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -62,8 +62,8 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -struct cfg80211_ops libipw_config_ops = { }; -void *libipw_wiphy_privid = &libipw_wiphy_privid; +static struct cfg80211_ops libipw_config_ops = { }; +static void *libipw_wiphy_privid = &libipw_wiphy_privid; static int libipw_networks_allocate(struct libipw_device *ieee) { diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c index da8beac7fcf..01c88a71abe 100644 --- a/drivers/net/wireless/ipw2x00/libipw_tx.c +++ b/drivers/net/wireless/ipw2x00/libipw_tx.c @@ -260,7 +260,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size, rts_required; unsigned long flags; - int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv; + int encrypt, host_encrypt, host_encrypt_msdu; __be16 ether_type; int bytes, fc, hdr_len; struct sk_buff *skb_frag; @@ -301,7 +301,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) host_encrypt = ieee->host_encrypt && encrypt && crypt; host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt; - host_build_iv = ieee->host_build_iv && encrypt && crypt; if (!encrypt && ieee->ieee802_1x && ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) { @@ -313,7 +312,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) skb_copy_from_linear_data(skb, dest, ETH_ALEN); skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN); - if (host_encrypt || host_build_iv) + if (host_encrypt) fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | IEEE80211_FCTL_PROTECTED; else @@ -467,7 +466,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) for (; i < nr_frags; i++) { skb_frag = txb->fragments[i]; - if (host_encrypt || host_build_iv) + if (host_encrypt) skb_reserve(skb_frag, crypt->ops->extra_mpdu_prefix_len); @@ -502,15 +501,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev) * to insert the IV between the header and the payload */ if (host_encrypt) libipw_encrypt_fragment(ieee, skb_frag, hdr_len); - else if (host_build_iv) { - atomic_inc(&crypt->refcnt); - if (crypt->ops->build_iv) - crypt->ops->build_iv(skb_frag, hdr_len, - ieee->sec.keys[ieee->sec.active_key], - ieee->sec.key_sizes[ieee->sec.active_key], - crypt->priv); - atomic_dec(&crypt->refcnt); - } if (ieee->config & (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS)) diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 3633c6682e4..d7bd6cf00a8 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c @@ -320,7 +320,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee, }; int i, key, key_provided, len; struct lib80211_crypt_data **crypt; - int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; + int host_crypto = ieee->host_encrypt || ieee->host_decrypt; DECLARE_SSID_BUF(ssid); LIBIPW_DEBUG_WX("SET_ENCODE\n"); @@ -411,10 +411,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee, /* If a new key was provided, set it up */ if (erq->length > 0) { -#ifdef CONFIG_LIBIPW_DEBUG - DECLARE_SSID_BUF(ssid); -#endif - len = erq->length <= 5 ? 5 : 13; memcpy(sec.keys[key], keybuf, erq->length); if (len > erq->length) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index dc8ed152766..a51e4da1bdf 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -30,9 +30,11 @@ config IWLWIFI_DEBUG config IWLWIFI_DEBUGFS bool "iwlagn debugfs support" - depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS + depends on IWLWIFI && MAC80211_DEBUGFS ---help--- - Enable creation of debugfs files for the iwlwifi drivers. + Enable creation of debugfs files for the iwlwifi drivers. This + is a low-impact option that allows getting insight into the + driver's state at runtime. config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" @@ -85,10 +87,15 @@ config IWL4965 This option enables support for Intel Wireless WiFi Link 4965AGN config IWL5000 - bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series" + bool "Intel Wireless-N/Advanced-N/Ultimate-N WiFi Link" depends on IWLAGN ---help--- - This option enables support for Intel Wireless WiFi Link 5000AGN Family + This option enables support for use with the following hardware: + Intel Wireless WiFi Link 6250AGN Adapter + Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) + Intel WiFi Link 1000BGN + Intel Wireless WiFi 5150AGN + Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN config IWL3945 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 7c723538551..728bb858ba9 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_IWLWIFI) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o +iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwlcore-objs += iwl-scan.o iwl-led.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o @@ -11,7 +11,7 @@ CFLAGS_iwl-devtrace.o := -I$(src) obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o -iwlagn-objs += iwl-agn-lib.o +iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 6be2992f8f2..8848333bc3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -129,8 +129,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->cfg->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; + priv->hw_params.max_stations = IWLAGN_STATION_COUNT; + priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -157,6 +157,10 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_TX_IQ_PERD) | BIT(IWL_CALIB_BASE_BAND); + if (priv->cfg->need_dc_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); + + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; return 0; } @@ -213,14 +217,18 @@ static struct iwl_lib_ops iwl1000_lib = { .set_ct_kill = iwl1000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c index 6a9c64a50e3..ef0835b01b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c @@ -28,6 +28,28 @@ #include "iwl-3945-debugfs.h" + +static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +{ + int p = 0; + + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", + le32_to_cpu(priv->_3945.statistics.flag)); + if (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, + "\tStatistics have been cleared\n"); + p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); + p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); + return p; +} + ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file, max_cck = &priv->_3945.max_delta.rx.cck; max_general = &priv->_3945.max_delta.rx.general; - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + pos += iwl3945_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_Rx - OFDM:"); @@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file, accum_tx = &priv->_3945.accum_statistics.tx; delta_tx = &priv->_3945.delta_statistics.tx; max_tx = &priv->_3945.max_delta.tx; - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + pos += iwl3945_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_Tx:"); @@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file, accum_div = &priv->_3945.accum_statistics.general.div; delta_div = &priv->_3945.delta_statistics.general.div; max_div = &priv->_3945.max_delta.general.div; - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + pos += iwl3945_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_General:"); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h index 042f6bc0df1..2c9ed2b502a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h @@ -175,13 +175,13 @@ struct iwl3945_tfd_tb { __le32 addr; __le32 len; -} __attribute__ ((packed)); +} __packed; struct iwl3945_tfd { __le32 control_flags; struct iwl3945_tfd_tb tbs[4]; u8 __pad[28]; -} __attribute__ ((packed)); +} __packed; #endif /* __iwl_3945_fh_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 91bcb4e3cdf..7c731a79363 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -96,7 +96,7 @@ struct iwl3945_eeprom_txpower_sample { u8 gain_index; /* index into power (gain) setup table ... */ s8 power; /* ... for this pwr level for this chnl group */ u16 v_det; /* PA output voltage */ -} __attribute__ ((packed)); +} __packed; /* * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. @@ -117,7 +117,7 @@ struct iwl3945_eeprom_txpower_group { u8 group_channel; /* "representative" channel # in this band */ s16 temperature; /* h/w temperature at factory calib this band * (signed) */ -} __attribute__ ((packed)); +} __packed; /* * Temperature-based Tx-power compensation data, not band-specific. @@ -131,7 +131,7 @@ struct iwl3945_eeprom_temperature_corr { u32 Tc; u32 Td; u32 Te; -} __attribute__ ((packed)); +} __packed; /* * EEPROM map @@ -215,7 +215,7 @@ struct iwl3945_eeprom { /* abs.ofs: 512 */ struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ u8 reserved16[172]; /* fill out to full 1024 byte block */ -} __attribute__ ((packed)); +} __packed; #define IWL3945_EEPROM_IMG_SIZE 1024 @@ -274,7 +274,7 @@ static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ struct iwl3945_shared { __le32 tx_base_ptr[8]; -} __attribute__ ((packed)); +} __packed; static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index c44a303e62e..a07310fefcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -279,8 +279,8 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); - tx_info->skb[0] = NULL; + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); + tx_info->skb = NULL; priv->cfg->ops->lib->txq_free_tfd(priv, txq); } @@ -315,7 +315,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, return; } - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); ieee80211_tx_info_clear_status(info); /* Fill the MRR chain with some info about on-chip retransmissions */ @@ -352,7 +352,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, * RX handler implementations * *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS /* * based on the assumption of all statistics counter are in DWORD * FIXME: This function is for debugging, do not deal with @@ -406,6 +406,11 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, unsigned int plcp_msec; unsigned long plcp_received_jiffies; + if (priv->cfg->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } memcpy(¤t_stat, pkt->u.raw, sizeof(struct iwl3945_notif_statistics)); /* @@ -460,7 +465,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(struct iwl3945_notif_statistics), le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); #endif iwl_recover_from_statistics(priv, pkt); @@ -475,7 +480,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv, __le32 *flag = (__le32 *)&pkt->u.raw; if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS memset(&priv->_3945.accum_statistics, 0, sizeof(struct iwl3945_notif_statistics)); memset(&priv->_3945.delta_statistics, 0, @@ -494,158 +499,6 @@ void iwl3945_reply_statistics(struct iwl_priv *priv, * Misc. internal state and helper functions * ******************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG - -/** - * iwl3945_report_frame - dump frame to syslog during debug sessions - * - * You may hack this function to show different aspects of received frames, - * including selective frame dumps. - * group100 parameter selects whether to show 1 out of 100 good frames. - */ -static void _iwl3945_dbg_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - struct ieee80211_hdr *header, int group100) -{ - u32 to_us; - u32 print_summary = 0; - u32 print_dump = 0; /* set to 1 to dump all frames' contents */ - u32 hundred = 0; - u32 dataframe = 0; - __le16 fc; - u16 seq_ctl; - u16 channel; - u16 phy_flags; - u16 length; - u16 status; - u16 bcn_tmr; - u32 tsf_low; - u64 tsf; - u8 rssi; - u8 agc; - u16 sig_avg; - u16 noise_diff; - struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); - u8 *data = IWL_RX_DATA(pkt); - - /* MAC header */ - fc = header->frame_control; - seq_ctl = le16_to_cpu(header->seq_ctrl); - - /* metadata */ - channel = le16_to_cpu(rx_hdr->channel); - phy_flags = le16_to_cpu(rx_hdr->phy_flags); - length = le16_to_cpu(rx_hdr->len); - - /* end-of-frame status and timestamp */ - status = le32_to_cpu(rx_end->status); - bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp); - tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff; - tsf = le64_to_cpu(rx_end->timestamp); - - /* signal statistics */ - rssi = rx_stats->rssi; - agc = rx_stats->agc; - sig_avg = le16_to_cpu(rx_stats->sig_avg); - noise_diff = le16_to_cpu(rx_stats->noise_diff); - - to_us = !compare_ether_addr(header->addr1, priv->mac_addr); - - /* if data frame is to us and all is good, - * (optionally) print summary for only 1 out of every 100 */ - if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == - cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { - dataframe = 1; - if (!group100) - print_summary = 1; /* print each frame */ - else if (priv->framecnt_to_us < 100) { - priv->framecnt_to_us++; - print_summary = 0; - } else { - priv->framecnt_to_us = 0; - print_summary = 1; - hundred = 1; - } - } else { - /* print summary for all other frames */ - print_summary = 1; - } - - if (print_summary) { - char *title; - int rate; - - if (hundred) - title = "100Frames"; - else if (ieee80211_has_retry(fc)) - title = "Retry"; - else if (ieee80211_is_assoc_resp(fc)) - title = "AscRsp"; - else if (ieee80211_is_reassoc_resp(fc)) - title = "RasRsp"; - else if (ieee80211_is_probe_resp(fc)) { - title = "PrbRsp"; - print_dump = 1; /* dump frame contents */ - } else if (ieee80211_is_beacon(fc)) { - title = "Beacon"; - print_dump = 1; /* dump frame contents */ - } else if (ieee80211_is_atim(fc)) - title = "ATIM"; - else if (ieee80211_is_auth(fc)) - title = "Auth"; - else if (ieee80211_is_deauth(fc)) - title = "DeAuth"; - else if (ieee80211_is_disassoc(fc)) - title = "DisAssoc"; - else - title = "Frame"; - - rate = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); - if (rate == -1) - rate = 0; - else - rate = iwl3945_rates[rate].ieee / 2; - - /* print frame summary. - * MAC addresses show just the last byte (for brevity), - * but you can hack it to show more, if you'd like to. */ - if (dataframe) - IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " - "len=%u, rssi=%d, chnl=%d, rate=%d,\n", - title, le16_to_cpu(fc), header->addr1[5], - length, rssi, channel, rate); - else { - /* src/dst addresses assume managed mode */ - IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, " - "src=0x%02x, rssi=%u, tim=%lu usec, " - "phy=0x%02x, chnl=%d\n", - title, le16_to_cpu(fc), header->addr1[5], - header->addr3[5], rssi, - tsf_low - priv->scan_start_tsf, - phy_flags, channel); - } - } - if (print_dump) - iwl_print_hex_dump(priv, IWL_DL_RX, data, length); -} - -static void iwl3945_dbg_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - struct ieee80211_hdr *header, int group100) -{ - if (iwl_get_debug_level(priv) & IWL_DL_RX) - _iwl3945_dbg_report_frame(priv, pkt, header, group100); -} - -#else -static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - struct ieee80211_hdr *header, int group100) -{ -} -#endif /* This is necessary only for a number of statistics, see the caller. */ static int iwl3945_is_network_packet(struct iwl_priv *priv, @@ -777,8 +630,6 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, rx_status.signal, rx_status.signal, rx_status.rate_idx); - /* Set "1" to report good data frames in groups of 100 */ - iwl3945_dbg_report_frame(priv, pkt, header, 1); iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); if (network_packet) { @@ -850,25 +701,28 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) /* Unmap tx_cmd */ if (counter) pci_unmap_single(dev, - pci_unmap_addr(&txq->meta[index], mapping), - pci_unmap_len(&txq->meta[index], len), + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), PCI_DMA_TODEVICE); /* unmap chunks if any */ - for (i = 1; i < counter; i++) { + for (i = 1; i < counter; i++) pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); - if (txq->txb[txq->q.read_ptr].skb[0]) { - struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0]; - if (txq->txb[txq->q.read_ptr].skb[0]) { - /* Can be called from interrupt context */ - dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb[0] = NULL; - } + + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; } } - return ; } /** @@ -947,8 +801,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); } -static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, - u16 tx_rate, u8 flags) +static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) { unsigned long flags_spin; struct iwl_station_entry *station; @@ -962,10 +815,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; station->sta.rate_n_flags = cpu_to_le16(tx_rate); station->sta.mode = STA_CONTROL_MODIFY_MSK; - + iwl_send_add_sta(priv, &station->sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - iwl_send_add_sta(priv, &station->sta, flags); IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", sta_id, tx_rate); return sta_id; @@ -997,7 +849,7 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) { - iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr); + iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma); iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), @@ -2473,8 +2325,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv, iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, - CMD_ASYNC); + IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP); iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); return 0; @@ -2590,6 +2441,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; + priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index cd4b61ae25b..9166794eda0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -787,6 +787,6 @@ enum { struct iwl4965_scd_bc_tbl { __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; -} __attribute__ ((packed)); +} __packed; #endif /* !__iwl_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d3afddae8d9..d6531ad3906 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -346,9 +346,19 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) { struct iwl_chain_noise_data *data = &(priv->chain_noise_data); - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && + iwl_is_associated(priv)) { struct iwl_calib_diff_gain_cmd cmd; + /* clear data for chain noise calibration algorithm */ + data->chain_noise_a = 0; + data->chain_noise_b = 0; + data->chain_noise_c = 0; + data->chain_signal_a = 0; + data->chain_signal_b = 0; + data->chain_signal_c = 0; + data->beacon_count = 0; + memset(&cmd, 0, sizeof(cmd)); cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; cmd.diff_gain_a = 0; @@ -419,13 +429,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, /* Mark so we run this algo only once! */ data->state = IWL_CHAIN_NOISE_CALIBRATED; } - data->chain_noise_a = 0; - data->chain_noise_b = 0; - data->chain_noise_c = 0; - data->chain_signal_a = 0; - data->chain_signal_b = 0; - data->chain_signal_c = 0; - data->beacon_count = 0; } static void iwl4965_bg_txpower_work(struct work_struct *work) @@ -669,6 +672,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); priv->hw_params.sens = &iwl4965_sensitivity; + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; return 0; } @@ -1441,7 +1445,8 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) return ret; } -static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) +static int iwl4965_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) { int rc; u8 band = 0; @@ -1449,11 +1454,14 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) u8 ctrl_chan_high = 0; struct iwl4965_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; - + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + struct ieee80211_vif *vif = priv->vif; band = priv->band == IEEE80211_BAND_2GHZ; - ch_info = iwl_get_channel_info(priv, priv->band, channel); - is_ht40 = is_ht40_channel(priv->staging_rxon.flags); if (is_ht40 && @@ -1462,26 +1470,56 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) cmd.band = band; cmd.expect_beacon = 0; - cmd.channel = cpu_to_le16(channel); + ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = priv->staging_rxon.flags; cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; - cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); if (ch_info) cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, channel); + priv->active_rxon.channel, ch); return -EFAULT; } - rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40, + rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40, ctrl_chan_high, &cmd.tx_power); if (rc) { IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); return rc; } - priv->switch_rxon.channel = cpu_to_le16(channel); + priv->switch_rxon.channel = cmd.channel; priv->switch_rxon.switch_in_progress = true; return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); @@ -1542,7 +1580,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) u32 R4; if (test_bit(STATUS_TEMPERATURE, &priv->status) && - (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { + (priv->_agn.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); @@ -1566,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv) if (!test_bit(STATUS_TEMPERATURE, &priv->status)) vt = sign_extend(R4, 23); else - vt = sign_extend( - le32_to_cpu(priv->statistics.general.temperature), 23); + vt = sign_extend(le32_to_cpu(priv->_agn.statistics. + general.common.temperature), 23); IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); @@ -1747,6 +1786,7 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, { unsigned long flags; u16 ra_tid; + int ret; if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues @@ -1762,7 +1802,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, ra_tid = BUILD_RAxTID(sta_id, tid); /* Modify device's station table to Tx this TID */ - iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); + ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); + if (ret) + return ret; spin_lock_irqsave(&priv->lock, flags); @@ -1870,7 +1912,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); + info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); info->status.rates[0].count = tx_resp->failure_frame + 1; info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= iwl_tx_status_to_mac80211(status); @@ -2026,6 +2068,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, int sta_id; int freed; u8 *qc = NULL; + unsigned long flags; if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " @@ -2035,7 +2078,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, return; } - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); @@ -2050,10 +2093,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, return; } + spin_lock_irqsave(&priv->sta_lock, flags); if (txq->sched_retry) { const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); struct iwl_ht_agg *agg = NULL; - WARN_ON(!qc); agg = &priv->stations[sta_id].tid[tid].agg; @@ -2110,6 +2153,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwl_check_abort_status(priv, tx_resp->frame_count, status); + + spin_unlock_irqrestore(&priv->sta_lock, flags); } static int iwl4965_calc_rssi(struct iwl_priv *priv, @@ -2235,11 +2280,14 @@ static struct iwl_lib_ops iwl4965_lib = { .set_ct_kill = iwl4965_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, }, + .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, }; @@ -2285,7 +2333,7 @@ struct iwl_cfg iwl4965_agn_cfg = { * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. */ - .scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, + .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, }; /* Module firmware */ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a28af7eb67e..8093ce2804f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -179,8 +179,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->cfg->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; + priv->hw_params.max_stations = IWLAGN_STATION_COUNT; + priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -208,6 +208,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_TX_IQ_PERD) | BIT(IWL_CALIB_BASE_BAND); + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; + return 0; } @@ -224,8 +226,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->cfg->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; + priv->hw_params.max_stations = IWLAGN_STATION_COUNT; + priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -247,10 +249,13 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) /* Set initial calibration set */ priv->hw_params.sens = &iwl5150_sensitivity; priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_DC) | BIT(IWL_CALIB_LO) | BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_BASE_BAND); + if (priv->cfg->need_dc_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); + + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; return 0; } @@ -260,40 +265,76 @@ static void iwl5150_temperature(struct iwl_priv *priv) u32 vt = 0; s32 offset = iwl_temp_calib_to_offset(priv); - vt = le32_to_cpu(priv->statistics.general.temperature); + vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; /* now vt hold the temperature in Kelvin */ priv->temperature = KELVIN_TO_CELSIUS(vt); iwl_tt_handler(priv); } -static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) +static int iwl5000_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) { struct iwl5000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + struct ieee80211_vif *vif = priv->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), - .flags = CMD_SIZE_HUGE, + .flags = CMD_SYNC, .data = &cmd, }; - IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", - priv->active_rxon.channel, channel); cmd.band = priv->band == IEEE80211_BAND_2GHZ; - cmd.channel = cpu_to_le16(channel); + ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", + priv->active_rxon.channel, ch); + cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = priv->staging_rxon.flags; cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; - cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); - ch_info = iwl_get_channel_info(priv, priv->band, channel); + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); if (ch_info) cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, channel); + priv->active_rxon.channel, ch); return -EFAULT; } - priv->switch_rxon.channel = cpu_to_le16(channel); + priv->switch_rxon.channel = cmd.channel; priv->switch_rxon.switch_in_progress = true; return iwl_send_cmd_sync(priv, &hcmd); @@ -352,14 +393,18 @@ static struct iwl_lib_ops iwl5000_lib = { .set_ct_kill = iwl5000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static struct iwl_lib_ops iwl5150_lib = { @@ -414,6 +459,7 @@ static struct iwl_lib_ops iwl5150_lib = { .set_ct_kill = iwl5150_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, @@ -422,6 +468,8 @@ static struct iwl_lib_ops iwl5150_lib = { .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl5000_ops = { @@ -620,6 +668,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .need_dc_calib = true, }; struct iwl_cfg iwl5150_abg_cfg = { @@ -649,6 +698,7 @@ struct iwl_cfg iwl5150_abg_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .need_dc_calib = true, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 9fbf54cd3e1..58270529a0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -71,6 +71,10 @@ #define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode" #define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api) +#define IWL6000G2B_FW_PRE "iwlwifi-6000g2b-" +#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" +#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) + static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { @@ -80,9 +84,10 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) } /* Indicate calibration version to uCode. */ -static void iwl6050_set_calib_version(struct iwl_priv *priv) +static void iwl6000_set_calib_version(struct iwl_priv *priv) { - if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) + if (priv->cfg->need_dc_calib && + (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)) iwl_set_bit(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } @@ -155,8 +160,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->cfg->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; + priv->hw_params.max_stations = IWLAGN_STATION_COUNT; + priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; @@ -182,83 +187,77 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_LO) | BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_BASE_BAND); + if (priv->cfg->need_dc_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); - return 0; -} - -static int iwl6050_hw_set_hw_params(struct iwl_priv *priv) -{ - if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && - priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = - priv->cfg->mod_params->num_of_queues; - - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; - priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; - priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * - sizeof(struct iwlagn_scd_bc_tbl); - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL5000_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; - - priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; - priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; - - priv->hw_params.max_bsm_size = 0; - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | - BIT(IEEE80211_BAND_5GHZ); - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; - - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); - priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; - priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); - - /* Set initial sensitivity parameters */ - /* Set initial calibration set */ - priv->hw_params.sens = &iwl6000_sensitivity; - priv->hw_params.calib_init_cfg = - BIT(IWL_CALIB_XTAL) | - BIT(IWL_CALIB_DC) | - BIT(IWL_CALIB_LO) | - BIT(IWL_CALIB_TX_IQ) | - BIT(IWL_CALIB_BASE_BAND); + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; return 0; } -static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel) +static int iwl6000_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) { struct iwl6000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); + struct ieee80211_vif *vif = priv->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), - .flags = CMD_SIZE_HUGE, + .flags = CMD_SYNC, .data = &cmd, }; - IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", - priv->active_rxon.channel, channel); - cmd.band = priv->band == IEEE80211_BAND_2GHZ; - cmd.channel = cpu_to_le16(channel); + ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", + priv->active_rxon.channel, ch); + cmd.channel = cpu_to_le16(ch); cmd.rxon_flags = priv->staging_rxon.flags; cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; - cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); - ch_info = iwl_get_channel_info(priv, priv->band, channel); + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); if (ch_info) cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, channel); + priv->active_rxon.channel, ch); return -EFAULT; } - priv->switch_rxon.channel = cpu_to_le16(channel); + priv->switch_rxon.channel = cmd.channel; priv->switch_rxon.switch_in_progress = true; return iwl_send_cmd_sync(priv, &hcmd); @@ -316,16 +315,21 @@ static struct iwl_lib_ops iwl6000_lib = { .temp_ops = { .temperature = iwlagn_temperature, .set_ct_kill = iwl6000_set_ct_threshold, + .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_station = iwl_update_bcast_station, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, }; static const struct iwl_ops iwl6000_ops = { @@ -335,79 +339,25 @@ static const struct iwl_ops iwl6000_ops = { .led = &iwlagn_led_ops, }; -static struct iwl_lib_ops iwl6050_lib = { - .set_hw_params = iwl6050_hw_set_hw_params, - .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, - .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, - .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .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, - .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, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_csr = iwl_dump_csr, - .dump_fh = iwl_dump_fh, - .init_alive_start = iwlagn_init_alive_start, - .alive_notify = iwlagn_alive_notify, - .send_tx_power = iwlagn_send_tx_power, - .update_chain_flags = iwl_update_chain_flags, - .set_channel_switch = iwl6000_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .stop = iwl_apm_stop, - .config = iwl6000_nic_config, - .set_pwr_src = iwl_set_pwr_src, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - .verify_signature = iwlcore_eeprom_verify_signature, - .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, - .release_semaphore = iwlcore_eeprom_release_semaphore, - .calib_version = iwlagn_eeprom_calib_version, - .query_addr = iwlagn_eeprom_query_addr, - .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, - }, - .post_associate = iwl_post_associate, - .isr = iwl_isr_ict, - .config_ap = iwl_config_ap, - .temp_ops = { - .temperature = iwlagn_temperature, - .set_ct_kill = iwl6000_set_ct_threshold, - .set_calib_version = iwl6050_set_calib_version, - }, - .manage_ibss_station = iwlagn_manage_ibss_station, - .debugfs_ops = { - .rx_stats_read = iwl_ucode_rx_stats_read, - .tx_stats_read = iwl_ucode_tx_stats_read, - .general_stats_read = iwl_ucode_general_stats_read, - }, - .recover_from_tx_stall = iwl_bg_monitor_recover, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, +static void do_not_send_bt_config(struct iwl_priv *priv) +{ +} + +static struct iwl_hcmd_ops iwl6000g2b_hcmd = { + .rxon_assoc = iwlagn_send_rxon_assoc, + .commit_rxon = iwl_commit_rxon, + .set_rxon_chain = iwl_set_rxon_chain, + .set_tx_ant = iwlagn_send_tx_ant_config, + .send_bt_config = do_not_send_bt_config, }; -static const struct iwl_ops iwl6050_ops = { - .lib = &iwl6050_lib, - .hcmd = &iwlagn_hcmd, +static const struct iwl_ops iwl6000g2b_ops = { + .lib = &iwl6000_lib, + .hcmd = &iwl6000g2b_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, }; - struct iwl_cfg iwl6000g2a_2agn_cfg = { .name = "6000 Series 2x2 AGN Gen2a", .fw_name_pre = IWL6000G2A_FW_PRE, @@ -443,6 +393,299 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl6000g2a_2abg_cfg = { + .name = "6000 Series 2x2 ABG Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .ops = &iwl6000_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl6000g2a_2bg_cfg = { + .name = "6000 Series 2x2 BG Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G, + .ops = &iwl6000_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl6000g2b_2agn_cfg = { + .name = "6000 Series 2x2 AGN Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .ht_greenfield_support = true, + .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, +}; + +struct iwl_cfg iwl6000g2b_2abg_cfg = { + .name = "6000 Series 2x2 ABG Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, +}; + +struct iwl_cfg iwl6000g2b_2bgn_cfg = { + .name = "6000 Series 2x2 BGN Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .ht_greenfield_support = true, + .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, +}; + +struct iwl_cfg iwl6000g2b_2bg_cfg = { + .name = "6000 Series 2x2 BG Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, +}; + +struct iwl_cfg iwl6000g2b_bgn_cfg = { + .name = "6000 Series 1x2 BGN Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .ht_greenfield_support = true, + .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, +}; + +struct iwl_cfg iwl6000g2b_bg_cfg = { + .name = "6000 Series 1x2 BG Gen2b", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G, + .ops = &iwl6000g2b_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 512, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, + .bt_statistics = true, }; /* @@ -561,7 +804,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6050_ops, + .ops = &iwl6000_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, @@ -590,6 +833,45 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl6050g2_bgn_cfg = { + .name = "6050 Series 1x2 BGN Gen2", + .fw_name_pre = IWL6050_FW_PRE, + .ucode_api_max = IWL6050_UCODE_API_MAX, + .ucode_api_min = IWL6050_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .ops = &iwl6000_ops, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .mod_params = &iwlagn_mod_params, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .pa_type = IWL_PA_SYSTEM, + .max_ll_items = OTP_MAX_LL_ITEMS_6x50, + .shadow_ram_support = true, + .ht_greenfield_support = true, + .led_compensation = 51, + .use_rts_for_ht = true, /* use rts/cts protection */ + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1500, + .monitor_recover_period = IWL_MONITORING_PERIOD, + .max_event_log_size = 1024, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .need_dc_calib = true, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -598,7 +880,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6050_ops, + .ops = &iwl6000_ops, .eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, @@ -625,6 +907,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .need_dc_calib = true, }; struct iwl_cfg iwl6000_3agn_cfg = { @@ -667,3 +950,4 @@ struct iwl_cfg iwl6000_3agn_cfg = { MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 7e822777321..c4c5691032a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -96,17 +96,16 @@ int iwl_send_calib_results(struct iwl_priv *priv) hcmd.len = priv->calib_results[i].buf_len; hcmd.data = priv->calib_results[i].buf; ret = iwl_send_cmd_sync(priv, &hcmd); - if (ret) - goto err; + if (ret) { + IWL_ERR(priv, "Error %d iteration %d\n", + ret, i); + break; + } } } - return 0; -err: - IWL_ERR(priv, "Error %d iteration %d\n", ret, i); return ret; } -EXPORT_SYMBOL(iwl_send_calib_results); int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) { @@ -121,7 +120,6 @@ int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len) memcpy(res->buf, buf, len); return 0; } -EXPORT_SYMBOL(iwl_calib_set); void iwl_calib_free_results(struct iwl_priv *priv) { @@ -133,7 +131,6 @@ void iwl_calib_free_results(struct iwl_priv *priv) priv->calib_results[i].buf_len = 0; } } -EXPORT_SYMBOL(iwl_calib_free_results); /***************************************************************************** * RUNTIME calibrations framework @@ -412,46 +409,34 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv, return 0; } -/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ -static int iwl_sensitivity_write(struct iwl_priv *priv) +static void iwl_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv, + struct iwl_sensitivity_data *data, + __le16 *tbl) { - struct iwl_sensitivity_cmd cmd ; - struct iwl_sensitivity_data *data = NULL; - struct iwl_host_cmd cmd_out = { - .id = SENSITIVITY_CMD, - .len = sizeof(struct iwl_sensitivity_cmd), - .flags = CMD_ASYNC, - .data = &cmd, - }; - - data = &(priv->sensitivity_data); - - memset(&cmd, 0, sizeof(cmd)); - - cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] = + tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] = cpu_to_le16((u16)data->auto_corr_ofdm); - cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] = + tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] = cpu_to_le16((u16)data->auto_corr_ofdm_mrc); - cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] = + tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] = cpu_to_le16((u16)data->auto_corr_ofdm_x1); - cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] = + tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] = cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1); - cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] = + tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] = cpu_to_le16((u16)data->auto_corr_cck); - cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] = + tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] = cpu_to_le16((u16)data->auto_corr_cck_mrc); - cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] = + tbl[HD_MIN_ENERGY_CCK_DET_INDEX] = cpu_to_le16((u16)data->nrg_th_cck); - cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] = + tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] = cpu_to_le16((u16)data->nrg_th_ofdm); - cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = + tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = cpu_to_le16(data->barker_corr_th_min); - cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = + tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = cpu_to_le16(data->barker_corr_th_min_mrc); - cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] = + tbl[HD_OFDM_ENERGY_TH_IN_INDEX] = cpu_to_le16(data->nrg_th_cca); IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n", @@ -462,6 +447,25 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n", data->auto_corr_cck, data->auto_corr_cck_mrc, data->nrg_th_cck); +} + +/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ +static int iwl_sensitivity_write(struct iwl_priv *priv) +{ + struct iwl_sensitivity_cmd cmd; + struct iwl_sensitivity_data *data = NULL; + struct iwl_host_cmd cmd_out = { + .id = SENSITIVITY_CMD, + .len = sizeof(struct iwl_sensitivity_cmd), + .flags = CMD_ASYNC, + .data = &cmd, + }; + + data = &(priv->sensitivity_data); + + memset(&cmd, 0, sizeof(cmd)); + + iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]); /* Update uCode's "work" table, and copy it to DSP */ cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; @@ -480,6 +484,70 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) return iwl_send_cmd(priv, &cmd_out); } +/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ +static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) +{ + struct iwl_enhance_sensitivity_cmd cmd; + struct iwl_sensitivity_data *data = NULL; + struct iwl_host_cmd cmd_out = { + .id = SENSITIVITY_CMD, + .len = sizeof(struct iwl_enhance_sensitivity_cmd), + .flags = CMD_ASYNC, + .data = &cmd, + }; + + data = &(priv->sensitivity_data); + + memset(&cmd, 0, sizeof(cmd)); + + iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); + + cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = + HD_INA_NON_SQUARE_DET_OFDM_DATA; + cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = + HD_INA_NON_SQUARE_DET_CCK_DATA; + cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] = + HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA; + cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] = + HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA; + cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = + HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA; + cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] = + HD_OFDM_NON_SQUARE_DET_SLOPE_DATA; + cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] = + HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA; + cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] = + HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA; + cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = + HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA; + cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] = + HD_CCK_NON_SQUARE_DET_SLOPE_DATA; + cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] = + HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA; + + /* Update uCode's "work" table, and copy it to DSP */ + cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; + + /* Don't send command to uCode if nothing has changed */ + if (!memcmp(&cmd.enhance_table[0], &(priv->sensitivity_tbl[0]), + sizeof(u16)*HD_TABLE_SIZE) && + !memcmp(&cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX], + &(priv->enhance_sensitivity_tbl[0]), + sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES)) { + IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n"); + return 0; + } + + /* Copy table for comparison next time */ + memcpy(&(priv->sensitivity_tbl[0]), &(cmd.enhance_table[0]), + sizeof(u16)*HD_TABLE_SIZE); + memcpy(&(priv->enhance_sensitivity_tbl[0]), + &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), + sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); + + return iwl_send_cmd(priv, &cmd_out); +} + void iwl_init_sensitivity(struct iwl_priv *priv) { int ret = 0; @@ -530,13 +598,14 @@ void iwl_init_sensitivity(struct iwl_priv *priv) data->last_bad_plcp_cnt_cck = 0; data->last_fa_cnt_cck = 0; - ret |= iwl_sensitivity_write(priv); + if (priv->enhance_sensitivity_table) + ret |= iwl_enhance_sensitivity_write(priv); + else + ret |= iwl_sensitivity_write(priv); IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); } -EXPORT_SYMBOL(iwl_init_sensitivity); -void iwl_sensitivity_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *resp) +void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) { u32 rx_enable_time; u32 fa_cck; @@ -546,8 +615,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, u32 norm_fa_ofdm; u32 norm_fa_cck; struct iwl_sensitivity_data *data = NULL; - struct statistics_rx_non_phy *rx_info = &(resp->rx.general); - struct statistics_rx *statistics = &(resp->rx); + struct statistics_rx_non_phy *rx_info; + struct statistics_rx_phy *ofdm, *cck; unsigned long flags; struct statistics_general_data statis; @@ -562,6 +631,16 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, } spin_lock_irqsave(&priv->lock, flags); + if (priv->cfg->bt_statistics) { + rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> + rx.general.common); + ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); + cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck); + } else { + rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); + ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); + cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); + } if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -570,23 +649,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, /* Extract Statistics: */ rx_enable_time = le32_to_cpu(rx_info->channel_load); - fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt); - fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt); - bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err); - bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err); + fa_cck = le32_to_cpu(cck->false_alarm_cnt); + fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt); + bad_plcp_cck = le32_to_cpu(cck->plcp_err); + bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err); statis.beacon_silence_rssi_a = - le32_to_cpu(statistics->general.beacon_silence_rssi_a); + le32_to_cpu(rx_info->beacon_silence_rssi_a); statis.beacon_silence_rssi_b = - le32_to_cpu(statistics->general.beacon_silence_rssi_b); + le32_to_cpu(rx_info->beacon_silence_rssi_b); statis.beacon_silence_rssi_c = - le32_to_cpu(statistics->general.beacon_silence_rssi_c); + le32_to_cpu(rx_info->beacon_silence_rssi_c); statis.beacon_energy_a = - le32_to_cpu(statistics->general.beacon_energy_a); + le32_to_cpu(rx_info->beacon_energy_a); statis.beacon_energy_b = - le32_to_cpu(statistics->general.beacon_energy_b); + le32_to_cpu(rx_info->beacon_energy_b); statis.beacon_energy_c = - le32_to_cpu(statistics->general.beacon_energy_c); + le32_to_cpu(rx_info->beacon_energy_c); spin_unlock_irqrestore(&priv->lock, flags); @@ -637,9 +716,11 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); - iwl_sensitivity_write(priv); + if (priv->enhance_sensitivity_table) + iwl_enhance_sensitivity_write(priv); + else + iwl_sensitivity_write(priv); } -EXPORT_SYMBOL(iwl_sensitivity_calibration); static inline u8 find_first_chain(u8 mask) { @@ -656,8 +737,7 @@ static inline u8 find_first_chain(u8 mask) * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. */ -void iwl_chain_noise_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *stat_resp) +void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) { struct iwl_chain_noise_data *data = NULL; @@ -681,7 +761,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, u32 active_chains = 0; u8 num_tx_chains; unsigned long flags; - struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general); + struct statistics_rx_non_phy *rx_info; u8 first_chain; if (priv->disable_chain_noise_cal) @@ -700,6 +780,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, } spin_lock_irqsave(&priv->lock, flags); + if (priv->cfg->bt_statistics) { + rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> + rx.general.common); + } else { + rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> + rx.general); + } if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -708,8 +795,19 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); - stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); - stat_chnum = le32_to_cpu(stat_resp->flag) >> 16; + if (priv->cfg->bt_statistics) { + stat_band24 = !!(((struct iwl_bt_notif_statistics *) + stat_resp)->flag & + STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *) + stat_resp)->flag) >> 16; + } else { + stat_band24 = !!(((struct iwl_notif_statistics *) + stat_resp)->flag & + STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) + stat_resp)->flag) >> 16; + } /* Make sure we accumulate data for just the associated channel * (even if scanning). */ @@ -846,6 +944,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, } } + if (active_chains != priv->hw_params.valid_rx_ant && + active_chains != priv->chain_noise_data.active_chains) + IWL_DEBUG_CALIB(priv, + "Detected that not all antennas are connected! " + "Connected: %#x, valid: %#x.\n", + active_chains, priv->hw_params.valid_rx_ant); + /* Save for use within RXON, TX, SCAN commands, etc. */ priv->chain_noise_data.active_chains = active_chains; IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n", @@ -890,8 +995,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, data->state = IWL_CHAIN_NOISE_DONE; iwl_power_update_mode(priv, false); } -EXPORT_SYMBOL(iwl_chain_noise_calibration); - void iwl_reset_run_time_calib(struct iwl_priv *priv) { @@ -908,5 +1011,3 @@ void iwl_reset_run_time_calib(struct iwl_priv *priv) * periodically after association */ iwl_send_statistics_request(priv, CMD_ASYNC, true); } -EXPORT_SYMBOL(iwl_reset_run_time_calib); - diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index 48c023b4ca3..f052c6d09b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -28,6 +28,30 @@ #include "iwl-agn-debugfs.h" +static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +{ + int p = 0; + u32 flag; + + if (priv->cfg->bt_statistics) + flag = le32_to_cpu(priv->_agn.statistics_bt.flag); + else + flag = le32_to_cpu(priv->_agn.statistics.flag); + + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); + if (flag & UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, + "\tStatistics have been cleared\n"); + p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", + (flag & UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); + p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", + (flag & UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); + + return p; +} + ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -58,24 +82,45 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - ofdm = &priv->statistics.rx.ofdm; - cck = &priv->statistics.rx.cck; - general = &priv->statistics.rx.general; - ht = &priv->statistics.rx.ofdm_ht; - accum_ofdm = &priv->accum_statistics.rx.ofdm; - accum_cck = &priv->accum_statistics.rx.cck; - accum_general = &priv->accum_statistics.rx.general; - accum_ht = &priv->accum_statistics.rx.ofdm_ht; - delta_ofdm = &priv->delta_statistics.rx.ofdm; - delta_cck = &priv->delta_statistics.rx.cck; - delta_general = &priv->delta_statistics.rx.general; - delta_ht = &priv->delta_statistics.rx.ofdm_ht; - max_ofdm = &priv->max_delta.rx.ofdm; - max_cck = &priv->max_delta.rx.cck; - max_general = &priv->max_delta.rx.general; - max_ht = &priv->max_delta.rx.ofdm_ht; - - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + if (priv->cfg->bt_statistics) { + ofdm = &priv->_agn.statistics_bt.rx.ofdm; + cck = &priv->_agn.statistics_bt.rx.cck; + general = &priv->_agn.statistics_bt.rx.general.common; + ht = &priv->_agn.statistics_bt.rx.ofdm_ht; + accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; + accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; + accum_general = + &priv->_agn.accum_statistics_bt.rx.general.common; + accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; + delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; + delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; + delta_general = + &priv->_agn.delta_statistics_bt.rx.general.common; + delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; + max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; + max_cck = &priv->_agn.max_delta_bt.rx.cck; + max_general = &priv->_agn.max_delta_bt.rx.general.common; + max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht; + } else { + ofdm = &priv->_agn.statistics.rx.ofdm; + cck = &priv->_agn.statistics.rx.cck; + general = &priv->_agn.statistics.rx.general; + ht = &priv->_agn.statistics.rx.ofdm_ht; + accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; + accum_cck = &priv->_agn.accum_statistics.rx.cck; + accum_general = &priv->_agn.accum_statistics.rx.general; + accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; + delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; + delta_cck = &priv->_agn.delta_statistics.rx.cck; + delta_general = &priv->_agn.delta_statistics.rx.general; + delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; + max_ofdm = &priv->_agn.max_delta.rx.ofdm; + max_cck = &priv->_agn.max_delta.rx.cck; + max_general = &priv->_agn.max_delta.rx.general; + max_ht = &priv->_agn.max_delta.rx.ofdm_ht; + } + + pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_Rx - OFDM:"); @@ -539,11 +584,19 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - tx = &priv->statistics.tx; - accum_tx = &priv->accum_statistics.tx; - delta_tx = &priv->delta_statistics.tx; - max_tx = &priv->max_delta.tx; - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + if (priv->cfg->bt_statistics) { + tx = &priv->_agn.statistics_bt.tx; + accum_tx = &priv->_agn.accum_statistics_bt.tx; + delta_tx = &priv->_agn.delta_statistics_bt.tx; + max_tx = &priv->_agn.max_delta_bt.tx; + } else { + tx = &priv->_agn.statistics.tx; + accum_tx = &priv->_agn.accum_statistics.tx; + delta_tx = &priv->_agn.delta_statistics.tx; + max_tx = &priv->_agn.max_delta.tx; + } + + pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_Tx:"); @@ -738,8 +791,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, char *buf; int bufsz = sizeof(struct statistics_general) * 10 + 300; ssize_t ret; - struct statistics_general *general, *accum_general; - struct statistics_general *delta_general, *max_general; + struct statistics_general_common *general, *accum_general; + struct statistics_general_common *delta_general, *max_general; struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; struct statistics_div *div, *accum_div, *delta_div, *max_div; @@ -756,19 +809,35 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - general = &priv->statistics.general; - dbg = &priv->statistics.general.dbg; - div = &priv->statistics.general.div; - accum_general = &priv->accum_statistics.general; - delta_general = &priv->delta_statistics.general; - max_general = &priv->max_delta.general; - accum_dbg = &priv->accum_statistics.general.dbg; - delta_dbg = &priv->delta_statistics.general.dbg; - max_dbg = &priv->max_delta.general.dbg; - accum_div = &priv->accum_statistics.general.div; - delta_div = &priv->delta_statistics.general.div; - max_div = &priv->max_delta.general.div; - pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); + if (priv->cfg->bt_statistics) { + general = &priv->_agn.statistics_bt.general.common; + dbg = &priv->_agn.statistics_bt.general.common.dbg; + div = &priv->_agn.statistics_bt.general.common.div; + accum_general = &priv->_agn.accum_statistics_bt.general.common; + accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; + accum_div = &priv->_agn.accum_statistics_bt.general.common.div; + delta_general = &priv->_agn.delta_statistics_bt.general.common; + max_general = &priv->_agn.max_delta_bt.general.common; + delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; + max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; + delta_div = &priv->_agn.delta_statistics_bt.general.common.div; + max_div = &priv->_agn.max_delta_bt.general.common.div; + } else { + general = &priv->_agn.statistics.general.common; + dbg = &priv->_agn.statistics.general.common.dbg; + div = &priv->_agn.statistics.general.common.div; + accum_general = &priv->_agn.accum_statistics.general.common; + accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; + accum_div = &priv->_agn.accum_statistics.general.common.div; + delta_general = &priv->_agn.delta_statistics.general.common; + max_general = &priv->_agn.max_delta.general.common; + delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; + max_dbg = &priv->_agn.max_delta.general.common.dbg; + delta_div = &priv->_agn.delta_statistics.general.common.div; + max_div = &priv->_agn.max_delta.general.common.div; + } + + pos += iwl_statistics_flag(priv, buf, bufsz); pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" "acumulative delta max\n", "Statistics_General:"); @@ -792,6 +861,13 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, delta_dbg->burst_count, max_dbg->burst_count); pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u %10u %10u %10u\n", + "wait_for_silence_timeout_count:", + le32_to_cpu(dbg->wait_for_silence_timeout_cnt), + accum_dbg->wait_for_silence_timeout_cnt, + delta_dbg->wait_for_silence_timeout_cnt, + max_dbg->wait_for_silence_timeout_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "sleep_time:", le32_to_cpu(general->sleep_time), accum_general->sleep_time, @@ -848,3 +924,90 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, kfree(buf); return ret; } + +ssize_t iwl_ucode_bt_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; + ssize_t ret; + struct statistics_bt_activity *bt, *accum_bt; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + /* make request to uCode to retrieve statistics information */ + mutex_lock(&priv->mutex); + ret = iwl_send_statistics_request(priv, CMD_SYNC, false); + mutex_unlock(&priv->mutex); + + if (ret) { + IWL_ERR(priv, + "Error sending statistics request: %zd\n", ret); + return -EAGAIN; + } + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * the statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + bt = &priv->_agn.statistics_bt.general.activity; + accum_bt = &priv->_agn.accum_statistics_bt.general.activity; + + pos += iwl_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "\t\t\tcurrent\t\t\taccumulative\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", + le32_to_cpu(bt->hi_priority_tx_req_cnt), + accum_bt->hi_priority_tx_req_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", + le32_to_cpu(bt->hi_priority_tx_denied_cnt), + accum_bt->hi_priority_tx_denied_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", + le32_to_cpu(bt->lo_priority_tx_req_cnt), + accum_bt->lo_priority_tx_req_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", + le32_to_cpu(bt->lo_priority_tx_denied_cnt), + accum_bt->lo_priority_tx_denied_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", + le32_to_cpu(bt->hi_priority_rx_req_cnt), + accum_bt->hi_priority_rx_req_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", + le32_to_cpu(bt->hi_priority_rx_denied_cnt), + accum_bt->hi_priority_rx_denied_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", + le32_to_cpu(bt->lo_priority_rx_req_cnt), + accum_bt->lo_priority_rx_req_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", + le32_to_cpu(bt->lo_priority_rx_denied_cnt), + accum_bt->lo_priority_rx_denied_cnt); + + pos += scnprintf(buf + pos, bufsz - pos, + "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", + le32_to_cpu(priv->_agn.statistics_bt.rx. + general.num_bt_kills), + priv->_agn.accum_statistics_bt.rx. + general.num_bt_kills); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h index 59b1f25f0d8..bbdce5913ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h @@ -37,6 +37,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); +ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); #else static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -53,4 +55,9 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user { return 0; } +static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 44ef5d93bef..a7216dda978 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -37,7 +37,7 @@ #include "iwl-io.h" #include "iwl-agn.h" -static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) +int iwlagn_send_rxon_assoc(struct iwl_priv *priv) { int ret = 0; struct iwl5000_rxon_assoc_cmd rxon_assoc; @@ -84,7 +84,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) return ret; } -static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) +int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) { struct iwl_tx_ant_config_cmd tx_ant_cmd = { .valid = cpu_to_le32(valid_tx_ant), @@ -164,7 +164,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; + cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; cmd.hdr.data_valid = 1; @@ -176,14 +176,6 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, data->radio_write = 1; data->state = IWL_CHAIN_NOISE_CALIBRATED; } - - data->chain_noise_a = 0; - data->chain_noise_b = 0; - data->chain_noise_c = 0; - data->chain_signal_a = 0; - data->chain_signal_b = 0; - data->chain_signal_c = 0; - data->beacon_count = 0; } static void iwlagn_chain_noise_reset(struct iwl_priv *priv) @@ -191,11 +183,21 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) struct iwl_chain_noise_data *data = &priv->chain_noise_data; int ret; - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && + iwl_is_associated(priv)) { struct iwl_calib_chain_noise_reset_cmd cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD; + /* clear data for chain noise calibration algorithm */ + data->chain_noise_a = 0; + data->chain_noise_b = 0; + data->chain_noise_c = 0; + data->chain_signal_a = 0; + data->chain_signal_b = 0; + data->chain_signal_c = 0; + data->beacon_count = 0; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd; cmd.hdr.first_group = 0; cmd.hdr.groups_num = 1; cmd.hdr.data_valid = 1; @@ -212,11 +214,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) static void iwlagn_rts_tx_cmd_flag(struct ieee80211_tx_info *info, __le32 *tx_flags) { - if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || - (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) - *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; - else - *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; + *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; } /* Calc max signal level (dBm) among 3 possible receivers */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index f9a3fbb6338..a52b82c8e7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -112,7 +112,7 @@ */ struct iwlagn_scd_bc_tbl { __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; -} __attribute__ ((packed)); +} __packed; #endif /* __iwl_agn_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0f292a210ed..a1b6d202d57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -77,7 +77,7 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); + info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); info->status.rates[0].count = tx_resp->failure_frame + 1; info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= iwl_tx_status_to_mac80211(status); @@ -93,6 +93,12 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, } else { /* Two or more frames were attempted; expect block-ack */ u64 bitmap = 0; + + /* + * Start is the lowest frame sent. It may not be the first + * frame in the batch; we figure this out dynamically during + * the following loop. + */ int start = agg->start_idx; /* Construct bit-map of pending frames within Tx window */ @@ -131,25 +137,58 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", i, idx, SEQ_TO_SN(sc)); + /* + * sh -> how many frames ahead of the starting frame is + * the current one? + * + * Note that all frames sent in the batch must be in a + * 64-frame window, so this number should be in [0,63]. + * If outside of this window, then we've found a new + * "first" frame in the batch and need to change start. + */ sh = idx - start; - if (sh > 64) { - sh = (start - idx) + 0xff; + + /* + * If >= 64, out of window. start must be at the front + * of the circular buffer, idx must be near the end of + * the buffer, and idx is the new "first" frame. Shift + * the indices around. + */ + if (sh >= 64) { + /* Shift bitmap by start - idx, wrapped */ + sh = 0x100 - idx + start; bitmap = bitmap << sh; + /* Now idx is the new start so sh = 0 */ sh = 0; start = idx; - } else if (sh < -64) - sh = 0xff - (start - idx); - else if (sh < 0) { + /* + * If <= -64 then wraps the 256-pkt circular buffer + * (e.g., start = 255 and idx = 0, sh should be 1) + */ + } else if (sh <= -64) { + sh = 0x100 - start + idx; + /* + * If < 0 but > -64, out of window. idx is before start + * but not wrapped. Shift the indices around. + */ + } else if (sh < 0) { + /* Shift by how far start is ahead of idx */ sh = start - idx; - start = idx; bitmap = bitmap << sh; + /* Now idx is the new start so sh = 0 */ + start = idx; sh = 0; } + /* Sequence number start + sh was sent in this batch */ bitmap |= 1ULL << sh; IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", start, (unsigned long long)bitmap); } + /* + * Store the bitmap and possibly the new start, if we wrapped + * the buffer above + */ agg->bitmap = bitmap; agg->start_idx = start; IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", @@ -166,7 +205,9 @@ void iwl_check_abort_status(struct iwl_priv *priv, u8 frame_count, u32 status) { if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { - IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n"); + IWL_ERR(priv, "Tx flush command to flush out all frames\n"); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->tx_flush); } } @@ -184,6 +225,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, int tid; int sta_id; int freed; + unsigned long flags; if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " @@ -193,15 +235,16 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, return; } - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; + spin_lock_irqsave(&priv->sta_lock, flags); if (txq->sched_retry) { const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); - struct iwl_ht_agg *agg = NULL; + struct iwl_ht_agg *agg; agg = &priv->stations[sta_id].tid[tid].agg; @@ -256,6 +299,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); iwl_check_abort_status(priv, tx_resp->frame_count, status); + spin_unlock_irqrestore(&priv->sta_lock, flags); } void iwlagn_rx_handler_setup(struct iwl_priv *priv) @@ -319,7 +363,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv) { /* store temperature from statistics (in Celsius) */ - priv->temperature = le32_to_cpu(priv->statistics.general.temperature); + priv->temperature = + le32_to_cpu(priv->_agn.statistics.general.common.temperature); iwl_tt_handler(priv); } @@ -444,7 +489,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) /* Tell device where to find RBD circular buffer in DRAM */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, - (u32)(rxq->dma_addr >> 8)); + (u32)(rxq->bd_dma >> 8)); /* Tell device where in DRAM to update its Rx status */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, @@ -709,7 +754,7 @@ void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) } dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); + rxq->bd_dma); dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; @@ -755,132 +800,6 @@ static inline int iwlagn_calc_rssi(struct iwl_priv *priv, return priv->cfg->ops->utils->calc_rssi(priv, rx_resp); } -#ifdef CONFIG_IWLWIFI_DEBUG -/** - * iwlagn_dbg_report_frame - dump frame to syslog during debug sessions - * - * You may hack this function to show different aspects of received frames, - * including selective frame dumps. - * group100 parameter selects whether to show 1 out of 100 good data frames. - * All beacon and probe response frames are printed. - */ -static void iwlagn_dbg_report_frame(struct iwl_priv *priv, - struct iwl_rx_phy_res *phy_res, u16 length, - struct ieee80211_hdr *header, int group100) -{ - u32 to_us; - u32 print_summary = 0; - u32 print_dump = 0; /* set to 1 to dump all frames' contents */ - u32 hundred = 0; - u32 dataframe = 0; - __le16 fc; - u16 seq_ctl; - u16 channel; - u16 phy_flags; - u32 rate_n_flags; - u32 tsf_low; - int rssi; - - if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX))) - return; - - /* MAC header */ - fc = header->frame_control; - seq_ctl = le16_to_cpu(header->seq_ctrl); - - /* metadata */ - channel = le16_to_cpu(phy_res->channel); - phy_flags = le16_to_cpu(phy_res->phy_flags); - rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); - - /* signal statistics */ - rssi = iwlagn_calc_rssi(priv, phy_res); - tsf_low = le64_to_cpu(phy_res->timestamp) & 0x0ffffffff; - - to_us = !compare_ether_addr(header->addr1, priv->mac_addr); - - /* if data frame is to us and all is good, - * (optionally) print summary for only 1 out of every 100 */ - if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == - cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { - dataframe = 1; - if (!group100) - print_summary = 1; /* print each frame */ - else if (priv->framecnt_to_us < 100) { - priv->framecnt_to_us++; - print_summary = 0; - } else { - priv->framecnt_to_us = 0; - print_summary = 1; - hundred = 1; - } - } else { - /* print summary for all other frames */ - print_summary = 1; - } - - if (print_summary) { - char *title; - int rate_idx; - u32 bitrate; - - if (hundred) - title = "100Frames"; - else if (ieee80211_has_retry(fc)) - title = "Retry"; - else if (ieee80211_is_assoc_resp(fc)) - title = "AscRsp"; - else if (ieee80211_is_reassoc_resp(fc)) - title = "RasRsp"; - else if (ieee80211_is_probe_resp(fc)) { - title = "PrbRsp"; - print_dump = 1; /* dump frame contents */ - } else if (ieee80211_is_beacon(fc)) { - title = "Beacon"; - print_dump = 1; /* dump frame contents */ - } else if (ieee80211_is_atim(fc)) - title = "ATIM"; - else if (ieee80211_is_auth(fc)) - title = "Auth"; - else if (ieee80211_is_deauth(fc)) - title = "DeAuth"; - else if (ieee80211_is_disassoc(fc)) - title = "DisAssoc"; - else - title = "Frame"; - - rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); - if (unlikely((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT))) { - bitrate = 0; - WARN_ON_ONCE(1); - } else { - bitrate = iwl_rates[rate_idx].ieee / 2; - } - - /* print frame summary. - * MAC addresses show just the last byte (for brevity), - * but you can hack it to show more, if you'd like to. */ - if (dataframe) - IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, " - "len=%u, rssi=%d, chnl=%d, rate=%u,\n", - title, le16_to_cpu(fc), header->addr1[5], - length, rssi, channel, bitrate); - else { - /* src/dst addresses assume managed mode */ - IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, " - "len=%u, rssi=%d, tim=%lu usec, " - "phy=0x%02x, chnl=%d\n", - title, le16_to_cpu(fc), header->addr1[5], - header->addr3[5], length, rssi, - tsf_low - priv->scan_start_tsf, - phy_flags, channel); - } - } - if (print_dump) - iwl_print_hex_dump(priv, IWL_DL_RX, header, length); -} -#endif - static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) { u32 decrypt_out = 0; @@ -988,7 +907,7 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_phy_res *phy_res; __le32 rx_pkt_status; - struct iwl4965_rx_mpdu_res_start *amsdu; + struct iwl_rx_mpdu_res_start *amsdu; u32 len; u32 ampdu_status; u32 rate_n_flags; @@ -1017,7 +936,7 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, return; } phy_res = &priv->_agn.last_phy_res; - amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; + amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); len = le16_to_cpu(amsdu->byte_count); rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); @@ -1060,11 +979,6 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, /* Find max signal strength (dBm) among 3 antenna/receiver chains */ rx_status.signal = iwlagn_calc_rssi(priv, phy_res); -#ifdef CONFIG_IWLWIFI_DEBUG - /* Set "1" to report good data frames in groups of 100 */ - if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX)) - iwlagn_dbg_report_frame(priv, phy_res, len, header, 1); -#endif iwl_dbg_log_rx_data_frame(priv, len, header); IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", rx_status.signal, (unsigned long long)rx_status.mactime); @@ -1252,6 +1166,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) bool is_active = false; int chan_mod; u8 active_chains; + u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; conf = ieee80211_get_hw_conf(priv->hw); @@ -1319,7 +1234,10 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); spin_lock_irqsave(&priv->lock, flags); - interval = vif ? vif->bss_conf.beacon_int : 0; + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; @@ -1403,11 +1321,14 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) band = priv->scan_band; - if (priv->cfg->scan_antennas[band]) - rx_ant = priv->cfg->scan_antennas[band]; + if (priv->cfg->scan_rx_antennas[band]) + rx_ant = priv->cfg->scan_rx_antennas[band]; + + if (priv->cfg->scan_tx_antennas[band]) + scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; - priv->scan_tx_ant[band] = - iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]); + priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], + scan_tx_antennas); rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); @@ -1433,13 +1354,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (!priv->is_internal_short_scan) { cmd_len = iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, + vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, IWL_MAX_SCAN_SIZE - sizeof(*scan)); } else { + /* use bcast addr, will not be transmitted but must be valid */ cmd_len = iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - NULL, 0, + iwl_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan)); } @@ -1502,3 +1425,96 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); } + +void iwl_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed) +{ + WARN_ON(!spin_is_locked(&priv->sta_lock)); + + if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) + priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + else { + IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", + priv->stations[sta_id].tid[tid].tfds_in_queue, + freed); + priv->stations[sta_id].tid[tid].tfds_in_queue = 0; + } +} + +#define IWL_FLUSH_WAIT_MS 2000 + +int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv) +{ + struct iwl_tx_queue *txq; + struct iwl_queue *q; + int cnt; + unsigned long now = jiffies; + int ret = 0; + + /* waiting for all the tx frames complete might take a while */ + for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { + if (cnt == IWL_CMD_QUEUE_NUM) + continue; + txq = &priv->txq[cnt]; + q = &txq->q; + while (q->read_ptr != q->write_ptr && !time_after(jiffies, + now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) + msleep(1); + + if (q->read_ptr != q->write_ptr) { + IWL_ERR(priv, "fail to flush all tx fifo queues\n"); + ret = -ETIMEDOUT; + break; + } + } + return ret; +} + +#define IWL_TX_QUEUE_MSK 0xfffff + +/** + * iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode + * + * pre-requirements: + * 1. acquire mutex before calling + * 2. make sure rf is on and not in exit state + */ +int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) +{ + struct iwl_txfifo_flush_cmd flush_cmd; + struct iwl_host_cmd cmd = { + .id = REPLY_TXFIFO_FLUSH, + .len = sizeof(struct iwl_txfifo_flush_cmd), + .flags = CMD_SYNC, + .data = &flush_cmd, + }; + + might_sleep(); + + memset(&flush_cmd, 0, sizeof(flush_cmd)); + flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK | + IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK; + if (priv->cfg->sku & IWL_SKU_N) + flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; + + IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", + flush_cmd.fifo_control); + flush_cmd.flush_control = cpu_to_le16(flush_control); + + return iwl_send_cmd(priv, &cmd); +} + +void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) +{ + mutex_lock(&priv->mutex); + ieee80211_stop_queues(priv->hw); + if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { + IWL_ERR(priv, "flush request fail\n"); + goto done; + } + IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n"); + iwlagn_wait_tx_queue_empty(priv); +done: + ieee80211_wake_queues(priv->hw); + mutex_unlock(&priv->mutex); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index cf4a95bae4f..35c86d22b14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -313,8 +313,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, */ IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", tid); - ieee80211_stop_tx_ba_session(sta, tid, - WLAN_BACK_INITIATOR); + ieee80211_stop_tx_ba_session(sta, tid); } } else IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid); @@ -325,18 +324,11 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, struct iwl_lq_sta *lq_data, struct ieee80211_sta *sta) { - if ((tid < TID_MAX_LOAD_COUNT) && - !rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta)) { - if (priv->cfg->use_rts_for_ht) { - /* - * switch to RTS/CTS if it is the prefer protection - * method for HT traffic - */ - IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n"); - priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; - iwlcore_commit_rxon(priv); - } - } + if (tid < TID_MAX_LOAD_COUNT) + rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); + else + IWL_ERR(priv, "tid exceeds max load count: %d/%d\n", + tid, TID_MAX_LOAD_COUNT); } static inline int get_num_of_ant_from_rate(u32 rate_n_flags) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c new file mode 100644 index 00000000000..9490eced119 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -0,0 +1,351 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * 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.GPL. + * + * Contact Information: + * Intel Linux Wireless <ilw@linux.intel.com> + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/sched.h> + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-calib.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-agn-hw.h" +#include "iwl-agn.h" + +void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) + +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_missed_beacon_notif *missed_beacon; + + missed_beacon = &pkt->u.missed_beacon; + if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > + priv->missed_beacon_threshold) { + IWL_DEBUG_CALIB(priv, + "missed bcn cnsq %d totl %d rcd %d expctd %d\n", + le32_to_cpu(missed_beacon->consecutive_missed_beacons), + le32_to_cpu(missed_beacon->total_missed_becons), + le32_to_cpu(missed_beacon->num_recvd_beacons), + le32_to_cpu(missed_beacon->num_expected_beacons)); + if (!test_bit(STATUS_SCANNING, &priv->status)) + iwl_init_sensitivity(priv); + } +} + +/* Calculate noise level, based on measurements during network silence just + * before arriving beacon. This measurement can be done only if we know + * exactly when to expect beacons, therefore only when we're associated. */ +static void iwl_rx_calc_noise(struct iwl_priv *priv) +{ + struct statistics_rx_non_phy *rx_info; + int num_active_rx = 0; + int total_silence = 0; + int bcn_silence_a, bcn_silence_b, bcn_silence_c; + int last_rx_noise; + + if (priv->cfg->bt_statistics) + rx_info = &(priv->_agn.statistics_bt.rx.general.common); + else + rx_info = &(priv->_agn.statistics.rx.general); + bcn_silence_a = + le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; + bcn_silence_b = + le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; + bcn_silence_c = + le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; + + if (bcn_silence_a) { + total_silence += bcn_silence_a; + num_active_rx++; + } + if (bcn_silence_b) { + total_silence += bcn_silence_b; + num_active_rx++; + } + if (bcn_silence_c) { + total_silence += bcn_silence_c; + num_active_rx++; + } + + /* Average among active antennas */ + if (num_active_rx) + last_rx_noise = (total_silence / num_active_rx) - 107; + else + last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; + + IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", + bcn_silence_a, bcn_silence_b, bcn_silence_c, + last_rx_noise); +} + +#ifdef CONFIG_IWLWIFI_DEBUGFS +/* + * based on the assumption of all statistics counter are in DWORD + * FIXME: This function is for debugging, do not deal with + * the case of counters roll-over. + */ +static void iwl_accumulative_statistics(struct iwl_priv *priv, + __le32 *stats) +{ + int i, size; + __le32 *prev_stats; + u32 *accum_stats; + u32 *delta, *max_delta; + struct statistics_general_common *general, *accum_general; + struct statistics_tx *tx, *accum_tx; + + if (priv->cfg->bt_statistics) { + prev_stats = (__le32 *)&priv->_agn.statistics_bt; + accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; + size = sizeof(struct iwl_bt_notif_statistics); + general = &priv->_agn.statistics_bt.general.common; + accum_general = &priv->_agn.accum_statistics_bt.general.common; + tx = &priv->_agn.statistics_bt.tx; + accum_tx = &priv->_agn.accum_statistics_bt.tx; + delta = (u32 *)&priv->_agn.delta_statistics_bt; + max_delta = (u32 *)&priv->_agn.max_delta_bt; + } else { + prev_stats = (__le32 *)&priv->_agn.statistics; + accum_stats = (u32 *)&priv->_agn.accum_statistics; + size = sizeof(struct iwl_notif_statistics); + general = &priv->_agn.statistics.general.common; + accum_general = &priv->_agn.accum_statistics.general.common; + tx = &priv->_agn.statistics.tx; + accum_tx = &priv->_agn.accum_statistics.tx; + delta = (u32 *)&priv->_agn.delta_statistics; + max_delta = (u32 *)&priv->_agn.max_delta; + } + for (i = sizeof(__le32); i < size; + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - + le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } + + /* reset accumulative statistics for "no-counter" type statistics */ + accum_general->temperature = general->temperature; + accum_general->temperature_m = general->temperature_m; + accum_general->ttl_timestamp = general->ttl_timestamp; + accum_tx->tx_power.ant_a = tx->tx_power.ant_a; + accum_tx->tx_power.ant_b = tx->tx_power.ant_b; + accum_tx->tx_power.ant_c = tx->tx_power.ant_c; +} +#endif + +#define REG_RECALIB_PERIOD (60) + +/** + * iwl_good_plcp_health - checks for plcp error. + * + * When the plcp error is exceeding the thresholds, reset the radio + * to improve the throughput. + */ +bool iwl_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + bool rc = true; + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; + + if (priv->cfg->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } + + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + struct statistics_rx_phy *ofdm; + struct statistics_rx_ht_phy *ofdm_ht; + + if (priv->cfg->bt_statistics) { + ofdm = &pkt->u.stats_bt.rx.ofdm; + ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_agn.statistics_bt. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_agn.statistics_bt. + rx.ofdm_ht.plcp_err)); + } else { + ofdm = &pkt->u.stats.rx.ofdm; + ofdm_ht = &pkt->u.stats.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_agn.statistics. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_agn.statistics. + rx.ofdm_ht.plcp_err)); + } + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, + * the following data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * Received ofdm_ht.plcp_err, + * Current ofdm_ht.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); + + rc = false; + } + } + return rc; +} + +void iwl_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + int change; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + if (priv->cfg->bt_statistics) { + IWL_DEBUG_RX(priv, + "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl_bt_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & + FH_RSCSR_FRAME_SIZE_MSK); + + change = ((priv->_agn.statistics_bt.general.common.temperature != + pkt->u.stats_bt.general.common.temperature) || + ((priv->_agn.statistics_bt.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats_bt.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK))); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); +#endif + + } else { + IWL_DEBUG_RX(priv, + "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & + FH_RSCSR_FRAME_SIZE_MSK); + + change = ((priv->_agn.statistics.general.common.temperature != + pkt->u.stats.general.common.temperature) || + ((priv->_agn.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK))); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); +#endif + + } + + iwl_recover_from_statistics(priv, pkt); + + if (priv->cfg->bt_statistics) + memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, + sizeof(priv->_agn.statistics_bt)); + else + memcpy(&priv->_agn.statistics, &pkt->u.stats, + sizeof(priv->_agn.statistics)); + + set_bit(STATUS_STATISTICS, &priv->status); + + /* Reschedule the statistics timer to occur in + * REG_RECALIB_PERIOD seconds to ensure we get a + * thermal update even if the uCode doesn't give + * us one */ + mod_timer(&priv->statistics_periodic, jiffies + + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); + + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { + iwl_rx_calc_noise(priv); + queue_work(priv->workqueue, &priv->run_time_calib_work); + } + if (priv->cfg->ops->lib->temp_ops.temperature && change) + priv->cfg->ops->lib->temp_ops.temperature(priv); +} + +void iwl_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { +#ifdef CONFIG_IWLWIFI_DEBUGFS + memset(&priv->_agn.accum_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.delta_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.max_delta, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.accum_statistics_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->_agn.delta_statistics_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->_agn.max_delta_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); +#endif + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); + } + iwl_rx_statistics(priv, rxb); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 7d614c4d3c6..55a1b31fd09 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -233,6 +233,7 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, { unsigned long flags; u16 ra_tid; + int ret; if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues @@ -248,7 +249,9 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, ra_tid = BUILD_RAxTID(sta_id, tid); /* Modify device's station table to Tx this TID */ - iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); + ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); + if (ret) + return ret; spin_lock_irqsave(&priv->lock, flags); @@ -469,7 +472,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, } /* Set up antennas */ - priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + priv->hw_params.valid_tx_ant); rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); /* Set the rate in the TX cmd */ @@ -567,10 +571,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - if (!info->control.sta) - sta_id = priv->hw_params.bcast_sta_id; - else - sta_id = iwl_sta_id(info->control.sta); + sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -598,11 +599,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) } txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); + + /* irqs already disabled/saved above when locking priv->lock */ + spin_lock(&priv->sta_lock); + if (ieee80211_is_data_qos(fc)) { qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - if (unlikely(tid >= MAX_TID_COUNT)) + if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) { + spin_unlock(&priv->sta_lock); goto drop_unlock; + } seq_number = priv->stations[sta_id].tid[tid].seq_number; seq_number &= IEEE80211_SCTL_SEQ; hdr->seq_ctrl = hdr->seq_ctrl & @@ -620,15 +627,22 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) swq_id = txq->swq_id; q = &txq->q; - if (unlikely(iwl_queue_space(q) < q->high_mark)) + if (unlikely(iwl_queue_space(q) < q->high_mark)) { + spin_unlock(&priv->sta_lock); goto drop_unlock; + } - if (ieee80211_is_data_qos(fc)) + if (ieee80211_is_data_qos(fc)) { priv->stations[sta_id].tid[tid].tfds_in_queue++; + if (!ieee80211_has_morefrags(fc)) + priv->stations[sta_id].tid[tid].seq_number = seq_number; + } + + spin_unlock(&priv->sta_lock); /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->write_ptr].skb[0] = skb; + txq->txb[q->write_ptr].skb = skb; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; @@ -694,8 +708,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, len, PCI_DMA_BIDIRECTIONAL); - pci_unmap_addr_set(out_meta, mapping, txcmd_phys); - pci_unmap_len_set(out_meta, len, len); + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, len); /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, @@ -703,8 +717,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; - if (qc) - priv->stations[sta_id].tid[tid].seq_number = seq_number; } else { wait_write_ptr = 1; txq->need_update = 0; @@ -938,9 +950,12 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, + if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), - 1000); + 1000)) + IWL_ERR(priv, "Failing on timeout while stopping" + " DMA channel %d [0x%08x]", ch, + iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&priv->lock, flags); } @@ -1009,6 +1024,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, if (ret) return ret; + spin_lock_irqsave(&priv->sta_lock, flags); + tid_data = &priv->stations[sta_id].tid[tid]; if (tid_data->tfds_in_queue == 0) { IWL_DEBUG_HT(priv, "HW queue is empty\n"); tid_data->agg.state = IWL_AGG_ON; @@ -1018,6 +1035,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data->tfds_in_queue); tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; } + spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; } @@ -1040,11 +1058,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, return -ENXIO; } + spin_lock_irqsave(&priv->sta_lock, flags); + if (priv->stations[sta_id].tid[tid].agg.state == IWL_EMPTYING_HW_QUEUE_ADDBA) { IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; + spin_unlock_irqrestore(&priv->sta_lock, flags); return 0; } @@ -1062,13 +1083,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); priv->stations[sta_id].tid[tid].agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; + spin_unlock_irqrestore(&priv->sta_lock, flags); return 0; } IWL_DEBUG_HT(priv, "HW queue is empty\n"); priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; - spin_lock_irqsave(&priv->lock, flags); + /* do not restore/save irqs */ + spin_unlock(&priv->sta_lock); + spin_lock(&priv->lock); + /* * the only reason this call can fail is queue number out of range, * which can happen if uCode is reloaded and all the station @@ -1092,6 +1117,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, u8 *addr = priv->stations[sta_id].sta.sta.addr; struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; + WARN_ON(!spin_is_locked(&priv->sta_lock)); + switch (priv->stations[sta_id].tid[tid].agg.state) { case IWL_EMPTYING_HW_QUEUE_DELBA: /* We are reclaiming the last packet of the */ @@ -1116,6 +1143,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, } break; } + return 0; } @@ -1159,12 +1187,12 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - iwlagn_tx_status(priv, tx_info->skb[0]); + iwlagn_tx_status(priv, tx_info->skb); - hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data; + hdr = (struct ieee80211_hdr *)tx_info->skb->data; if (hdr && ieee80211_is_data_qos(hdr->frame_control)) nfreed++; - tx_info->skb[0] = NULL; + tx_info->skb = NULL; if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); @@ -1188,7 +1216,7 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, int i, sh, ack; u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); - u64 bitmap; + u64 bitmap, sent_bitmap; int successes = 0; struct ieee80211_tx_info *info; @@ -1216,24 +1244,26 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, /* check for success or failure according to the * transmitted bitmap and block-ack bitmap */ - bitmap &= agg->bitmap; + sent_bitmap = bitmap & agg->bitmap; /* For each frame attempted in aggregation, * update driver's record of tx frame's status. */ - for (i = 0; i < agg->frame_count ; i++) { - ack = bitmap & (1ULL << i); - successes += !!ack; + i = 0; + while (sent_bitmap) { + ack = sent_bitmap & 1ULL; + successes += ack; IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff, agg->start_idx + i); + sent_bitmap >>= 1; + ++i; } - info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]); + info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; info->status.ampdu_ack_len = successes; - info->status.ampdu_ack_map = bitmap; info->status.ampdu_len = agg->frame_count; iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); @@ -1281,6 +1311,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, int index; int sta_id; int tid; + unsigned long flags; /* "flow" corresponds to Tx queue */ u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); @@ -1308,7 +1339,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, /* Find index just before block-ack window */ index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); - /* TODO: Need to get this copy more safely - now good for debug */ + spin_lock_irqsave(&priv->sta_lock, flags); IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " "sta_id = %d\n", @@ -1344,4 +1375,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); } + + spin_unlock_irqrestore(&priv->sta_lock, flags); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 637286c396f..6f77441cb65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -423,3 +423,126 @@ int iwlagn_alive_notify(struct iwl_priv *priv) return 0; } + + +/** + * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, + * using sample data 100 bytes apart. If these sample points are good, + * it's a pretty good bet that everything between them is good, too. + */ +static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + int ret = 0; + u32 errcnt = 0; + u32 i; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, + i + IWLAGN_RTC_INST_LOWER_BOUND); + val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + ret = -EIO; + errcnt++; + if (errcnt >= 3) + break; + } + } + + return ret; +} + +/** + * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, + * looking at all data. + */ +static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, + u32 len) +{ + u32 val; + u32 save_len = len; + int ret = 0; + u32 errcnt; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, + IWLAGN_RTC_INST_LOWER_BOUND); + + errcnt = 0; + for (; len > 0; len -= sizeof(u32), image++) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + save_len - len, val, le32_to_cpu(*image)); + ret = -EIO; + errcnt++; + if (errcnt >= 20) + break; + } + } + + if (!errcnt) + IWL_DEBUG_INFO(priv, + "ucode image in INSTRUCTION memory is good\n"); + + return ret; +} + +/** + * iwl_verify_ucode - determine which instruction image is in SRAM, + * and verify its contents + */ +int iwl_verify_ucode(struct iwl_priv *priv) +{ + __le32 *image; + u32 len; + int ret; + + /* Try bootstrap */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + ret = iwlcore_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); + return 0; + } + + /* Try initialize */ + image = (__le32 *)priv->ucode_init.v_addr; + len = priv->ucode_init.len; + ret = iwlcore_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); + return 0; + } + + /* Try runtime/protocol */ + image = (__le32 *)priv->ucode_code.v_addr; + len = priv->ucode_code.len; + ret = iwlcore_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); + return 0; + } + + IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); + + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + ret = iwl_verify_inst_full(priv, image, len); + + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 24aff654fa9..35337b1e7ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -27,6 +27,8 @@ * *****************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -120,7 +122,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) (priv->switch_rxon.channel != priv->staging_rxon.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", le16_to_cpu(priv->switch_rxon.channel)); - priv->switch_rxon.switch_in_progress = false; + iwl_chswitch_done(priv, false); } /* If we don't need to send a full RXON, we can use @@ -292,9 +294,7 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon || - ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && - (priv->iw_mode != NL80211_IFTYPE_AP))) + if (!priv->ibss_beacon) return 0; if (priv->ibss_beacon->len > left) @@ -367,7 +367,8 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, /* Set up packet rate and flags */ rate = iwl_rate_get_lowest_plcp(priv); - priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant); + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + priv->hw_params.valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) rate_flags |= RATE_MCS_CCK_MSK; @@ -474,18 +475,25 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) /* Unmap tx_cmd */ if (num_tbs) pci_unmap_single(dev, - pci_unmap_addr(&txq->meta[index], mapping), - pci_unmap_len(&txq->meta[index], len), + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), PCI_DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ - for (i = 1; i < num_tbs; i++) { + for (i = 1; i < num_tbs; i++) pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); - if (txq->txb) { - dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]); - txq->txb[txq->q.read_ptr].skb[i - 1] = NULL; + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; } } } @@ -851,6 +859,24 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) return 0; } +static void iwl_bg_tx_flush(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, tx_flush); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* do nothing if rf-kill is on */ + if (!iwl_is_ready_rf(priv)) + return; + + if (priv->cfg->ops->lib->txfifo_flush) { + IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); + } +} + /** * iwl_setup_rx_handlers - Initialize Rx handler callbacks * @@ -933,6 +959,8 @@ void iwl_rx_handle(struct iwl_priv *priv) fill_rx = 1; while (i != r) { + int len; + rxb = rxq->queue[i]; /* If an RXB doesn't have a Rx queue slot associated with it, @@ -947,8 +975,9 @@ void iwl_rx_handle(struct iwl_priv *priv) PCI_DMA_FROMDEVICE); pkt = rxb_addr(rxb); - trace_iwlwifi_dev_rx(priv, pkt, - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_dev_rx(priv, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -1450,13 +1479,13 @@ bool iwl_good_ack_health(struct iwl_priv *priv, actual_ack_cnt_delta = le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - - le32_to_cpu(priv->statistics.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->statistics.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->statistics.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) @@ -1466,12 +1495,17 @@ bool iwl_good_ack_health(struct iwl_priv *priv, " expected_ack_cnt = %d\n", actual_ack_cnt_delta, expected_ack_cnt_delta); -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS + /* + * This is ifdef'ed on DEBUGFS because otherwise the + * 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", - priv->delta_statistics.tx.rx_detected_cnt); + priv->_agn.delta_statistics.tx.rx_detected_cnt); IWL_DEBUG_RADIO(priv, "ack_or_ba_timeout_collision delta = %d\n", - priv->delta_statistics.tx. + priv->_agn.delta_statistics.tx. ack_or_ba_timeout_collision); #endif IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", @@ -1658,6 +1692,7 @@ static void iwl_nic_start(struct iwl_priv *priv) struct iwlagn_ucode_capabilities { u32 max_probe_length; + u32 standard_phy_calibration_size; }; static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); @@ -1694,6 +1729,9 @@ struct iwlagn_firmware_pieces { size_t inst_size, data_size, init_size, init_data_size, boot_size; u32 build; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; }; static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, @@ -1787,12 +1825,20 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, const u8 *data; int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp; u64 alternatives; + u32 tlv_len; + enum iwl_ucode_tlv_type tlv_type; + const u8 *tlv_data; - if (len < sizeof(*ucode)) + if (len < sizeof(*ucode)) { + IWL_ERR(priv, "uCode has invalid length: %zd\n", len); return -EINVAL; + } - if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) + if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { + IWL_ERR(priv, "invalid uCode magic: 0X%x\n", + le32_to_cpu(ucode->magic)); return -EINVAL; + } /* * Check which alternatives are present, and "downgrade" @@ -1818,10 +1864,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, len -= sizeof(*ucode); while (len >= sizeof(*tlv)) { - u32 tlv_len; - enum iwl_ucode_tlv_type tlv_type; u16 tlv_alt; - const u8 *tlv_data; len -= sizeof(*tlv); tlv = (void *)data; @@ -1831,8 +1874,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, tlv_alt = le16_to_cpu(tlv->alternative); tlv_data = tlv->data; - if (len < tlv_len) + if (len < tlv_len) { + IWL_ERR(priv, "invalid TLV len: %zd/%u\n", + len, tlv_len); return -EINVAL; + } len -= ALIGN(tlv_len, 4); data += sizeof(*tlv) + ALIGN(tlv_len, 4); @@ -1866,20 +1912,77 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, pieces->boot_size = tlv_len; break; case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != 4) - return -EINVAL; + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; capa->max_probe_length = - le32_to_cpup((__le32 *)tlv_data); + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_ENHANCE_SENS_TBL: + if (tlv_len) + goto invalid_tlv_len; + priv->enhance_sensitivity_table = true; + break; + case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->standard_phy_calibration_size = + le32_to_cpup((__le32 *)tlv_data); break; default: + IWL_WARN(priv, "unknown TLV: %d\n", tlv_type); break; } } - if (len) + if (len) { + IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); return -EINVAL; + } return 0; + + invalid_tlv_len: + IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); + + return -EINVAL; } /** @@ -1901,6 +2004,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) u32 build; struct iwlagn_ucode_capabilities ucode_capa = { .max_probe_length = 200, + .standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, }; memset(&pieces, 0, sizeof(pieces)); @@ -2063,6 +2168,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) goto err_pci_alloc; } + /* Now that we can no longer fail, copy information */ + + /* + * The (size - 16) / 12 formula is based on the information recorded + * for each event, which is of mode 1 (including timestamp) for all + * new microcodes that include this information. + */ + priv->_agn.init_evtlog_ptr = pieces.init_evtlog_ptr; + if (pieces.init_evtlog_size) + priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + else + priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr; + priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr; + if (pieces.inst_evtlog_size) + priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + else + priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; + /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -2102,6 +2227,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) pieces.boot_size); memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + if (ucode_capa.standard_phy_calibration_size > + IWL_MAX_PHY_CALIBRATE_TBL_SIZE) + ucode_capa.standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + priv->_agn.phy_calib_chain_noise_reset_cmd = + ucode_capa.standard_phy_calibration_size; + priv->_agn.phy_calib_chain_noise_gain_cmd = + ucode_capa.standard_phy_calibration_size + 1; + /************************************************** * This is still part of probe() in a sense... * @@ -2172,17 +2311,41 @@ static const char *desc_lookup_text[] = { "DEBUG_1", "DEBUG_2", "DEBUG_3", - "ADVANCED SYSASSERT" }; -static const char *desc_lookup(int i) +static struct { char *name; u8 num; } advanced_lookup[] = { + { "NMI_INTERRUPT_WDG", 0x34 }, + { "SYSASSERT", 0x35 }, + { "UCODE_VERSION_MISMATCH", 0x37 }, + { "BAD_COMMAND", 0x38 }, + { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, + { "FATAL_ERROR", 0x3D }, + { "NMI_TRM_HW_ERR", 0x46 }, + { "NMI_INTERRUPT_TRM", 0x4C }, + { "NMI_INTERRUPT_BREAK_POINT", 0x54 }, + { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C }, + { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 }, + { "NMI_INTERRUPT_HOST", 0x66 }, + { "NMI_INTERRUPT_ACTION_PT", 0x7C }, + { "NMI_INTERRUPT_UNKNOWN", 0x84 }, + { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, + { "ADVANCED_SYSASSERT", 0 }, +}; + +static const char *desc_lookup(u32 num) { - int max = ARRAY_SIZE(desc_lookup_text) - 1; + int i; + int max = ARRAY_SIZE(desc_lookup_text); - if (i < 0 || i > max) - i = max; + if (num < max) + return desc_lookup_text[num]; - return desc_lookup_text[i]; + max = ARRAY_SIZE(advanced_lookup) - 1; + for (i = 0; i < max; i++) { + if (advanced_lookup[i].num == num) + break;; + } + return advanced_lookup[i].name; } #define ERROR_START_OFFSET (1 * sizeof(u32)) @@ -2195,10 +2358,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) u32 blink1, blink2, ilink1, ilink2; u32 pc, hcmd; - if (priv->ucode_type == UCODE_INIT) + if (priv->ucode_type == UCODE_INIT) { base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); - else + if (!base) + base = priv->_agn.init_errlog_ptr; + } else { base = le32_to_cpu(priv->card_alive.error_event_table_ptr); + if (!base) + base = priv->_agn.inst_errlog_ptr; + } if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { IWL_ERR(priv, @@ -2230,9 +2398,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, blink1, blink2, ilink1, ilink2); - IWL_ERR(priv, "Desc Time " + IWL_ERR(priv, "Desc Time " "data1 data2 line\n"); - IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", + IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", desc_lookup(desc), desc, time, data1, data2, line); IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", @@ -2258,10 +2426,16 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, if (num_events == 0) return pos; - if (priv->ucode_type == UCODE_INIT) + + if (priv->ucode_type == UCODE_INIT) { base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); - else + if (!base) + base = priv->_agn.init_evtlog_ptr; + } else { base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!base) + base = priv->_agn.inst_evtlog_ptr; + } if (mode == 0) event_size = 2 * sizeof(u32); @@ -2363,13 +2537,21 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ u32 size; /* # entries that we'll print */ + u32 logsize; int pos = 0; size_t bufsz = 0; - if (priv->ucode_type == UCODE_INIT) + if (priv->ucode_type == UCODE_INIT) { base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); - else + logsize = priv->_agn.init_evtlog_size; + if (!base) + base = priv->_agn.init_evtlog_ptr; + } else { base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + logsize = priv->_agn.inst_evtlog_size; + if (!base) + base = priv->_agn.inst_evtlog_ptr; + } if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { IWL_ERR(priv, @@ -2384,16 +2566,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); - if (capacity > priv->cfg->max_event_log_size) { + if (capacity > logsize) { IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->max_event_log_size); - capacity = priv->cfg->max_event_log_size; + capacity, logsize); + capacity = logsize; } - if (next_entry > priv->cfg->max_event_log_size) { + if (next_entry > logsize) { IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->max_event_log_size); - next_entry = priv->cfg->max_event_log_size; + next_entry, logsize); + next_entry = logsize; } size = num_wraps ? capacity : next_entry; @@ -2518,8 +2700,6 @@ static void iwl_alive_start(struct iwl_priv *priv) if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv); - - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); } /* Configure Bluetooth device coexistence support */ @@ -2843,9 +3023,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - iwl_chain_noise_calibration(priv, &priv->statistics); - - iwl_sensitivity_calibration(priv, &priv->statistics); + if (priv->cfg->bt_statistics) { + iwl_chain_noise_calibration(priv, + (void *)&priv->_agn.statistics_bt); + iwl_sensitivity_calibration(priv, + (void *)&priv->_agn.statistics_bt); + } else { + iwl_chain_noise_calibration(priv, + (void *)&priv->_agn.statistics); + iwl_sensitivity_calibration(priv, + (void *)&priv->_agn.statistics); + } } mutex_unlock(&priv->mutex); @@ -2934,20 +3122,16 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); - if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + if (vif->bss_conf.use_short_preamble) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.assoc_capability & - WLAN_CAPABILITY_SHORT_SLOT_TIME) + if (vif->bss_conf.use_short_slot) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - - if (vif->type == NL80211_IFTYPE_ADHOC) - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } iwlcore_commit_rxon(priv); @@ -3173,8 +3357,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->staging_rxon.assoc_id = 0; - if (vif->bss_conf.assoc_capability & - WLAN_CAPABILITY_SHORT_PREAMBLE) + if (vif->bss_conf.use_short_preamble) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else @@ -3182,17 +3365,12 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) ~RXON_FLG_SHORT_PREAMBLE_MSK; if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.assoc_capability & - WLAN_CAPABILITY_SHORT_SLOT_TIME) + if (vif->bss_conf.use_short_slot) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - - if (vif->type == NL80211_IFTYPE_ADHOC) - priv->staging_rxon.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; @@ -3238,17 +3416,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - if (sta) { - sta_id = iwl_sta_id(sta); - - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", - sta->addr); - return -EINVAL; - } - } else { - sta_id = priv->hw_params.bcast_sta_id; - } + sta_id = iwl_sta_id_or_broadcast(priv, sta); + if (sta_id == IWL_INVALID_STATION) + return -EINVAL; mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 100); @@ -3294,13 +3464,32 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } +/* + * switch to RTS/CTS for TX + */ +static void iwl_enable_rts_cts(struct iwl_priv *priv) +{ + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_INFO(priv, "use RTS/CTS protection\n"); + iwlcore_commit_rxon(priv); + } else { + /* scanning, defer the request until scan completed */ + IWL_DEBUG_INFO(priv, "defer setting RTS/CTS protection\n"); + } +} + static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn) { struct iwl_priv *priv = hw->priv; - int ret; + int ret = -EINVAL; IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); @@ -3308,17 +3497,19 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, if (!(priv->cfg->sku & IWL_SKU_N)) return -EACCES; + mutex_lock(&priv->mutex); + switch (action) { case IEEE80211_AMPDU_RX_START: IWL_DEBUG_HT(priv, "start Rx\n"); - return iwl_sta_rx_agg_start(priv, sta, tid, *ssn); + ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); + break; case IEEE80211_AMPDU_RX_STOP: IWL_DEBUG_HT(priv, "stop Rx\n"); ret = iwl_sta_rx_agg_stop(priv, sta, tid); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return 0; - else - return ret; + ret = 0; + break; case IEEE80211_AMPDU_TX_START: IWL_DEBUG_HT(priv, "start Tx\n"); ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); @@ -3327,7 +3518,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n", priv->_agn.agg_tids_count); } - return ret; + break; case IEEE80211_AMPDU_TX_STOP: IWL_DEBUG_HT(priv, "stop Tx\n"); ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); @@ -3337,18 +3528,22 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, priv->_agn.agg_tids_count); } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return 0; - else - return ret; + ret = 0; + break; case IEEE80211_AMPDU_TX_OPERATIONAL: - /* do nothing */ - return -EOPNOTSUPP; - default: - IWL_DEBUG_HT(priv, "unknown\n"); - return -EINVAL; + if (priv->cfg->use_rts_for_ht) { + /* + * switch to RTS/CTS if it is the prefer protection + * method for HT traffic + */ + iwl_enable_rts_cts(priv); + } + ret = 0; break; } - return 0; + mutex_unlock(&priv->mutex); + + return ret; } static void iwl_mac_sta_notify(struct ieee80211_hw *hw, @@ -3423,6 +3618,136 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, return 0; } +static void iwl_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + u16 ch; + unsigned long flags = 0; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (iwl_is_rfkill(priv)) + goto out_exit; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) + goto out_exit; + + if (!iwl_is_associated(priv)) + goto out_exit; + + /* channel switch in progress */ + if (priv->switch_rxon.switch_in_progress == true) + goto out_exit; + + mutex_lock(&priv->mutex); + if (priv->cfg->ops->lib->set_channel_switch) { + + ch = ieee80211_frequency_to_channel( + ch_switch->channel->center_freq); + if (le16_to_cpu(priv->active_rxon.channel) != ch) { + ch_info = iwl_get_channel_info(priv, + conf->channel->band, + ch); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + goto out; + } + spin_lock_irqsave(&priv->lock, flags); + + priv->current_ht_config.smps = conf->smps_mode; + + /* Configure HT40 channels */ + ht_conf->is_ht = conf_is_ht(conf); + if (ht_conf->is_ht) { + if (conf_is_ht40_minus(conf)) { + ht_conf->extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ht_conf->is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ht_conf->extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ht_conf->is_40mhz = true; + } else { + ht_conf->extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ht_conf->is_40mhz = false; + } + } else + ht_conf->is_40mhz = false; + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) + priv->staging_rxon.flags = 0; + + iwl_set_rxon_channel(priv, conf->channel); + iwl_set_rxon_ht(priv, ht_conf); + iwl_set_flags_for_band(priv, conf->channel->band, + priv->vif); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_set_rate(priv); + /* + * at this point, staging_rxon has the + * configuration for channel switch + */ + if (priv->cfg->ops->lib->set_channel_switch(priv, + ch_switch)) + priv->switch_rxon.switch_in_progress = false; + } + } +out: + mutex_unlock(&priv->mutex); +out_exit: + if (!priv->switch_rxon.switch_in_progress) + ieee80211_chswitch_done(priv->vif, false); + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) +{ + struct iwl_priv *priv = hw->priv; + + mutex_lock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "enter\n"); + + /* do not support "flush" */ + if (!priv->cfg->ops->lib->txfifo_flush) + goto done; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); + goto done; + } + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); + goto done; + } + + /* + * mac80211 will not push any more frames for transmit + * until the flush is completed + */ + if (drop) { + IWL_DEBUG_MAC80211(priv, "send flush command\n"); + if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) { + IWL_ERR(priv, "flush request fail\n"); + goto done; + } + } + IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); + iwlagn_wait_tx_queue_empty(priv); +done: + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + /***************************************************************************** * * driver setup and teardown @@ -3439,6 +3764,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); + INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); @@ -3479,6 +3805,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_delayed_work(&priv->scan_check); cancel_work_sync(&priv->start_internal_scan); cancel_delayed_work(&priv->alive_start); + cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); @@ -3594,6 +3921,8 @@ static struct ieee80211_ops iwl_hw_ops = { .sta_notify = iwl_mac_sta_notify, .sta_add = iwlagn_mac_sta_add, .sta_remove = iwl_mac_sta_remove, + .channel_switch = iwl_mac_channel_switch, + .flush = iwl_mac_flush, }; static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -3603,7 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); unsigned long flags; - u16 pci_cmd; + u16 pci_cmd, num_mac; /************************ * 1. Allocating HW data @@ -3633,9 +3962,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; -#ifdef CONFIG_IWLWIFI_DEBUG - atomic_set(&priv->restrict_refcnt, 0); -#endif if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); @@ -3724,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_free_eeprom; /* extract MAC Address */ - iwl_eeprom_get_mac(priv, priv->mac_addr); - IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr); - SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); + iwl_eeprom_get_mac(priv, priv->addresses[0].addr); + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); + priv->hw->wiphy->addresses = priv->addresses; + priv->hw->wiphy->n_addresses = 1; + num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); + if (num_mac > 1) { + memcpy(priv->addresses[1].addr, priv->addresses[0].addr, + ETH_ALEN); + priv->addresses[1].addr[5]++; + priv->hw->wiphy->n_addresses++; + } /************************ * 5. Setup HW constants @@ -3993,6 +4327,47 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)}, + +/* 6x00 Series Gen2b */ + {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)}, /* 6x50 WiFi/WiMax Series */ {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, @@ -4002,6 +4377,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, +/* 6x50 WiFi/WiMax Series Gen2 */ + {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6050g2_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6050g2_bgn_cfg)}, + /* 1000 Series WiFi */ {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, @@ -4036,19 +4419,18 @@ static int __init iwl_init(void) { int ret; - printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); - printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); ret = iwlagn_rate_control_register(); if (ret) { - printk(KERN_ERR DRV_NAME - "Unable to register rate control algorithm: %d\n", ret); + pr_err("Unable to register rate control algorithm: %d\n", ret); return ret; } ret = pci_register_driver(&iwl_driver); if (ret) { - printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); + pr_err("Unable to initialize PCI module\n"); goto error_register; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2d748053358..cc6464dc72e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -65,6 +65,34 @@ #include "iwl-dev.h" +/* configuration for the _agn devices */ +extern struct iwl_cfg iwl4965_agn_cfg; +extern struct iwl_cfg iwl5300_agn_cfg; +extern struct iwl_cfg iwl5100_agn_cfg; +extern struct iwl_cfg iwl5350_agn_cfg; +extern struct iwl_cfg iwl5100_bgn_cfg; +extern struct iwl_cfg iwl5100_abg_cfg; +extern struct iwl_cfg iwl5150_agn_cfg; +extern struct iwl_cfg iwl5150_abg_cfg; +extern struct iwl_cfg iwl6000g2a_2agn_cfg; +extern struct iwl_cfg iwl6000g2a_2abg_cfg; +extern struct iwl_cfg iwl6000g2a_2bg_cfg; +extern struct iwl_cfg iwl6000g2b_bgn_cfg; +extern struct iwl_cfg iwl6000g2b_bg_cfg; +extern struct iwl_cfg iwl6000g2b_2agn_cfg; +extern struct iwl_cfg iwl6000g2b_2abg_cfg; +extern struct iwl_cfg iwl6000g2b_2bgn_cfg; +extern struct iwl_cfg iwl6000g2b_2bg_cfg; +extern struct iwl_cfg iwl6000i_2agn_cfg; +extern struct iwl_cfg iwl6000i_2abg_cfg; +extern struct iwl_cfg iwl6000i_2bg_cfg; +extern struct iwl_cfg iwl6000_3agn_cfg; +extern struct iwl_cfg iwl6050_2agn_cfg; +extern struct iwl_cfg iwl6050_2abg_cfg; +extern struct iwl_cfg iwl6050g2_bgn_cfg; +extern struct iwl_cfg iwl1000_bgn_cfg; +extern struct iwl_cfg iwl1000_bg_cfg; + extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; @@ -93,6 +121,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo); void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); +void iwl_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed); /* uCode */ int iwlagn_load_ucode(struct iwl_priv *priv); @@ -102,6 +132,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwlagn_init_alive_start(struct iwl_priv *priv); int iwlagn_alive_notify(struct iwl_priv *priv); +int iwl_verify_ucode(struct iwl_priv *priv); /* lib */ void iwl_check_abort_status(struct iwl_priv *priv, @@ -117,6 +148,9 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_hw_nic_init(struct iwl_priv *priv); +int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); +int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); +void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); @@ -171,6 +205,16 @@ static inline bool iwl_is_tx_success(u32 status) (status == TX_STATUS_DIRECT_DONE); } +/* rx */ +void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +bool iwl_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt); +void iwl_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); + /* scan */ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); @@ -178,4 +222,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); +/* hcmd */ +int iwlagn_send_rxon_assoc(struct iwl_priv *priv); +int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h index 2b7b1df83ba..ba9523fbb30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-calib.h @@ -66,10 +66,8 @@ #include "iwl-core.h" #include "iwl-commands.h" -void iwl_chain_noise_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *stat_resp); -void iwl_sensitivity_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *resp); +void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); +void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); void iwl_init_sensitivity(struct iwl_priv *priv); void iwl_reset_run_time_calib(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9aab020c474..60725a5c1b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -95,8 +95,9 @@ enum { /* Multi-Station support */ REPLY_ADD_STA = 0x18, - REPLY_REMOVE_STA = 0x19, /* not used */ + REPLY_REMOVE_STA = 0x19, REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ + REPLY_TXFIFO_FLUSH = 0x1e, /* Security */ REPLY_WEPKEY = 0x20, @@ -227,7 +228,7 @@ struct iwl_cmd_header { /* command or response/notification data follows immediately */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; /** @@ -247,7 +248,7 @@ struct iwl_cmd_header { struct iwl3945_tx_power { u8 tx_gain; /* gain for analog radio */ u8 dsp_atten; /* gain for DSP */ -} __attribute__ ((packed)); +} __packed; /** * struct iwl3945_power_per_rate @@ -258,7 +259,7 @@ struct iwl3945_power_per_rate { u8 rate; /* plcp */ struct iwl3945_tx_power tpc; u8 reserved; -} __attribute__ ((packed)); +} __packed; /** * iwlagn rate_n_flags bit fields @@ -389,7 +390,7 @@ union iwl4965_tx_power_dual_stream { */ struct tx_power_dual_stream { __le32 dw; -} __attribute__ ((packed)); +} __packed; /** * struct iwl4965_tx_power_db @@ -398,7 +399,7 @@ struct tx_power_dual_stream { */ struct iwl4965_tx_power_db { struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; -} __attribute__ ((packed)); +} __packed; /** * Command REPLY_TX_POWER_DBM_CMD = 0x98 @@ -412,7 +413,7 @@ struct iwl5000_tx_power_dbm_cmd { u8 flags; s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ u8 reserved; -} __attribute__ ((packed)); +} __packed; /** * Command TX_ANT_CONFIGURATION_CMD = 0x98 @@ -422,7 +423,7 @@ struct iwl5000_tx_power_dbm_cmd { */ struct iwl_tx_ant_config_cmd { __le32 valid; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (0a) @@ -478,7 +479,7 @@ struct iwl_init_alive_resp { __le32 therm_r4[2]; /* signed */ __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups, * 2 Tx chains */ -} __attribute__ ((packed)); +} __packed; /** @@ -570,7 +571,7 @@ struct iwl_alive_resp { __le32 error_event_table_ptr; /* SRAM address for error log */ __le32 timestamp; __le32 is_valid; -} __attribute__ ((packed)); +} __packed; /* * REPLY_ERROR = 0x2 (response only, not a command) @@ -582,7 +583,7 @@ struct iwl_error_resp { __le16 bad_cmd_seq_num; __le32 error_info; __le64 timestamp; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (1) @@ -718,7 +719,7 @@ struct iwl3945_rxon_cmd { __le32 filter_flags; __le16 channel; __le16 reserved5; -} __attribute__ ((packed)); +} __packed; struct iwl4965_rxon_cmd { u8 node_addr[6]; @@ -738,7 +739,7 @@ struct iwl4965_rxon_cmd { __le16 channel; u8 ofdm_ht_single_stream_basic_rates; u8 ofdm_ht_dual_stream_basic_rates; -} __attribute__ ((packed)); +} __packed; /* 5000 HW just extend this command */ struct iwl_rxon_cmd { @@ -763,7 +764,7 @@ struct iwl_rxon_cmd { u8 reserved5; __le16 acquisition_data; __le16 reserved6; -} __attribute__ ((packed)); +} __packed; /* * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) @@ -774,7 +775,7 @@ struct iwl3945_rxon_assoc_cmd { u8 ofdm_basic_rates; u8 cck_basic_rates; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwl4965_rxon_assoc_cmd { __le32 flags; @@ -785,7 +786,7 @@ struct iwl4965_rxon_assoc_cmd { u8 ofdm_ht_dual_stream_basic_rates; __le16 rx_chain_select_flags; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwl5000_rxon_assoc_cmd { __le32 flags; @@ -800,7 +801,7 @@ struct iwl5000_rxon_assoc_cmd { __le16 rx_chain_select_flags; __le16 acquisition_data; __le32 reserved3; -} __attribute__ ((packed)); +} __packed; #define IWL_CONN_MAX_LISTEN_INTERVAL 10 #define IWL_MAX_UCODE_BEACON_INTERVAL 4 /* 4096 */ @@ -816,7 +817,7 @@ struct iwl_rxon_time_cmd { __le32 beacon_init_val; __le16 listen_interval; __le16 reserved; -} __attribute__ ((packed)); +} __packed; /* * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) @@ -829,7 +830,7 @@ struct iwl3945_channel_switch_cmd { __le32 rxon_filter_flags; __le32 switch_time; struct iwl3945_power_per_rate power[IWL_MAX_RATES]; -} __attribute__ ((packed)); +} __packed; struct iwl4965_channel_switch_cmd { u8 band; @@ -839,7 +840,7 @@ struct iwl4965_channel_switch_cmd { __le32 rxon_filter_flags; __le32 switch_time; struct iwl4965_tx_power_db tx_power; -} __attribute__ ((packed)); +} __packed; /** * struct iwl5000_channel_switch_cmd @@ -860,7 +861,7 @@ struct iwl5000_channel_switch_cmd { __le32 rxon_filter_flags; __le32 switch_time; __le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; -} __attribute__ ((packed)); +} __packed; /** * struct iwl6000_channel_switch_cmd @@ -881,7 +882,7 @@ struct iwl6000_channel_switch_cmd { __le32 rxon_filter_flags; __le32 switch_time; __le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES]; -} __attribute__ ((packed)); +} __packed; /* * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) @@ -890,7 +891,7 @@ struct iwl_csa_notification { __le16 band; __le16 channel; __le32 status; /* 0 - OK, 1 - fail */ -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (2) @@ -920,7 +921,7 @@ struct iwl_ac_qos { u8 aifsn; u8 reserved1; __le16 edca_txop; -} __attribute__ ((packed)); +} __packed; /* QoS flags defines */ #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) @@ -939,7 +940,7 @@ struct iwl_ac_qos { struct iwl_qosparam_cmd { __le32 qos_flags; struct iwl_ac_qos ac[AC_NUM]; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (3) @@ -952,20 +953,19 @@ struct iwl_qosparam_cmd { /* Special, dedicated locations within device's station table */ #define IWL_AP_ID 0 -#define IWL_MULTICAST_ID 1 #define IWL_STA_ID 2 #define IWL3945_BROADCAST_ID 24 #define IWL3945_STATION_COUNT 25 #define IWL4965_BROADCAST_ID 31 #define IWL4965_STATION_COUNT 32 -#define IWL5000_BROADCAST_ID 15 -#define IWL5000_STATION_COUNT 16 +#define IWLAGN_BROADCAST_ID 15 +#define IWLAGN_STATION_COUNT 16 #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ #define IWL_INVALID_STATION 255 -#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2); -#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); +#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) +#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) #define STA_FLG_MAX_AGG_SIZE_POS (19) @@ -1015,7 +1015,7 @@ struct iwl4965_keyinfo { u8 key_offset; u8 reserved2; u8 key[16]; /* 16-byte unicast decryption key */ -} __attribute__ ((packed)); +} __packed; /* 5000 */ struct iwl_keyinfo { @@ -1029,7 +1029,7 @@ struct iwl_keyinfo { __le64 tx_secur_seq_cnt; __le64 hw_tkip_mic_rx_key; __le64 hw_tkip_mic_tx_key; -} __attribute__ ((packed)); +} __packed; /** * struct sta_id_modify @@ -1049,7 +1049,7 @@ struct sta_id_modify { u8 sta_id; u8 modify_mask; __le16 reserved2; -} __attribute__ ((packed)); +} __packed; /* * REPLY_ADD_STA = 0x18 (command) @@ -1103,7 +1103,7 @@ struct iwl3945_addsta_cmd { /* Starting Sequence Number for added block-ack support. * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ __le16 add_immediate_ba_ssn; -} __attribute__ ((packed)); +} __packed; struct iwl4965_addsta_cmd { u8 mode; /* 1: modify existing, 0: add new station */ @@ -1140,7 +1140,7 @@ struct iwl4965_addsta_cmd { __le16 sleep_tx_count; __le16 reserved2; -} __attribute__ ((packed)); +} __packed; /* 5000 */ struct iwl_addsta_cmd { @@ -1178,7 +1178,7 @@ struct iwl_addsta_cmd { __le16 sleep_tx_count; __le16 reserved2; -} __attribute__ ((packed)); +} __packed; #define ADD_STA_SUCCESS_MSK 0x1 @@ -1190,7 +1190,7 @@ struct iwl_addsta_cmd { */ struct iwl_add_sta_resp { u8 status; /* ADD_STA_* */ -} __attribute__ ((packed)); +} __packed; #define REM_STA_SUCCESS_MSK 0x1 /* @@ -1198,7 +1198,7 @@ struct iwl_add_sta_resp { */ struct iwl_rem_sta_resp { u8 status; -} __attribute__ ((packed)); +} __packed; /* * REPLY_REM_STA = 0x19 (command) @@ -1208,7 +1208,44 @@ struct iwl_rem_sta_cmd { u8 reserved[3]; u8 addr[ETH_ALEN]; /* MAC addr of the first station */ u8 reserved2[2]; -} __attribute__ ((packed)); +} __packed; + +#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0)) +#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1)) +#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2)) +#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3)) +#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) + +#define IWL_DROP_SINGLE 0 +#define IWL_DROP_SELECTED 1 +#define IWL_DROP_ALL 2 + +/* + * REPLY_TXFIFO_FLUSH = 0x1e(command and response) + * + * When using full FIFO flush this command checks the scheduler HW block WR/RD + * pointers to check if all the frames were transferred by DMA into the + * relevant TX FIFO queue. Only when the DMA is finished and the queue is + * empty the command can finish. + * This command is used to flush the TXFIFO from transmit commands, it may + * operate on single or multiple queues, the command queue can't be flushed by + * this command. The command response is returned when all the queue flush + * operations are done. Each TX command flushed return response with the FLUSH + * status set in the TX response status. When FIFO flush operation is used, + * the flush operation ends when both the scheduler DMA done and TXFIFO empty + * are set. + * + * @fifo_control: bit mask for which queues to flush + * @flush_control: flush controls + * 0: Dump single MSDU + * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. + * 2: Dump all FIFO + */ +struct iwl_txfifo_flush_cmd { + __le32 fifo_control; + __le16 flush_control; + __le16 reserved; +} __packed; /* * REPLY_WEP_KEY = 0x20 @@ -1220,7 +1257,7 @@ struct iwl_wep_key { u8 key_size; u8 reserved2[3]; u8 key[16]; -} __attribute__ ((packed)); +} __packed; struct iwl_wep_cmd { u8 num_keys; @@ -1228,7 +1265,7 @@ struct iwl_wep_cmd { u8 flags; u8 reserved; struct iwl_wep_key key[0]; -} __attribute__ ((packed)); +} __packed; #define WEP_KEY_WEP_TYPE 1 #define WEP_KEYS_MAX 4 @@ -1282,7 +1319,7 @@ struct iwl3945_rx_frame_stats { __le16 sig_avg; __le16 noise_diff; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct iwl3945_rx_frame_hdr { __le16 channel; @@ -1291,13 +1328,13 @@ struct iwl3945_rx_frame_hdr { u8 rate; __le16 len; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct iwl3945_rx_frame_end { __le32 status; __le64 timestamp; __le32 beacon_timestamp; -} __attribute__ ((packed)); +} __packed; /* * REPLY_3945_RX = 0x1b (response only, not a command) @@ -1311,7 +1348,7 @@ struct iwl3945_rx_frame { struct iwl3945_rx_frame_stats stats; struct iwl3945_rx_frame_hdr hdr; struct iwl3945_rx_frame_end end; -} __attribute__ ((packed)); +} __packed; #define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) @@ -1327,7 +1364,7 @@ struct iwl4965_rx_non_cfg_phy { __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ u8 pad[0]; -} __attribute__ ((packed)); +} __packed; #define IWL50_RX_RES_PHY_CNT 8 @@ -1345,7 +1382,7 @@ struct iwl4965_rx_non_cfg_phy { struct iwl5000_non_cfg_phy { __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* up to 8 phy entries */ -} __attribute__ ((packed)); +} __packed; /* @@ -1365,12 +1402,12 @@ struct iwl_rx_phy_res { __le32 rate_n_flags; /* RATE_MCS_* */ __le16 byte_count; /* frame's byte-count */ __le16 reserved3; -} __attribute__ ((packed)); +} __packed; -struct iwl4965_rx_mpdu_res_start { +struct iwl_rx_mpdu_res_start { __le16 byte_count; __le16 reserved; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** @@ -1400,18 +1437,27 @@ struct iwl4965_rx_mpdu_res_start { /* REPLY_TX Tx flags field */ -/* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it +/* + * 1: Use RTS/CTS protocol or CTS-to-self if spec allows it * before this frame. if CTS-to-self required check - * RXON_FLG_SELF_CTS_EN status. */ -#define TX_CMD_FLG_RTS_CTS_MSK cpu_to_le32(1 << 0) + * RXON_FLG_SELF_CTS_EN status. + * unused in 3945/4965, used in 5000 series and after + */ +#define TX_CMD_FLG_PROT_REQUIRE_MSK cpu_to_le32(1 << 0) -/* 1: Use Request-To-Send protocol before this frame. - * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ +/* + * 1: Use Request-To-Send protocol before this frame. + * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. + * used in 3945/4965, unused in 5000 series and after + */ #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) -/* 1: Transmit Clear-To-Send to self before this frame. +/* + * 1: Transmit Clear-To-Send to self before this frame. * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. - * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ + * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. + * used in 3945/4965, unused in 5000 series and after + */ #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) /* 1: Expect ACK from receiving station @@ -1431,8 +1477,11 @@ struct iwl4965_rx_mpdu_res_start { * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) -/* 1: Frame requires full Tx-Op protection. - * Set this if either RTS or CTS Tx Flag gets set. */ +/* + * 1: Frame requires full Tx-Op protection. + * Set this if either RTS or CTS Tx Flag gets set. + * used in 3945/4965, unused in 5000 series and after + */ #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. @@ -1557,7 +1606,7 @@ struct iwl3945_tx_cmd { */ u8 payload[0]; struct ieee80211_hdr hdr[0]; -} __attribute__ ((packed)); +} __packed; /* * REPLY_TX = 0x1c (response) @@ -1569,7 +1618,7 @@ struct iwl3945_tx_resp { u8 rate; __le32 wireless_media_time; __le32 status; /* TX status */ -} __attribute__ ((packed)); +} __packed; /* @@ -1581,7 +1630,7 @@ struct iwl_dram_scratch { u8 try_cnt; /* Tx attempts */ u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */ __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwl_tx_cmd { /* @@ -1660,7 +1709,7 @@ struct iwl_tx_cmd { */ u8 payload[0]; struct ieee80211_hdr hdr[0]; -} __attribute__ ((packed)); +} __packed; /* TX command response is sent after *3945* transmission attempts. * @@ -1826,7 +1875,7 @@ enum { struct agg_tx_status { __le16 status; __le16 sequence; -} __attribute__ ((packed)); +} __packed; struct iwl4965_tx_resp { u8 frame_count; /* 1 no aggregation, >1 aggregation */ @@ -1863,7 +1912,7 @@ struct iwl4965_tx_resp { __le32 status; struct agg_tx_status agg_status[0]; /* for each agg frame */ } u; -} __attribute__ ((packed)); +} __packed; /* * definitions for initial rate index field @@ -1927,7 +1976,7 @@ struct iwl5000_tx_resp { */ struct agg_tx_status status; /* TX status (in aggregation - * status of 1st frame) */ -} __attribute__ ((packed)); +} __packed; /* * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) * @@ -1945,7 +1994,7 @@ struct iwl_compressed_ba_resp { __le64 bitmap; __le16 scd_flow; __le16 scd_ssn; -} __attribute__ ((packed)); +} __packed; /* * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) @@ -1958,14 +2007,14 @@ struct iwl3945_txpowertable_cmd { u8 reserved; __le16 channel; struct iwl3945_power_per_rate power[IWL_MAX_RATES]; -} __attribute__ ((packed)); +} __packed; struct iwl4965_txpowertable_cmd { u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ u8 reserved; __le16 channel; struct iwl4965_tx_power_db tx_power; -} __attribute__ ((packed)); +} __packed; /** @@ -1987,13 +2036,13 @@ struct iwl3945_rate_scaling_info { __le16 rate_n_flags; u8 try_cnt; u8 next_rate_index; -} __attribute__ ((packed)); +} __packed; struct iwl3945_rate_scaling_cmd { u8 table_id; u8 reserved[3]; struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; -} __attribute__ ((packed)); +} __packed; /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ @@ -2040,7 +2089,7 @@ struct iwl_link_qual_general_params { * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. */ u8 start_rate_index[LINK_QUAL_AC_NUM]; -} __attribute__ ((packed)); +} __packed; #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ #define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535) @@ -2081,7 +2130,7 @@ struct iwl_link_qual_agg_params { u8 agg_frame_cnt_limit; __le32 reserved; -} __attribute__ ((packed)); +} __packed; /* * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) @@ -2287,7 +2336,7 @@ struct iwl_link_quality_cmd { __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ } rs_table[LINK_QUAL_MAX_RETRY_NUM]; __le32 reserved2; -} __attribute__ ((packed)); +} __packed; /* * BT configuration enable flags: @@ -2328,7 +2377,7 @@ struct iwl_bt_cmd { u8 reserved; __le32 kill_ack_mask; __le32 kill_cts_mask; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (6) @@ -2353,7 +2402,7 @@ struct iwl_measure_channel { u8 channel; /* channel to measure */ u8 type; /* see enum iwl_measure_type */ __le16 reserved; -} __attribute__ ((packed)); +} __packed; /* * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) @@ -2372,7 +2421,7 @@ struct iwl_spectrum_cmd { __le16 channel_count; /* minimum 1, maximum 10 */ __le16 reserved3; struct iwl_measure_channel channels[10]; -} __attribute__ ((packed)); +} __packed; /* * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) @@ -2383,7 +2432,7 @@ struct iwl_spectrum_resp { __le16 status; /* 0 - command will be handled * 1 - cannot handle (conflicts with another * measurement) */ -} __attribute__ ((packed)); +} __packed; enum iwl_measurement_state { IWL_MEASUREMENT_START = 0, @@ -2406,13 +2455,13 @@ enum iwl_measurement_status { struct iwl_measurement_histogram { __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ -} __attribute__ ((packed)); +} __packed; /* clear channel availability counters */ struct iwl_measurement_cca_counters { __le32 ofdm; __le32 cck; -} __attribute__ ((packed)); +} __packed; enum iwl_measure_type { IWL_MEASURE_BASIC = (1 << 0), @@ -2448,7 +2497,7 @@ struct iwl_spectrum_notification { struct iwl_measurement_histogram histogram; __le32 stop_time; /* lower 32-bits of TSF */ __le32 status; /* see iwl_measurement_status */ -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (7) @@ -2504,7 +2553,7 @@ struct iwl3945_powertable_cmd { __le32 rx_data_timeout; __le32 tx_data_timeout; __le32 sleep_interval[IWL_POWER_VEC_SIZE]; -} __attribute__ ((packed)); +} __packed; struct iwl_powertable_cmd { __le16 flags; @@ -2514,7 +2563,7 @@ struct iwl_powertable_cmd { __le32 tx_data_timeout; __le32 sleep_interval[IWL_POWER_VEC_SIZE]; __le32 keep_alive_beacons; -} __attribute__ ((packed)); +} __packed; /* * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) @@ -2527,7 +2576,7 @@ struct iwl_sleep_notification { __le32 sleep_time; __le32 tsf_low; __le32 bcon_timer; -} __attribute__ ((packed)); +} __packed; /* Sleep states. 3945 and 4965 identical. */ enum { @@ -2552,14 +2601,14 @@ enum { #define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ struct iwl_card_state_cmd { __le32 status; /* CARD_STATE_CMD_* request new power state */ -} __attribute__ ((packed)); +} __packed; /* * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) */ struct iwl_card_state_notif { __le32 flags; -} __attribute__ ((packed)); +} __packed; #define HW_CARD_DISABLED 0x01 #define SW_CARD_DISABLED 0x02 @@ -2570,14 +2619,14 @@ struct iwl_ct_kill_config { __le32 reserved; __le32 critical_temperature_M; __le32 critical_temperature_R; -} __attribute__ ((packed)); +} __packed; /* 1000, and 6x00 */ struct iwl_ct_kill_throttling_config { __le32 critical_temperature_exit; __le32 reserved; __le32 critical_temperature_enter; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (8) @@ -2622,7 +2671,7 @@ struct iwl3945_scan_channel { struct iwl3945_tx_power tpc; __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ -} __attribute__ ((packed)); +} __packed; /* set number of direct probes u8 type */ #define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1)))) @@ -2641,7 +2690,7 @@ struct iwl_scan_channel { u8 dsp_atten; /* gain for DSP */ __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ -} __attribute__ ((packed)); +} __packed; /* set number of direct probes __le32 type */ #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) @@ -2658,7 +2707,7 @@ struct iwl_ssid_ie { u8 id; u8 len; u8 ssid[32]; -} __attribute__ ((packed)); +} __packed; #define PROBE_OPTION_MAX_3945 4 #define PROBE_OPTION_MAX 20 @@ -2764,7 +2813,7 @@ struct iwl3945_scan_cmd { * before requesting another scan. */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct iwl_scan_cmd { __le16 len; @@ -2808,7 +2857,7 @@ struct iwl_scan_cmd { * before requesting another scan. */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* Can abort will notify by complete notification with abort status. */ #define CAN_ABORT_STATUS cpu_to_le32(0x1) @@ -2820,7 +2869,7 @@ struct iwl_scan_cmd { */ struct iwl_scanreq_notification { __le32 status; /* 1: okay, 2: cannot fulfill request */ -} __attribute__ ((packed)); +} __packed; /* * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) @@ -2833,7 +2882,7 @@ struct iwl_scanstart_notification { u8 band; u8 reserved[2]; __le32 status; -} __attribute__ ((packed)); +} __packed; #define SCAN_OWNER_STATUS 0x1; #define MEASURE_OWNER_STATUS 0x2; @@ -2849,7 +2898,7 @@ struct iwl_scanresults_notification { __le32 tsf_low; __le32 tsf_high; __le32 statistics[NUMBER_OF_STATISTICS]; -} __attribute__ ((packed)); +} __packed; /* * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) @@ -2861,7 +2910,7 @@ struct iwl_scancomplete_notification { u8 last_channel; __le32 tsf_low; __le32 tsf_high; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** @@ -2879,14 +2928,14 @@ struct iwl3945_beacon_notif { __le32 low_tsf; __le32 high_tsf; __le32 ibss_mgr_status; -} __attribute__ ((packed)); +} __packed; struct iwl4965_beacon_notif { struct iwl4965_tx_resp beacon_notify_hdr; __le32 low_tsf; __le32 high_tsf; __le32 ibss_mgr_status; -} __attribute__ ((packed)); +} __packed; /* * REPLY_TX_BEACON = 0x91 (command, has simple generic response) @@ -2898,7 +2947,7 @@ struct iwl3945_tx_beacon_cmd { u8 tim_size; u8 reserved1; struct ieee80211_hdr frame[0]; /* beacon frame */ -} __attribute__ ((packed)); +} __packed; struct iwl_tx_beacon_cmd { struct iwl_tx_cmd tx; @@ -2906,7 +2955,7 @@ struct iwl_tx_beacon_cmd { u8 tim_size; u8 reserved1; struct ieee80211_hdr frame[0]; /* beacon frame */ -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (10) @@ -2932,7 +2981,7 @@ struct rate_histogram { __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; } failed; -} __attribute__ ((packed)); +} __packed; /* statistics command response */ @@ -2952,7 +3001,7 @@ struct iwl39_statistics_rx_phy { __le32 rxe_frame_limit_overrun; __le32 sent_ack_cnt; __le32 sent_cts_cnt; -} __attribute__ ((packed)); +} __packed; struct iwl39_statistics_rx_non_phy { __le32 bogus_cts; /* CTS received when not expecting CTS */ @@ -2963,13 +3012,13 @@ struct iwl39_statistics_rx_non_phy { * filtering process */ __le32 non_channel_beacons; /* beacons with our bss id but not on * our serving channel */ -} __attribute__ ((packed)); +} __packed; struct iwl39_statistics_rx { struct iwl39_statistics_rx_phy ofdm; struct iwl39_statistics_rx_phy cck; struct iwl39_statistics_rx_non_phy general; -} __attribute__ ((packed)); +} __packed; struct iwl39_statistics_tx { __le32 preamble_cnt; @@ -2981,20 +3030,21 @@ struct iwl39_statistics_tx { __le32 ack_timeout; __le32 expected_ack_cnt; __le32 actual_ack_cnt; -} __attribute__ ((packed)); +} __packed; struct statistics_dbg { __le32 burst_check; __le32 burst_count; - __le32 reserved[4]; -} __attribute__ ((packed)); + __le32 wait_for_silence_timeout_cnt; + __le32 reserved[3]; +} __packed; struct iwl39_statistics_div { __le32 tx_on_a; __le32 tx_on_b; __le32 exec_time; __le32 probe_time; -} __attribute__ ((packed)); +} __packed; struct iwl39_statistics_general { __le32 temperature; @@ -3004,7 +3054,7 @@ struct iwl39_statistics_general { __le32 slots_idle; __le32 ttl_timestamp; struct iwl39_statistics_div div; -} __attribute__ ((packed)); +} __packed; struct statistics_rx_phy { __le32 ina_cnt; @@ -3027,7 +3077,7 @@ struct statistics_rx_phy { __le32 mh_format_err; __le32 re_acq_main_rssi_sum; __le32 reserved3; -} __attribute__ ((packed)); +} __packed; struct statistics_rx_ht_phy { __le32 plcp_err; @@ -3040,7 +3090,7 @@ struct statistics_rx_ht_phy { __le32 agg_mpdu_cnt; __le32 agg_cnt; __le32 unsupport_mcs; -} __attribute__ ((packed)); +} __packed; #define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) @@ -3075,14 +3125,28 @@ struct statistics_rx_non_phy { __le32 beacon_energy_a; __le32 beacon_energy_b; __le32 beacon_energy_c; -} __attribute__ ((packed)); +} __packed; + +struct statistics_rx_non_phy_bt { + struct statistics_rx_non_phy common; + /* additional stats for bt */ + __le32 num_bt_kills; + __le32 reserved[2]; +} __packed; struct statistics_rx { struct statistics_rx_phy ofdm; struct statistics_rx_phy cck; struct statistics_rx_non_phy general; struct statistics_rx_ht_phy ofdm_ht; -} __attribute__ ((packed)); +} __packed; + +struct statistics_rx_bt { + struct statistics_rx_phy ofdm; + struct statistics_rx_phy cck; + struct statistics_rx_non_phy_bt general; + struct statistics_rx_ht_phy ofdm_ht; +} __packed; /** * struct statistics_tx_power - current tx power @@ -3096,7 +3160,7 @@ struct statistics_tx_power { u8 ant_b; u8 ant_c; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct statistics_tx_non_phy_agg { __le32 ba_timeout; @@ -3109,7 +3173,7 @@ struct statistics_tx_non_phy_agg { __le32 underrun; __le32 bt_prio_kill; __le32 rx_ba_rsp_cnt; -} __attribute__ ((packed)); +} __packed; struct statistics_tx { __le32 preamble_cnt; @@ -3134,7 +3198,7 @@ struct statistics_tx { */ struct statistics_tx_power tx_power; __le32 reserved1; -} __attribute__ ((packed)); +} __packed; struct statistics_div { @@ -3144,9 +3208,9 @@ struct statistics_div { __le32 probe_time; __le32 reserved1; __le32 reserved2; -} __attribute__ ((packed)); +} __packed; -struct statistics_general { +struct statistics_general_common { __le32 temperature; /* radio temperature */ __le32 temperature_m; /* for 5000 and up, this is radio voltage */ struct statistics_dbg dbg; @@ -3162,9 +3226,33 @@ struct statistics_general { * in order to get out of bad PHY status */ __le32 num_of_sos_states; +} __packed; + +struct statistics_bt_activity { + /* Tx statistics */ + __le32 hi_priority_tx_req_cnt; + __le32 hi_priority_tx_denied_cnt; + __le32 lo_priority_tx_req_cnt; + __le32 lo_priority_tx_denied_cnt; + /* Rx statistics */ + __le32 hi_priority_rx_req_cnt; + __le32 hi_priority_rx_denied_cnt; + __le32 lo_priority_rx_req_cnt; + __le32 lo_priority_rx_denied_cnt; +} __packed; + +struct statistics_general { + struct statistics_general_common common; __le32 reserved2; __le32 reserved3; -} __attribute__ ((packed)); +} __packed; + +struct statistics_general_bt { + struct statistics_general_common common; + struct statistics_bt_activity activity; + __le32 reserved2; + __le32 reserved3; +} __packed; #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) @@ -3189,7 +3277,7 @@ struct statistics_general { #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ struct iwl_statistics_cmd { __le32 configuration_flags; /* IWL_STATS_CONF_* */ -} __attribute__ ((packed)); +} __packed; /* * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) @@ -3214,15 +3302,21 @@ struct iwl3945_notif_statistics { struct iwl39_statistics_rx rx; struct iwl39_statistics_tx tx; struct iwl39_statistics_general general; -} __attribute__ ((packed)); +} __packed; struct iwl_notif_statistics { __le32 flag; struct statistics_rx rx; struct statistics_tx tx; struct statistics_general general; -} __attribute__ ((packed)); +} __packed; +struct iwl_bt_notif_statistics { + __le32 flag; + struct statistics_rx_bt rx; + struct statistics_tx tx; + struct statistics_general_bt general; +} __packed; /* * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) @@ -3253,7 +3347,7 @@ struct iwl_missed_beacon_notif { __le32 total_missed_becons; __le32 num_expected_beacons; __le32 num_recvd_beacons; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** @@ -3441,6 +3535,41 @@ struct iwl_missed_beacon_notif { #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) #define HD_OFDM_ENERGY_TH_IN_INDEX (10) +/* + * Additional table entries in enhance SENSITIVITY_CMD + */ +#define HD_INA_NON_SQUARE_DET_OFDM_INDEX (11) +#define HD_INA_NON_SQUARE_DET_CCK_INDEX (12) +#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX (13) +#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX (14) +#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (15) +#define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX (16) +#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX (17) +#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX (18) +#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (19) +#define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX (20) +#define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX (21) +#define HD_RESERVED (22) + +/* number of entries for enhanced tbl */ +#define ENHANCE_HD_TABLE_SIZE (23) + +/* number of additional entries for enhanced tbl */ +#define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) + +#define HD_INA_NON_SQUARE_DET_OFDM_DATA cpu_to_le16(0) +#define HD_INA_NON_SQUARE_DET_CCK_DATA cpu_to_le16(0) +#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA cpu_to_le16(0) +#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(668) +#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) +#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(486) +#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(37) +#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(853) +#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) +#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(476) +#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(99) + + /* Control field in struct iwl_sensitivity_cmd */ #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) #define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) @@ -3455,7 +3584,15 @@ struct iwl_missed_beacon_notif { struct iwl_sensitivity_cmd { __le16 control; /* always use "1" */ __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ -} __attribute__ ((packed)); +} __packed; + +/* + * + */ +struct iwl_enhance_sensitivity_cmd { + __le16 control; /* always use "1" */ + __le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */ +} __packed; /** @@ -3523,10 +3660,10 @@ enum { IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, - IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18, - IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19, + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18, }; +#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) @@ -3536,31 +3673,31 @@ struct iwl_calib_cfg_elmnt_s { __le32 send_res; __le32 apply_res; __le32 reserved; -} __attribute__ ((packed)); +} __packed; struct iwl_calib_cfg_status_s { struct iwl_calib_cfg_elmnt_s once; struct iwl_calib_cfg_elmnt_s perd; __le32 flags; -} __attribute__ ((packed)); +} __packed; struct iwl_calib_cfg_cmd { struct iwl_calib_cfg_status_s ucd_calib_cfg; struct iwl_calib_cfg_status_s drv_calib_cfg; __le32 reserved1; -} __attribute__ ((packed)); +} __packed; struct iwl_calib_hdr { u8 op_code; u8 first_group; u8 groups_num; u8 data_valid; -} __attribute__ ((packed)); +} __packed; struct iwl_calib_cmd { struct iwl_calib_hdr hdr; u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ struct iwl_calib_diff_gain_cmd { @@ -3569,14 +3706,14 @@ struct iwl_calib_diff_gain_cmd { s8 diff_gain_b; s8 diff_gain_c; u8 reserved1; -} __attribute__ ((packed)); +} __packed; struct iwl_calib_xtal_freq_cmd { struct iwl_calib_hdr hdr; u8 cap_pin1; u8 cap_pin2; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ struct iwl_calib_chain_noise_reset_cmd { @@ -3590,7 +3727,7 @@ struct iwl_calib_chain_noise_gain_cmd { u8 delta_gain_1; u8 delta_gain_2; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** * (12) @@ -3613,7 +3750,7 @@ struct iwl_led_cmd { u8 on; /* # intervals on while blinking; * "0", regardless of "off", turns LED off */ u8 reserved; -} __attribute__ ((packed)); +} __packed; /* * station priority table entries @@ -3749,7 +3886,7 @@ struct iwl_wimax_coex_event_entry { u8 win_medium_prio; u8 reserved; u8 flags; -} __attribute__ ((packed)); +} __packed; /* COEX flag masks */ @@ -3766,7 +3903,7 @@ struct iwl_wimax_coex_cmd { u8 flags; u8 reserved[3]; struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS]; -} __attribute__ ((packed)); +} __packed; /* * Coexistence MEDIUM NOTIFICATION @@ -3795,7 +3932,7 @@ struct iwl_wimax_coex_cmd { struct iwl_coex_medium_notification { __le32 status; __le32 events; -} __attribute__ ((packed)); +} __packed; /* * Coexistence EVENT Command @@ -3810,11 +3947,11 @@ struct iwl_coex_event_cmd { u8 flags; u8 event; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwl_coex_event_resp { __le32 status; -} __attribute__ ((packed)); +} __packed; /****************************************************************************** @@ -3851,6 +3988,7 @@ struct iwl_rx_packet { struct iwl_sleep_notification sleep_notif; struct iwl_spectrum_resp spectrum; struct iwl_notif_statistics stats; + struct iwl_bt_notif_statistics stats_bt; struct iwl_compressed_ba_resp compressed_ba; struct iwl_missed_beacon_notif missed_beacon; struct iwl_coex_medium_notification coex_medium_notif; @@ -3858,7 +3996,7 @@ struct iwl_rx_packet { __le32 status; u8 raw[0]; } u; -} __attribute__ ((packed)); +} __packed; int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 426e95567de..8024d44ce4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -141,13 +141,14 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) } EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) { int i; u8 ind = ant; + for (i = 0; i < RATE_ANT_NUM - 1; i++) { ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; - if (priv->hw_params.valid_tx_ant & BIT(ind)) + if (valid & BIT(ind)) return ind; } return ant; @@ -169,7 +170,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, struct ieee80211_hw *hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); if (hw == NULL) { - printk(KERN_ERR "%s: Can not allocate network device\n", + pr_err("%s: Can not allocate network device\n", cfg->name); goto out; } @@ -457,7 +458,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, if (!sta_ht_inf->ht_supported) return 0; } -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS if (priv->disable_ht40) return 0; #endif @@ -506,11 +507,11 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) } beacon_int = iwl_adjust_beacon_interval(beacon_int, - priv->hw_params.max_beacon_itrvl * 1024); + priv->hw_params.max_beacon_itrvl * TIME_UNIT); priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ - interval_tm = beacon_int * 1024; + interval_tm = beacon_int * TIME_UNIT; rem = do_div(tsf, interval_tm); priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); @@ -932,9 +933,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) } EXPORT_SYMBOL(iwl_set_rxon_channel); -static void iwl_set_flags_for_band(struct iwl_priv *priv, - enum ieee80211_band band, - struct ieee80211_vif *vif) +void iwl_set_flags_for_band(struct iwl_priv *priv, + enum ieee80211_band band, + struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { priv->staging_rxon.flags &= @@ -943,19 +944,17 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv, priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { /* Copied from iwl_post_associate() */ - if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) + if (vif && vif->bss_conf.use_short_slot) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - if (vif && vif->type == NL80211_IFTYPE_ADHOC) - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; } } +EXPORT_SYMBOL(iwl_set_flags_for_band); /* * initialize rxon structure with default values from eeprom @@ -1021,15 +1020,17 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, /* clear both MIX and PURE40 mode flag */ priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); + + if (vif) + memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN); + priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; } EXPORT_SYMBOL(iwl_connection_init_rx_config); -static void iwl_set_rate(struct iwl_priv *priv) +void iwl_set_rate(struct iwl_priv *priv) { const struct ieee80211_supported_band *hw = NULL; struct ieee80211_rate *rate; @@ -1057,6 +1058,21 @@ static void iwl_set_rate(struct iwl_priv *priv) priv->staging_rxon.ofdm_basic_rates = (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } +EXPORT_SYMBOL(iwl_set_rate); + +void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->switch_rxon.switch_in_progress) { + ieee80211_chswitch_done(priv->vif, is_success); + mutex_lock(&priv->mutex); + priv->switch_rxon.switch_in_progress = false; + mutex_unlock(&priv->mutex); + } +} +EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -1071,11 +1087,12 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) priv->staging_rxon.channel = csa->channel; IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); - } else + iwl_chswitch_done(priv, true); + } else { IWL_ERR(priv, "CSA notif (fail) : channel %d\n", le16_to_cpu(csa->channel)); - - priv->switch_rxon.switch_in_progress = false; + iwl_chswitch_done(priv, false); + } } } EXPORT_SYMBOL(iwl_rx_csa); @@ -1314,7 +1331,6 @@ void iwl_configure_filter(struct ieee80211_hw *hw, changed_flags, *total_flags); CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); - CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK); CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); @@ -1329,6 +1345,12 @@ void iwl_configure_filter(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); + /* + * Receiving all multicast frames is always enabled by the + * default flags setup in iwl_connection_init_rx_config() + * since we currently do not support programming multicast + * filters into the device. + */ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; } @@ -1502,130 +1524,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) } EXPORT_SYMBOL(iwl_send_statistics_request); -/** - * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, - * using sample data 100 bytes apart. If these sample points are good, - * it's a pretty good bet that everything between them is good, too. - */ -static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) -{ - u32 val; - int ret = 0; - u32 errcnt = 0; - u32 i; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - i + IWL49_RTC_INST_LOWER_BOUND); - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { - ret = -EIO; - errcnt++; - if (errcnt >= 3) - break; - } - } - - return ret; -} - -/** - * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host, - * looking at all data. - */ -static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, - u32 len) -{ - u32 val; - u32 save_len = len; - int ret = 0; - u32 errcnt; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - IWL49_RTC_INST_LOWER_BOUND); - - errcnt = 0; - for (; len > 0; len -= sizeof(u32), image++) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - save_len - len, val, le32_to_cpu(*image)); - ret = -EIO; - errcnt++; - if (errcnt >= 20) - break; - } - } - - if (!errcnt) - IWL_DEBUG_INFO(priv, - "ucode image in INSTRUCTION memory is good\n"); - - return ret; -} - -/** - * iwl_verify_ucode - determine which instruction image is in SRAM, - * and verify its contents - */ -int iwl_verify_ucode(struct iwl_priv *priv) -{ - __le32 *image; - u32 len; - int ret; - - /* Try bootstrap */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { - IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); - return 0; - } - - /* Try initialize */ - image = (__le32 *)priv->ucode_init.v_addr; - len = priv->ucode_init.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { - IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); - return 0; - } - - /* Try runtime/protocol */ - image = (__le32 *)priv->ucode_code.v_addr; - len = priv->ucode_code.len; - ret = iwlcore_verify_inst_sparse(priv, image, len); - if (!ret) { - IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); - return 0; - } - - IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - - /* Since nothing seems to match, show first several data entries in - * instruction SRAM, so maybe visual inspection will give a clue. - * Selection of bootstrap image (vs. other images) is arbitrary. */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - ret = iwl_verify_inst_full(priv, image, len); - - return ret; -} -EXPORT_SYMBOL(iwl_verify_ucode); - - void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; @@ -1850,6 +1748,37 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv) iwlcore_commit_rxon(priv); } +static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->ibss_beacon) + dev_kfree_skb(priv->ibss_beacon); + + priv->ibss_beacon = skb; + + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + priv->cfg->ops->lib->post_associate(priv, priv->vif); + + return 0; +} + void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -1865,6 +1794,15 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (changes & BSS_CHANGED_QOS) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + priv->qos_data.qos_active = bss_conf->qos; + iwl_update_qos(priv); + spin_unlock_irqrestore(&priv->lock, flags); + } + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = ieee80211_beacon_get(hw, vif); @@ -2007,38 +1945,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_bss_info_changed); -int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = skb; - - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - priv->cfg->ops->lib->post_associate(priv, priv->vif); - - return 0; -} -EXPORT_SYMBOL(iwl_mac_beacon_update); - static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { iwl_connection_init_rx_config(priv, vif); @@ -2046,8 +1952,6 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv); - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - return iwlcore_commit_rxon(priv); } @@ -2056,7 +1960,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct iwl_priv *priv = hw->priv; int err = 0; - IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type); + IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", + vif->type, vif->addr); mutex_lock(&priv->mutex); @@ -2074,9 +1979,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) priv->vif = vif; priv->iw_mode = vif->type; - IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); - memcpy(priv->mac_addr, vif->addr, ETH_ALEN); - err = iwl_set_mode(priv, vif); if (err) goto out_err; @@ -2110,6 +2012,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } if (priv->vif == vif) { priv->vif = NULL; + if (priv->scan_vif == vif) { + ieee80211_scan_completed(priv->hw, true); + priv->scan_vif = NULL; + priv->scan_request = NULL; + } memset(priv->bssid, 0, ETH_ALEN); } mutex_unlock(&priv->mutex); @@ -2210,22 +2117,10 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) iwl_set_flags_for_band(priv, conf->channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); - if (iwl_is_associated(priv) && - (le16_to_cpu(priv->active_rxon.channel) != ch) && - priv->cfg->ops->lib->set_channel_switch) { - iwl_set_rate(priv); - /* - * at this point, staging_rxon has the - * configuration for channel switch - */ - ret = priv->cfg->ops->lib->set_channel_switch(priv, - ch); - if (!ret) { - iwl_print_rx_config_cmd(priv); - goto out; - } - priv->switch_rxon.switch_in_progress = false; - } + + if (priv->cfg->ops->lib->update_bcast_station) + ret = priv->cfg->ops->lib->update_bcast_station(priv); + set_ch_out: /* The list of supported rates and rate mask can be different * for each band; since the band may have changed, reset @@ -2247,15 +2142,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) iwl_set_tx_power(priv, conf->power_level, false); } - if (changed & IEEE80211_CONF_CHANGE_QOS) { - bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS); - - spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.qos_active = qos_active; - iwl_update_qos(priv); - spin_unlock_irqrestore(&priv->lock, flags); - } - if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; @@ -2583,7 +2469,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_update_stats); #endif -const static char *get_csr_string(int cmd) +static const char *get_csr_string(int cmd) { switch (cmd) { IWL_CMD(CSR_HW_IF_CONFIG_REG); @@ -2654,7 +2540,7 @@ void iwl_dump_csr(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_dump_csr); -const static char *get_fh_string(int cmd) +static const char *get_fh_string(int cmd) { switch (cmd) { IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); @@ -2740,7 +2626,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv) } -int iwl_force_reset(struct iwl_priv *priv, int mode) +int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) { struct iwl_force_reset *force_reset; @@ -2753,12 +2639,14 @@ int iwl_force_reset(struct iwl_priv *priv, int mode) } force_reset = &priv->force_reset[mode]; force_reset->reset_request_count++; - if (force_reset->last_force_reset_jiffies && - time_after(force_reset->last_force_reset_jiffies + - force_reset->reset_duration, jiffies)) { - IWL_DEBUG_INFO(priv, "force reset rejected\n"); - force_reset->reset_reject_count++; - return -EAGAIN; + if (!external) { + if (force_reset->last_force_reset_jiffies && + time_after(force_reset->last_force_reset_jiffies + + force_reset->reset_duration, jiffies)) { + IWL_DEBUG_INFO(priv, "force reset rejected\n"); + force_reset->reset_reject_count++; + return -EAGAIN; + } } force_reset->reset_success_count++; force_reset->last_force_reset_jiffies = jiffies; @@ -2768,6 +2656,19 @@ int iwl_force_reset(struct iwl_priv *priv, int mode) iwl_force_rf_reset(priv); break; case IWL_FW_RESET: + /* + * if the request is from external(ex: debugfs), + * then always perform the request in regardless the module + * parameter setting + * if the request is from internal (uCode error or driver + * detect failure), then fw_restart module parameter + * need to be check before performing firmware reload + */ + if (!external && !priv->cfg->mod_params->restart_fw) { + IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " + "module parameter setting\n"); + break; + } IWL_ERR(priv, "On demand firmware reload\n"); /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->status); @@ -2826,7 +2727,7 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) "queue %d stuck %d time. Fw reload.\n", q->id, q->repeat_same_read_ptr); q->repeat_same_read_ptr = 0; - iwl_force_reset(priv, IWL_FW_RESET); + iwl_force_reset(priv, IWL_FW_RESET, false); } else { q->repeat_same_read_ptr++; IWL_DEBUG_RADIO(priv, @@ -2876,6 +2777,61 @@ void iwl_bg_monitor_recover(unsigned long data) } EXPORT_SYMBOL(iwl_bg_monitor_recover); + +/* + * extended beacon time format + * time in usec will be changed into a 32-bit value in extended:internal format + * the extended part is the beacon counts + * the internal part is the time in usec within one beacon interval + */ +u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) +{ + u32 quot; + u32 rem; + u32 interval = beacon_interval * TIME_UNIT; + + if (!interval || !usec) + return 0; + + quot = (usec / interval) & + (iwl_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits) >> + priv->hw_params.beacon_time_tsf_bits); + rem = (usec % interval) & iwl_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + + return (quot << priv->hw_params.beacon_time_tsf_bits) + rem; +} +EXPORT_SYMBOL(iwl_usecs_to_beacons); + +/* base is usually what we get from ucode with each received frame, + * the same as HW timer counter counting down + */ +__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, + u32 addon, u32 beacon_interval) +{ + u32 base_low = base & iwl_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + u32 addon_low = addon & iwl_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + u32 interval = beacon_interval * TIME_UNIT; + u32 res = (base & iwl_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits)) + + (addon & iwl_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits)); + + if (base_low > addon_low) + res += base_low - addon_low; + else if (base_low < addon_low) { + res += interval + base_low - addon_low; + res += (1 << priv->hw_params.beacon_time_tsf_bits); + } else + res += (1 << priv->hw_params.beacon_time_tsf_bits); + + return cpu_to_le32(res); +} +EXPORT_SYMBOL(iwl_add_beacon_time); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) @@ -2903,6 +2859,7 @@ int iwl_pci_resume(struct pci_dev *pdev) { struct iwl_priv *priv = pci_get_drvdata(pdev); int ret; + bool hw_rfkill = false; /* * We disable the RETRY_TIMEOUT register (0x41) to keep @@ -2917,6 +2874,17 @@ int iwl_pci_resume(struct pci_dev *pdev) pci_restore_state(pdev); iwl_enable_interrupts(priv); + if (!(iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) + hw_rfkill = true; + + if (hw_rfkill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rfkill); + return 0; } EXPORT_SYMBOL(iwl_pci_resume); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 31775bd9c36..e9d23f2f869 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -79,6 +79,8 @@ struct iwl_cmd; .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ .driver_data = (kernel_ulong_t)&(cfg) +#define TIME_UNIT 1024 + #define IWL_SKU_G 0x1 #define IWL_SKU_A 0x2 #define IWL_SKU_N 0x8 @@ -123,6 +125,8 @@ struct iwl_debugfs_ops { size_t count, loff_t *ppos); ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); + ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); }; struct iwl_temp_ops { @@ -173,7 +177,8 @@ struct iwl_lib_ops { void (*dump_nic_error_log)(struct iwl_priv *priv); void (*dump_csr)(struct iwl_priv *priv); int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); - int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); + int (*set_channel_switch)(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch); /* power management */ struct iwl_apm_ops apm_ops; @@ -193,6 +198,7 @@ struct iwl_lib_ops { /* station management */ int (*manage_ibss_station)(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); + int (*update_bcast_station)(struct iwl_priv *priv); /* recover from tx queue stall */ void (*recover_from_tx_stall)(unsigned long data); /* check for plcp health */ @@ -201,6 +207,9 @@ struct iwl_lib_ops { /* check for ack health */ bool (*check_ack_health)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); + int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); + void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); + struct iwl_debugfs_ops debugfs_ops; }; @@ -325,7 +334,10 @@ struct iwl_cfg { const bool ucode_tracing; const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; - u8 scan_antennas[IEEE80211_NUM_BANDS]; + u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; + u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + const bool need_dc_calib; + const bool bt_statistics; }; /*************************** @@ -343,6 +355,9 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv); int iwl_full_rxon_required(struct iwl_priv *priv); void iwl_set_rxon_chain(struct iwl_priv *priv); int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); +void iwl_set_flags_for_band(struct iwl_priv *priv, + enum ieee80211_band band, + struct ieee80211_vif *vif); u8 iwl_get_single_channel_number(struct iwl_priv *priv, enum ieee80211_band band); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); @@ -350,6 +365,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *sta_ht_inf); void iwl_connection_init_rx_config(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwl_set_rate(struct iwl_priv *priv); int iwl_set_decrypted_flag(struct iwl_priv *priv, struct ieee80211_hdr *hdr, u32 decrypt_res, @@ -364,7 +380,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); int iwl_commit_rxon(struct iwl_priv *priv); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); @@ -447,20 +462,11 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, int iwl_rx_queue_space(const struct iwl_rx_queue *q); void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* Handlers */ -void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); -bool iwl_good_ack_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt); -void iwl_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); +void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* TX helpers */ @@ -474,8 +480,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, dma_addr_t addr, u16 len, u8 reset, u8 pad); int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq); -void iwl_free_tfds_in_queue(struct iwl_priv *priv, - int sta_id, int tid, int freed); void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); @@ -495,7 +499,7 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx); +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) { @@ -526,9 +530,9 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); void iwl_bg_start_internal_scan(struct work_struct *work); void iwl_internal_short_hw_scan(struct iwl_priv *priv); -int iwl_force_reset(struct iwl_priv *priv, int mode); +int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ie, int ie_len, int left); + const u8 *ta, const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); u16 iwl_get_active_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -595,6 +599,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) } void iwl_bg_monitor_recover(unsigned long data); +u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); +__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, + u32 addon, u32 beacon_interval); #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); @@ -693,7 +700,6 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); -extern int iwl_verify_ucode(struct iwl_priv *priv); extern int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_link_quality_cmd *lq, u8 flags, bool init); void iwl_apm_stop(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 254c35ae8b3..ecf98e7ac4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -298,6 +298,7 @@ #define CSR_HW_REV_TYPE_1000 (0x0000060) #define CSR_HW_REV_TYPE_6x00 (0x0000070) #define CSR_HW_REV_TYPE_6x50 (0x0000080) +#define CSR_HW_REV_TYPE_6x50g2 (0x0000084) #define CSR_HW_REV_TYPE_6x00g2 (0x00000B0) #define CSR_HW_REV_TYPE_NONE (0x00000F0) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9659c5d01df..e96a1bb1278 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -106,27 +106,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .open = iwl_dbgfs_open_file_generic, \ }; -int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) -{ - int p = 0; - - p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", - le32_to_cpu(priv->statistics.flag)); - if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK) - p += scnprintf(buf + p, bufsz - p, - "\tStatistics have been cleared\n"); - p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", - (le32_to_cpu(priv->statistics.flag) & - UCODE_STATISTICS_FREQUENCY_MSK) - ? "2.4 GHz" : "5.2 GHz"); - p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", - (le32_to_cpu(priv->statistics.flag) & - UCODE_STATISTICS_NARROW_BAND_MSK) - ? "enabled" : "disabled"); - return p; -} -EXPORT_SYMBOL(iwl_dbgfs_statistics_flag); - static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -330,45 +309,35 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, for (i = 0; i < max_sta; i++) { station = &priv->stations[i]; - if (station->used) { - pos += scnprintf(buf + pos, bufsz - pos, - "station %d:\ngeneral data:\n", i+1); - pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", - station->sta.sta.sta_id); - pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", - station->sta.mode); - pos += scnprintf(buf + pos, bufsz - pos, - "flags: 0x%x\n", - station->sta.station_flags_msk); - pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "seq_num\t\ttxq_id"); - pos += scnprintf(buf + pos, bufsz - pos, - "\tframe_count\twait_for_ba\t"); - pos += scnprintf(buf + pos, bufsz - pos, - "start_idx\tbitmap0\t"); - pos += scnprintf(buf + pos, bufsz - pos, - "bitmap1\trate_n_flags"); - pos += scnprintf(buf + pos, bufsz - pos, "\n"); + if (!station->used) + continue; + pos += scnprintf(buf + pos, bufsz - pos, + "station %d - addr: %pM, flags: %#x\n", + i, station->sta.sta.addr, + station->sta.station_flags_msk); + pos += scnprintf(buf + pos, bufsz - pos, + "TID\tseq_num\ttxq_id\tframes\ttfds\t"); + pos += scnprintf(buf + pos, bufsz - pos, + "start_idx\tbitmap\t\t\trate_n_flags\n"); - for (j = 0; j < MAX_TID_COUNT; j++) { - pos += scnprintf(buf + pos, bufsz - pos, - "[%d]:\t\t%u", j, - station->tid[j].seq_number); - pos += scnprintf(buf + pos, bufsz - pos, - "\t%u\t\t%u\t\t%u\t\t", - station->tid[j].agg.txq_id, - station->tid[j].agg.frame_count, - station->tid[j].agg.wait_for_ba); + for (j = 0; j < MAX_TID_COUNT; j++) { + pos += scnprintf(buf + pos, bufsz - pos, + "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", + j, station->tid[j].seq_number, + station->tid[j].agg.txq_id, + station->tid[j].agg.frame_count, + station->tid[j].tfds_in_queue, + station->tid[j].agg.start_idx, + station->tid[j].agg.bitmap, + station->tid[j].agg.rate_n_flags); + + if (station->tid[j].agg.wait_for_ba) pos += scnprintf(buf + pos, bufsz - pos, - "%u\t%llu\t%u", - station->tid[j].agg.start_idx, - (unsigned long long)station->tid[j].agg.bitmap, - station->tid[j].agg.rate_n_flags); - pos += scnprintf(buf + pos, bufsz - pos, "\n"); - } + " - waitforba"); pos += scnprintf(buf + pos, bufsz - pos, "\n"); } + + pos += scnprintf(buf + pos, bufsz - pos, "\n"); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -1049,8 +1018,13 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, rxq->write); pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", rxq->free_count); - pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", + if (rxq->rb_stts) { + pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); + } else { + pos += scnprintf(buf + pos, bufsz - pos, + "closed_rb_num: Not Allocated\n"); + } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1293,7 +1267,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + struct iwl_priv *priv = file->private_data; int pos = 0; char buf[128]; const size_t bufsz = sizeof(buf); @@ -1343,7 +1317,7 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + struct iwl_priv *priv = file->private_data; int len = 0; char buf[20]; @@ -1355,7 +1329,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + struct iwl_priv *priv = file->private_data; int len = 0; char buf[20]; @@ -1368,7 +1342,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + struct iwl_priv *priv = file->private_data; char *buf; int pos = 0; ssize_t ret = -EFAULT; @@ -1430,7 +1404,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + struct iwl_priv *priv = file->private_data; int pos = 0; char buf[12]; const size_t bufsz = sizeof(buf); @@ -1456,10 +1430,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, return -EFAULT; if (sscanf(buf, "%d", &plcp) != 1) return -EINVAL; - if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || + if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) priv->cfg->plcp_delta_threshold = - IWL_MAX_PLCP_ERR_THRESHOLD_DEF; + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; else priv->cfg->plcp_delta_threshold = plcp; return count; @@ -1513,7 +1487,7 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file, switch (reset) { case IWL_RF_RESET: case IWL_FW_RESET: - ret = iwl_force_reset(priv, reset); + ret = iwl_force_reset(priv, reset, true); break; default: return -EINVAL; @@ -1521,6 +1495,40 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file, return ret ? ret : count; } +static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int flush; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &flush) != 1) + return -EINVAL; + + if (iwl_is_rfkill(priv)) + return -EFAULT; + + priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); + + return count; +} + +static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + + return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file, + user_buf, count, ppos); +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1542,6 +1550,8 @@ DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); DEBUGFS_READ_WRITE_FILE_OPS(force_reset); DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); +DEBUGFS_WRITE_FILE_OPS(txfifo_flush); +DEBUGFS_READ_FILE_OPS(ucode_bt_stats); /* * Create the debugfs files and directories @@ -1600,6 +1610,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); + if (priv->cfg->ops->lib->dev_txfifo_flush) + DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); if (priv->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); @@ -1607,6 +1619,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); + if (priv->cfg->bt_statistics) + DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); if (priv->cfg->sensitivity_calib_by_driver) diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f3f3473c5c7..f35bcad56e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -48,25 +48,6 @@ #include "iwl-power.h" #include "iwl-agn-rs.h" -/* configuration for the iwl4965 */ -extern struct iwl_cfg iwl4965_agn_cfg; -extern struct iwl_cfg iwl5300_agn_cfg; -extern struct iwl_cfg iwl5100_agn_cfg; -extern struct iwl_cfg iwl5350_agn_cfg; -extern struct iwl_cfg iwl5100_bgn_cfg; -extern struct iwl_cfg iwl5100_abg_cfg; -extern struct iwl_cfg iwl5150_agn_cfg; -extern struct iwl_cfg iwl5150_abg_cfg; -extern struct iwl_cfg iwl6000g2a_2agn_cfg; -extern struct iwl_cfg iwl6000i_2agn_cfg; -extern struct iwl_cfg iwl6000i_2abg_cfg; -extern struct iwl_cfg iwl6000i_2bg_cfg; -extern struct iwl_cfg iwl6000_3agn_cfg; -extern struct iwl_cfg iwl6050_2agn_cfg; -extern struct iwl_cfg iwl6050_2abg_cfg; -extern struct iwl_cfg iwl1000_bgn_cfg; -extern struct iwl_cfg iwl1000_bg_cfg; - struct iwl_tx_queue; /* CT-KILL constants */ @@ -133,8 +114,8 @@ struct iwl_cmd_meta { * structure is stored at the end of the shared queue memory. */ u32 flags; - DECLARE_PCI_UNMAP_ADDR(mapping) - DECLARE_PCI_UNMAP_LEN(len) + DEFINE_DMA_UNMAP_ADDR(mapping); + DEFINE_DMA_UNMAP_LEN(len); }; /* @@ -157,11 +138,11 @@ struct iwl_queue { * space more than this */ int high_mark; /* high watermark, stop queue if free * space less than this */ -} __attribute__ ((packed)); +} __packed; /* One for each TFD */ struct iwl_tx_info { - struct sk_buff *skb[IWL_NUM_OF_TBS - 1]; + struct sk_buff *skb; }; /** @@ -343,8 +324,8 @@ struct iwl_device_cmd { struct iwl_tx_cmd tx; struct iwl6000_channel_switch_cmd chswitch; u8 payload[DEF_CMD_PAYLOAD_SIZE]; - } __attribute__ ((packed)) cmd; -} __attribute__ ((packed)); + } __packed cmd; +} __packed; #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) @@ -367,7 +348,7 @@ struct iwl_host_cmd { /** * struct iwl_rx_queue - Rx queue * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) - * @dma_addr: bus address of buffer of receive buffer descriptors (rbd) + * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) * @read: Shared index to newest available Rx buffer * @write: Shared index to oldest written Rx packet * @free_count: Number of pre-allocated buffers in rx_free @@ -381,7 +362,7 @@ struct iwl_host_cmd { */ struct iwl_rx_queue { __le32 *bd; - dma_addr_t dma_addr; + dma_addr_t bd_dma; struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; u32 read; @@ -433,7 +414,7 @@ struct iwl_ht_agg { struct iwl_tid_data { - u16 seq_number; + u16 seq_number; /* agn only */ u16 tfds_in_queue; struct iwl_ht_agg agg; }; @@ -583,6 +564,14 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_INIT_DATA = 4, IWL_UCODE_TLV_BOOT = 5, IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, + IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, + IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, + IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, + IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, + IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, + IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, + IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, }; struct iwl_ucode_tlv { @@ -590,7 +579,7 @@ struct iwl_ucode_tlv { __le16 alternative; /* see comment */ __le32 length; /* not including type/length fields */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define IWL_TLV_UCODE_MAGIC 0x0a4c5749 @@ -675,6 +664,7 @@ struct iwl_sensitivity_ranges { * @sw_crypto: 0 for hw, 1 for sw * @max_xxx_size: for ucode uses * @ct_kill_threshold: temperature threshold + * @beacon_time_tsf_bits: number of valid tsf bits for beacon time * @calib_init_cfg: setup initial calibrations for the hw * @struct iwl_sensitivity_ranges: range of sensitivity values */ @@ -701,6 +691,7 @@ struct iwl_hw_params { u32 ct_kill_threshold; /* value in hw-dependent units */ u32 ct_kill_exit_threshold; /* value in hw-dependent units */ /* for 1000, 6000 series and up */ + u16 beacon_time_tsf_bits; u32 calib_init_cfg; const struct iwl_sensitivity_ranges *sens; }; @@ -1047,11 +1038,12 @@ struct iwl_event_log { * This is the threshold value of plcp error rate per 100mSecs. It is * used to set and check for the validity of plcp_delta. */ -#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0) +#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) #define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) #define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) #define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) #define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) @@ -1075,6 +1067,20 @@ struct iwl_force_reset { unsigned long last_force_reset_jiffies; }; +/* extend beacon time format bit shifting */ +/* + * for _3945 devices + * bits 31:24 - extended + * bits 23:0 - interval + */ +#define IWL3945_EXT_BEACON_TIME_POS 24 +/* + * for _agn devices + * bits 31:22 - extended + * bits 21:0 - interval + */ +#define IWLAGN_EXT_BEACON_TIME_POS 22 + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1109,7 +1115,7 @@ struct iwl_priv { /* force reset */ struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; - /* we allocate array of iwl4965_channel_info for NIC's valid channels. + /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ struct iwl_channel_info *channel_info; /* channel info array */ u8 channel_count; /* # of channels */ @@ -1127,6 +1133,7 @@ struct iwl_priv { void *scan_cmd; enum ieee80211_band scan_band; struct cfg80211_scan_request *scan_request; + struct ieee80211_vif *scan_vif; bool is_internal_short_scan; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; @@ -1147,6 +1154,9 @@ struct iwl_priv { u32 hw_wa_rev; u8 rev_id; + /* EEPROM MAC addresses */ + struct mac_address addresses[2]; + /* uCode images, save to reload in case of failure */ int fw_index; /* firmware we're trying to load */ u32 ucode_ver; /* version of ucode, copy of @@ -1174,7 +1184,7 @@ struct iwl_priv { struct iwl_switch_rxon switch_rxon; /* 1st responses from initialize and runtime uCode images. - * 4965's initialize alive response contains some calibration data. */ + * _agn's initialize alive response contains some calibration data. */ struct iwl_init_alive_resp card_alive_init; struct iwl_alive_resp card_alive; @@ -1188,7 +1198,9 @@ struct iwl_priv { u8 start_calib; struct iwl_sensitivity_data sensitivity_data; struct iwl_chain_noise_data chain_noise_data; + bool enhance_sensitivity_table; __le16 sensitivity_tbl[HD_TABLE_SIZE]; + __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES]; struct iwl_ht_config current_ht_config; @@ -1220,18 +1232,12 @@ struct iwl_priv { struct iwl_power_mgr power_data; struct iwl_tt_mgmt thermal_throttle; - struct iwl_notif_statistics statistics; -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_notif_statistics accum_statistics; - struct iwl_notif_statistics delta_statistics; - struct iwl_notif_statistics max_delta; -#endif - /* context information */ u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ - u8 mac_addr[ETH_ALEN]; - /*station table variables */ + /* station table variables */ + + /* Note: if lock and sta_lock are needed, lock must be acquired first */ spinlock_t sta_lock; int num_stations; struct iwl_station_entry stations[IWL_STATION_COUNT]; @@ -1273,7 +1279,7 @@ struct iwl_priv { struct delayed_work rfkill_poll; struct iwl3945_notif_statistics statistics; -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl3945_notif_statistics accum_statistics; struct iwl3945_notif_statistics delta_statistics; struct iwl3945_notif_statistics max_delta; @@ -1315,6 +1321,28 @@ struct iwl_priv { bool last_phy_res_valid; struct completion firmware_loading_complete; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; + + /* + * chain noise reset and gain commands are the + * two extra calibration commands follows the standard + * phy calibration commands + */ + u8 phy_calib_chain_noise_reset_cmd; + u8 phy_calib_chain_noise_gain_cmd; + + struct iwl_notif_statistics statistics; + struct iwl_bt_notif_statistics statistics_bt; +#ifdef CONFIG_IWLWIFI_DEBUGFS + struct iwl_notif_statistics accum_statistics; + struct iwl_notif_statistics delta_statistics; + struct iwl_notif_statistics max_delta; + struct iwl_bt_notif_statistics accum_statistics_bt; + struct iwl_bt_notif_statistics delta_statistics_bt; + struct iwl_bt_notif_statistics max_delta_bt; +#endif } _agn; #endif }; @@ -1336,6 +1364,7 @@ struct iwl_priv { struct work_struct ct_enter; struct work_struct ct_exit; struct work_struct start_internal_scan; + struct work_struct tx_flush; struct tasklet_struct irq_tasklet; @@ -1353,9 +1382,7 @@ struct iwl_priv { /* debugging info */ u32 debug_level; /* per device debugging will override global iwl_debug_level if set */ - u32 framecnt_to_us; - atomic_t restrict_refcnt; - bool disable_ht40; +#endif /* CONFIG_IWLWIFI_DEBUG */ #ifdef CONFIG_IWLWIFI_DEBUGFS /* debugfs */ u16 tx_traffic_idx; @@ -1364,8 +1391,8 @@ struct iwl_priv { u8 *rx_traffic; struct dentry *debugfs_dir; u32 dbgfs_sram_offset, dbgfs_sram_len; + bool disable_ht40; #endif /* CONFIG_IWLWIFI_DEBUGFS */ -#endif /* CONFIG_IWLWIFI_DEBUG */ struct work_struct txpower_work; u32 disable_sens_cal; @@ -1419,9 +1446,9 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv) static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, int txq_id, int idx) { - if (priv->txq[txq_id].txb[idx].skb[0]) + if (priv->txq[txq_id].txb[idx].skb) return (struct ieee80211_hdr *)priv->txq[txq_id]. - txb[idx].skb[0]->data; + txb[idx].skb->data; return NULL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index ee11452519e..a45d02e555c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -629,6 +629,9 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) calib_ver < priv->cfg->eeprom_calib_ver) goto err; + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", + eeprom_ver, calib_ver); + return 0; err: IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 95aa202c85e..a4772aff51f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -118,7 +118,7 @@ enum { struct iwl_eeprom_channel { u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ -} __attribute__ ((packed)); +} __packed; /** * iwl_eeprom_enhanced_txpwr structure @@ -144,7 +144,7 @@ struct iwl_eeprom_enhanced_txpwr { s8 reserved; s8 mimo2_max; s8 mimo3_max; -} __attribute__ ((packed)); +} __packed; /* 3945 Specific */ #define EEPROM_3945_EEPROM_VERSION (0x2f) @@ -276,6 +276,10 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6050_TX_POWER_VERSION (4) #define EEPROM_6050_EEPROM_VERSION (0x532) +/* 6x50g2 Specific */ +#define EEPROM_6050G2_TX_POWER_VERSION (6) +#define EEPROM_6050G2_EEPROM_VERSION (0x553) + /* 6x00g2 Specific */ #define EEPROM_6000G2_TX_POWER_VERSION (6) #define EEPROM_6000G2_EEPROM_VERSION (0x709) @@ -312,7 +316,7 @@ struct iwl_eeprom_calib_measure { u8 gain_idx; /* Index into gain table */ u8 actual_pow; /* Measured RF output power, half-dBm */ s8 pa_det; /* Power amp detector level (not used) */ -} __attribute__ ((packed)); +} __packed; /* @@ -328,7 +332,7 @@ struct iwl_eeprom_calib_ch_info { struct iwl_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS] [EEPROM_TX_POWER_MEASUREMENTS]; -} __attribute__ ((packed)); +} __packed; /* * txpower subband info. @@ -345,7 +349,7 @@ struct iwl_eeprom_calib_subband_info { u8 ch_to; /* channel number of highest channel in subband */ struct iwl_eeprom_calib_ch_info ch1; struct iwl_eeprom_calib_ch_info ch2; -} __attribute__ ((packed)); +} __packed; /* @@ -374,7 +378,7 @@ struct iwl_eeprom_calib_info { __le16 voltage; /* signed */ struct iwl_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS]; -} __attribute__ ((packed)); +} __packed; #define ADDRESS_MSK 0x0000FFFF @@ -398,6 +402,7 @@ struct iwl_eeprom_calib_info { #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ #define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */ +#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 113c3669b9c..55b8370bc6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -398,12 +398,7 @@ */ #define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018) -#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) -#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16) - -#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) \ - (FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \ - FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl)) +#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) ((1 << (_chnl)) << 16) /* Tx service channels */ #define FH_SRVC_CHNL (9) @@ -449,7 +444,7 @@ struct iwl_rb_status { __le16 finished_rb_num; __le16 finished_fr_nam; __le32 __unused; /* 3945 only */ -} __attribute__ ((packed)); +} __packed; #define TFD_QUEUE_SIZE_MAX (256) @@ -475,7 +470,7 @@ static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr) struct iwl_tfd_tb { __le32 lo; __le16 hi_n_len; -} __attribute__((packed)); +} __packed; /** * struct iwl_tfd @@ -510,7 +505,7 @@ struct iwl_tfd { u8 num_tbs; struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS]; __le32 __pad; -} __attribute__ ((packed)); +} __packed; /* Keep Warm Size */ #define IWL_KW_SIZE 0x1000 /* 4k */ diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 51f89e7ba68..258d059ef41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -49,6 +49,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_ADD_STA); IWL_CMD(REPLY_REMOVE_STA); IWL_CMD(REPLY_REMOVE_ALL_STA); + IWL_CMD(REPLY_TXFIFO_FLUSH); IWL_CMD(REPLY_WEPKEY); IWL_CMD(REPLY_3945_RX); IWL_CMD(REPLY_TX); diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 3ff6b9d25a1..621abe3c5af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) { + if (!desc->len) { + desc->v_addr = NULL; + return -EINVAL; + } + desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, &desc->p_addr, GFP_KERNEL); return (desc->v_addr != NULL) ? 0 : -ENOMEM; @@ -170,4 +175,26 @@ static inline void iwl_enable_interrupts(struct iwl_priv *priv) iwl_write32(priv, CSR_INT_MASK, priv->inta_mask); } +/** + * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time + * @priv -- pointer to iwl_priv data structure + * @tsf_bits -- number of bits need to shift for masking) + */ +static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv, + u16 tsf_bits) +{ + return (1 << tsf_bits) - 1; +} + +/** + * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time + * @priv -- pointer to iwl_priv data structure + * @tsf_bits -- number of bits need to shift for masking) + */ +static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv, + u16 tsf_bits) +{ + return ((1 << (32 - tsf_bits)) - 1) << tsf_bits; +} + #endif /* __iwl_helpers_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 0a5d7cf2519..79773e353ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -175,7 +175,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) INIT_LIST_HEAD(&rxq->rx_used); /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr, + rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, GFP_KERNEL); if (!rxq->bd) goto err_bd; @@ -199,32 +199,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) err_rb: dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); + rxq->bd_dma); err_bd: return -ENOMEM; } EXPORT_SYMBOL(iwl_rx_queue_alloc); -void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) - -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_missed_beacon_notif *missed_beacon; - - missed_beacon = &pkt->u.missed_beacon; - if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > - priv->missed_beacon_threshold) { - IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", - le32_to_cpu(missed_beacon->consecutive_missed_beacons), - le32_to_cpu(missed_beacon->total_missed_becons), - le32_to_cpu(missed_beacon->num_recvd_beacons), - le32_to_cpu(missed_beacon->num_expected_beacons)); - if (!test_bit(STATUS_SCANNING, &priv->status)) - iwl_init_sensitivity(priv); - } -} -EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -243,161 +223,6 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); - - -/* Calculate noise level, based on measurements during network silence just - * before arriving beacon. This measurement can be done only if we know - * exactly when to expect beacons, therefore only when we're associated. */ -static void iwl_rx_calc_noise(struct iwl_priv *priv) -{ - struct statistics_rx_non_phy *rx_info - = &(priv->statistics.rx.general); - int num_active_rx = 0; - int total_silence = 0; - int bcn_silence_a = - le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; - int bcn_silence_b = - le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; - int bcn_silence_c = - le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; - int last_rx_noise; - - if (bcn_silence_a) { - total_silence += bcn_silence_a; - num_active_rx++; - } - if (bcn_silence_b) { - total_silence += bcn_silence_b; - num_active_rx++; - } - if (bcn_silence_c) { - total_silence += bcn_silence_c; - num_active_rx++; - } - - /* Average among active antennas */ - if (num_active_rx) - last_rx_noise = (total_silence / num_active_rx) - 107; - else - last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; - - IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", - bcn_silence_a, bcn_silence_b, bcn_silence_c, - last_rx_noise); -} - -#ifdef CONFIG_IWLWIFI_DEBUG -/* - * based on the assumption of all statistics counter are in DWORD - * FIXME: This function is for debugging, do not deal with - * the case of counters roll-over. - */ -static void iwl_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) -{ - int i; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - - prev_stats = (__le32 *)&priv->statistics; - accum_stats = (u32 *)&priv->accum_statistics; - delta = (u32 *)&priv->delta_statistics; - max_delta = (u32 *)&priv->max_delta; - - for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) - *max_delta = *delta; - } - } - - /* reset accumulative statistics for "no-counter" type statistics */ - priv->accum_statistics.general.temperature = - priv->statistics.general.temperature; - priv->accum_statistics.general.temperature_m = - priv->statistics.general.temperature_m; - priv->accum_statistics.general.ttl_timestamp = - priv->statistics.general.ttl_timestamp; - priv->accum_statistics.tx.tx_power.ant_a = - priv->statistics.tx.tx_power.ant_a; - priv->accum_statistics.tx.tx_power.ant_b = - priv->statistics.tx.tx_power.ant_b; - priv->accum_statistics.tx.tx_power.ant_c = - priv->statistics.tx.tx_power.ant_c; -} -#endif - -#define REG_RECALIB_PERIOD (60) - -/** - * iwl_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - combined_plcp_delta = - (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - - le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) + - (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - - le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, - * the following data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * Received ofdm_ht.plcp_err, - * Current ofdm_ht.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, - le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), - le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), - le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), - le32_to_cpu( - priv->statistics.rx.ofdm_ht.plcp_err), - combined_plcp_delta, plcp_msec); - rc = false; - } - } - return rc; -} -EXPORT_SYMBOL(iwl_good_plcp_health); - void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { @@ -413,7 +238,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, */ IWL_ERR(priv, "low ack count detected, " "restart firmware\n"); - if (!iwl_force_reset(priv, IWL_FW_RESET)) + if (!iwl_force_reset(priv, IWL_FW_RESET, false)) return; } } @@ -424,76 +249,13 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, * high plcp error detected * reset Radio */ - iwl_force_reset(priv, IWL_RF_RESET); + iwl_force_reset(priv, IWL_RF_RESET, false); } } } } EXPORT_SYMBOL(iwl_recover_from_statistics); -void iwl_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - int change; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - - IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", - (int)sizeof(priv->statistics), - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->statistics.general.temperature != - pkt->u.stats.general.temperature) || - ((priv->statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); - -#ifdef CONFIG_IWLWIFI_DEBUG - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); -#endif - iwl_recover_from_statistics(priv, pkt); - - memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); - - set_bit(STATUS_STATISTICS, &priv->status); - - /* Reschedule the statistics timer to occur in - * REG_RECALIB_PERIOD seconds to ensure we get a - * thermal update even if the uCode doesn't give - * us one */ - mod_timer(&priv->statistics_periodic, jiffies + - msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); - - if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && - (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { - iwl_rx_calc_noise(priv); - queue_work(priv->workqueue, &priv->run_time_calib_work); - } - if (priv->cfg->ops->lib->temp_ops.temperature && change) - priv->cfg->ops->lib->temp_ops.temperature(priv); -} -EXPORT_SYMBOL(iwl_rx_statistics); - -void iwl_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUG - memset(&priv->accum_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->delta_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->max_delta, 0, - sizeof(struct iwl_notif_statistics)); -#endif - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); - } - iwl_rx_statistics(priv, rxb); -} -EXPORT_SYMBOL(iwl_reply_statistics); - /* * returns non-zero if packet should be dropped */ diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 386c5f96eff..b0c6b047390 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -333,7 +333,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } - if (test_bit(STATUS_SCANNING, &priv->status)) { + if (test_bit(STATUS_SCANNING, &priv->status) && + !priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); ret = -EAGAIN; goto out_unlock; @@ -348,8 +349,16 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, /* mac80211 will only ask for one band at a time */ priv->scan_band = req->channels[0]->band; priv->scan_request = req; + priv->scan_vif = vif; - ret = iwl_scan_initiate(priv, vif); + /* + * If an internal scan is in progress, just set + * up the scan_request as per above. + */ + if (priv->is_internal_short_scan) + ret = 0; + else + ret = iwl_scan_initiate(priv, vif); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -420,11 +429,10 @@ void iwl_bg_scan_check(struct work_struct *data) return; mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) || - test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting " - "adapter (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + if (test_bit(STATUS_SCANNING, &priv->status) && + !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) iwl_send_scan_abort(priv); @@ -438,7 +446,7 @@ EXPORT_SYMBOL(iwl_bg_scan_check); */ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ies, int ie_len, int left) + const u8 *ta, const u8 *ies, int ie_len, int left) { int len = 0; u8 *pos = NULL; @@ -451,7 +459,7 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); - memcpy(frame->sa, priv->mac_addr, ETH_ALEN); + memcpy(frame->sa, ta, ETH_ALEN); memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); frame->seq_ctrl = 0; @@ -489,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work) !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) return; - mutex_lock(&priv->mutex); - - cancel_delayed_work_sync(&priv->scan_check); - set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); + cancel_delayed_work(&priv->scan_check); + mutex_lock(&priv->mutex); + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) + iwl_send_scan_abort(priv); mutex_unlock(&priv->mutex); } EXPORT_SYMBOL(iwl_bg_abort_scan); @@ -514,7 +521,30 @@ void iwl_bg_scan_completed(struct work_struct *work) priv->is_internal_short_scan = false; IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); internal = true; + } else { + priv->scan_request = NULL; + priv->scan_vif = NULL; } + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + goto out; + + if (internal && priv->scan_request) + iwl_scan_initiate(priv, priv->scan_vif); + + /* Since setting the TXPOWER may have been deferred while + * performing the scan, fire one off */ + iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&priv->active_rxon, + &priv->staging_rxon, sizeof(priv->staging_rxon))) + iwlcore_commit_rxon(priv); + + out: mutex_unlock(&priv->mutex); /* @@ -524,15 +554,6 @@ void iwl_bg_scan_completed(struct work_struct *work) */ if (!internal) ieee80211_scan_completed(priv->hw, false); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* Since setting the TXPOWER may have been deferred while - * performing the scan, fire one off */ - mutex_lock(&priv->mutex); - iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); - mutex_unlock(&priv->mutex); } EXPORT_SYMBOL(iwl_bg_scan_completed); diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h index af6babee289..c4ca0b5d77d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h @@ -42,7 +42,7 @@ struct ieee80211_basic_report { __le64 start_time; __le16 duration; u8 map; -} __attribute__ ((packed)); +} __packed; enum { /* ieee80211_measurement_request.mode */ /* Bit 0 is reserved */ @@ -63,13 +63,13 @@ struct ieee80211_measurement_params { u8 channel; __le64 start_time; __le16 duration; -} __attribute__ ((packed)); +} __packed; struct ieee80211_info_element { u8 id; u8 len; u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct ieee80211_measurement_request { struct ieee80211_info_element ie; @@ -77,7 +77,7 @@ struct ieee80211_measurement_request { u8 mode; u8 type; struct ieee80211_measurement_params params[0]; -} __attribute__ ((packed)); +} __packed; struct ieee80211_measurement_report { struct ieee80211_info_element ie; @@ -87,6 +87,6 @@ struct ieee80211_measurement_report { union { struct ieee80211_basic_report basic[0]; } u; -} __attribute__ ((packed)); +} __packed; #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c27c13fbb1a..9511f03f07e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -30,6 +30,7 @@ #include <net/mac80211.h> #include <linux/etherdevice.h> #include <linux/sched.h> +#include <linux/lockdep.h> #include "iwl-dev.h" #include "iwl-core.h" @@ -54,18 +55,19 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) } } -static void iwl_process_add_sta_resp(struct iwl_priv *priv, - struct iwl_addsta_cmd *addsta, - struct iwl_rx_packet *pkt, - bool sync) +static int iwl_process_add_sta_resp(struct iwl_priv *priv, + struct iwl_addsta_cmd *addsta, + struct iwl_rx_packet *pkt, + bool sync) { u8 sta_id = addsta->sta.sta_id; unsigned long flags; + int ret = -EIO; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", pkt->hdr.flags); - return; + return ret; } IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", @@ -77,6 +79,7 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv, case ADD_STA_SUCCESS_MSK: IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); iwl_sta_ucode_activate(priv, sta_id); + ret = 0; break; case ADD_STA_NO_ROOM_IN_TABLE: IWL_ERR(priv, "Adding station %d failed, no room in table.\n", @@ -114,6 +117,8 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv, STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", addsta->sta.addr); spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; } static void iwl_add_sta_callback(struct iwl_priv *priv, @@ -145,8 +150,10 @@ int iwl_send_add_sta(struct iwl_priv *priv, if (flags & CMD_ASYNC) cmd.callback = iwl_add_sta_callback; - else + else { cmd.flags |= CMD_WANT_SKB; + might_sleep(); + } cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); ret = iwl_send_cmd(priv, &cmd); @@ -156,7 +163,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, if (ret == 0) { pkt = (struct iwl_rx_packet *)cmd.reply_page; - iwl_process_add_sta_resp(priv, sta, pkt, true); + ret = iwl_process_add_sta_resp(priv, sta, pkt, true); } iwl_free_pages(priv, cmd.reply_page); @@ -311,10 +318,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r) { - struct iwl_station_entry *station; unsigned long flags_spin; int ret = 0; u8 sta_id; + struct iwl_addsta_cmd sta_cmd; *sta_id_r = 0; spin_lock_irqsave(&priv->sta_lock, flags_spin); @@ -347,14 +354,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, } priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; - station = &priv->stations[sta_id]; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags_spin); /* Add station to device's station table */ - ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC); + ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr); spin_lock_irqsave(&priv->sta_lock, flags_spin); + IWL_ERR(priv, "Adding station %pM failed.\n", + priv->stations[sta_id].sta.sta.addr); priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; spin_unlock_irqrestore(&priv->sta_lock, flags_spin); @@ -488,7 +496,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) } static int iwl_send_remove_station(struct iwl_priv *priv, - struct iwl_station_entry *station) + const u8 *addr, int sta_id) { struct iwl_rx_packet *pkt; int ret; @@ -505,7 +513,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); rm_sta_cmd.num_sta = 1; - memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN); + memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN); cmd.flags |= CMD_WANT_SKB; @@ -525,7 +533,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, switch (pkt->u.rem_sta.status) { case REM_STA_SUCCESS_MSK: spin_lock_irqsave(&priv->sta_lock, flags_spin); - iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id); + iwl_sta_ucode_deactivate(priv, sta_id); spin_unlock_irqrestore(&priv->sta_lock, flags_spin); IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); break; @@ -546,7 +554,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr) { - struct iwl_station_entry *station; unsigned long flags; if (!iwl_is_ready(priv)) { @@ -592,10 +599,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, BUG_ON(priv->num_stations < 0); - station = &priv->stations[sta_id]; spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl_send_remove_station(priv, station); + return iwl_send_remove_station(priv, addr, sta_id); out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; @@ -643,11 +649,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations); */ void iwl_restore_stations(struct iwl_priv *priv) { - struct iwl_station_entry *station; + struct iwl_addsta_cmd sta_cmd; + struct iwl_link_quality_cmd lq; unsigned long flags_spin; int i; bool found = false; int ret; + bool send_lq; if (!iwl_is_ready(priv)) { IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); @@ -669,13 +677,20 @@ void iwl_restore_stations(struct iwl_priv *priv) for (i = 0; i < priv->hw_params.max_stations; i++) { if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { + memcpy(&sta_cmd, &priv->stations[i].sta, + sizeof(struct iwl_addsta_cmd)); + send_lq = false; + if (priv->stations[i].lq) { + memcpy(&lq, priv->stations[i].lq, + sizeof(struct iwl_link_quality_cmd)); + send_lq = true; + } spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - station = &priv->stations[i]; - ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC); + ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - IWL_ERR(priv, "Adding station %pM failed.\n", - station->sta.sta.addr); spin_lock_irqsave(&priv->sta_lock, flags_spin); + IWL_ERR(priv, "Adding station %pM failed.\n", + priv->stations[i].sta.sta.addr); priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; spin_unlock_irqrestore(&priv->sta_lock, flags_spin); @@ -684,8 +699,8 @@ void iwl_restore_stations(struct iwl_priv *priv) * Rate scaling has already been initialized, send * current LQ command */ - if (station->lq) - iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true); + if (send_lq) + iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true); spin_lock_irqsave(&priv->sta_lock, flags_spin); priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; } @@ -823,7 +838,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, { unsigned long flags; __le16 key_flags = 0; - int ret; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; @@ -863,11 +880,10 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - return ret; + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, @@ -876,7 +892,9 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, { unsigned long flags; __le16 key_flags = 0; - int ret; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); @@ -911,11 +929,10 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - return ret; + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, @@ -972,24 +989,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv, unsigned long flags; int i; - if (sta) { - sta_id = iwl_sta_id(sta); - - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n", - sta->addr); - return; - } - } else - sta_id = priv->hw_params.bcast_sta_id; - - if (iwl_scan_cancel(priv)) { /* cancel scan failed, just live w/ bad key and rely briefly on SW decryption */ return; } + sta_id = iwl_sta_id_or_broadcast(priv, sta); + if (sta_id == IWL_INVALID_STATION) + return; + spin_lock_irqsave(&priv->sta_lock, flags); priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; @@ -1013,9 +1022,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id) { unsigned long flags; - int ret = 0; u16 key_flags; u8 keyidx; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); priv->key_mapping_key--; @@ -1062,9 +1073,10 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); return 0; } - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - return ret; + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } EXPORT_SYMBOL(iwl_remove_dynamic_key); @@ -1073,6 +1085,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, { int ret; + lockdep_assert_held(&priv->mutex); + priv->key_mapping_key++; keyconf->hw_key_idx = HW_KEY_DYNAMIC; @@ -1245,6 +1259,36 @@ int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq) } EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); +/** + * iwl_update_bcast_station - update broadcast station's LQ command + * + * Only used by iwlagn. Placed here to have all bcast station management + * code together. + */ +int iwl_update_bcast_station(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_link_quality_cmd *link_cmd; + u8 sta_id = priv->hw_params.bcast_sta_id; + + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (priv->stations[sta_id].lq) + kfree(priv->stations[sta_id].lq); + else + IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(iwl_update_bcast_station); + void iwl_dealloc_bcast_station(struct iwl_priv *priv) { unsigned long flags; @@ -1268,18 +1312,22 @@ EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); /** * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table */ -void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) { unsigned long flags; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); /* Remove "disable" flag, to enable Tx for this TID */ spin_lock_irqsave(&priv->sta_lock, flags); priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); @@ -1288,6 +1336,9 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, { unsigned long flags; int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) @@ -1299,10 +1350,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, - CMD_ASYNC); + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } EXPORT_SYMBOL(iwl_sta_rx_agg_start); @@ -1311,6 +1362,9 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, { unsigned long flags; int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) { @@ -1323,10 +1377,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, - CMD_ASYNC); + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } EXPORT_SYMBOL(iwl_sta_rx_agg_stop); @@ -1340,9 +1394,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) priv->stations[sta_id].sta.sta.modify_mask = 0; priv->stations[sta_id].sta.sleep_tx_count = 0; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } EXPORT_SYMBOL(iwl_sta_modify_ps_wake); @@ -1357,9 +1411,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) STA_MODIFY_SLEEP_TX_COUNT_MSK; priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index c2a453a1a99..d38a350ba0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -60,6 +60,7 @@ void iwl_restore_stations(struct iwl_priv *priv); void iwl_clear_ucode_stations(struct iwl_priv *priv); int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); void iwl_dealloc_bcast_station(struct iwl_priv *priv); +int iwl_update_bcast_station(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags); @@ -73,7 +74,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid, u16 ssn); int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, @@ -97,6 +98,17 @@ static inline void iwl_clear_driver_stations(struct iwl_priv *priv) spin_lock_irqsave(&priv->sta_lock, flags); memset(priv->stations, 0, sizeof(priv->stations)); priv->num_stations = 0; + + /* + * Remove all key information that is not stored as part of station + * information since mac80211 may not have had a + * chance to remove all the keys. When device is reconfigured by + * mac80211 after an error all keys will be reconfigured. + */ + priv->ucode_key_table = 0; + priv->key_mapping_key = 0; + memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); + spin_unlock_irqrestore(&priv->sta_lock, flags); } @@ -107,4 +119,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; } + +/** + * iwl_sta_id_or_broadcast - return sta_id or broadcast sta + * @priv: iwl priv + * @sta: mac80211 station + * + * In certain circumstances mac80211 passes a station pointer + * that may be %NULL, for example during TX or key setup. In + * that case, we need to use the broadcast station, so this + * inline wraps that pattern. + */ +static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, + struct ieee80211_sta *sta) +{ + int sta_id; + + if (!sta) + return priv->hw_params.bcast_sta_id; + + sta_id = iwl_sta_id(sta); + + /* + * mac80211 should not be passing a partially + * initialised station! + */ + WARN_ON(sta_id == IWL_INVALID_STATION); + + return sta_id; +} #endif /* __iwl_sta_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1ece2ea0977..a81989c0698 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -77,21 +77,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) } EXPORT_SYMBOL(iwl_txq_update_write_ptr); - -void iwl_free_tfds_in_queue(struct iwl_priv *priv, - int sta_id, int tid, int freed) -{ - if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) - priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; - else { - IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", - priv->stations[sta_id].tid[tid].tfds_in_queue, - freed); - priv->stations[sta_id].tid[tid].tfds_in_queue = 0; - } -} -EXPORT_SYMBOL(iwl_free_tfds_in_queue); - /** * iwl_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. @@ -169,15 +154,15 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) } pci_unmap_single(priv->pci_dev, - pci_unmap_addr(&txq->meta[i], mapping), - pci_unmap_len(&txq->meta[i], len), + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } if (huge) { i = q->n_window; pci_unmap_single(priv->pci_dev, - pci_unmap_addr(&txq->meta[i], mapping), - pci_unmap_len(&txq->meta[i], len), + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } @@ -287,7 +272,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, /* Driver private data, only for Tx (not command) queues, * not shared with device. */ if (id != IWL_CMD_QUEUE_NUM) { - txq->txb = kmalloc(sizeof(txq->txb[0]) * + txq->txb = kzalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, GFP_KERNEL); if (!txq->txb) { IWL_ERR(priv, "kmalloc for auxiliary BD " @@ -531,8 +516,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, fix_size, PCI_DMA_BIDIRECTIONAL); - pci_unmap_addr_set(out_meta, mapping, phys_addr); - pci_unmap_len_set(out_meta, len, fix_size); + dma_unmap_addr_set(out_meta, mapping, phys_addr); + dma_unmap_len_set(out_meta, len, fix_size); trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); @@ -626,8 +611,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) meta = &txq->meta[cmd_index]; pci_unmap_single(priv->pci_dev, - pci_unmap_addr(meta, mapping), - pci_unmap_len(meta, len), + dma_unmap_addr(meta, mapping), + dma_unmap_len(meta, len), PCI_DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a27872de410..d24eb47d370 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -27,6 +27,8 @@ * *****************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -197,6 +199,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) { unsigned long flags; + struct iwl_addsta_cmd sta_cmd; spin_lock_irqsave(&priv->sta_lock, flags); memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); @@ -205,11 +208,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); - return 0; + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } static int iwl3945_set_dynamic_key(struct iwl_priv *priv, @@ -310,9 +313,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon || - ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && - (priv->iw_mode != NL80211_IFTYPE_AP))) + if (!iwl_is_associated(priv) || !priv->ibss_beacon) return 0; if (priv->ibss_beacon->len > left) @@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) u8 unicast; u8 sta_id; u8 tid = 0; - u16 seq_number = 0; __le16 fc; u8 wait_write_ptr = 0; - u8 *qc = NULL; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); @@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - if (!info->control.sta) - sta_id = priv->hw_params.bcast_sta_id; - else - sta_id = iwl_sta_id(info->control.sta); + sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); + u8 *qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; if (unlikely(tid >= MAX_TID_COUNT)) goto drop; - seq_number = priv->stations[sta_id].tid[tid].seq_number & - IEEE80211_SCTL_SEQ; - hdr->seq_ctrl = cpu_to_le16(seq_number) | - (hdr->seq_ctrl & - cpu_to_le16(IEEE80211_SCTL_FRAG)); - seq_number += 0x10; } /* Descriptor for chosen Tx queue */ @@ -548,7 +538,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->write_ptr].skb[0] = skb; + txq->txb[q->write_ptr].skb = skb; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; @@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; - if (qc) - priv->stations[sta_id].tid[tid].seq_number = seq_number; } else { wait_write_ptr = 1; txq->need_update = 0; @@ -631,8 +619,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) len, PCI_DMA_TODEVICE); /* we do not map meta data ... so we can safely access address to * provide to unmap command*/ - pci_unmap_addr_set(out_meta, mapping, txcmd_phys); - pci_unmap_len_set(out_meta, len, len); + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, len); /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ @@ -677,55 +665,6 @@ drop: return -1; } -#define BEACON_TIME_MASK_LOW 0x00FFFFFF -#define BEACON_TIME_MASK_HIGH 0xFF000000 -#define TIME_UNIT 1024 - -/* - * extended beacon time format - * time in usec will be changed into a 32-bit value in 8:24 format - * the high 1 byte is the beacon counts - * the lower 3 bytes is the time in usec within one beacon interval - */ - -static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval) -{ - u32 quot; - u32 rem; - u32 interval = beacon_interval * 1024; - - if (!interval || !usec) - return 0; - - quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24); - rem = (usec % interval) & BEACON_TIME_MASK_LOW; - - return (quot << 24) + rem; -} - -/* base is usually what we get from ucode with each received frame, - * the same as HW timer counter counting down - */ - -static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) -{ - u32 base_low = base & BEACON_TIME_MASK_LOW; - u32 addon_low = addon & BEACON_TIME_MASK_LOW; - u32 interval = beacon_interval * TIME_UNIT; - u32 res = (base & BEACON_TIME_MASK_HIGH) + - (addon & BEACON_TIME_MASK_HIGH); - - if (base_low > addon_low) - res += base_low - addon_low; - else if (base_low < addon_low) { - res += interval + base_low - addon_low; - res += (1 << 24); - } else - res += (1 << 24); - - return cpu_to_le32(res); -} - static int iwl3945_get_measurement(struct iwl_priv *priv, struct ieee80211_measurement_params *params, u8 type) @@ -743,8 +682,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, int duration = le16_to_cpu(params->duration); if (iwl_is_associated(priv)) - add_time = - iwl3945_usecs_to_beacons( + add_time = iwl_usecs_to_beacons(priv, le64_to_cpu(params->start_time) - priv->_3945.last_tsf, le16_to_cpu(priv->rxon_timing.beacon_interval)); @@ -759,8 +697,8 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, if (iwl_is_associated(priv)) spectrum.start_time = - iwl3945_add_beacon_time(priv->_3945.last_beacon_time, - add_time, + iwl_add_beacon_time(priv, + priv->_3945.last_beacon_time, add_time, le16_to_cpu(priv->rxon_timing.beacon_interval)); else spectrum.start_time = 0; @@ -1233,7 +1171,7 @@ static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rx } dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); + rxq->bd_dma); dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); rxq->bd = NULL; @@ -1314,6 +1252,8 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); while (i != r) { + int len; + rxb = rxq->queue[i]; /* If an RXB doesn't have a Rx queue slot associated with it, @@ -1328,8 +1268,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) PCI_DMA_FROMDEVICE); pkt = rxb_addr(rxb); - trace_iwlwifi_dev_rx(priv, pkt, - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_dev_rx(priv, pkt, len); /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -1483,7 +1424,7 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); IWL_ERR(priv, - "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", + "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", desc_lookup(desc), desc, time, blink1, blink2, ilink1, ilink2, data1); trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0, @@ -2942,7 +2883,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); spin_lock_irqsave(&priv->lock, flags); - interval = vif ? vif->bss_conf.beacon_int : 0; + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; @@ -3022,14 +2966,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->tx_cmd.len = cpu_to_le16( iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, + vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, IWL_MAX_SCAN_SIZE - sizeof(*scan))); } else { + /* use bcast addr, will not be transmitted but must be valid */ scan->tx_cmd.len = cpu_to_le16( iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - NULL, 0, + iwl_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan))); } /* select Rx antennas */ @@ -3158,19 +3104,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); - if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + if (vif->bss_conf.use_short_preamble) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) + if (vif->bss_conf.use_short_slot) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - - if (vif->type == NL80211_IFTYPE_ADHOC) - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } iwlcore_commit_rxon(priv); @@ -3334,8 +3277,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->staging_rxon.assoc_id = 0; - if (vif->bss_conf.assoc_capability & - WLAN_CAPABILITY_SHORT_PREAMBLE) + if (vif->bss_conf.use_short_preamble) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else @@ -3343,17 +3285,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) ~RXON_FLG_SHORT_PREAMBLE_MSK; if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.assoc_capability & - WLAN_CAPABILITY_SHORT_SLOT_TIME) + if (vif->bss_conf.use_short_slot) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - - if (vif->type == NL80211_IFTYPE_ADHOC) - priv->staging_rxon.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; @@ -3386,17 +3323,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static_key = !iwl_is_associated(priv); if (!static_key) { - if (!sta) { - sta_id = priv->hw_params.bcast_sta_id; - } else { - sta_id = iwl_sta_id(sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211(priv, - "leave - %pM not in station map.\n", - sta->addr); - return -EINVAL; - } - } + sta_id = iwl_sta_id_or_broadcast(priv, sta); + if (sta_id == IWL_INVALID_STATION) + return -EINVAL; } mutex_lock(&priv->mutex); @@ -4006,7 +3935,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * space for this driver's private structure */ hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); if (hw == NULL) { - printk(KERN_ERR DRV_NAME "Can not allocate network device\n"); + pr_err("Can not allocate network device\n"); err = -ENOMEM; goto out; } @@ -4028,9 +3957,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; -#ifdef CONFIG_IWLWIFI_DEBUG - atomic_set(&priv->restrict_refcnt, 0); -#endif if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); @@ -4099,9 +4025,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e } /* MAC Address location in EEPROM same for 3945/4965 */ eeprom = (struct iwl3945_eeprom *)priv->eeprom; - memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN); - IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr); - SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address); + SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address); /*********************** * 5. Setup HW Constants @@ -4302,19 +4227,18 @@ static int __init iwl3945_init(void) { int ret; - printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); - printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); ret = iwl3945_rate_control_register(); if (ret) { - printk(KERN_ERR DRV_NAME - "Unable to register rate control algorithm: %d\n", ret); + pr_err("Unable to register rate control algorithm: %d\n", ret); return ret; } ret = pci_register_driver(&iwl3945_driver); if (ret) { - printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); + pr_err("Unable to initialize PCI module\n"); goto error_register; } diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 902e95f70f6..60619678f4e 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -670,20 +670,24 @@ static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, } static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, - enum tx_power_setting type, int dbm) + enum nl80211_tx_power_setting type, int mbm) { struct iwm_priv *iwm = wiphy_to_iwm(wiphy); int ret; switch (type) { - case TX_POWER_AUTOMATIC: + case NL80211_TX_POWER_AUTOMATIC: return 0; - case TX_POWER_FIXED: + case NL80211_TX_POWER_FIXED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + if (!test_bit(IWM_STATUS_READY, &iwm->status)) return 0; ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, - CFG_TX_PWR_LIMIT_USR, dbm * 2); + CFG_TX_PWR_LIMIT_USR, + MBM_TO_DBM(mbm) * 2); if (ret < 0) return ret; diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 7e16bcf5997..6421689f5e8 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h @@ -56,7 +56,7 @@ struct iwm_umac_cmd_reset { __le32 flags; -} __attribute__ ((packed)); +} __packed; #define UMAC_PARAM_TBL_ORD_FIX 0x0 #define UMAC_PARAM_TBL_ORD_VAR 0x1 @@ -220,37 +220,37 @@ struct iwm_umac_cmd_set_param_fix { __le16 tbl; __le16 key; __le32 value; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_set_param_var { __le16 tbl; __le16 key; __le16 len; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_get_param { __le16 tbl; __le16 key; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_get_param_resp { __le16 tbl; __le16 key; __le16 len; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_eeprom_proxy_hdr { __le32 type; __le32 offset; __le32 len; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_eeprom_proxy { struct iwm_umac_cmd_eeprom_proxy_hdr hdr; u8 buf[0]; -} __attribute__ ((packed)); +} __packed; #define IWM_UMAC_CMD_EEPROM_TYPE_READ 0x1 #define IWM_UMAC_CMD_EEPROM_TYPE_WRITE 0x2 @@ -267,13 +267,13 @@ struct iwm_umac_channel_info { u8 reserved; u8 flags; __le32 channels_mask; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_get_channel_list { __le16 count; __le16 reserved; struct iwm_umac_channel_info ch[0]; -} __attribute__ ((packed)); +} __packed; /* UMAC WiFi interface commands */ @@ -304,7 +304,7 @@ struct iwm_umac_ssid { u8 ssid_len; u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_scan_request { struct iwm_umac_wifi_if hdr; @@ -314,7 +314,7 @@ struct iwm_umac_cmd_scan_request { u8 timeout; /* In seconds */ u8 reserved; struct iwm_umac_ssid ssids[UMAC_WIFI_IF_PROBE_OPTION_MAX]; -} __attribute__ ((packed)); +} __packed; #define UMAC_CIPHER_TYPE_NONE 0xFF #define UMAC_CIPHER_TYPE_USE_GROUPCAST 0x00 @@ -357,7 +357,7 @@ struct iwm_umac_security { u8 ucast_cipher; u8 mcast_cipher; u8 flags; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_ibss { u8 beacon_interval; /* in millisecond */ @@ -366,7 +366,7 @@ struct iwm_umac_ibss { u8 band; u8 channel; u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; #define UMAC_MODE_BSS 0 #define UMAC_MODE_IBSS 1 @@ -385,13 +385,13 @@ struct iwm_umac_profile { __le16 flags; u8 wireless_mode; u8 bss_num; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_invalidate_profile { struct iwm_umac_wifi_if hdr; u8 reason; u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; /* Encryption key commands */ struct iwm_umac_key_wep40 { @@ -400,7 +400,7 @@ struct iwm_umac_key_wep40 { u8 key[WLAN_KEY_LEN_WEP40]; u8 static_key; u8 reserved[2]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_key_wep104 { struct iwm_umac_wifi_if hdr; @@ -408,7 +408,7 @@ struct iwm_umac_key_wep104 { u8 key[WLAN_KEY_LEN_WEP104]; u8 static_key; u8 reserved[2]; -} __attribute__ ((packed)); +} __packed; #define IWM_TKIP_KEY_SIZE 16 #define IWM_TKIP_MIC_SIZE 8 @@ -420,7 +420,7 @@ struct iwm_umac_key_tkip { u8 tkip_key[IWM_TKIP_KEY_SIZE]; u8 mic_rx_key[IWM_TKIP_MIC_SIZE]; u8 mic_tx_key[IWM_TKIP_MIC_SIZE]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_key_ccmp { struct iwm_umac_wifi_if hdr; @@ -428,27 +428,27 @@ struct iwm_umac_key_ccmp { u8 iv_count[6]; u8 reserved[2]; u8 key[WLAN_KEY_LEN_CCMP]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_key_remove { struct iwm_umac_wifi_if hdr; struct iwm_umac_key_hdr key_hdr; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_tx_key_id { struct iwm_umac_wifi_if hdr; u8 key_idx; u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_pwr_trigger { struct iwm_umac_wifi_if hdr; __le32 reseved; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_stats_req { __le32 flags; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_cmd_stop_resume_tx { u8 flags; @@ -456,7 +456,7 @@ struct iwm_umac_cmd_stop_resume_tx { __le16 stop_resume_tid_msk; __le16 last_seq_num[IWM_UMAC_TID_NR]; u16 reserved; -} __attribute__ ((packed)); +} __packed; #define IWM_CMD_PMKID_ADD 1 #define IWM_CMD_PMKID_DEL 2 @@ -468,7 +468,7 @@ struct iwm_umac_pmkid_update { u8 bssid[ETH_ALEN]; __le16 reserved; u8 pmkid[WLAN_PMKID_LEN]; -} __attribute__ ((packed)); +} __packed; /* LMAC commands */ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac); diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index 9531b18cf72..907ac890997 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c @@ -54,7 +54,7 @@ * LMAC. If you look at LMAC commands you'll se that they * are actually regular iwlwifi target commands encapsulated * into a special UMAC command called UMAC passthrough. - * This is due to the fact the the host talks exclusively + * This is due to the fact the host talks exclusively * to the UMAC and so there needs to be a special UMAC * command for talking to the LMAC. * This is how a wifi command is layed out: diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 13266c3842f..51d7efa15ae 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -162,7 +162,7 @@ struct iwm_umac_key_hdr { u8 mac[ETH_ALEN]; u8 key_idx; u8 multicast; /* BCast encrypt & BCast decrypt of frames FROM mac */ -} __attribute__ ((packed)); +} __packed; struct iwm_key { struct iwm_umac_key_hdr hdr; diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h index a855a99e49b..5ddcdf8c70c 100644 --- a/drivers/net/wireless/iwmc3200wifi/lmac.h +++ b/drivers/net/wireless/iwmc3200wifi/lmac.h @@ -43,7 +43,7 @@ struct iwm_lmac_hdr { u8 id; u8 flags; __le16 seq_num; -} __attribute__ ((packed)); +} __packed; /* LMAC commands */ #define CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK 0x1 @@ -54,23 +54,23 @@ struct iwm_lmac_cal_cfg_elt { __le32 send_res; /* 1 for sending back results */ __le32 apply_res; /* 1 for applying calibration results to HW */ __le32 reserved; -} __attribute__ ((packed)); +} __packed; struct iwm_lmac_cal_cfg_status { struct iwm_lmac_cal_cfg_elt init; struct iwm_lmac_cal_cfg_elt periodic; __le32 flags; /* CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK */ -} __attribute__ ((packed)); +} __packed; struct iwm_lmac_cal_cfg_cmd { struct iwm_lmac_cal_cfg_status ucode_cfg; struct iwm_lmac_cal_cfg_status driver_cfg; __le32 reserved; -} __attribute__ ((packed)); +} __packed; struct iwm_lmac_cal_cfg_resp { __le32 status; -} __attribute__ ((packed)); +} __packed; #define IWM_CARD_STATE_SW_HW_ENABLED 0x00 #define IWM_CARD_STATE_HW_DISABLED 0x01 @@ -80,7 +80,7 @@ struct iwm_lmac_cal_cfg_resp { struct iwm_lmac_card_state { __le32 flags; -} __attribute__ ((packed)); +} __packed; /** * COEX_PRIORITY_TABLE_CMD @@ -131,7 +131,7 @@ struct coex_event { u8 win_med_prio; u8 reserved; u8 flags; -} __attribute__ ((packed)); +} __packed; #define COEX_FLAGS_STA_TABLE_VALID_MSK 0x1 #define COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK 0x4 @@ -142,7 +142,7 @@ struct iwm_coex_prio_table_cmd { u8 flags; u8 reserved[3]; struct coex_event sta_prio[COEX_EVENTS_NUM]; -} __attribute__ ((packed)); +} __packed; /* Coexistence definitions * @@ -192,7 +192,7 @@ struct iwm_ct_kill_cfg_cmd { u32 exit_threshold; u32 reserved; u32 entry_threshold; -} __attribute__ ((packed)); +} __packed; /* LMAC OP CODES */ @@ -428,7 +428,7 @@ struct iwm_lmac_calib_hdr { u8 first_grp; u8 grp_num; u8 all_data_valid; -} __attribute__ ((packed)); +} __packed; #define IWM_LMAC_CALIB_FREQ_GROUPS_NR 7 #define IWM_CALIB_FREQ_GROUPS_NR 5 @@ -437,20 +437,20 @@ struct iwm_lmac_calib_hdr { struct iwm_calib_rxiq_entry { u16 ptam_postdist_ars; u16 ptam_postdist_arc; -} __attribute__ ((packed)); +} __packed; struct iwm_calib_rxiq_group { struct iwm_calib_rxiq_entry mode[IWM_CALIB_DC_MODES_NR]; -} __attribute__ ((packed)); +} __packed; struct iwm_lmac_calib_rxiq { struct iwm_calib_rxiq_group group[IWM_LMAC_CALIB_FREQ_GROUPS_NR]; -} __attribute__ ((packed)); +} __packed; struct iwm_calib_rxiq { struct iwm_lmac_calib_hdr hdr; struct iwm_calib_rxiq_group group[IWM_CALIB_FREQ_GROUPS_NR]; -} __attribute__ ((packed)); +} __packed; #define LMAC_STA_ID_SEED 0x0f #define LMAC_STA_ID_POS 0 @@ -463,7 +463,7 @@ struct iwm_lmac_power_report { u8 pa_integ_res_A[3]; u8 pa_integ_res_B[3]; u8 pa_integ_res_C[3]; -} __attribute__ ((packed)); +} __packed; struct iwm_lmac_tx_resp { u8 frame_cnt; /* 1-no aggregation, greater then 1 - aggregation */ @@ -479,6 +479,6 @@ struct iwm_lmac_tx_resp { u8 ra_tid; __le16 frame_ctl; __le32 status; -} __attribute__ ((packed)); +} __packed; #endif diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index e1184deca55..c02fcedea9f 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -321,14 +321,14 @@ iwm_rx_ticket_node_alloc(struct iwm_priv *iwm, struct iwm_rx_ticket *ticket) return ERR_PTR(-ENOMEM); } - ticket_node->ticket = kzalloc(sizeof(struct iwm_rx_ticket), GFP_KERNEL); + ticket_node->ticket = kmemdup(ticket, sizeof(struct iwm_rx_ticket), + GFP_KERNEL); if (!ticket_node->ticket) { IWM_ERR(iwm, "Couldn't allocate RX ticket\n"); kfree(ticket_node); return ERR_PTR(-ENOMEM); } - memcpy(ticket_node->ticket, ticket, sizeof(struct iwm_rx_ticket)); INIT_LIST_HEAD(&ticket_node->node); return ticket_node; diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h index 0cbba3ecc81..4a137d334a4 100644 --- a/drivers/net/wireless/iwmc3200wifi/umac.h +++ b/drivers/net/wireless/iwmc3200wifi/umac.h @@ -42,19 +42,19 @@ struct iwm_udma_in_hdr { __le32 cmd; __le32 size; -} __attribute__ ((packed)); +} __packed; struct iwm_udma_out_nonwifi_hdr { __le32 cmd; __le32 addr; __le32 op1_sz; __le32 op2; -} __attribute__ ((packed)); +} __packed; struct iwm_udma_out_wifi_hdr { __le32 cmd; __le32 meta_data; -} __attribute__ ((packed)); +} __packed; /* Sequence numbering */ #define UMAC_WIFI_SEQ_NUM_BASE 1 @@ -408,12 +408,12 @@ struct iwm_rx_ticket { __le16 flags; u8 payload_offset; /* includes: MAC header, pad, IV */ u8 tail_len; /* includes: MIC, ICV, CRC (w/o STATUS) */ -} __attribute__ ((packed)); +} __packed; struct iwm_rx_mpdu_hdr { __le16 len; __le16 reserved; -} __attribute__ ((packed)); +} __packed; /* UMAC SW WIFI API */ @@ -421,31 +421,31 @@ struct iwm_dev_cmd_hdr { u8 cmd; u8 flags; __le16 seq_num; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_fw_cmd_hdr { __le32 meta_data; struct iwm_dev_cmd_hdr cmd; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_wifi_out_hdr { struct iwm_udma_out_wifi_hdr hw_hdr; struct iwm_umac_fw_cmd_hdr sw_hdr; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_nonwifi_out_hdr { struct iwm_udma_out_nonwifi_hdr hw_hdr; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_wifi_in_hdr { struct iwm_udma_in_hdr hw_hdr; struct iwm_umac_fw_cmd_hdr sw_hdr; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_nonwifi_in_hdr { struct iwm_udma_in_hdr hw_hdr; __le32 time_stamp; -} __attribute__ ((packed)); +} __packed; #define IWM_UMAC_PAGE_SIZE 0x200 @@ -521,7 +521,7 @@ struct iwm_umac_notif_wifi_if { u8 status; u8 flags; __le16 buf_size; -} __attribute__ ((packed)); +} __packed; #define UMAC_ROAM_REASON_FIRST_SELECTION 0x1 #define UMAC_ROAM_REASON_AP_DEAUTH 0x2 @@ -535,7 +535,7 @@ struct iwm_umac_notif_assoc_start { __le32 roam_reason; u8 bssid[ETH_ALEN]; u8 reserved[2]; -} __attribute__ ((packed)); +} __packed; #define UMAC_ASSOC_COMPLETE_SUCCESS 0x0 #define UMAC_ASSOC_COMPLETE_FAILURE 0x1 @@ -546,7 +546,7 @@ struct iwm_umac_notif_assoc_complete { u8 bssid[ETH_ALEN]; u8 band; u8 channel; -} __attribute__ ((packed)); +} __packed; #define UMAC_PROFILE_INVALID_ASSOC_TIMEOUT 0x0 #define UMAC_PROFILE_INVALID_ROAM_TIMEOUT 0x1 @@ -556,7 +556,7 @@ struct iwm_umac_notif_assoc_complete { struct iwm_umac_notif_profile_invalidate { struct iwm_umac_notif_wifi_if mlme_hdr; __le32 reason; -} __attribute__ ((packed)); +} __packed; #define UMAC_SCAN_RESULT_SUCCESS 0x0 #define UMAC_SCAN_RESULT_ABORTED 0x1 @@ -568,7 +568,7 @@ struct iwm_umac_notif_scan_complete { __le32 type; __le32 result; u8 seq_num; -} __attribute__ ((packed)); +} __packed; #define UMAC_OPCODE_ADD_MODIFY 0x0 #define UMAC_OPCODE_REMOVE 0x1 @@ -582,7 +582,7 @@ struct iwm_umac_notif_sta_info { u8 mac_addr[ETH_ALEN]; u8 sta_id; /* bits 0-3: station ID, bits 4-7: station color */ u8 flags; -} __attribute__ ((packed)); +} __packed; #define UMAC_BAND_2GHZ 0 #define UMAC_BAND_5GHZ 1 @@ -601,7 +601,7 @@ struct iwm_umac_notif_bss_info { s8 rssi; u8 reserved; u8 frame_buf[1]; -} __attribute__ ((packed)); +} __packed; #define IWM_BSS_REMOVE_INDEX_MSK 0x0fff #define IWM_BSS_REMOVE_FLAGS_MSK 0xfc00 @@ -614,13 +614,13 @@ struct iwm_umac_notif_bss_removed { struct iwm_umac_notif_wifi_if mlme_hdr; __le32 count; __le16 entries[0]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_mgt_frame { struct iwm_umac_notif_wifi_if mlme_hdr; __le16 len; u8 frame[1]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_alive { struct iwm_umac_wifi_in_hdr hdr; @@ -630,13 +630,13 @@ struct iwm_umac_notif_alive { __le16 reserved2; __le16 page_grp_count; __le32 page_grp_state[IWM_MACS_OUT_GROUPS]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_init_complete { struct iwm_umac_wifi_in_hdr hdr; __le16 status; __le16 reserved; -} __attribute__ ((packed)); +} __packed; /* error categories */ enum { @@ -667,12 +667,12 @@ struct iwm_fw_error_hdr { __le32 dbm_buf_end; __le32 dbm_buf_write_ptr; __le32 dbm_buf_cycle_cnt; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_error { struct iwm_umac_wifi_in_hdr hdr; struct iwm_fw_error_hdr err; -} __attribute__ ((packed)); +} __packed; #define UMAC_DEALLOC_NTFY_CHANGES_CNT_POS 0 #define UMAC_DEALLOC_NTFY_CHANGES_CNT_SEED 0xff @@ -687,20 +687,20 @@ struct iwm_umac_notif_page_dealloc { struct iwm_umac_wifi_in_hdr hdr; __le32 changes; __le32 grp_info[IWM_MACS_OUT_GROUPS]; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_wifi_status { struct iwm_umac_wifi_in_hdr hdr; __le16 status; __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct iwm_umac_notif_rx_ticket { struct iwm_umac_wifi_in_hdr hdr; u8 num_tickets; u8 reserved[3]; struct iwm_rx_ticket tickets[1]; -} __attribute__ ((packed)); +} __packed; /* Tx/Rx rates window (number of max of last update window per second) */ #define UMAC_NTF_RATE_SAMPLE_NR 4 @@ -758,7 +758,7 @@ struct iwm_umac_notif_stats { __le32 roam_unassoc; __le32 roam_deauth; __le32 roam_ap_loadblance; -} __attribute__ ((packed)); +} __packed; #define UMAC_STOP_TX_FLAG 0x1 #define UMAC_RESUME_TX_FLAG 0x2 @@ -770,7 +770,7 @@ struct iwm_umac_notif_stop_resume_tx { u8 flags; /* UMAC_*_TX_FLAG_* */ u8 sta_id; __le16 stop_resume_tid_msk; /* tid bitmask */ -} __attribute__ ((packed)); +} __packed; #define UMAC_MAX_NUM_PMKIDS 4 @@ -779,7 +779,7 @@ struct iwm_umac_wifi_if { u8 oid; u8 flags; __le16 buf_size; -} __attribute__ ((packed)); +} __packed; #define IWM_SEQ_NUM_HOST_MSK 0x0000 #define IWM_SEQ_NUM_UMAC_MSK 0x4000 diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index 45e870e3311..f7d01bfa2e4 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile @@ -1,4 +1,3 @@ -libertas-y += assoc.o libertas-y += cfg.o libertas-y += cmd.o libertas-y += cmdresp.o @@ -6,9 +5,7 @@ libertas-y += debugfs.o libertas-y += ethtool.o libertas-y += main.o libertas-y += rx.o -libertas-y += scan.o libertas-y += tx.o -libertas-y += wext.o libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o usb8xxx-objs += if_usb.o diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 2726c044430..60fd1afe89a 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README @@ -226,6 +226,18 @@ setuserscan All entries in the scan table (not just the new scan data when keep=1) will be displayed upon completion by use of the getscantable ioctl. +hostsleep + This command is used to enable/disable host sleep. + Note: Host sleep parameters should be configured using + "ethtool -s ethX wol X" command before enabling host sleep. + + Path: /sys/kernel/debug/libertas_wireless/ethX/ + + Usage: + cat hostsleep: reads the current hostsleep state + echo "1" > hostsleep : enable host sleep. + echo "0" > hostsleep : disable host sleep + ======================== IWCONFIG COMMANDS ======================== diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c deleted file mode 100644 index aa06070e5ea..00000000000 --- a/drivers/net/wireless/libertas/assoc.c +++ /dev/null @@ -1,2264 +0,0 @@ -/* Copyright (C) 2006, Red Hat, Inc. */ - -#include <linux/types.h> -#include <linux/etherdevice.h> -#include <linux/ieee80211.h> -#include <linux/if_arp.h> -#include <linux/slab.h> -#include <net/lib80211.h> - -#include "assoc.h" -#include "decl.h" -#include "host.h" -#include "scan.h" -#include "cmd.h" - -static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -/* The firmware needs the following bits masked out of the beacon-derived - * capability field when associating/joining to a BSS: - * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) - */ -#define CAPINFO_MASK (~(0xda00)) - -/** - * 802.11b/g supported bitrates (in 500Kb/s units) - */ -u8 lbs_bg_rates[MAX_RATES] = - { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, -0x00, 0x00 }; - - -static int assoc_helper_wep_keys(struct lbs_private *priv, - struct assoc_request *assoc_req); - -/** - * @brief This function finds common rates between rates and card rates. - * - * It will fill common rates in rates as output if found. - * - * NOTE: Setting the MSB of the basic rates need to be taken - * care, either before or after calling this function - * - * @param priv A pointer to struct lbs_private structure - * @param rates the buffer which keeps input and output - * @param rates_size the size of rates buffer; new size of buffer on return, - * which will be less than or equal to original rates_size - * - * @return 0 on success, or -1 on error - */ -static int get_common_rates(struct lbs_private *priv, - u8 *rates, - u16 *rates_size) -{ - int i, j; - u8 intersection[MAX_RATES]; - u16 intersection_size; - u16 num_rates = 0; - - intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection)); - - /* Allow each rate from 'rates' that is supported by the hardware */ - for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) { - for (j = 0; j < intersection_size && rates[j]; j++) { - if (rates[j] == lbs_bg_rates[i]) - intersection[num_rates++] = rates[j]; - } - } - - lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); - lbs_deb_hex(LBS_DEB_JOIN, "card rates ", lbs_bg_rates, - ARRAY_SIZE(lbs_bg_rates)); - lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates); - lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); - - if (!priv->enablehwauto) { - for (i = 0; i < num_rates; i++) { - if (intersection[i] == priv->cur_rate) - goto done; - } - lbs_pr_alert("Previously set fixed data rate %#x isn't " - "compatible with the network.\n", priv->cur_rate); - return -1; - } - -done: - memset(rates, 0, *rates_size); - *rates_size = num_rates; - memcpy(rates, intersection, num_rates); - return 0; -} - - -/** - * @brief Sets the MSB on basic rates as the firmware requires - * - * Scan through an array and set the MSB for basic data rates. - * - * @param rates buffer of data rates - * @param len size of buffer - */ -static void lbs_set_basic_rate_flags(u8 *rates, size_t len) -{ - int i; - - for (i = 0; i < len; i++) { - if (rates[i] == 0x02 || rates[i] == 0x04 || - rates[i] == 0x0b || rates[i] == 0x16) - rates[i] |= 0x80; - } -} - - -static u8 iw_auth_to_ieee_auth(u8 auth) -{ - if (auth == IW_AUTH_ALG_OPEN_SYSTEM) - return 0x00; - else if (auth == IW_AUTH_ALG_SHARED_KEY) - return 0x01; - else if (auth == IW_AUTH_ALG_LEAP) - return 0x80; - - lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth); - return 0; -} - -/** - * @brief This function prepares the authenticate command. AUTHENTICATE only - * sets the authentication suite for future associations, as the firmware - * handles authentication internally during the ASSOCIATE command. - * - * @param priv A pointer to struct lbs_private structure - * @param bssid The peer BSSID with which to authenticate - * @param auth The authentication mode to use (from wireless.h) - * - * @return 0 or -1 - */ -static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth) -{ - struct cmd_ds_802_11_authenticate cmd; - int ret = -1; - - lbs_deb_enter(LBS_DEB_JOIN); - - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - memcpy(cmd.bssid, bssid, ETH_ALEN); - - cmd.authtype = iw_auth_to_ieee_auth(auth); - - lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", bssid, cmd.authtype); - - ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); - - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); - return ret; -} - - -int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, - struct assoc_request *assoc) -{ - struct cmd_ds_802_11_set_wep cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - cmd.action = cpu_to_le16(cmd_action); - - if (cmd_action == CMD_ACT_ADD) { - int i; - - /* default tx key index */ - cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx & - CMD_WEP_KEY_INDEX_MASK); - - /* Copy key types and material to host command structure */ - for (i = 0; i < 4; i++) { - struct enc_key *pkey = &assoc->wep_keys[i]; - - switch (pkey->len) { - case KEY_LEN_WEP_40: - cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; - memmove(cmd.keymaterial[i], pkey->key, pkey->len); - lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); - break; - case KEY_LEN_WEP_104: - cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; - memmove(cmd.keymaterial[i], pkey->key, pkey->len); - lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); - break; - case 0: - break; - default: - lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", - i, pkey->len); - ret = -1; - goto done; - break; - } - } - } else if (cmd_action == CMD_ACT_REMOVE) { - /* ACT_REMOVE clears _all_ WEP keys */ - - /* default tx key index */ - cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx & - CMD_WEP_KEY_INDEX_MASK); - lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx); - } - - ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); -done: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, - uint16_t *enable) -{ - struct cmd_ds_802_11_enable_rsn cmd; - int ret; - - lbs_deb_enter(LBS_DEB_CMD); - - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(cmd_action); - - if (cmd_action == CMD_ACT_GET) - cmd.enable = 0; - else { - if (*enable) - cmd.enable = cpu_to_le16(CMD_ENABLE_RSN); - else - cmd.enable = cpu_to_le16(CMD_DISABLE_RSN); - lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); - } - - ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); - if (!ret && cmd_action == CMD_ACT_GET) - *enable = le16_to_cpu(cmd.enable); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, - struct enc_key *key) -{ - lbs_deb_enter(LBS_DEB_CMD); - - if (key->flags & KEY_INFO_WPA_ENABLED) - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); - if (key->flags & KEY_INFO_WPA_UNICAST) - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); - if (key->flags & KEY_INFO_WPA_MCAST) - keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); - - keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); - keyparam->keytypeid = cpu_to_le16(key->type); - keyparam->keylen = cpu_to_le16(key->len); - memcpy(keyparam->key, key->key, key->len); - - /* Length field doesn't include the {type,length} header */ - keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); - lbs_deb_leave(LBS_DEB_CMD); -} - -int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, - struct assoc_request *assoc) -{ - struct cmd_ds_802_11_key_material cmd; - int ret = 0; - int index = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - cmd.action = cpu_to_le16(cmd_action); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - if (cmd_action == CMD_ACT_GET) { - cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_header) + 2); - } else { - memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); - - if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { - set_one_wpa_key(&cmd.keyParamSet[index], - &assoc->wpa_unicast_key); - index++; - } - - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { - set_one_wpa_key(&cmd.keyParamSet[index], - &assoc->wpa_mcast_key); - index++; - } - - /* The common header and as many keys as we included */ - cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), - keyParamSet[index])); - } - ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); - /* Copy the returned key to driver private data */ - if (!ret && cmd_action == CMD_ACT_GET) { - void *buf_ptr = cmd.keyParamSet; - void *resp_end = &(&cmd)[1]; - - while (buf_ptr < resp_end) { - struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; - struct enc_key *key; - uint16_t param_set_len = le16_to_cpu(keyparam->length); - uint16_t key_len = le16_to_cpu(keyparam->keylen); - uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); - uint16_t key_type = le16_to_cpu(keyparam->keytypeid); - void *end; - - end = (void *)keyparam + sizeof(keyparam->type) - + sizeof(keyparam->length) + param_set_len; - - /* Make sure we don't access past the end of the IEs */ - if (end > resp_end) - break; - - if (key_flags & KEY_INFO_WPA_UNICAST) - key = &priv->wpa_unicast_key; - else if (key_flags & KEY_INFO_WPA_MCAST) - key = &priv->wpa_mcast_key; - else - break; - - /* Copy returned key into driver */ - memset(key, 0, sizeof(struct enc_key)); - if (key_len > sizeof(key->key)) - break; - key->type = key_type; - key->flags = key_flags; - key->len = key_len; - memcpy(key->key, keyparam->key, key->len); - - buf_ptr = end + 1; - } - } - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok) -{ -/* Bit Rate -* 15:13 Reserved -* 12 54 Mbps -* 11 48 Mbps -* 10 36 Mbps -* 9 24 Mbps -* 8 18 Mbps -* 7 12 Mbps -* 6 9 Mbps -* 5 6 Mbps -* 4 Reserved -* 3 11 Mbps -* 2 5.5 Mbps -* 1 2 Mbps -* 0 1 Mbps -**/ - - uint16_t ratemask; - int i = lbs_data_rate_to_fw_index(rate); - if (lower_rates_ok) - ratemask = (0x1fef >> (12 - i)); - else - ratemask = (1 << i); - return cpu_to_le16(ratemask); -} - -int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, - uint16_t cmd_action) -{ - struct cmd_ds_802_11_rate_adapt_rateset cmd; - int ret; - - lbs_deb_enter(LBS_DEB_CMD); - - if (!priv->cur_rate && !priv->enablehwauto) - return -EINVAL; - - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - cmd.action = cpu_to_le16(cmd_action); - cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); - cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); - ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); - if (!ret && cmd_action == CMD_ACT_GET) - priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -/** - * @brief Set the data rate - * - * @param priv A pointer to struct lbs_private structure - * @param rate The desired data rate, or 0 to clear a locked rate - * - * @return 0 on success, error on failure - */ -int lbs_set_data_rate(struct lbs_private *priv, u8 rate) -{ - struct cmd_ds_802_11_data_rate cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - if (rate > 0) { - cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE); - cmd.rates[0] = lbs_data_rate_to_fw_index(rate); - if (cmd.rates[0] == 0) { - lbs_deb_cmd("DATA_RATE: invalid requested rate of" - " 0x%02X\n", rate); - ret = 0; - goto out; - } - lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]); - } else { - cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO); - lbs_deb_cmd("DATA_RATE: setting auto\n"); - } - - ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); - if (ret) - goto out; - - lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd)); - - /* FIXME: get actual rates FW can do if this command actually returns - * all data rates supported. - */ - priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]); - lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate); - -out: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - - -int lbs_cmd_802_11_rssi(struct lbs_private *priv, - struct cmd_ds_command *cmd) -{ - - lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(CMD_802_11_RSSI); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + - sizeof(struct cmd_header)); - cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR); - - /* reset Beacon SNR/NF/RSSI values */ - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0; - priv->SNR[TYPE_BEACON][TYPE_AVG] = 0; - priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0; - priv->NF[TYPE_BEACON][TYPE_AVG] = 0; - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0; - priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0; - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - -int lbs_ret_802_11_rssi(struct lbs_private *priv, - struct cmd_ds_command *resp) -{ - struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; - - lbs_deb_enter(LBS_DEB_CMD); - - /* store the non average value */ - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); - priv->NF[TYPE_BEACON][TYPE_NOAVG] = - get_unaligned_le16(&rssirsp->noisefloor); - - priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); - priv->NF[TYPE_BEACON][TYPE_AVG] = - get_unaligned_le16(&rssirsp->avgnoisefloor); - - priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], - priv->NF[TYPE_BEACON][TYPE_NOAVG]); - - priv->RSSI[TYPE_BEACON][TYPE_AVG] = - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, - priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); - - lbs_deb_cmd("RSSI: beacon %d, avg %d\n", - priv->RSSI[TYPE_BEACON][TYPE_NOAVG], - priv->RSSI[TYPE_BEACON][TYPE_AVG]); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - - -int lbs_cmd_bcn_ctrl(struct lbs_private *priv, - struct cmd_ds_command *cmd, - u16 cmd_action) -{ - struct cmd_ds_802_11_beacon_control - *bcn_ctrl = &cmd->params.bcn_ctrl; - - lbs_deb_enter(LBS_DEB_CMD); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control) - + sizeof(struct cmd_header)); - cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL); - - bcn_ctrl->action = cpu_to_le16(cmd_action); - bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable); - bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period); - - lbs_deb_leave(LBS_DEB_CMD); - return 0; -} - -int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, - struct cmd_ds_command *resp) -{ - struct cmd_ds_802_11_beacon_control *bcn_ctrl = - &resp->params.bcn_ctrl; - - lbs_deb_enter(LBS_DEB_CMD); - - if (bcn_ctrl->action == CMD_ACT_GET) { - priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); - priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); - } - - lbs_deb_enter(LBS_DEB_CMD); - return 0; -} - - - -static int lbs_assoc_post(struct lbs_private *priv, - struct cmd_ds_802_11_associate_response *resp) -{ - int ret = 0; - union iwreq_data wrqu; - struct bss_descriptor *bss; - u16 status_code; - - lbs_deb_enter(LBS_DEB_ASSOC); - - if (!priv->in_progress_assoc_req) { - lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n"); - ret = -1; - goto done; - } - bss = &priv->in_progress_assoc_req->bss; - - /* - * Older FW versions map the IEEE 802.11 Status Code in the association - * response to the following values returned in resp->statuscode: - * - * IEEE Status Code Marvell Status Code - * 0 -> 0x0000 ASSOC_RESULT_SUCCESS - * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * others -> 0x0003 ASSOC_RESULT_REFUSED - * - * Other response codes: - * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) - * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for - * association response from the AP) - */ - - status_code = le16_to_cpu(resp->statuscode); - if (priv->fwrelease < 0x09000000) { - switch (status_code) { - case 0x00: - break; - case 0x01: - lbs_deb_assoc("ASSOC_RESP: invalid parameters\n"); - break; - case 0x02: - lbs_deb_assoc("ASSOC_RESP: internal timer " - "expired while waiting for the AP\n"); - break; - case 0x03: - lbs_deb_assoc("ASSOC_RESP: association " - "refused by AP\n"); - break; - case 0x04: - lbs_deb_assoc("ASSOC_RESP: authentication " - "refused by AP\n"); - break; - default: - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x " - " unknown\n", status_code); - break; - } - } else { - /* v9+ returns the AP's association response */ - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code); - } - - if (status_code) { - lbs_mac_event_disconnected(priv); - ret = status_code; - goto done; - } - - lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", - (void *) (resp + sizeof (resp->hdr)), - le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr)); - - /* Send a Media Connected event, according to the Spec */ - priv->connect_status = LBS_CONNECTED; - - /* Update current SSID and BSSID */ - memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); - priv->curbssparams.ssid_len = bss->ssid_len; - memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); - - priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; - priv->NF[TYPE_RXPD][TYPE_AVG] = 0; - - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); - memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); - priv->nextSNRNF = 0; - priv->numSNRNF = 0; - - netif_carrier_on(priv->dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->dev); - - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - -done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -/** - * @brief This function prepares an association-class command. - * - * @param priv A pointer to struct lbs_private structure - * @param assoc_req The association request describing the BSS to associate - * or reassociate with - * @param command The actual command, either CMD_802_11_ASSOCIATE or - * CMD_802_11_REASSOCIATE - * - * @return 0 or -1 - */ -static int lbs_associate(struct lbs_private *priv, - struct assoc_request *assoc_req, - u16 command) -{ - struct cmd_ds_802_11_associate cmd; - int ret = 0; - struct bss_descriptor *bss = &assoc_req->bss; - u8 *pos = &(cmd.iebuf[0]); - u16 tmpcap, tmplen, tmpauth; - struct mrvl_ie_ssid_param_set *ssid; - struct mrvl_ie_ds_param_set *ds; - struct mrvl_ie_cf_param_set *cf; - struct mrvl_ie_rates_param_set *rates; - struct mrvl_ie_rsn_param_set *rsn; - struct mrvl_ie_auth_type *auth; - - lbs_deb_enter(LBS_DEB_ASSOC); - - BUG_ON((command != CMD_802_11_ASSOCIATE) && - (command != CMD_802_11_REASSOCIATE)); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.command = cpu_to_le16(command); - - /* Fill in static fields */ - memcpy(cmd.bssid, bss->bssid, ETH_ALEN); - cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); - - /* Capability info */ - tmpcap = (bss->capability & CAPINFO_MASK); - if (bss->mode == IW_MODE_INFRA) - tmpcap |= WLAN_CAPABILITY_ESS; - cmd.capability = cpu_to_le16(tmpcap); - lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap); - - /* SSID */ - ssid = (struct mrvl_ie_ssid_param_set *) pos; - ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); - tmplen = bss->ssid_len; - ssid->header.len = cpu_to_le16(tmplen); - memcpy(ssid->ssid, bss->ssid, tmplen); - pos += sizeof(ssid->header) + tmplen; - - ds = (struct mrvl_ie_ds_param_set *) pos; - ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); - ds->header.len = cpu_to_le16(1); - ds->channel = bss->phy.ds.channel; - pos += sizeof(ds->header) + 1; - - cf = (struct mrvl_ie_cf_param_set *) pos; - cf->header.type = cpu_to_le16(TLV_TYPE_CF); - tmplen = sizeof(*cf) - sizeof (cf->header); - cf->header.len = cpu_to_le16(tmplen); - /* IE payload should be zeroed, firmware fills it in for us */ - pos += sizeof(*cf); - - rates = (struct mrvl_ie_rates_param_set *) pos; - rates->header.type = cpu_to_le16(TLV_TYPE_RATES); - tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES); - memcpy(&rates->rates, &bss->rates, tmplen); - if (get_common_rates(priv, rates->rates, &tmplen)) { - ret = -1; - goto done; - } - pos += sizeof(rates->header) + tmplen; - rates->header.len = cpu_to_le16(tmplen); - lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen); - - /* Copy the infra. association rates into Current BSS state structure */ - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); - memcpy(&priv->curbssparams.rates, &rates->rates, tmplen); - - /* Set MSB on basic rates as the firmware requires, but _after_ - * copying to current bss rates. - */ - lbs_set_basic_rate_flags(rates->rates, tmplen); - - /* Firmware v9+ indicate authentication suites as a TLV */ - if (priv->fwrelease >= 0x09000000) { - auth = (struct mrvl_ie_auth_type *) pos; - auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); - auth->header.len = cpu_to_le16(2); - tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode); - auth->auth = cpu_to_le16(tmpauth); - pos += sizeof(auth->header) + 2; - - lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", - bss->bssid, priv->secinfo.auth_mode); - } - - /* WPA/WPA2 IEs */ - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { - rsn = (struct mrvl_ie_rsn_param_set *) pos; - /* WPA_IE or WPA2_IE */ - rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]); - tmplen = (u16) assoc_req->wpa_ie[1]; - rsn->header.len = cpu_to_le16(tmplen); - memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen); - lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn, - sizeof(rsn->header) + tmplen); - pos += sizeof(rsn->header) + tmplen; - } - - cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) + - (u16)(pos - (u8 *) &cmd.iebuf)); - - /* update curbssparams */ - priv->channel = bss->phy.ds.channel; - - ret = lbs_cmd_with_response(priv, command, &cmd); - if (ret == 0) { - ret = lbs_assoc_post(priv, - (struct cmd_ds_802_11_associate_response *) &cmd); - } - -done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -/** - * @brief Associate to a specific BSS discovered in a scan - * - * @param priv A pointer to struct lbs_private structure - * @param assoc_req The association request describing the BSS to associate with - * - * @return 0-success, otherwise fail - */ -static int lbs_try_associate(struct lbs_private *priv, - struct assoc_request *assoc_req) -{ - int ret; - u8 preamble = RADIO_PREAMBLE_LONG; - - lbs_deb_enter(LBS_DEB_ASSOC); - - /* FW v9 and higher indicate authentication suites as a TLV in the - * association command, not as a separate authentication command. - */ - if (priv->fwrelease < 0x09000000) { - ret = lbs_set_authentication(priv, assoc_req->bss.bssid, - priv->secinfo.auth_mode); - if (ret) - goto out; - } - - /* Use short preamble only when both the BSS and firmware support it */ - if (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - preamble = RADIO_PREAMBLE_SHORT; - - ret = lbs_set_radio(priv, preamble, 1); - if (ret) - goto out; - - ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); - /* If the association fails with current auth mode, let's - * try by changing the auth mode - */ - if ((priv->authtype_auto) && - (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) && - (assoc_req->secinfo.wep_enabled) && - (priv->connect_status != LBS_CONNECTED)) { - if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM) - priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; - else - priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - if (!assoc_helper_wep_keys(priv, assoc_req)) - ret = lbs_associate(priv, assoc_req, - CMD_802_11_ASSOCIATE); - } - - if (ret) - ret = -1; -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -static int lbs_adhoc_post(struct lbs_private *priv, - struct cmd_ds_802_11_ad_hoc_result *resp) -{ - int ret = 0; - u16 command = le16_to_cpu(resp->hdr.command); - u16 result = le16_to_cpu(resp->hdr.result); - union iwreq_data wrqu; - struct bss_descriptor *bss; - DECLARE_SSID_BUF(ssid); - - lbs_deb_enter(LBS_DEB_JOIN); - - if (!priv->in_progress_assoc_req) { - lbs_deb_join("ADHOC_RESP: no in-progress association " - "request\n"); - ret = -1; - goto done; - } - bss = &priv->in_progress_assoc_req->bss; - - /* - * Join result code 0 --> SUCCESS - */ - if (result) { - lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result); - if (priv->connect_status == LBS_CONNECTED) - lbs_mac_event_disconnected(priv); - ret = -1; - goto done; - } - - /* Send a Media Connected event, according to the Spec */ - priv->connect_status = LBS_CONNECTED; - - if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { - /* Update the created network descriptor with the new BSSID */ - memcpy(bss->bssid, resp->bssid, ETH_ALEN); - } - - /* Set the BSSID from the joined/started descriptor */ - memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); - - /* Set the new SSID to current SSID */ - memcpy(&priv->curbssparams.ssid, &bss->ssid, IEEE80211_MAX_SSID_LEN); - priv->curbssparams.ssid_len = bss->ssid_len; - - netif_carrier_on(priv->dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->dev); - - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - - lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", - print_ssid(ssid, bss->ssid, bss->ssid_len), - priv->curbssparams.bssid, - priv->channel); - -done: - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); - return ret; -} - -/** - * @brief Join an adhoc network found in a previous scan - * - * @param priv A pointer to struct lbs_private structure - * @param assoc_req The association request describing the BSS to join - * - * @return 0 on success, error on failure - */ -static int lbs_adhoc_join(struct lbs_private *priv, - struct assoc_request *assoc_req) -{ - struct cmd_ds_802_11_ad_hoc_join cmd; - struct bss_descriptor *bss = &assoc_req->bss; - u8 preamble = RADIO_PREAMBLE_LONG; - DECLARE_SSID_BUF(ssid); - u16 ratesize = 0; - int ret = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - lbs_deb_join("current SSID '%s', ssid length %u\n", - print_ssid(ssid, priv->curbssparams.ssid, - priv->curbssparams.ssid_len), - priv->curbssparams.ssid_len); - lbs_deb_join("requested ssid '%s', ssid length %u\n", - print_ssid(ssid, bss->ssid, bss->ssid_len), - bss->ssid_len); - - /* check if the requested SSID is already joined */ - if (priv->curbssparams.ssid_len && - !lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - bss->ssid, bss->ssid_len) && - (priv->mode == IW_MODE_ADHOC) && - (priv->connect_status == LBS_CONNECTED)) { - union iwreq_data wrqu; - - lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as " - "current, not attempting to re-join"); - - /* Send the re-association event though, because the association - * request really was successful, even if just a null-op. - */ - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, - ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - goto out; - } - - /* Use short preamble only when both the BSS and firmware support it */ - if (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { - lbs_deb_join("AdhocJoin: Short preamble\n"); - preamble = RADIO_PREAMBLE_SHORT; - } - - ret = lbs_set_radio(priv, preamble, 1); - if (ret) - goto out; - - lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); - lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); - - priv->adhoccreate = 0; - priv->channel = bss->channel; - - /* Build the join command */ - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - cmd.bss.type = CMD_BSS_TYPE_IBSS; - cmd.bss.beaconperiod = cpu_to_le16(bss->beaconperiod); - - memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN); - memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len); - - memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set)); - - memcpy(&cmd.bss.ibss, &bss->ss.ibss, - sizeof(struct ieee_ie_ibss_param_set)); - - cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); - lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", - bss->capability, CAPINFO_MASK); - - /* information on BSSID descriptor passed to FW */ - lbs_deb_join("ADHOC_J_CMD: BSSID = %pM, SSID = '%s'\n", - cmd.bss.bssid, cmd.bss.ssid); - - /* Only v8 and below support setting these */ - if (priv->fwrelease < 0x09000000) { - /* failtimeout */ - cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); - /* probedelay */ - cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); - } - - /* Copy Data rates from the rates recorded in scan response */ - memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates)); - ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates)); - memcpy(cmd.bss.rates, bss->rates, ratesize); - if (get_common_rates(priv, cmd.bss.rates, &ratesize)) { - lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n"); - ret = -1; - goto out; - } - - /* Copy the ad-hoc creation rates into Current BSS state structure */ - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); - memcpy(&priv->curbssparams.rates, cmd.bss.rates, ratesize); - - /* Set MSB on basic rates as the firmware requires, but _after_ - * copying to current bss rates. - */ - lbs_set_basic_rate_flags(cmd.bss.rates, ratesize); - - cmd.bss.ibss.atimwindow = bss->atimwindow; - - if (assoc_req->secinfo.wep_enabled) { - u16 tmp = le16_to_cpu(cmd.bss.capability); - tmp |= WLAN_CAPABILITY_PRIVACY; - cmd.bss.capability = cpu_to_le16(tmp); - } - - if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { - __le32 local_ps_mode = cpu_to_le32(LBS802_11POWERMODECAM); - - /* wake up first */ - ret = lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, - CMD_ACT_SET, 0, 0, - &local_ps_mode); - if (ret) { - ret = -1; - goto out; - } - } - - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); - if (ret == 0) { - ret = lbs_adhoc_post(priv, - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); - } - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -/** - * @brief Start an Adhoc Network - * - * @param priv A pointer to struct lbs_private structure - * @param assoc_req The association request describing the BSS to start - * - * @return 0 on success, error on failure - */ -static int lbs_adhoc_start(struct lbs_private *priv, - struct assoc_request *assoc_req) -{ - struct cmd_ds_802_11_ad_hoc_start cmd; - u8 preamble = RADIO_PREAMBLE_SHORT; - size_t ratesize = 0; - u16 tmpcap = 0; - int ret = 0; - DECLARE_SSID_BUF(ssid); - - lbs_deb_enter(LBS_DEB_ASSOC); - - ret = lbs_set_radio(priv, preamble, 1); - if (ret) - goto out; - - /* Build the start command */ - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - - memcpy(cmd.ssid, assoc_req->ssid, assoc_req->ssid_len); - - lbs_deb_join("ADHOC_START: SSID '%s', ssid length %u\n", - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len), - assoc_req->ssid_len); - - cmd.bsstype = CMD_BSS_TYPE_IBSS; - - if (priv->beacon_period == 0) - priv->beacon_period = MRVDRV_BEACON_INTERVAL; - cmd.beaconperiod = cpu_to_le16(priv->beacon_period); - - WARN_ON(!assoc_req->channel); - - /* set Physical parameter set */ - cmd.ds.header.id = WLAN_EID_DS_PARAMS; - cmd.ds.header.len = 1; - cmd.ds.channel = assoc_req->channel; - - /* set IBSS parameter set */ - cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS; - cmd.ibss.header.len = 2; - cmd.ibss.atimwindow = cpu_to_le16(0); - - /* set capability info */ - tmpcap = WLAN_CAPABILITY_IBSS; - if (assoc_req->secinfo.wep_enabled || - assoc_req->secinfo.WPAenabled || - assoc_req->secinfo.WPA2enabled) { - lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n"); - tmpcap |= WLAN_CAPABILITY_PRIVACY; - } else - lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n"); - - cmd.capability = cpu_to_le16(tmpcap); - - /* Only v8 and below support setting probe delay */ - if (priv->fwrelease < 0x09000000) - cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); - - ratesize = min(sizeof(cmd.rates), sizeof(lbs_bg_rates)); - memcpy(cmd.rates, lbs_bg_rates, ratesize); - - /* Copy the ad-hoc creating rates into Current BSS state structure */ - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); - memcpy(&priv->curbssparams.rates, &cmd.rates, ratesize); - - /* Set MSB on basic rates as the firmware requires, but _after_ - * copying to current bss rates. - */ - lbs_set_basic_rate_flags(cmd.rates, ratesize); - - lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n", - cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]); - - lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n", - assoc_req->channel, assoc_req->band); - - priv->adhoccreate = 1; - priv->mode = IW_MODE_ADHOC; - - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); - if (ret == 0) - ret = lbs_adhoc_post(priv, - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -/** - * @brief Stop and Ad-Hoc network and exit Ad-Hoc mode - * - * @param priv A pointer to struct lbs_private structure - * @return 0 on success, or an error - */ -int lbs_adhoc_stop(struct lbs_private *priv) -{ - struct cmd_ds_802_11_ad_hoc_stop cmd; - int ret; - - lbs_deb_enter(LBS_DEB_JOIN); - - memset(&cmd, 0, sizeof (cmd)); - cmd.hdr.size = cpu_to_le16 (sizeof (cmd)); - - ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd); - - /* Clean up everything even if there was an error */ - lbs_mac_event_disconnected(priv); - - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, - struct bss_descriptor *match_bss) -{ - if (!secinfo->wep_enabled && - !secinfo->WPAenabled && !secinfo->WPA2enabled && - match_bss->wpa_ie[0] != WLAN_EID_GENERIC && - match_bss->rsn_ie[0] != WLAN_EID_RSN && - !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) - return 1; - else - return 0; -} - -static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, - struct bss_descriptor *match_bss) -{ - if (secinfo->wep_enabled && - !secinfo->WPAenabled && !secinfo->WPA2enabled && - (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) - return 1; - else - return 0; -} - -static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, - struct bss_descriptor *match_bss) -{ - if (!secinfo->wep_enabled && secinfo->WPAenabled && - (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ - ) - return 1; - else - return 0; -} - -static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, - struct bss_descriptor *match_bss) -{ - if (!secinfo->wep_enabled && secinfo->WPA2enabled && - (match_bss->rsn_ie[0] == WLAN_EID_RSN) - /* privacy bit may NOT be set in some APs like LinkSys WRT54G - (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ - ) - return 1; - else - return 0; -} - -static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, - struct bss_descriptor *match_bss) -{ - if (!secinfo->wep_enabled && - !secinfo->WPAenabled && !secinfo->WPA2enabled && - (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) && - (match_bss->rsn_ie[0] != WLAN_EID_RSN) && - (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) - return 1; - else - return 0; -} - -/** - * @brief Check if a scanned network compatible with the driver settings - * - * WEP WPA WPA2 ad-hoc encrypt Network - * enabled enabled enabled AES mode privacy WPA WPA2 Compatible - * 0 0 0 0 NONE 0 0 0 yes No security - * 1 0 0 0 NONE 1 0 0 yes Static WEP - * 0 1 0 0 x 1x 1 x yes WPA - * 0 0 1 0 x 1x x 1 yes WPA2 - * 0 0 0 1 NONE 1 0 0 yes Ad-hoc AES - * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP - * - * - * @param priv A pointer to struct lbs_private - * @param index Index in scantable to check against current driver settings - * @param mode Network mode: Infrastructure or IBSS - * - * @return Index in scantable, or error code if negative - */ -static int is_network_compatible(struct lbs_private *priv, - struct bss_descriptor *bss, uint8_t mode) -{ - int matched = 0; - - lbs_deb_enter(LBS_DEB_SCAN); - - if (bss->mode != mode) - goto done; - - matched = match_bss_no_security(&priv->secinfo, bss); - if (matched) - goto done; - matched = match_bss_static_wep(&priv->secinfo, bss); - if (matched) - goto done; - matched = match_bss_wpa(&priv->secinfo, bss); - if (matched) { - lbs_deb_scan("is_network_compatible() WPA: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); - goto done; - } - matched = match_bss_wpa2(&priv->secinfo, bss); - if (matched) { - lbs_deb_scan("is_network_compatible() WPA2: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " - "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); - goto done; - } - matched = match_bss_dynamic_wep(&priv->secinfo, bss); - if (matched) { - lbs_deb_scan("is_network_compatible() dynamic WEP: " - "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n", - bss->wpa_ie[0], bss->rsn_ie[0], - (bss->capability & WLAN_CAPABILITY_PRIVACY)); - goto done; - } - - /* bss security settings don't match those configured on card */ - lbs_deb_scan("is_network_compatible() FAILED: wpa_ie 0x%x " - "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n", - bss->wpa_ie[0], bss->rsn_ie[0], - priv->secinfo.wep_enabled ? "e" : "d", - priv->secinfo.WPAenabled ? "e" : "d", - priv->secinfo.WPA2enabled ? "e" : "d", - (bss->capability & WLAN_CAPABILITY_PRIVACY)); - -done: - lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched); - return matched; -} - -/** - * @brief This function finds a specific compatible BSSID in the scan list - * - * Used in association code - * - * @param priv A pointer to struct lbs_private - * @param bssid BSSID to find in the scan list - * @param mode Network mode: Infrastructure or IBSS - * - * @return index in BSSID list, or error return code (< 0) - */ -static struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv, - uint8_t *bssid, uint8_t mode) -{ - struct bss_descriptor *iter_bss; - struct bss_descriptor *found_bss = NULL; - - lbs_deb_enter(LBS_DEB_SCAN); - - if (!bssid) - goto out; - - lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN); - - /* Look through the scan table for a compatible match. The loop will - * continue past a matched bssid that is not compatible in case there - * is an AP with multiple SSIDs assigned to the same BSSID - */ - mutex_lock(&priv->lock); - list_for_each_entry(iter_bss, &priv->network_list, list) { - if (compare_ether_addr(iter_bss->bssid, bssid)) - continue; /* bssid doesn't match */ - switch (mode) { - case IW_MODE_INFRA: - case IW_MODE_ADHOC: - if (!is_network_compatible(priv, iter_bss, mode)) - break; - found_bss = iter_bss; - break; - default: - found_bss = iter_bss; - break; - } - } - mutex_unlock(&priv->lock); - -out: - lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); - return found_bss; -} - -/** - * @brief This function finds ssid in ssid list. - * - * Used in association code - * - * @param priv A pointer to struct lbs_private - * @param ssid SSID to find in the list - * @param bssid BSSID to qualify the SSID selection (if provided) - * @param mode Network mode: Infrastructure or IBSS - * - * @return index in BSSID list - */ -static struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv, - uint8_t *ssid, uint8_t ssid_len, - uint8_t *bssid, uint8_t mode, - int channel) -{ - u32 bestrssi = 0; - struct bss_descriptor *iter_bss = NULL; - struct bss_descriptor *found_bss = NULL; - struct bss_descriptor *tmp_oldest = NULL; - - lbs_deb_enter(LBS_DEB_SCAN); - - mutex_lock(&priv->lock); - - list_for_each_entry(iter_bss, &priv->network_list, list) { - if (!tmp_oldest || - (iter_bss->last_scanned < tmp_oldest->last_scanned)) - tmp_oldest = iter_bss; - - if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, - ssid, ssid_len) != 0) - continue; /* ssid doesn't match */ - if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) - continue; /* bssid doesn't match */ - if ((channel > 0) && (iter_bss->channel != channel)) - continue; /* channel doesn't match */ - - switch (mode) { - case IW_MODE_INFRA: - case IW_MODE_ADHOC: - if (!is_network_compatible(priv, iter_bss, mode)) - break; - - if (bssid) { - /* Found requested BSSID */ - found_bss = iter_bss; - goto out; - } - - if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { - bestrssi = SCAN_RSSI(iter_bss->rssi); - found_bss = iter_bss; - } - break; - case IW_MODE_AUTO: - default: - if (SCAN_RSSI(iter_bss->rssi) > bestrssi) { - bestrssi = SCAN_RSSI(iter_bss->rssi); - found_bss = iter_bss; - } - break; - } - } - -out: - mutex_unlock(&priv->lock); - lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss); - return found_bss; -} - -static int assoc_helper_essid(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - struct bss_descriptor * bss; - int channel = -1; - DECLARE_SSID_BUF(ssid); - - lbs_deb_enter(LBS_DEB_ASSOC); - - /* FIXME: take channel into account when picking SSIDs if a channel - * is set. - */ - - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) - channel = assoc_req->channel; - - lbs_deb_assoc("SSID '%s' requested\n", - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len)); - if (assoc_req->mode == IW_MODE_INFRA) { - lbs_send_specific_ssid_scan(priv, assoc_req->ssid, - assoc_req->ssid_len); - - bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, - assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); - if (bss != NULL) { - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - ret = lbs_try_associate(priv, assoc_req); - } else { - lbs_deb_assoc("SSID not found; cannot associate\n"); - } - } else if (assoc_req->mode == IW_MODE_ADHOC) { - /* Scan for the network, do not save previous results. Stale - * scan data will cause us to join a non-existant adhoc network - */ - lbs_send_specific_ssid_scan(priv, assoc_req->ssid, - assoc_req->ssid_len); - - /* Search for the requested SSID in the scan table */ - bss = lbs_find_ssid_in_list(priv, assoc_req->ssid, - assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel); - if (bss != NULL) { - lbs_deb_assoc("SSID found, will join\n"); - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - lbs_adhoc_join(priv, assoc_req); - } else { - /* else send START command */ - lbs_deb_assoc("SSID not found, creating adhoc network\n"); - memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, - IEEE80211_MAX_SSID_LEN); - assoc_req->bss.ssid_len = assoc_req->ssid_len; - lbs_adhoc_start(priv, assoc_req); - } - } - - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_bssid(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - struct bss_descriptor * bss; - - lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %pM", assoc_req->bssid); - - /* Search for index position in list for requested MAC */ - bss = lbs_find_bssid_in_list(priv, assoc_req->bssid, - assoc_req->mode); - if (bss == NULL) { - lbs_deb_assoc("ASSOC: WAP: BSSID %pM not found, " - "cannot associate.\n", assoc_req->bssid); - goto out; - } - - memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - if (assoc_req->mode == IW_MODE_INFRA) { - ret = lbs_try_associate(priv, assoc_req); - lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n", - ret); - } else if (assoc_req->mode == IW_MODE_ADHOC) { - lbs_adhoc_join(priv, assoc_req); - } - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_associate(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0, done = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - /* If we're given and 'any' BSSID, try associating based on SSID */ - - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (compare_ether_addr(bssid_any, assoc_req->bssid) && - compare_ether_addr(bssid_off, assoc_req->bssid)) { - ret = assoc_helper_bssid(priv, assoc_req); - done = 1; - } - } - - if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - ret = assoc_helper_essid(priv, assoc_req); - } - - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_mode(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - if (assoc_req->mode == priv->mode) - goto done; - - if (assoc_req->mode == IW_MODE_INFRA) { - if (priv->psstate != PS_STATE_FULL_POWER) - lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); - priv->psmode = LBS802_11POWERMODECAM; - } - - priv->mode = assoc_req->mode; - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, - assoc_req->mode == IW_MODE_ADHOC ? 2 : 1); - -done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -static int assoc_helper_channel(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - ret = lbs_update_channel(priv); - if (ret) { - lbs_deb_assoc("ASSOC: channel: error getting channel.\n"); - goto done; - } - - if (assoc_req->channel == priv->channel) - goto done; - - if (priv->mesh_dev) { - /* Change mesh channel first; 21.p21 firmware won't let - you change channel otherwise (even though it'll return - an error to this */ - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, - assoc_req->channel); - } - - lbs_deb_assoc("ASSOC: channel: %d -> %d\n", - priv->channel, assoc_req->channel); - - ret = lbs_set_channel(priv, assoc_req->channel); - if (ret < 0) - lbs_deb_assoc("ASSOC: channel: error setting channel.\n"); - - /* FIXME: shouldn't need to grab the channel _again_ after setting - * it since the firmware is supposed to return the new channel, but - * whatever... */ - ret = lbs_update_channel(priv); - if (ret) { - lbs_deb_assoc("ASSOC: channel: error getting channel.\n"); - goto done; - } - - if (assoc_req->channel != priv->channel) { - lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n", - assoc_req->channel); - goto restore_mesh; - } - - if (assoc_req->secinfo.wep_enabled && - (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || - assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) { - /* Make sure WEP keys are re-sent to firmware */ - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); - } - - /* Must restart/rejoin adhoc networks after channel change */ - set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); - - restore_mesh: - if (priv->mesh_dev) - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, - priv->channel); - - done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_wep_keys(struct lbs_private *priv, - struct assoc_request *assoc_req) -{ - int i; - int ret = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - /* Set or remove WEP keys */ - if (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || - assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len) - ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_ADD, assoc_req); - else - ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_REMOVE, assoc_req); - - if (ret) - goto out; - - /* enable/disable the MAC's WEP packet filter */ - if (assoc_req->secinfo.wep_enabled) - priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; - else - priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; - - lbs_set_mac_control(priv); - - mutex_lock(&priv->lock); - - /* Copy WEP keys into priv wep key fields */ - for (i = 0; i < 4; i++) { - memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i], - sizeof(struct enc_key)); - } - priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx; - - mutex_unlock(&priv->lock); - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -static int assoc_helper_secinfo(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - uint16_t do_wpa; - uint16_t rsn = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - memcpy(&priv->secinfo, &assoc_req->secinfo, - sizeof(struct lbs_802_11_security)); - - lbs_set_mac_control(priv); - - /* If RSN is already enabled, don't try to enable it again, since - * ENABLE_RSN resets internal state machines and will clobber the - * 4-way WPA handshake. - */ - - /* Get RSN enabled/disabled */ - ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_GET, &rsn); - if (ret) { - lbs_deb_assoc("Failed to get RSN status: %d\n", ret); - goto out; - } - - /* Don't re-enable RSN if it's already enabled */ - do_wpa = assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled; - if (do_wpa == rsn) - goto out; - - /* Set RSN enabled/disabled */ - ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_SET, &do_wpa); - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_wpa_keys(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - unsigned int flags = assoc_req->flags; - - lbs_deb_enter(LBS_DEB_ASSOC); - - /* Work around older firmware bug where WPA unicast and multicast - * keys must be set independently. Seen in SDIO parts with firmware - * version 5.0.11p0. - */ - - if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { - clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); - ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); - assoc_req->flags = flags; - } - - if (ret) - goto out; - - memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key, - sizeof(struct enc_key)); - - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { - clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); - - ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req); - assoc_req->flags = flags; - - memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key, - sizeof(struct enc_key)); - } - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int assoc_helper_wpa_ie(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { - memcpy(&priv->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); - priv->wpa_ie_len = assoc_req->wpa_ie_len; - } else { - memset(&priv->wpa_ie, 0, MAX_WPA_IE_LEN); - priv->wpa_ie_len = 0; - } - - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int should_deauth_infrastructure(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - int ret = 0; - - if (priv->connect_status != LBS_CONNECTED) - return 0; - - lbs_deb_enter(LBS_DEB_ASSOC); - if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to new SSID\n"); - ret = 1; - goto out; - } - - if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { - if (priv->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { - lbs_deb_assoc("Deauthenticating due to new security\n"); - ret = 1; - goto out; - } - } - - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to new BSSID\n"); - ret = 1; - goto out; - } - - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to channel switch\n"); - ret = 1; - goto out; - } - - /* FIXME: deal with 'auto' mode somehow */ - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - if (assoc_req->mode != IW_MODE_INFRA) { - lbs_deb_assoc("Deauthenticating due to leaving " - "infra mode\n"); - ret = 1; - goto out; - } - } - -out: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - - -static int should_stop_adhoc(struct lbs_private *priv, - struct assoc_request * assoc_req) -{ - lbs_deb_enter(LBS_DEB_ASSOC); - - if (priv->connect_status != LBS_CONNECTED) - return 0; - - if (lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - assoc_req->ssid, assoc_req->ssid_len) != 0) - return 1; - - /* FIXME: deal with 'auto' mode somehow */ - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - if (assoc_req->mode != IW_MODE_ADHOC) - return 1; - } - - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { - if (assoc_req->channel != priv->channel) - return 1; - } - - lbs_deb_leave(LBS_DEB_ASSOC); - return 0; -} - - -/** - * @brief This function finds the best SSID in the Scan List - * - * Search the scan table for the best SSID that also matches the current - * adapter network preference (infrastructure or adhoc) - * - * @param priv A pointer to struct lbs_private - * - * @return index in BSSID list - */ -static struct bss_descriptor *lbs_find_best_ssid_in_list( - struct lbs_private *priv, uint8_t mode) -{ - uint8_t bestrssi = 0; - struct bss_descriptor *iter_bss; - struct bss_descriptor *best_bss = NULL; - - lbs_deb_enter(LBS_DEB_SCAN); - - mutex_lock(&priv->lock); - - list_for_each_entry(iter_bss, &priv->network_list, list) { - switch (mode) { - case IW_MODE_INFRA: - case IW_MODE_ADHOC: - if (!is_network_compatible(priv, iter_bss, mode)) - break; - if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) - break; - bestrssi = SCAN_RSSI(iter_bss->rssi); - best_bss = iter_bss; - break; - case IW_MODE_AUTO: - default: - if (SCAN_RSSI(iter_bss->rssi) <= bestrssi) - break; - bestrssi = SCAN_RSSI(iter_bss->rssi); - best_bss = iter_bss; - break; - } - } - - mutex_unlock(&priv->lock); - lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss); - return best_bss; -} - -/** - * @brief Find the best AP - * - * Used from association worker. - * - * @param priv A pointer to struct lbs_private structure - * @param pSSID A pointer to AP's ssid - * - * @return 0--success, otherwise--fail - */ -static int lbs_find_best_network_ssid(struct lbs_private *priv, - uint8_t *out_ssid, uint8_t *out_ssid_len, uint8_t preferred_mode, - uint8_t *out_mode) -{ - int ret = -1; - struct bss_descriptor *found; - - lbs_deb_enter(LBS_DEB_SCAN); - - priv->scan_ssid_len = 0; - lbs_scan_networks(priv, 1); - if (priv->surpriseremoved) - goto out; - - found = lbs_find_best_ssid_in_list(priv, preferred_mode); - if (found && (found->ssid_len > 0)) { - memcpy(out_ssid, &found->ssid, IEEE80211_MAX_SSID_LEN); - *out_ssid_len = found->ssid_len; - *out_mode = found->mode; - ret = 0; - } - -out: - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} - - -void lbs_association_worker(struct work_struct *work) -{ - struct lbs_private *priv = container_of(work, struct lbs_private, - assoc_work.work); - struct assoc_request * assoc_req = NULL; - int ret = 0; - int find_any_ssid = 0; - DECLARE_SSID_BUF(ssid); - - lbs_deb_enter(LBS_DEB_ASSOC); - - mutex_lock(&priv->lock); - assoc_req = priv->pending_assoc_req; - priv->pending_assoc_req = NULL; - priv->in_progress_assoc_req = assoc_req; - mutex_unlock(&priv->lock); - - if (!assoc_req) - goto done; - - lbs_deb_assoc( - "Association Request:\n" - " flags: 0x%08lx\n" - " SSID: '%s'\n" - " chann: %d\n" - " band: %d\n" - " mode: %d\n" - " BSSID: %pM\n" - " secinfo: %s%s%s\n" - " auth_mode: %d\n", - assoc_req->flags, - print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len), - assoc_req->channel, assoc_req->band, assoc_req->mode, - assoc_req->bssid, - assoc_req->secinfo.WPAenabled ? " WPA" : "", - assoc_req->secinfo.WPA2enabled ? " WPA2" : "", - assoc_req->secinfo.wep_enabled ? " WEP" : "", - assoc_req->secinfo.auth_mode); - - /* If 'any' SSID was specified, find an SSID to associate with */ - if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) && - !assoc_req->ssid_len) - find_any_ssid = 1; - - /* But don't use 'any' SSID if there's a valid locked BSSID to use */ - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (compare_ether_addr(assoc_req->bssid, bssid_any) && - compare_ether_addr(assoc_req->bssid, bssid_off)) - find_any_ssid = 0; - } - - if (find_any_ssid) { - u8 new_mode = assoc_req->mode; - - ret = lbs_find_best_network_ssid(priv, assoc_req->ssid, - &assoc_req->ssid_len, assoc_req->mode, &new_mode); - if (ret) { - lbs_deb_assoc("Could not find best network\n"); - ret = -ENETUNREACH; - goto out; - } - - /* Ensure we switch to the mode of the AP */ - if (assoc_req->mode == IW_MODE_AUTO) { - set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); - assoc_req->mode = new_mode; - } - } - - /* - * Check if the attributes being changing require deauthentication - * from the currently associated infrastructure access point. - */ - if (priv->mode == IW_MODE_INFRA) { - if (should_deauth_infrastructure(priv, assoc_req)) { - ret = lbs_cmd_80211_deauthenticate(priv, - priv->curbssparams.bssid, - WLAN_REASON_DEAUTH_LEAVING); - if (ret) { - lbs_deb_assoc("Deauthentication due to new " - "configuration request failed: %d\n", - ret); - } - } - } else if (priv->mode == IW_MODE_ADHOC) { - if (should_stop_adhoc(priv, assoc_req)) { - ret = lbs_adhoc_stop(priv); - if (ret) { - lbs_deb_assoc("Teardown of AdHoc network due to " - "new configuration request failed: %d\n", - ret); - } - - } - } - - /* Send the various configuration bits to the firmware */ - if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - ret = assoc_helper_mode(priv, assoc_req); - if (ret) - goto out; - } - - if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { - ret = assoc_helper_channel(priv, assoc_req); - if (ret) - goto out; - } - - if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { - ret = assoc_helper_secinfo(priv, assoc_req); - if (ret) - goto out; - } - - if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { - ret = assoc_helper_wpa_ie(priv, assoc_req); - if (ret) - goto out; - } - - /* - * v10 FW wants WPA keys to be set/cleared before WEP key operations, - * otherwise it will fail to correctly associate to WEP networks. - * Other firmware versions don't appear to care. - */ - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || - test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { - ret = assoc_helper_wpa_keys(priv, assoc_req); - if (ret) - goto out; - } - - if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || - test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { - ret = assoc_helper_wep_keys(priv, assoc_req); - if (ret) - goto out; - } - - - /* SSID/BSSID should be the _last_ config option set, because they - * trigger the association attempt. - */ - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) || - test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - int success = 1; - - ret = assoc_helper_associate(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC: association unsuccessful: %d\n", - ret); - success = 0; - } - - if (priv->connect_status != LBS_CONNECTED) { - lbs_deb_assoc("ASSOC: association unsuccessful, " - "not connected\n"); - success = 0; - } - - if (success) { - lbs_deb_assoc("associated to %pM\n", - priv->curbssparams.bssid); - lbs_prepare_and_send_command(priv, - CMD_802_11_RSSI, - 0, CMD_OPTION_WAITFORRSP, 0, NULL); - } else { - ret = -1; - } - } - -out: - if (ret) { - lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", - ret); - } - - mutex_lock(&priv->lock); - priv->in_progress_assoc_req = NULL; - mutex_unlock(&priv->lock); - kfree(assoc_req); - -done: - lbs_deb_leave(LBS_DEB_ASSOC); -} - - -/* - * Caller MUST hold any necessary locks - */ -struct assoc_request *lbs_get_association_request(struct lbs_private *priv) -{ - struct assoc_request * assoc_req; - - lbs_deb_enter(LBS_DEB_ASSOC); - if (!priv->pending_assoc_req) { - priv->pending_assoc_req = kzalloc(sizeof(struct assoc_request), - GFP_KERNEL); - if (!priv->pending_assoc_req) { - lbs_pr_info("Not enough memory to allocate association" - " request!\n"); - return NULL; - } - } - - /* Copy current configuration attributes to the association request, - * but don't overwrite any that are already set. - */ - assoc_req = priv->pending_assoc_req; - if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - memcpy(&assoc_req->ssid, &priv->curbssparams.ssid, - IEEE80211_MAX_SSID_LEN); - assoc_req->ssid_len = priv->curbssparams.ssid_len; - } - - if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) - assoc_req->channel = priv->channel; - - if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) - assoc_req->band = priv->curbssparams.band; - - if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) - assoc_req->mode = priv->mode; - - if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - memcpy(&assoc_req->bssid, priv->curbssparams.bssid, - ETH_ALEN); - } - - if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) { - int i; - for (i = 0; i < 4; i++) { - memcpy(&assoc_req->wep_keys[i], &priv->wep_keys[i], - sizeof(struct enc_key)); - } - } - - if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) - assoc_req->wep_tx_keyidx = priv->wep_tx_keyidx; - - if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { - memcpy(&assoc_req->wpa_mcast_key, &priv->wpa_mcast_key, - sizeof(struct enc_key)); - } - - if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { - memcpy(&assoc_req->wpa_unicast_key, &priv->wpa_unicast_key, - sizeof(struct enc_key)); - } - - if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { - memcpy(&assoc_req->secinfo, &priv->secinfo, - sizeof(struct lbs_802_11_security)); - } - - if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { - memcpy(&assoc_req->wpa_ie, &priv->wpa_ie, - MAX_WPA_IE_LEN); - assoc_req->wpa_ie_len = priv->wpa_ie_len; - } - - lbs_deb_leave(LBS_DEB_ASSOC); - return assoc_req; -} - - -/** - * @brief Deauthenticate from a specific BSS - * - * @param priv A pointer to struct lbs_private structure - * @param bssid The specific BSS to deauthenticate from - * @param reason The 802.11 sec. 7.3.1.7 Reason Code for deauthenticating - * - * @return 0 on success, error on failure - */ -int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN], - u16 reason) -{ - struct cmd_ds_802_11_deauthenticate cmd; - int ret; - - lbs_deb_enter(LBS_DEB_JOIN); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - memcpy(cmd.macaddr, &bssid[0], ETH_ALEN); - cmd.reasoncode = cpu_to_le16(reason); - - ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd); - - /* Clean up everything even if there was an error; can't assume that - * we're still authenticated to the AP after trying to deauth. - */ - lbs_mac_event_disconnected(priv); - - lbs_deb_leave(LBS_DEB_JOIN); - return ret; -} - diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h deleted file mode 100644 index 40621b789fc..00000000000 --- a/drivers/net/wireless/libertas/assoc.h +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright (C) 2006, Red Hat, Inc. */ - -#ifndef _LBS_ASSOC_H_ -#define _LBS_ASSOC_H_ - - -#include "defs.h" -#include "host.h" - - -struct lbs_private; - -/* - * In theory, the IE is limited to the IE length, 255, - * but in practice 64 bytes are enough. - */ -#define MAX_WPA_IE_LEN 64 - - - -struct lbs_802_11_security { - u8 WPAenabled; - u8 WPA2enabled; - u8 wep_enabled; - u8 auth_mode; - u32 key_mgmt; -}; - -/** Current Basic Service Set State Structure */ -struct current_bss_params { - /** bssid */ - u8 bssid[ETH_ALEN]; - /** ssid */ - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 ssid_len; - - /** band */ - u8 band; - /** channel is directly in priv->channel */ - /** zero-terminated array of supported data rates */ - u8 rates[MAX_RATES + 1]; -}; - -/** - * @brief Structure used to store information for each beacon/probe response - */ -struct bss_descriptor { - u8 bssid[ETH_ALEN]; - - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 ssid_len; - - u16 capability; - u32 rssi; - u32 channel; - u16 beaconperiod; - __le16 atimwindow; - - /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ - u8 mode; - - /* zero-terminated array of supported data rates */ - u8 rates[MAX_RATES + 1]; - - unsigned long last_scanned; - - union ieee_phy_param_set phy; - union ieee_ss_param_set ss; - - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - - u8 mesh; - - struct list_head list; -}; - -/** Association request - * - * Encapsulates all the options that describe a specific assocation request - * or configuration of the wireless card's radio, mode, and security settings. - */ -struct assoc_request { -#define ASSOC_FLAG_SSID 1 -#define ASSOC_FLAG_CHANNEL 2 -#define ASSOC_FLAG_BAND 3 -#define ASSOC_FLAG_MODE 4 -#define ASSOC_FLAG_BSSID 5 -#define ASSOC_FLAG_WEP_KEYS 6 -#define ASSOC_FLAG_WEP_TX_KEYIDX 7 -#define ASSOC_FLAG_WPA_MCAST_KEY 8 -#define ASSOC_FLAG_WPA_UCAST_KEY 9 -#define ASSOC_FLAG_SECINFO 10 -#define ASSOC_FLAG_WPA_IE 11 - unsigned long flags; - - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 ssid_len; - u8 channel; - u8 band; - u8 mode; - u8 bssid[ETH_ALEN] __attribute__ ((aligned (2))); - - /** WEP keys */ - struct enc_key wep_keys[4]; - u16 wep_tx_keyidx; - - /** WPA keys */ - struct enc_key wpa_mcast_key; - struct enc_key wpa_unicast_key; - - struct lbs_802_11_security secinfo; - - /** WPA Information Elements*/ - u8 wpa_ie[MAX_WPA_IE_LEN]; - u8 wpa_ie_len; - - /* BSS to associate with for infrastructure of Ad-Hoc join */ - struct bss_descriptor bss; -}; - - -extern u8 lbs_bg_rates[MAX_RATES]; - -void lbs_association_worker(struct work_struct *work); -struct assoc_request *lbs_get_association_request(struct lbs_private *priv); - -int lbs_adhoc_stop(struct lbs_private *priv); - -int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, - u8 bssid[ETH_ALEN], u16 reason); - -int lbs_cmd_802_11_rssi(struct lbs_private *priv, - struct cmd_ds_command *cmd); -int lbs_ret_802_11_rssi(struct lbs_private *priv, - struct cmd_ds_command *resp); - -int lbs_cmd_bcn_ctrl(struct lbs_private *priv, - struct cmd_ds_command *cmd, - u16 cmd_action); -int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv, - struct cmd_ds_command *resp); - -int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action, - struct assoc_request *assoc); - -int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, - uint16_t *enable); - -int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, - struct assoc_request *assoc); - -#endif /* _LBS_ASSOC_H */ diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 9d5d3ccf08c..25f90276098 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -7,8 +7,11 @@ */ #include <linux/slab.h> +#include <linux/ieee80211.h> #include <net/cfg80211.h> +#include <asm/unaligned.h> +#include "decl.h" #include "cfg.h" #include "cmd.h" @@ -39,26 +42,27 @@ static struct ieee80211_channel lbs_2ghz_channels[] = { CHAN2G(14, 2484, 0), }; -#define RATETAB_ENT(_rate, _rateid, _flags) { \ - .bitrate = (_rate), \ - .hw_value = (_rateid), \ - .flags = (_flags), \ +#define RATETAB_ENT(_rate, _hw_value, _flags) { \ + .bitrate = (_rate), \ + .hw_value = (_hw_value), \ + .flags = (_flags), \ } +/* Table 6 in section 3.2.1.1 */ static struct ieee80211_rate lbs_rates[] = { - RATETAB_ENT(10, 0x1, 0), - RATETAB_ENT(20, 0x2, 0), - RATETAB_ENT(55, 0x4, 0), - RATETAB_ENT(110, 0x8, 0), - RATETAB_ENT(60, 0x10, 0), - RATETAB_ENT(90, 0x20, 0), - RATETAB_ENT(120, 0x40, 0), - RATETAB_ENT(180, 0x80, 0), - RATETAB_ENT(240, 0x100, 0), - RATETAB_ENT(360, 0x200, 0), - RATETAB_ENT(480, 0x400, 0), - RATETAB_ENT(540, 0x800, 0), + RATETAB_ENT(10, 0, 0), + RATETAB_ENT(20, 1, 0), + RATETAB_ENT(55, 2, 0), + RATETAB_ENT(110, 3, 0), + RATETAB_ENT(60, 9, 0), + RATETAB_ENT(90, 6, 0), + RATETAB_ENT(120, 7, 0), + RATETAB_ENT(180, 8, 0), + RATETAB_ENT(240, 9, 0), + RATETAB_ENT(360, 10, 0), + RATETAB_ENT(480, 11, 0), + RATETAB_ENT(540, 12, 0), }; static struct ieee80211_supported_band lbs_band_2ghz = { @@ -76,22 +80,1616 @@ static const u32 cipher_suites[] = { WLAN_CIPHER_SUITE_CCMP, }; +/* Time to stay on the channel */ +#define LBS_DWELL_PASSIVE 100 +#define LBS_DWELL_ACTIVE 40 +/*************************************************************************** + * Misc utility functions + * + * TLVs are Marvell specific. They are very similar to IEs, they have the + * same structure: type, length, data*. The only difference: for IEs, the + * type and length are u8, but for TLVs they're __le16. + */ + +/* + * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1 + * in the firmware spec + */ +static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +{ + int ret = -ENOTSUPP; + + switch (auth_type) { + case NL80211_AUTHTYPE_OPEN_SYSTEM: + case NL80211_AUTHTYPE_SHARED_KEY: + ret = auth_type; + break; + case NL80211_AUTHTYPE_AUTOMATIC: + ret = NL80211_AUTHTYPE_OPEN_SYSTEM; + break; + case NL80211_AUTHTYPE_NETWORK_EAP: + ret = 0x80; + break; + default: + /* silence compiler */ + break; + } + return ret; +} + + +/* Various firmware commands need the list of supported rates, but with + the hight-bit set for basic rates */ +static int lbs_add_rates(u8 *rates) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { + u8 rate = lbs_rates[i].bitrate / 5; + if (rate == 0x02 || rate == 0x04 || + rate == 0x0b || rate == 0x16) + rate |= 0x80; + rates[i] = rate; + } + return ARRAY_SIZE(lbs_rates); +} + + +/*************************************************************************** + * TLV utility functions + * + * TLVs are Marvell specific. They are very similar to IEs, they have the + * same structure: type, length, data*. The only difference: for IEs, the + * type and length are u8, but for TLVs they're __le16. + */ + + +/* + * Add ssid TLV + */ +#define LBS_MAX_SSID_TLV_SIZE \ + (sizeof(struct mrvl_ie_header) \ + + IEEE80211_MAX_SSID_LEN) + +static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len) +{ + struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; + + /* + * TLV-ID SSID 00 00 + * length 06 00 + * ssid 4d 4e 54 45 53 54 + */ + ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); + ssid_tlv->header.len = cpu_to_le16(ssid_len); + memcpy(ssid_tlv->ssid, ssid, ssid_len); + return sizeof(ssid_tlv->header) + ssid_len; +} + + +/* + * Add channel list TLV (section 8.4.2) + * + * Actual channel data comes from priv->wdev->wiphy->channels. + */ +#define LBS_MAX_CHANNEL_LIST_TLV_SIZE \ + (sizeof(struct mrvl_ie_header) \ + + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset))) + +static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv, + int last_channel, int active_scan) +{ + int chanscanparamsize = sizeof(struct chanscanparamset) * + (last_channel - priv->scan_channel); + + struct mrvl_ie_header *header = (void *) tlv; + + /* + * TLV-ID CHANLIST 01 01 + * length 0e 00 + * channel 00 01 00 00 00 64 00 + * radio type 00 + * channel 01 + * scan type 00 + * min scan time 00 00 + * max scan time 64 00 + * channel 2 00 02 00 00 00 64 00 + * + */ + + header->type = cpu_to_le16(TLV_TYPE_CHANLIST); + header->len = cpu_to_le16(chanscanparamsize); + tlv += sizeof(struct mrvl_ie_header); + + /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel, + last_channel); */ + memset(tlv, 0, chanscanparamsize); + + while (priv->scan_channel < last_channel) { + struct chanscanparamset *param = (void *) tlv; + + param->radiotype = CMD_SCAN_RADIO_TYPE_BG; + param->channumber = + priv->scan_req->channels[priv->scan_channel]->hw_value; + if (active_scan) { + param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE); + } else { + param->chanscanmode.passivescan = 1; + param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE); + } + tlv += sizeof(struct chanscanparamset); + priv->scan_channel++; + } + return sizeof(struct mrvl_ie_header) + chanscanparamsize; +} + + +/* + * Add rates TLV + * + * The rates are in lbs_bg_rates[], but for the 802.11b + * rates the high bit is set. We add this TLV only because + * there's a firmware which otherwise doesn't report all + * APs in range. + */ +#define LBS_MAX_RATES_TLV_SIZE \ + (sizeof(struct mrvl_ie_header) \ + + (ARRAY_SIZE(lbs_rates))) + +/* Adds a TLV with all rates the hardware supports */ +static int lbs_add_supported_rates_tlv(u8 *tlv) +{ + size_t i; + struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; + + /* + * TLV-ID RATES 01 00 + * length 0e 00 + * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c + */ + rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); + tlv += sizeof(rate_tlv->header); + i = lbs_add_rates(tlv); + tlv += i; + rate_tlv->header.len = cpu_to_le16(i); + return sizeof(rate_tlv->header) + i; +} + + +/* + * Adds a TLV with all rates the hardware *and* BSS supports. + */ +static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) +{ + struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; + const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); + int n; + + /* + * 01 00 TLV_TYPE_RATES + * 04 00 len + * 82 84 8b 96 rates + */ + rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); + tlv += sizeof(rate_tlv->header); + + if (!rates_eid) { + /* Fallback: add basic 802.11b rates */ + *tlv++ = 0x82; + *tlv++ = 0x84; + *tlv++ = 0x8b; + *tlv++ = 0x96; + n = 4; + } else { + int hw, ap; + u8 ap_max = rates_eid[1]; + n = 0; + for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { + u8 hw_rate = lbs_rates[hw].bitrate / 5; + for (ap = 0; ap < ap_max; ap++) { + if (hw_rate == (rates_eid[ap+2] & 0x7f)) { + *tlv++ = rates_eid[ap+2]; + n++; + } + } + } + } + + rate_tlv->header.len = cpu_to_le16(n); + return sizeof(rate_tlv->header) + n; +} + + +/* + * Add auth type TLV. + * + * This is only needed for newer firmware (V9 and up). + */ +#define LBS_MAX_AUTH_TYPE_TLV_SIZE \ + sizeof(struct mrvl_ie_auth_type) + +static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type) +{ + struct mrvl_ie_auth_type *auth = (void *) tlv; + + /* + * 1f 01 TLV_TYPE_AUTH_TYPE + * 01 00 len + * 01 auth type + */ + auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); + auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header)); + auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type)); + return sizeof(*auth); +} + + +/* + * Add channel (phy ds) TLV + */ +#define LBS_MAX_CHANNEL_TLV_SIZE \ + sizeof(struct mrvl_ie_header) + +static int lbs_add_channel_tlv(u8 *tlv, u8 channel) +{ + struct mrvl_ie_ds_param_set *ds = (void *) tlv; + + /* + * 03 00 TLV_TYPE_PHY_DS + * 01 00 len + * 06 channel + */ + ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); + ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header)); + ds->channel = channel; + return sizeof(*ds); +} + + +/* + * Add (empty) CF param TLV of the form: + */ +#define LBS_MAX_CF_PARAM_TLV_SIZE \ + sizeof(struct mrvl_ie_header) + +static int lbs_add_cf_param_tlv(u8 *tlv) +{ + struct mrvl_ie_cf_param_set *cf = (void *)tlv; + + /* + * 04 00 TLV_TYPE_CF + * 06 00 len + * 00 cfpcnt + * 00 cfpperiod + * 00 00 cfpmaxduration + * 00 00 cfpdurationremaining + */ + cf->header.type = cpu_to_le16(TLV_TYPE_CF); + cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header)); + return sizeof(*cf); +} + +/* + * Add WPA TLV + */ +#define LBS_MAX_WPA_TLV_SIZE \ + (sizeof(struct mrvl_ie_header) \ + + 128 /* TODO: I guessed the size */) + +static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) +{ + size_t tlv_len; + + /* + * We need just convert an IE to an TLV. IEs use u8 for the header, + * u8 type + * u8 len + * u8[] data + * but TLVs use __le16 instead: + * __le16 type + * __le16 len + * u8[] data + */ + *tlv++ = *ie++; + *tlv++ = 0; + tlv_len = *tlv++ = *ie++; + *tlv++ = 0; + while (tlv_len--) + *tlv++ = *ie++; + /* the TLV is two bytes larger than the IE */ + return ie_len + 2; +} + +/*************************************************************************** + * Set Channel + */ + static int lbs_cfg_set_channel(struct wiphy *wiphy, struct net_device *netdev, - struct ieee80211_channel *chan, + struct ieee80211_channel *channel, enum nl80211_channel_type channel_type) { struct lbs_private *priv = wiphy_priv(wiphy); int ret = -ENOTSUPP; - lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", chan->center_freq, channel_type); + lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", + channel->center_freq, channel_type); if (channel_type != NL80211_CHAN_NO_HT) goto out; - ret = lbs_set_channel(priv, chan->hw_value); + ret = lbs_set_channel(priv, channel->hw_value); + + out: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + +/*************************************************************************** + * Scanning + */ + +/* + * When scanning, the firmware doesn't send a nul packet with the power-safe + * bit to the AP. So we cannot stay away from our current channel too long, + * otherwise we loose data. So take a "nap" while scanning every other + * while. + */ +#define LBS_SCAN_BEFORE_NAP 4 + + +/* + * When the firmware reports back a scan-result, it gives us an "u8 rssi", + * which isn't really an RSSI, as it becomes larger when moving away from + * the AP. Anyway, we need to convert that into mBm. + */ +#define LBS_SCAN_RSSI_TO_MBM(rssi) \ + ((-(int)rssi + 3)*100) + +static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, + struct cmd_header *resp) +{ + struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; + int bsssize; + const u8 *pos; + u16 nr_sets; + const u8 *tsfdesc; + int tsfsize; + int i; + int ret = -EILSEQ; + + lbs_deb_enter(LBS_DEB_CFG80211); + + bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); + nr_sets = le16_to_cpu(resp->size); + + /* + * The general layout of the scan response is described in chapter + * 5.7.1. Basically we have a common part, then any number of BSS + * descriptor sections. Finally we have section with the same number + * of TSFs. + * + * cmd_ds_802_11_scan_rsp + * cmd_header + * pos_size + * nr_sets + * bssdesc 1 + * bssid + * rssi + * timestamp + * intvl + * capa + * IEs + * bssdesc 2 + * bssdesc n + * MrvlIEtypes_TsfFimestamp_t + * TSF for BSS 1 + * TSF for BSS 2 + * TSF for BSS n + */ + + pos = scanresp->bssdesc_and_tlvbuffer; + + tsfdesc = pos + bsssize; + tsfsize = 4 + 8 * scanresp->nr_sets; + + /* Validity check: we expect a Marvell-Local TLV */ + i = get_unaligned_le16(tsfdesc); + tsfdesc += 2; + if (i != TLV_TYPE_TSFTIMESTAMP) + goto done; + /* Validity check: the TLV holds TSF values with 8 bytes each, so + * the size in the TLV must match the nr_sets value */ + i = get_unaligned_le16(tsfdesc); + tsfdesc += 2; + if (i / 8 != scanresp->nr_sets) + goto done; + + for (i = 0; i < scanresp->nr_sets; i++) { + const u8 *bssid; + const u8 *ie; + int left; + int ielen; + int rssi; + u16 intvl; + u16 capa; + int chan_no = -1; + const u8 *ssid = NULL; + u8 ssid_len = 0; + DECLARE_SSID_BUF(ssid_buf); + + int len = get_unaligned_le16(pos); + pos += 2; + + /* BSSID */ + bssid = pos; + pos += ETH_ALEN; + /* RSSI */ + rssi = *pos++; + /* Packet time stamp */ + pos += 8; + /* Beacon interval */ + intvl = get_unaligned_le16(pos); + pos += 2; + /* Capabilities */ + capa = get_unaligned_le16(pos); + pos += 2; + + /* To find out the channel, we must parse the IEs */ + ie = pos; + /* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon + interval, capabilities */ + ielen = left = len - (6 + 1 + 8 + 2 + 2); + while (left >= 2) { + u8 id, elen; + id = *pos++; + elen = *pos++; + left -= 2; + if (elen > left || elen == 0) + goto done; + if (id == WLAN_EID_DS_PARAMS) + chan_no = *pos; + if (id == WLAN_EID_SSID) { + ssid = pos; + ssid_len = elen; + } + left -= elen; + pos += elen; + } + + /* No channel, no luck */ + if (chan_no != -1) { + struct wiphy *wiphy = priv->wdev->wiphy; + int freq = ieee80211_channel_to_frequency(chan_no); + struct ieee80211_channel *channel = + ieee80211_get_channel(wiphy, freq); + + lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, " + "%d dBm\n", + bssid, capa, chan_no, + print_ssid(ssid_buf, ssid, ssid_len), + LBS_SCAN_RSSI_TO_MBM(rssi)/100); + + if (channel || + !(channel->flags & IEEE80211_CHAN_DISABLED)) + cfg80211_inform_bss(wiphy, channel, + bssid, le64_to_cpu(*(__le64 *)tsfdesc), + capa, intvl, ie, ielen, + LBS_SCAN_RSSI_TO_MBM(rssi), + GFP_KERNEL); + } + tsfdesc += 8; + } + ret = 0; + + done: + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); + return ret; +} + + +/* + * Our scan command contains a TLV, consting of a SSID TLV, a channel list + * TLV and a rates TLV. Determine the maximum size of them: + */ +#define LBS_SCAN_MAX_CMD_SIZE \ + (sizeof(struct cmd_ds_802_11_scan) \ + + LBS_MAX_SSID_TLV_SIZE \ + + LBS_MAX_CHANNEL_LIST_TLV_SIZE \ + + LBS_MAX_RATES_TLV_SIZE) + +/* + * Assumes priv->scan_req is initialized and valid + * Assumes priv->scan_channel is initialized + */ +static void lbs_scan_worker(struct work_struct *work) +{ + struct lbs_private *priv = + container_of(work, struct lbs_private, scan_work.work); + struct cmd_ds_802_11_scan *scan_cmd; + u8 *tlv; /* pointer into our current, growing TLV storage area */ + int last_channel; + int running, carrier; + + lbs_deb_enter(LBS_DEB_SCAN); + + scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL); + if (scan_cmd == NULL) + goto out_no_scan_cmd; + + /* prepare fixed part of scan command */ + scan_cmd->bsstype = CMD_BSS_TYPE_ANY; + + /* stop network while we're away from our main channel */ + running = !netif_queue_stopped(priv->dev); + carrier = netif_carrier_ok(priv->dev); + if (running) + netif_stop_queue(priv->dev); + if (carrier) + netif_carrier_off(priv->dev); + + /* prepare fixed part of scan command */ + tlv = scan_cmd->tlvbuffer; + + /* add SSID TLV */ + if (priv->scan_req->n_ssids) + tlv += lbs_add_ssid_tlv(tlv, + priv->scan_req->ssids[0].ssid, + priv->scan_req->ssids[0].ssid_len); + + /* add channel TLVs */ + last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP; + if (last_channel > priv->scan_req->n_channels) + last_channel = priv->scan_req->n_channels; + tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel, + priv->scan_req->n_ssids); + + /* add rates TLV */ + tlv += lbs_add_supported_rates_tlv(tlv); + + if (priv->scan_channel < priv->scan_req->n_channels) { + cancel_delayed_work(&priv->scan_work); + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(300)); + } + + /* This is the final data we are about to send */ + scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd); + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, + sizeof(*scan_cmd)); + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, + tlv - scan_cmd->tlvbuffer); + + __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, + le16_to_cpu(scan_cmd->hdr.size), + lbs_ret_scan, 0); + + if (priv->scan_channel >= priv->scan_req->n_channels) { + /* Mark scan done */ + cfg80211_scan_done(priv->scan_req, false); + priv->scan_req = NULL; + } + + /* Restart network */ + if (carrier) + netif_carrier_on(priv->dev); + if (running && !priv->tx_pending_len) + netif_wake_queue(priv->dev); + + kfree(scan_cmd); + + out_no_scan_cmd: + lbs_deb_leave(LBS_DEB_SCAN); +} + + +static int lbs_cfg_scan(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_scan_request *request) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + if (priv->scan_req || delayed_work_pending(&priv->scan_work)) { + /* old scan request not yet processed */ + ret = -EAGAIN; + goto out; + } + + lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n", + request->n_ssids, request->n_channels, request->ie_len); + + priv->scan_channel = 0; + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(50)); + + if (priv->surpriseremoved) + ret = -EIO; + + priv->scan_req = request; + + out: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + + +/*************************************************************************** + * Events + */ + +void lbs_send_disconnect_notification(struct lbs_private *priv) +{ + lbs_deb_enter(LBS_DEB_CFG80211); + + cfg80211_disconnected(priv->dev, + 0, + NULL, 0, + GFP_KERNEL); + + lbs_deb_leave(LBS_DEB_CFG80211); +} + +void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) +{ + lbs_deb_enter(LBS_DEB_CFG80211); + + cfg80211_michael_mic_failure(priv->dev, + priv->assoc_bss, + event == MACREG_INT_CODE_MIC_ERR_MULTICAST ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE, + -1, + NULL, + GFP_KERNEL); + + lbs_deb_leave(LBS_DEB_CFG80211); +} + + + + +/*************************************************************************** + * Connect/disconnect + */ + + +/* + * This removes all WEP keys + */ +static int lbs_remove_wep_keys(struct lbs_private *priv) +{ + struct cmd_ds_802_11_set_wep cmd; + int ret; + + lbs_deb_enter(LBS_DEB_CFG80211); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.keyindex = cpu_to_le16(priv->wep_tx_key); + cmd.action = cpu_to_le16(CMD_ACT_REMOVE); + + ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + +/* + * Set WEP keys + */ +static int lbs_set_wep_keys(struct lbs_private *priv) +{ + struct cmd_ds_802_11_set_wep cmd; + int i; + int ret; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* + * command 13 00 + * size 50 00 + * sequence xx xx + * result 00 00 + * action 02 00 ACT_ADD + * transmit key 00 00 + * type for key 1 01 WEP40 + * type for key 2 00 + * type for key 3 00 + * type for key 4 00 + * key 1 39 39 39 39 39 00 00 00 + * 00 00 00 00 00 00 00 00 + * key 2 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * key 3 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * key 4 00 00 00 00 00 00 00 00 + */ + if (priv->wep_key_len[0] || priv->wep_key_len[1] || + priv->wep_key_len[2] || priv->wep_key_len[3]) { + /* Only set wep keys if we have at least one of them */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.keyindex = cpu_to_le16(priv->wep_tx_key); + cmd.action = cpu_to_le16(CMD_ACT_ADD); + + for (i = 0; i < 4; i++) { + switch (priv->wep_key_len[i]) { + case WLAN_KEY_LEN_WEP40: + cmd.keytype[i] = CMD_TYPE_WEP_40_BIT; + break; + case WLAN_KEY_LEN_WEP104: + cmd.keytype[i] = CMD_TYPE_WEP_104_BIT; + break; + default: + cmd.keytype[i] = 0; + break; + } + memcpy(cmd.keymaterial[i], priv->wep_key[i], + priv->wep_key_len[i]); + } + + ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd); + } else { + /* Otherwise remove all wep keys */ + ret = lbs_remove_wep_keys(priv); + } + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + + +/* + * Enable/Disable RSN status + */ +static int lbs_enable_rsn(struct lbs_private *priv, int enable) +{ + struct cmd_ds_802_11_enable_rsn cmd; + int ret; + + lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable); + + /* + * cmd 2f 00 + * size 0c 00 + * sequence xx xx + * result 00 00 + * action 01 00 ACT_SET + * enable 01 00 + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); + cmd.enable = cpu_to_le16(enable); + + ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd); + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + + +/* + * Set WPA/WPA key material + */ + +/* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we + * get rid of WEXT, this should go into host.h */ + +struct cmd_key_material { + struct cmd_header hdr; + + __le16 action; + struct MrvlIEtype_keyParamSet param; +} __packed; + +static int lbs_set_key_material(struct lbs_private *priv, + int key_type, + int key_info, + u8 *key, u16 key_len) +{ + struct cmd_key_material cmd; + int ret; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* + * Example for WPA (TKIP): + * + * cmd 5e 00 + * size 34 00 + * sequence xx xx + * result 00 00 + * action 01 00 + * TLV type 00 01 key param + * length 00 26 + * key type 01 00 TKIP + * key info 06 00 UNICAST | ENABLED + * key len 20 00 + * key 32 bytes + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); + cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4); + cmd.param.keytypeid = cpu_to_le16(key_type); + cmd.param.keyinfo = cpu_to_le16(key_info); + cmd.param.keylen = cpu_to_le16(key_len); + if (key && key_len) + memcpy(cmd.param.key, key, key_len); + + ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + + +/* + * Sets the auth type (open, shared, etc) in the firmware. That + * we use CMD_802_11_AUTHENTICATE is misleading, this firmware + * command doesn't send an authentication frame at all, it just + * stores the auth_type. + */ +static int lbs_set_authtype(struct lbs_private *priv, + struct cfg80211_connect_params *sme) +{ + struct cmd_ds_802_11_authenticate cmd; + int ret; + + lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type); + + /* + * cmd 11 00 + * size 19 00 + * sequence xx xx + * result 00 00 + * BSS id 00 13 19 80 da 30 + * auth type 00 + * reserved 00 00 00 00 00 00 00 00 00 00 + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + if (sme->bssid) + memcpy(cmd.bssid, sme->bssid, ETH_ALEN); + /* convert auth_type */ + ret = lbs_auth_to_authtype(sme->auth_type); + if (ret < 0) + goto done; + + cmd.authtype = ret; + ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); + + done: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + +/* + * Create association request + */ +#define LBS_ASSOC_MAX_CMD_SIZE \ + (sizeof(struct cmd_ds_802_11_associate) \ + - 512 /* cmd_ds_802_11_associate.iebuf */ \ + + LBS_MAX_SSID_TLV_SIZE \ + + LBS_MAX_CHANNEL_TLV_SIZE \ + + LBS_MAX_CF_PARAM_TLV_SIZE \ + + LBS_MAX_AUTH_TYPE_TLV_SIZE \ + + LBS_MAX_WPA_TLV_SIZE) + +static int lbs_associate(struct lbs_private *priv, + struct cfg80211_bss *bss, + struct cfg80211_connect_params *sme) +{ + struct cmd_ds_802_11_associate_response *resp; + struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE, + GFP_KERNEL); + const u8 *ssid_eid; + size_t len, resp_ie_len; + int status; + int ret; + u8 *pos = &(cmd->iebuf[0]); + + lbs_deb_enter(LBS_DEB_CFG80211); + + if (!cmd) { + ret = -ENOMEM; + goto done; + } + + /* + * cmd 50 00 + * length 34 00 + * sequence xx xx + * result 00 00 + * BSS id 00 13 19 80 da 30 + * capabilities 11 00 + * listen interval 0a 00 + * beacon interval 00 00 + * DTIM period 00 + * TLVs xx (up to 512 bytes) + */ + cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE); + + /* Fill in static fields */ + memcpy(cmd->bssid, bss->bssid, ETH_ALEN); + cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); + cmd->capability = cpu_to_le16(bss->capability); + + /* add SSID TLV */ + ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); + if (ssid_eid) + pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]); + else + lbs_deb_assoc("no SSID\n"); + + /* add DS param TLV */ + if (bss->channel) + pos += lbs_add_channel_tlv(pos, bss->channel->hw_value); + else + lbs_deb_assoc("no channel\n"); + + /* add (empty) CF param TLV */ + pos += lbs_add_cf_param_tlv(pos); + + /* add rates TLV */ + pos += lbs_add_common_rates_tlv(pos, bss); + + /* add auth type TLV */ + if (priv->fwrelease >= 0x09000000) + pos += lbs_add_auth_type_tlv(pos, sme->auth_type); + + /* add WPA/WPA2 TLV */ + if (sme->ie && sme->ie_len) + pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len); + + len = (sizeof(*cmd) - sizeof(cmd->iebuf)) + + (u16)(pos - (u8 *) &cmd->iebuf); + cmd->hdr.size = cpu_to_le16(len); + + /* store for later use */ + memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); + + ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd); + if (ret) + goto done; + + + /* generate connect message to cfg80211 */ + + resp = (void *) cmd; /* recast for easier field access */ + status = le16_to_cpu(resp->statuscode); + + /* Convert statis code of old firmware */ + if (priv->fwrelease < 0x09000000) + switch (status) { + case 0: + break; + case 1: + lbs_deb_assoc("invalid association parameters\n"); + status = WLAN_STATUS_CAPS_UNSUPPORTED; + break; + case 2: + lbs_deb_assoc("timer expired while waiting for AP\n"); + status = WLAN_STATUS_AUTH_TIMEOUT; + break; + case 3: + lbs_deb_assoc("association refused by AP\n"); + status = WLAN_STATUS_ASSOC_DENIED_UNSPEC; + break; + case 4: + lbs_deb_assoc("authentication refused by AP\n"); + status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; + break; + default: + lbs_deb_assoc("association failure %d\n", status); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + } + + lbs_deb_assoc("status %d, capability 0x%04x\n", status, + le16_to_cpu(resp->capability)); + + resp_ie_len = le16_to_cpu(resp->hdr.size) + - sizeof(resp->hdr) + - 6; + cfg80211_connect_result(priv->dev, + priv->assoc_bss, + sme->ie, sme->ie_len, + resp->iebuf, resp_ie_len, + status, + GFP_KERNEL); + + if (status == 0) { + /* TODO: get rid of priv->connect_status */ + priv->connect_status = LBS_CONNECTED; + netif_carrier_on(priv->dev); + if (!priv->tx_pending_len) + netif_tx_wake_all_queues(priv->dev); + } + + +done: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + +static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_connect_params *sme) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + struct cfg80211_bss *bss = NULL; + int ret = 0; + u8 preamble = RADIO_PREAMBLE_SHORT; + + lbs_deb_enter(LBS_DEB_CFG80211); + + if (sme->bssid) { + bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, + sme->ssid, sme->ssid_len, + WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); + } else { + /* + * Here we have an impedance mismatch. The firmware command + * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot + * connect otherwise. However, for the connect-API of + * cfg80211 the bssid is purely optional. We don't get one, + * except the user specifies one on the "iw" command line. + * + * If we don't got one, we could initiate a scan and look + * for the best matching cfg80211_bss entry. + * + * Or, better yet, net/wireless/sme.c get's rewritten into + * something more generally useful. + */ + lbs_pr_err("TODO: no BSS specified\n"); + ret = -ENOTSUPP; + goto done; + } + + + if (!bss) { + lbs_pr_err("assicate: bss %pM not in scan results\n", + sme->bssid); + ret = -ENOENT; + goto done; + } + lbs_deb_assoc("trying %pM", sme->bssid); + lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n", + sme->crypto.cipher_group, + sme->key_idx, sme->key_len); + + /* As this is a new connection, clear locally stored WEP keys */ + priv->wep_tx_key = 0; + memset(priv->wep_key, 0, sizeof(priv->wep_key)); + memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); + + /* set/remove WEP keys */ + switch (sme->crypto.cipher_group) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + /* Store provided WEP keys in priv-> */ + priv->wep_tx_key = sme->key_idx; + priv->wep_key_len[sme->key_idx] = sme->key_len; + memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len); + /* Set WEP keys and WEP mode */ + lbs_set_wep_keys(priv); + priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE; + lbs_set_mac_control(priv); + /* No RSN mode for WEP */ + lbs_enable_rsn(priv, 0); + break; + case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */ + /* + * If we don't have no WEP, no WPA and no WPA2, + * we remove all keys like in the WPA/WPA2 setup, + * we just don't set RSN. + * + * Therefore: fall-throught + */ + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + /* Remove WEP keys and WEP mode */ + lbs_remove_wep_keys(priv); + priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE; + lbs_set_mac_control(priv); + + /* clear the WPA/WPA2 keys */ + lbs_set_key_material(priv, + KEY_TYPE_ID_WEP, /* doesn't matter */ + KEY_INFO_WPA_UNICAST, + NULL, 0); + lbs_set_key_material(priv, + KEY_TYPE_ID_WEP, /* doesn't matter */ + KEY_INFO_WPA_MCAST, + NULL, 0); + /* RSN mode for WPA/WPA2 */ + lbs_enable_rsn(priv, sme->crypto.cipher_group != 0); + break; + default: + lbs_pr_err("unsupported cipher group 0x%x\n", + sme->crypto.cipher_group); + ret = -ENOTSUPP; + goto done; + } + + lbs_set_authtype(priv, sme); + lbs_set_radio(priv, preamble, 1); + + /* Do the actual association */ + lbs_associate(priv, bss, sme); + + done: + if (bss) + cfg80211_put_bss(bss); + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + +static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev, + u16 reason_code) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + struct cmd_ds_802_11_deauthenticate cmd; + + lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code); + + /* store for lbs_cfg_ret_disconnect() */ + priv->disassoc_reason = reason_code; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + /* Mildly ugly to use a locally store my own BSSID ... */ + memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN); + cmd.reasoncode = cpu_to_le16(reason_code); + + if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd)) + return -EFAULT; + + cfg80211_disconnected(priv->dev, + priv->disassoc_reason, + NULL, 0, + GFP_KERNEL); + priv->connect_status = LBS_DISCONNECTED; + + return 0; +} + + +static int lbs_cfg_set_default_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + + lbs_deb_enter(LBS_DEB_CFG80211); + + if (key_index != priv->wep_tx_key) { + lbs_deb_assoc("set_default_key: to %d\n", key_index); + priv->wep_tx_key = key_index; + lbs_set_wep_keys(priv); + } + + return 0; +} + + +static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, + u8 idx, const u8 *mac_addr, + struct key_params *params) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + u16 key_info; + u16 key_type; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n", + params->cipher, mac_addr); + lbs_deb_assoc("add_key: key index %d, key len %d\n", + idx, params->key_len); + if (params->key_len) + lbs_deb_hex(LBS_DEB_CFG80211, "KEY", + params->key, params->key_len); + + lbs_deb_assoc("add_key: seq len %d\n", params->seq_len); + if (params->seq_len) + lbs_deb_hex(LBS_DEB_CFG80211, "SEQ", + params->seq, params->seq_len); + + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + /* actually compare if something has changed ... */ + if ((priv->wep_key_len[idx] != params->key_len) || + memcmp(priv->wep_key[idx], + params->key, params->key_len) != 0) { + priv->wep_key_len[idx] = params->key_len; + memcpy(priv->wep_key[idx], + params->key, params->key_len); + lbs_set_wep_keys(priv); + } + break; + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + key_info = KEY_INFO_WPA_ENABLED | ((idx == 0) + ? KEY_INFO_WPA_UNICAST + : KEY_INFO_WPA_MCAST); + key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP) + ? KEY_TYPE_ID_TKIP + : KEY_TYPE_ID_AES; + lbs_set_key_material(priv, + key_type, + key_info, + params->key, params->key_len); + break; + default: + lbs_pr_err("unhandled cipher 0x%x\n", params->cipher); + ret = -ENOTSUPP; + break; + } + + return ret; +} + + +static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, + u8 key_index, const u8 *mac_addr) +{ + + lbs_deb_enter(LBS_DEB_CFG80211); + + lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n", + key_index, mac_addr); + +#ifdef TODO + struct lbs_private *priv = wiphy_priv(wiphy); + /* + * I think can keep this a NO-OP, because: + + * - we clear all keys whenever we do lbs_cfg_connect() anyway + * - neither "iw" nor "wpa_supplicant" won't call this during + * an ongoing connection + * - TODO: but I have to check if this is still true when + * I set the AP to periodic re-keying + * - we've not kzallec() something when we've added a key at + * lbs_cfg_connect() or lbs_cfg_add_key(). + * + * This causes lbs_cfg_del_key() only called at disconnect time, + * where we'd just waste time deleting a key that is not going + * to be used anyway. + */ + if (key_index < 3 && priv->wep_key_len[key_index]) { + priv->wep_key_len[key_index] = 0; + lbs_set_wep_keys(priv); + } +#endif + + return 0; +} + + +/*************************************************************************** + * Get station + */ + +static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, + u8 *mac, struct station_info *sinfo) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + s8 signal, noise; + int ret; + size_t i; + + lbs_deb_enter(LBS_DEB_CFG80211); + + sinfo->filled |= STATION_INFO_TX_BYTES | + STATION_INFO_TX_PACKETS | + STATION_INFO_RX_BYTES | + STATION_INFO_RX_PACKETS; + sinfo->tx_bytes = priv->dev->stats.tx_bytes; + sinfo->tx_packets = priv->dev->stats.tx_packets; + sinfo->rx_bytes = priv->dev->stats.rx_bytes; + sinfo->rx_packets = priv->dev->stats.rx_packets; + + /* Get current RSSI */ + ret = lbs_get_rssi(priv, &signal, &noise); + if (ret == 0) { + sinfo->signal = signal; + sinfo->filled |= STATION_INFO_SIGNAL; + } + + /* Convert priv->cur_rate from hw_value to NL80211 value */ + for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { + if (priv->cur_rate == lbs_rates[i].hw_value) { + sinfo->txrate.legacy = lbs_rates[i].bitrate; + sinfo->filled |= STATION_INFO_TX_BITRATE; + break; + } + } + + return 0; +} + + + + +/*************************************************************************** + * "Site survey", here just current channel and noise level + */ + +static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, + int idx, struct survey_info *survey) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + s8 signal, noise; + int ret; + + if (idx != 0) + ret = -ENOENT; + + lbs_deb_enter(LBS_DEB_CFG80211); + + survey->channel = ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(priv->channel)); + + ret = lbs_get_rssi(priv, &signal, &noise); + if (ret == 0) { + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = noise; + } + + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + + +/*************************************************************************** + * Change interface + */ + +static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + switch (type) { + case NL80211_IFTYPE_MONITOR: + ret = lbs_set_monitor_mode(priv, 1); + break; + case NL80211_IFTYPE_STATION: + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) + ret = lbs_set_monitor_mode(priv, 0); + if (!ret) + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1); + break; + case NL80211_IFTYPE_ADHOC: + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) + ret = lbs_set_monitor_mode(priv, 0); + if (!ret) + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2); + break; + default: + ret = -ENOTSUPP; + } + + if (!ret) + priv->wdev->iftype = type; + + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + +/*************************************************************************** + * IBSS (Ad-Hoc) + */ + +/* The firmware needs the following bits masked out of the beacon-derived + * capability field when associating/joining to a BSS: + * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) + */ +#define CAPINFO_MASK (~(0xda00)) + + +static void lbs_join_post(struct lbs_private *priv, + struct cfg80211_ibss_params *params, + u8 *bssid, u16 capability) +{ + u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */ + 2 + 4 + /* basic rates */ + 2 + 1 + /* DS parameter */ + 2 + 2 + /* atim */ + 2 + 8]; /* extended rates */ + u8 *fake = fake_ie; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* + * For cfg80211_inform_bss, we'll need a fake IE, as we can't get + * the real IE from the firmware. So we fabricate a fake IE based on + * what the firmware actually sends (sniffed with wireshark). + */ + /* Fake SSID IE */ + *fake++ = WLAN_EID_SSID; + *fake++ = params->ssid_len; + memcpy(fake, params->ssid, params->ssid_len); + fake += params->ssid_len; + /* Fake supported basic rates IE */ + *fake++ = WLAN_EID_SUPP_RATES; + *fake++ = 4; + *fake++ = 0x82; + *fake++ = 0x84; + *fake++ = 0x8b; + *fake++ = 0x96; + /* Fake DS channel IE */ + *fake++ = WLAN_EID_DS_PARAMS; + *fake++ = 1; + *fake++ = params->channel->hw_value; + /* Fake IBSS params IE */ + *fake++ = WLAN_EID_IBSS_PARAMS; + *fake++ = 2; + *fake++ = 0; /* ATIM=0 */ + *fake++ = 0; + /* Fake extended rates IE, TODO: don't add this for 802.11b only, + * but I don't know how this could be checked */ + *fake++ = WLAN_EID_EXT_SUPP_RATES; + *fake++ = 8; + *fake++ = 0x0c; + *fake++ = 0x12; + *fake++ = 0x18; + *fake++ = 0x24; + *fake++ = 0x30; + *fake++ = 0x48; + *fake++ = 0x60; + *fake++ = 0x6c; + lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); + + cfg80211_inform_bss(priv->wdev->wiphy, + params->channel, + bssid, + 0, + capability, + params->beacon_interval, + fake_ie, fake - fake_ie, + 0, GFP_KERNEL); + + memcpy(priv->wdev->ssid, params->ssid, params->ssid_len); + priv->wdev->ssid_len = params->ssid_len; + + cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL); + + /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */ + priv->connect_status = LBS_CONNECTED; + netif_carrier_on(priv->dev); + if (!priv->tx_pending_len) + netif_wake_queue(priv->dev); + + lbs_deb_leave(LBS_DEB_CFG80211); +} + +static int lbs_ibss_join_existing(struct lbs_private *priv, + struct cfg80211_ibss_params *params, + struct cfg80211_bss *bss) +{ + const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); + struct cmd_ds_802_11_ad_hoc_join cmd; + u8 preamble = RADIO_PREAMBLE_SHORT; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + /* TODO: set preamble based on scan result */ + ret = lbs_set_radio(priv, preamble, 1); + if (ret) + goto out; + + /* + * Example CMD_802_11_AD_HOC_JOIN command: + * + * command 2c 00 CMD_802_11_AD_HOC_JOIN + * size 65 00 + * sequence xx xx + * result 00 00 + * bssid 02 27 27 97 2f 96 + * ssid 49 42 53 53 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * type 02 CMD_BSS_TYPE_IBSS + * beacon period 64 00 + * dtim period 00 + * timestamp 00 00 00 00 00 00 00 00 + * localtime 00 00 00 00 00 00 00 00 + * IE DS 03 + * IE DS len 01 + * IE DS channel 01 + * reserveed 00 00 00 00 + * IE IBSS 06 + * IE IBSS len 02 + * IE IBSS atim 00 00 + * reserved 00 00 00 00 + * capability 02 00 + * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c 00 + * fail timeout ff 00 + * probe delay 00 00 + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + + memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN); + memcpy(cmd.bss.ssid, params->ssid, params->ssid_len); + cmd.bss.type = CMD_BSS_TYPE_IBSS; + cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); + cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; + cmd.bss.ds.header.len = 1; + cmd.bss.ds.channel = params->channel->hw_value; + cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; + cmd.bss.ibss.header.len = 2; + cmd.bss.ibss.atimwindow = 0; + cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); + + /* set rates to the intersection of our rates and the rates in the + bss */ + if (!rates_eid) { + lbs_add_rates(cmd.bss.rates); + } else { + int hw, i; + u8 rates_max = rates_eid[1]; + u8 *rates = cmd.bss.rates; + for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { + u8 hw_rate = lbs_rates[hw].bitrate / 5; + for (i = 0; i < rates_max; i++) { + if (hw_rate == (rates_eid[i+2] & 0x7f)) { + u8 rate = rates_eid[i+2]; + if (rate == 0x02 || rate == 0x04 || + rate == 0x0b || rate == 0x16) + rate |= 0x80; + *rates++ = rate; + } + } + } + } + + /* Only v8 and below support setting this */ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { + cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); + cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); + } + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); + if (ret) + goto out; + + /* + * This is a sample response to CMD_802_11_AD_HOC_JOIN: + * + * response 2c 80 + * size 09 00 + * sequence xx xx + * result 00 00 + * reserved 00 + */ + lbs_join_post(priv, params, bss->bssid, bss->capability); out: lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); @@ -100,9 +1698,169 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy, +static int lbs_ibss_start_new(struct lbs_private *priv, + struct cfg80211_ibss_params *params) +{ + struct cmd_ds_802_11_ad_hoc_start cmd; + struct cmd_ds_802_11_ad_hoc_result *resp = + (struct cmd_ds_802_11_ad_hoc_result *) &cmd; + u8 preamble = RADIO_PREAMBLE_SHORT; + int ret = 0; + u16 capability; + + lbs_deb_enter(LBS_DEB_CFG80211); + + ret = lbs_set_radio(priv, preamble, 1); + if (ret) + goto out; + + /* + * Example CMD_802_11_AD_HOC_START command: + * + * command 2b 00 CMD_802_11_AD_HOC_START + * size b1 00 + * sequence xx xx + * result 00 00 + * ssid 54 45 53 54 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 + * bss type 02 + * beacon period 64 00 + * dtim period 00 + * IE IBSS 06 + * IE IBSS len 02 + * IE IBSS atim 00 00 + * reserved 00 00 00 00 + * IE DS 03 + * IE DS len 01 + * IE DS channel 01 + * reserved 00 00 00 00 + * probe delay 00 00 + * capability 02 00 + * rates 82 84 8b 96 (basic rates with have bit 7 set) + * 0c 12 18 24 30 48 60 6c + * padding 100 bytes + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + memcpy(cmd.ssid, params->ssid, params->ssid_len); + cmd.bsstype = CMD_BSS_TYPE_IBSS; + cmd.beaconperiod = cpu_to_le16(params->beacon_interval); + cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS; + cmd.ibss.header.len = 2; + cmd.ibss.atimwindow = 0; + cmd.ds.header.id = WLAN_EID_DS_PARAMS; + cmd.ds.header.len = 1; + cmd.ds.channel = params->channel->hw_value; + /* Only v8 and below support setting probe delay */ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) + cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); + /* TODO: mix in WLAN_CAPABILITY_PRIVACY */ + capability = WLAN_CAPABILITY_IBSS; + cmd.capability = cpu_to_le16(capability); + lbs_add_rates(cmd.rates); + + + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); + if (ret) + goto out; + + /* + * This is a sample response to CMD_802_11_AD_HOC_JOIN: + * + * response 2b 80 + * size 14 00 + * sequence xx xx + * result 00 00 + * reserved 00 + * bssid 02 2b 7b 0f 86 0e + */ + lbs_join_post(priv, params, resp->bssid, capability); + + out: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + +static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + int ret = 0; + struct cfg80211_bss *bss; + DECLARE_SSID_BUF(ssid_buf); + + lbs_deb_enter(LBS_DEB_CFG80211); + + if (!params->channel) { + ret = -ENOTSUPP; + goto out; + } + + ret = lbs_set_channel(priv, params->channel->hw_value); + if (ret) + goto out; + + /* Search if someone is beaconing. This assumes that the + * bss list is populated already */ + bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, + params->ssid, params->ssid_len, + WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); + + if (bss) { + ret = lbs_ibss_join_existing(priv, params, bss); + cfg80211_put_bss(bss); + } else + ret = lbs_ibss_start_new(priv, params); + + + out: + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + +static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + struct cmd_ds_802_11_ad_hoc_stop cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CFG80211); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd); + + /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */ + lbs_mac_event_disconnected(priv); + + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); + return ret; +} + + + + +/*************************************************************************** + * Initialization + */ static struct cfg80211_ops lbs_cfg80211_ops = { .set_channel = lbs_cfg_set_channel, + .scan = lbs_cfg_scan, + .connect = lbs_cfg_connect, + .disconnect = lbs_cfg_disconnect, + .add_key = lbs_cfg_add_key, + .del_key = lbs_cfg_del_key, + .set_default_key = lbs_cfg_set_default_key, + .get_station = lbs_cfg_get_station, + .dump_survey = lbs_get_survey, + .change_virtual_intf = lbs_change_intf, + .join_ibss = lbs_join_ibss, + .leave_ibss = lbs_leave_ibss, }; @@ -142,6 +1900,36 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev) } +static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv) +{ + struct region_code_mapping { + const char *cn; + int code; + }; + + /* Section 5.17.2 */ + static struct region_code_mapping regmap[] = { + {"US ", 0x10}, /* US FCC */ + {"CA ", 0x20}, /* Canada */ + {"EU ", 0x30}, /* ETSI */ + {"ES ", 0x31}, /* Spain */ + {"FR ", 0x32}, /* France */ + {"JP ", 0x40}, /* Japan */ + }; + size_t i; + + lbs_deb_enter(LBS_DEB_CFG80211); + + for (i = 0; i < ARRAY_SIZE(regmap); i++) + if (regmap[i].code == priv->regioncode) { + regulatory_hint(priv->wdev->wiphy, regmap[i].cn); + break; + } + + lbs_deb_leave(LBS_DEB_CFG80211); +} + + /* * This function get's called after lbs_setup_firmware() determined the * firmware capabities. So we can setup the wiphy according to our @@ -157,10 +1945,12 @@ int lbs_cfg_register(struct lbs_private *priv) wdev->wiphy->max_scan_ssids = 1; wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - /* TODO: BIT(NL80211_IFTYPE_ADHOC); */ - wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + wdev->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + if (lbs_rtap_supported(priv)) + wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); - /* TODO: honor priv->regioncode */ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz; /* @@ -169,6 +1959,7 @@ int lbs_cfg_register(struct lbs_private *priv) */ wdev->wiphy->cipher_suites = cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + wdev->wiphy->reg_notifier = lbs_reg_notifier; ret = wiphy_register(wdev->wiphy); if (ret < 0) @@ -180,10 +1971,36 @@ int lbs_cfg_register(struct lbs_private *priv) if (ret) lbs_pr_err("cannot register network device\n"); + INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); + + lbs_cfg_set_regulatory_hint(priv); + lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); return ret; } +int lbs_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct lbs_private *priv = wiphy_priv(wiphy); + int ret; + + lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " + "callback for domain %c%c\n", request->alpha2[0], + request->alpha2[1]); + + ret = lbs_set_11d_domain_info(priv, request, wiphy->bands); + + lbs_deb_leave(LBS_DEB_CFG80211); + return ret; +} + +void lbs_scan_deinit(struct lbs_private *priv) +{ + lbs_deb_enter(LBS_DEB_CFG80211); + cancel_delayed_work_sync(&priv->scan_work); +} + void lbs_cfg_free(struct lbs_private *priv) { diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h index e09a193a34d..4f46bb744be 100644 --- a/drivers/net/wireless/libertas/cfg.h +++ b/drivers/net/wireless/libertas/cfg.h @@ -1,16 +1,21 @@ #ifndef __LBS_CFG80211_H__ #define __LBS_CFG80211_H__ -#include "dev.h" +struct device; +struct lbs_private; +struct regulatory_request; +struct wiphy; struct wireless_dev *lbs_cfg_alloc(struct device *dev); int lbs_cfg_register(struct lbs_private *priv); void lbs_cfg_free(struct lbs_private *priv); -int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, - u8 ssid_len); -int lbs_scan_networks(struct lbs_private *priv, int full_scan); -void lbs_cfg_scan_worker(struct work_struct *work); +int lbs_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request); +void lbs_send_disconnect_notification(struct lbs_private *priv); +void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); + +void lbs_scan_deinit(struct lbs_private *priv); #endif diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index cdb9b9650d7..70745928f3f 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -6,18 +6,14 @@ #include <linux/kfifo.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/if_arp.h> -#include "host.h" #include "decl.h" -#include "defs.h" -#include "dev.h" -#include "assoc.h" -#include "wext.h" -#include "scan.h" +#include "cfg.h" #include "cmd.h" - -static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); +#define CAL_NF(nf) ((s32)(-(s32)(nf))) +#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf))) /** * @brief Simple callback that copies response back into command @@ -70,6 +66,8 @@ static u8 is_command_allowed_in_ps(u16 cmd) switch (cmd) { case CMD_802_11_RSSI: return 1; + case CMD_802_11_HOST_SLEEP_CFG: + return 1; default: break; } @@ -77,30 +75,6 @@ static u8 is_command_allowed_in_ps(u16 cmd) } /** - * @brief This function checks if the command is allowed. - * - * @param priv A pointer to lbs_private structure - * @return allowed or not allowed. - */ - -static int lbs_is_cmd_allowed(struct lbs_private *priv) -{ - int ret = 1; - - lbs_deb_enter(LBS_DEB_CMD); - - if (!priv->is_auto_deep_sleep_enabled) { - if (priv->is_deep_sleep) { - lbs_deb_cmd("command not allowed in deep sleep\n"); - ret = 0; - } - } - - lbs_deb_leave(LBS_DEB_CMD); - return ret; -} - -/** * @brief Updates the hardware details like MAC address and regulatory region * * @param priv A pointer to struct lbs_private structure @@ -175,16 +149,28 @@ int lbs_update_hw_spec(struct lbs_private *priv) if (priv->mesh_dev) memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN); - if (lbs_set_regiontable(priv, priv->regioncode, 0)) { - ret = -1; - goto out; - } - out: lbs_deb_leave(LBS_DEB_CMD); return ret; } +static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy, + struct cmd_header *resp) +{ + lbs_deb_enter(LBS_DEB_CMD); + if (priv->is_host_sleep_activated) { + priv->is_host_sleep_configured = 0; + if (priv->psstate == PS_STATE_FULL_POWER) { + priv->is_host_sleep_activated = 0; + wake_up_interruptible(&priv->host_sleep_q); + } + } else { + priv->is_host_sleep_configured = 1; + } + lbs_deb_leave(LBS_DEB_CMD); + return 0; +} + int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, struct wol_config *p_wol_config) { @@ -202,12 +188,11 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, else cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE; - ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); + ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr, + le16_to_cpu(cmd_config.hdr.size), + lbs_ret_host_sleep_cfg, 0); if (!ret) { - if (criteria) { - lbs_deb_cmd("Set WOL criteria to %x\n", criteria); - priv->wol_criteria = criteria; - } else + if (p_wol_config) memcpy((uint8_t *) p_wol_config, (uint8_t *)&cmd_config.wol_conf, sizeof(struct wol_config)); @@ -219,42 +204,49 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, } EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); -static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd, - u16 cmd_action) +/** + * @brief Sets the Power Save mode + * + * @param priv A pointer to struct lbs_private structure + * @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or + * PS_MODE_ACTION_EXIT_PS) + * @param block Whether to block on a response or not + * + * @return 0 on success, error on failure + */ +int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) { - struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; + struct cmd_ds_802_11_ps_mode cmd; + int ret = 0; lbs_deb_enter(LBS_DEB_CMD); - cmd->command = cpu_to_le16(CMD_802_11_PS_MODE); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + - sizeof(struct cmd_header)); - psm->action = cpu_to_le16(cmd_action); - psm->multipledtim = 0; - switch (cmd_action) { - case CMD_SUBCMD_ENTER_PS: - lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); - - psm->locallisteninterval = 0; - psm->nullpktinterval = 0; - psm->multipledtim = - cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM); - break; - - case CMD_SUBCMD_EXIT_PS: - lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); - break; - - case CMD_SUBCMD_SLEEP_CONFIRMED: - lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); - break; + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(cmd_action); - default: - break; + if (cmd_action == PS_MODE_ACTION_ENTER_PS) { + lbs_deb_cmd("PS_MODE: action ENTER_PS\n"); + cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */ + } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) { + lbs_deb_cmd("PS_MODE: action EXIT_PS\n"); + } else { + /* We don't handle CONFIRM_SLEEP here because it needs to + * be fastpathed to the firmware. + */ + lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action); + ret = -EOPNOTSUPP; + goto out; } - lbs_deb_leave(LBS_DEB_CMD); - return 0; + if (block) + ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd); + else + lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd)); + +out: + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; } int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, @@ -353,6 +345,65 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep) return ret; } +static int lbs_ret_host_sleep_activate(struct lbs_private *priv, + unsigned long dummy, + struct cmd_header *cmd) +{ + lbs_deb_enter(LBS_DEB_FW); + priv->is_host_sleep_activated = 1; + wake_up_interruptible(&priv->host_sleep_q); + lbs_deb_leave(LBS_DEB_FW); + return 0; +} + +int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep) +{ + struct cmd_header cmd; + int ret = 0; + uint32_t criteria = EHS_REMOVE_WAKEUP; + + lbs_deb_enter(LBS_DEB_CMD); + + if (host_sleep) { + if (priv->is_host_sleep_activated != 1) { + memset(&cmd, 0, sizeof(cmd)); + ret = lbs_host_sleep_cfg(priv, priv->wol_criteria, + (struct wol_config *)NULL); + if (ret) { + lbs_pr_info("Host sleep configuration failed: " + "%d\n", ret); + return ret; + } + if (priv->psstate == PS_STATE_FULL_POWER) { + ret = __lbs_cmd(priv, + CMD_802_11_HOST_SLEEP_ACTIVATE, + &cmd, + sizeof(cmd), + lbs_ret_host_sleep_activate, 0); + if (ret) + lbs_pr_info("HOST_SLEEP_ACTIVATE " + "failed: %d\n", ret); + } + + if (!wait_event_interruptible_timeout( + priv->host_sleep_q, + priv->is_host_sleep_activated, + (10 * HZ))) { + lbs_pr_err("host_sleep_q: timer expired\n"); + ret = -1; + } + } else { + lbs_pr_err("host sleep: already enabled\n"); + } + } else { + if (priv->is_host_sleep_activated) + ret = lbs_host_sleep_cfg(priv, criteria, + (struct wol_config *)NULL); + } + + return ret; +} + /** * @brief Set an SNMP MIB value * @@ -509,23 +560,35 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) return ret; } -static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf) +/** + * @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW) + * + * @param priv A pointer to struct lbs_private structure + * @param enable 1 to enable monitor mode, 0 to disable + * + * @return 0 on success, error on failure + */ +int lbs_set_monitor_mode(struct lbs_private *priv, int enable) { - struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor; + struct cmd_ds_802_11_monitor_mode cmd; + int ret; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); + if (enable) + cmd.mode = cpu_to_le16(0x1); - cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) + - sizeof(struct cmd_header)); + lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable); - monitor->action = cpu_to_le16(cmd_action); - if (cmd_action == CMD_ACT_SET) { - monitor->mode = - cpu_to_le16((u16) (*(u32 *) pdata_buf)); + ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); + if (ret == 0) { + priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP : + ARPHRD_ETHER; } - return 0; + lbs_deb_leave(LBS_DEB_CMD); + return ret; } /** @@ -610,78 +673,242 @@ out: return ret; } -static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, - u8 cmd_action, void *pdata_buf) +/** + * @brief Get current RSSI and noise floor + * + * @param priv A pointer to struct lbs_private structure + * @param rssi On successful return, signal level in mBm + * + * @return The channel on success, error on failure + */ +int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) { - struct lbs_offset_value *offval; + struct cmd_ds_802_11_rssi cmd; + int ret = 0; lbs_deb_enter(LBS_DEB_CMD); - offval = (struct lbs_offset_value *)pdata_buf; + BUG_ON(rssi == NULL); + BUG_ON(nf == NULL); - switch (le16_to_cpu(cmdptr->command)) { - case CMD_MAC_REG_ACCESS: - { - struct cmd_ds_mac_reg_access *macreg; + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + /* Average SNR over last 8 beacons */ + cmd.n_or_snr = cpu_to_le16(8); - cmdptr->size = - cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access) - + sizeof(struct cmd_header)); - macreg = - (struct cmd_ds_mac_reg_access *)&cmdptr->params. - macreg; + ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); + if (ret == 0) { + *nf = CAL_NF(le16_to_cpu(cmd.nf)); + *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf)); + } - macreg->action = cpu_to_le16(cmd_action); - macreg->offset = cpu_to_le16((u16) offval->offset); - macreg->value = cpu_to_le32(offval->value); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} - break; - } +/** + * @brief Send regulatory and 802.11d domain information to the firmware + * + * @param priv pointer to struct lbs_private + * @param request cfg80211 regulatory request structure + * @param bands the device's supported bands and channels + * + * @return 0 on success, error code on failure +*/ +int lbs_set_11d_domain_info(struct lbs_private *priv, + struct regulatory_request *request, + struct ieee80211_supported_band **bands) +{ + struct cmd_ds_802_11d_domain_info cmd; + struct mrvl_ie_domain_param_set *domain = &cmd.domain; + struct ieee80211_country_ie_triplet *t; + enum ieee80211_band band; + struct ieee80211_channel *ch; + u8 num_triplet = 0; + u8 num_parsed_chan = 0; + u8 first_channel = 0, next_chan = 0, max_pwr = 0; + u8 i, flag = 0; + size_t triplet_size; + int ret; - case CMD_BBP_REG_ACCESS: - { - struct cmd_ds_bbp_reg_access *bbpreg; + lbs_deb_enter(LBS_DEB_11D); - cmdptr->size = - cpu_to_le16(sizeof - (struct cmd_ds_bbp_reg_access) - + sizeof(struct cmd_header)); - bbpreg = - (struct cmd_ds_bbp_reg_access *)&cmdptr->params. - bbpreg; + memset(&cmd, 0, sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); - bbpreg->action = cpu_to_le16(cmd_action); - bbpreg->offset = cpu_to_le16((u16) offval->offset); - bbpreg->value = (u8) offval->value; + lbs_deb_11d("Setting country code '%c%c'\n", + request->alpha2[0], request->alpha2[1]); - break; - } + domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); - case CMD_RF_REG_ACCESS: - { - struct cmd_ds_rf_reg_access *rfreg; + /* Set country code */ + domain->country_code[0] = request->alpha2[0]; + domain->country_code[1] = request->alpha2[1]; + domain->country_code[2] = ' '; - cmdptr->size = - cpu_to_le16(sizeof - (struct cmd_ds_rf_reg_access) + - sizeof(struct cmd_header)); - rfreg = - (struct cmd_ds_rf_reg_access *)&cmdptr->params. - rfreg; + /* Now set up the channel triplets; firmware is somewhat picky here + * and doesn't validate channel numbers and spans; hence it would + * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since + * the last 3 aren't valid channels, the driver is responsible for + * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20) + * etc. + */ + for (band = 0; + (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS); + band++) { + + if (!bands[band]) + continue; + + for (i = 0; + (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS); + i++) { + ch = &bands[band]->channels[i]; + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (!flag) { + flag = 1; + next_chan = first_channel = (u32) ch->hw_value; + max_pwr = ch->max_power; + num_parsed_chan = 1; + continue; + } - rfreg->action = cpu_to_le16(cmd_action); - rfreg->offset = cpu_to_le16((u16) offval->offset); - rfreg->value = (u8) offval->value; + if ((ch->hw_value == next_chan + 1) && + (ch->max_power == max_pwr)) { + /* Consolidate adjacent channels */ + next_chan++; + num_parsed_chan++; + } else { + /* Add this triplet */ + lbs_deb_11d("11D triplet (%d, %d, %d)\n", + first_channel, num_parsed_chan, + max_pwr); + t = &domain->triplet[num_triplet]; + t->chans.first_channel = first_channel; + t->chans.num_channels = num_parsed_chan; + t->chans.max_power = max_pwr; + num_triplet++; + flag = 0; + } + } - break; + if (flag) { + /* Add last triplet */ + lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel, + num_parsed_chan, max_pwr); + t = &domain->triplet[num_triplet]; + t->chans.first_channel = first_channel; + t->chans.num_channels = num_parsed_chan; + t->chans.max_power = max_pwr; + num_triplet++; } + } - default: - break; + lbs_deb_11d("# triplets %d\n", num_triplet); + + /* Set command header sizes */ + triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet); + domain->header.len = cpu_to_le16(sizeof(domain->country_code) + + triplet_size); + + lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set", + (u8 *) &cmd.domain.country_code, + le16_to_cpu(domain->header.len)); + + cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) + + sizeof(cmd.action) + + sizeof(cmd.domain.header) + + sizeof(cmd.domain.country_code) + + triplet_size); + + ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); + + lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); + return ret; +} + +/** + * @brief Read a MAC, Baseband, or RF register + * + * @param priv pointer to struct lbs_private + * @param cmd register command, one of CMD_MAC_REG_ACCESS, + * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS + * @param offset byte offset of the register to get + * @param value on success, the value of the register at 'offset' + * + * @return 0 on success, error code on failure +*/ +int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) +{ + struct cmd_ds_reg_access cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + BUG_ON(value == NULL); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_GET); + + if (reg != CMD_MAC_REG_ACCESS && + reg != CMD_BBP_REG_ACCESS && + reg != CMD_RF_REG_ACCESS) { + ret = -EINVAL; + goto out; } - lbs_deb_leave(LBS_DEB_CMD); - return 0; + ret = lbs_cmd_with_response(priv, reg, &cmd); + if (ret) { + if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) + *value = cmd.value.bbp_rf; + else if (reg == CMD_MAC_REG_ACCESS) + *value = le32_to_cpu(cmd.value.mac); + } + +out: + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief Write a MAC, Baseband, or RF register + * + * @param priv pointer to struct lbs_private + * @param cmd register command, one of CMD_MAC_REG_ACCESS, + * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS + * @param offset byte offset of the register to set + * @param value the value to write to the register at 'offset' + * + * @return 0 on success, error code on failure +*/ +int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) +{ + struct cmd_ds_reg_access cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_SET); + + if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) + cmd.value.bbp_rf = (u8) (value & 0xFF); + else if (reg == CMD_MAC_REG_ACCESS) + cmd.value.mac = cpu_to_le32(value); + else { + ret = -EINVAL; + goto out; + } + + ret = lbs_cmd_with_response(priv, reg, &cmd); + +out: + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; } static void lbs_queue_cmd(struct lbs_private *priv, @@ -704,14 +931,17 @@ static void lbs_queue_cmd(struct lbs_private *priv, /* Exit_PS command needs to be queued in the header always. */ if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { - struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1]; + struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf; - if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { + if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { if (priv->psstate != PS_STATE_FULL_POWER) addtail = 0; } } + if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) + addtail = 0; + spin_lock_irqsave(&priv->driver_lock, flags); if (addtail) @@ -744,7 +974,6 @@ static void lbs_submit_command(struct lbs_private *priv, spin_lock_irqsave(&priv->driver_lock, flags); priv->cur_cmd = cmdnode; - priv->cur_cmd_retcode = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); cmdsize = le16_to_cpu(cmd->size); @@ -817,9 +1046,6 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, int result) { - if (cmd == priv->cur_cmd) - priv->cur_cmd_retcode = result; - cmd->result = result; cmd->cmdwaitqwoken = 1; wake_up_interruptible(&cmd->cmdwait_q); @@ -887,175 +1113,6 @@ void lbs_set_mac_control(struct lbs_private *priv) } /** - * @brief This function prepare the command before send to firmware. - * - * @param priv A pointer to struct lbs_private structure - * @param cmd_no command number - * @param cmd_action command action: GET or SET - * @param wait_option wait option: wait response or not - * @param cmd_oid cmd oid: treated as sub command - * @param pdata_buf A pointer to informaion buffer - * @return 0 or -1 - */ -int lbs_prepare_and_send_command(struct lbs_private *priv, - u16 cmd_no, - u16 cmd_action, - u16 wait_option, u32 cmd_oid, void *pdata_buf) -{ - int ret = 0; - struct cmd_ctrl_node *cmdnode; - struct cmd_ds_command *cmdptr; - unsigned long flags; - - lbs_deb_enter(LBS_DEB_HOST); - - if (!priv) { - lbs_deb_host("PREP_CMD: priv is NULL\n"); - ret = -1; - goto done; - } - - if (priv->surpriseremoved) { - lbs_deb_host("PREP_CMD: card removed\n"); - ret = -1; - goto done; - } - - if (!lbs_is_cmd_allowed(priv)) { - ret = -EBUSY; - goto done; - } - - cmdnode = lbs_get_cmd_ctrl_node(priv); - - if (cmdnode == NULL) { - lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); - - /* Wake up main thread to execute next command */ - wake_up_interruptible(&priv->waitq); - ret = -1; - goto done; - } - - cmdnode->callback = NULL; - cmdnode->callback_arg = (unsigned long)pdata_buf; - - cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf; - - lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no); - - /* Set sequence number, command and INT option */ - priv->seqnum++; - cmdptr->seqnum = cpu_to_le16(priv->seqnum); - - cmdptr->command = cpu_to_le16(cmd_no); - cmdptr->result = 0; - - switch (cmd_no) { - case CMD_802_11_PS_MODE: - ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); - break; - - case CMD_MAC_REG_ACCESS: - case CMD_BBP_REG_ACCESS: - case CMD_RF_REG_ACCESS: - ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); - break; - - case CMD_802_11_MONITOR_MODE: - ret = lbs_cmd_802_11_monitor_mode(cmdptr, - cmd_action, pdata_buf); - break; - - case CMD_802_11_RSSI: - ret = lbs_cmd_802_11_rssi(priv, cmdptr); - break; - - case CMD_802_11_SET_AFC: - case CMD_802_11_GET_AFC: - - cmdptr->command = cpu_to_le16(cmd_no); - cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) + - sizeof(struct cmd_header)); - - memmove(&cmdptr->params.afc, - pdata_buf, sizeof(struct cmd_ds_802_11_afc)); - - ret = 0; - goto done; - - case CMD_802_11_TPC_CFG: - cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG); - cmdptr->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) + - sizeof(struct cmd_header)); - - memmove(&cmdptr->params.tpccfg, - pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg)); - - ret = 0; - break; - -#ifdef CONFIG_LIBERTAS_MESH - - case CMD_BT_ACCESS: - ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf); - break; - - case CMD_FWT_ACCESS: - ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf); - break; - -#endif - - case CMD_802_11_BEACON_CTRL: - ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); - break; - case CMD_802_11_DEEP_SLEEP: - cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP); - cmdptr->size = cpu_to_le16(sizeof(struct cmd_header)); - break; - default: - lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no); - ret = -1; - break; - } - - /* return error, since the command preparation failed */ - if (ret != 0) { - lbs_deb_host("PREP_CMD: command preparation failed\n"); - lbs_cleanup_and_insert_cmd(priv, cmdnode); - ret = -1; - goto done; - } - - cmdnode->cmdwaitqwoken = 0; - - lbs_queue_cmd(priv, cmdnode); - wake_up_interruptible(&priv->waitq); - - if (wait_option & CMD_OPTION_WAITFORRSP) { - lbs_deb_host("PREP_CMD: wait for response\n"); - might_sleep(); - wait_event_interruptible(cmdnode->cmdwait_q, - cmdnode->cmdwaitqwoken); - } - - spin_lock_irqsave(&priv->driver_lock, flags); - if (priv->cur_cmd_retcode) { - lbs_deb_host("PREP_CMD: command failed with return code %d\n", - priv->cur_cmd_retcode); - priv->cur_cmd_retcode = 0; - ret = -1; - } - spin_unlock_irqrestore(&priv->driver_lock, flags); - -done: - lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); - return ret; -} - -/** * @brief This function allocates the command buffer and link * it to command free queue. * @@ -1148,7 +1205,7 @@ done: * @param priv A pointer to struct lbs_private structure * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL */ -static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) +static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) { struct cmd_ctrl_node *tempnode; unsigned long flags; @@ -1231,10 +1288,10 @@ int lbs_execute_next_command(struct lbs_private *priv) /* * 1. Non-PS command: * Queue it. set needtowakeup to TRUE if current state - * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS. - * 2. PS command but not Exit_PS: + * is SLEEP, otherwise call send EXIT_PS. + * 2. PS command but not EXIT_PS: * Ignore it. - * 3. PS command Exit_PS: + * 3. PS command EXIT_PS: * Set needtowakeup to TRUE if current state is SLEEP, * otherwise send this command down to firmware * immediately. @@ -1248,8 +1305,11 @@ int lbs_execute_next_command(struct lbs_private *priv) /* w/ new scheme, it will not reach here. since it is blocked in main_thread. */ priv->needtowakeup = 1; - } else - lbs_ps_wakeup(priv, 0); + } else { + lbs_set_ps_mode(priv, + PS_MODE_ACTION_EXIT_PS, + false); + } ret = 0; goto done; @@ -1264,7 +1324,7 @@ int lbs_execute_next_command(struct lbs_private *priv) "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", psm->action); if (psm->action != - cpu_to_le16(CMD_SUBCMD_EXIT_PS)) { + cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); list_del(&cmdnode->list); @@ -1303,6 +1363,15 @@ int lbs_execute_next_command(struct lbs_private *priv) * check if in power save mode, if yes, put the device back * to PS mode */ +#ifdef TODO + /* + * This was the old code for libertas+wext. Someone that + * understands this beast should re-code it in a sane way. + * + * I actually don't understand why this is related to WPA + * and to connection status, shouldn't powering should be + * independ of such things? + */ if ((priv->psmode != LBS802_11POWERMODECAM) && (priv->psstate == PS_STATE_FULL_POWER) && ((priv->connect_status == LBS_CONNECTED) || @@ -1315,15 +1384,19 @@ int lbs_execute_next_command(struct lbs_private *priv) lbs_deb_host( "EXEC_NEXT_CMD: WPA enabled and GTK_SET" " go back to PS_SLEEP"); - lbs_ps_sleep(priv, 0); + lbs_set_ps_mode(priv, + PS_MODE_ACTION_ENTER_PS, + false); } } else { lbs_deb_host( "EXEC_NEXT_CMD: cmdpendingq empty, " "go back to PS_SLEEP"); - lbs_ps_sleep(priv, 0); + lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, + false); } } +#endif } ret = 0; @@ -1353,6 +1426,11 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) /* We don't get a response on the sleep-confirmation */ priv->dnld_sent = DNLD_RES_RECEIVED; + if (priv->is_host_sleep_configured) { + priv->is_host_sleep_activated = 1; + wake_up_interruptible(&priv->host_sleep_q); + } + /* If nothing to do, go back to sleep (?) */ if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) priv->psstate = PS_STATE_SLEEP; @@ -1363,43 +1441,6 @@ out: lbs_deb_leave(LBS_DEB_HOST); } -void lbs_ps_sleep(struct lbs_private *priv, int wait_option) -{ - lbs_deb_enter(LBS_DEB_HOST); - - /* - * PS is currently supported only in Infrastructure mode - * Remove this check if it is to be supported in IBSS mode also - */ - - lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, - CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL); - - lbs_deb_leave(LBS_DEB_HOST); -} - -/** - * @brief This function sends Exit_PS command to firmware. - * - * @param priv A pointer to struct lbs_private structure - * @param wait_option wait response or not - * @return n/a - */ -void lbs_ps_wakeup(struct lbs_private *priv, int wait_option) -{ - __le32 Localpsmode; - - lbs_deb_enter(LBS_DEB_HOST); - - Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM); - - lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, - CMD_SUBCMD_EXIT_PS, - wait_option, 0, &Localpsmode); - - lbs_deb_leave(LBS_DEB_HOST); -} - /** * @brief This function checks condition and prepares to * send sleep confirm command to firmware if ok. @@ -1524,12 +1565,18 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, goto done; } - if (!lbs_is_cmd_allowed(priv)) { - cmdnode = ERR_PTR(-EBUSY); - goto done; + /* No commands are allowed in Deep Sleep until we toggle the GPIO + * to wake up the card and it has signaled that it's ready. + */ + if (!priv->is_auto_deep_sleep_enabled) { + if (priv->is_deep_sleep) { + lbs_deb_cmd("command not allowed in deep sleep\n"); + cmdnode = ERR_PTR(-EBUSY); + goto done; + } } - cmdnode = lbs_get_cmd_ctrl_node(priv); + cmdnode = lbs_get_free_cmd_node(priv); if (cmdnode == NULL) { lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index cb4138a55fd..7109d6b717e 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h @@ -3,6 +3,8 @@ #ifndef _LBS_CMD_H_ #define _LBS_CMD_H_ +#include <net/cfg80211.h> + #include "host.h" #include "dev.h" @@ -37,11 +39,6 @@ struct cmd_ctrl_node { #define lbs_cmd_with_response(priv, cmdnr, cmd) \ lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd)) -int lbs_prepare_and_send_command(struct lbs_private *priv, - u16 cmd_no, - u16 cmd_action, - u16 wait_option, u32 cmd_oid, void *pdata_buf); - void lbs_cmd_async(struct lbs_private *priv, uint16_t command, struct cmd_header *in_cmd, int in_cmd_size); @@ -92,10 +89,6 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, struct sleep_params *sp); -void lbs_ps_sleep(struct lbs_private *priv, int wait_option); - -void lbs_ps_wakeup(struct lbs_private *priv, int wait_option); - void lbs_ps_confirm_sleep(struct lbs_private *priv); int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on); @@ -127,4 +120,20 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm); int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep); +int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep); + +int lbs_set_monitor_mode(struct lbs_private *priv, int enable); + +int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf); + +int lbs_set_11d_domain_info(struct lbs_private *priv, + struct regulatory_request *request, + struct ieee80211_supported_band **bands); + +int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value); + +int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value); + +int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block); + #endif /* _LBS_CMD_H */ diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 88f7131d66e..5e95da9dcc2 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -5,18 +5,11 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/sched.h> -#include <linux/if_arp.h> -#include <linux/netdevice.h> #include <asm/unaligned.h> -#include <net/iw_handler.h> +#include <net/cfg80211.h> -#include "host.h" -#include "decl.h" +#include "cfg.h" #include "cmd.h" -#include "defs.h" -#include "dev.h" -#include "assoc.h" -#include "wext.h" /** * @brief This function handles disconnect event. it @@ -38,7 +31,9 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) * It causes problem in the Supplicant */ msleep_interruptible(1000); - lbs_send_disconnect_notification(priv); + + if (priv->wdev->iftype == NL80211_IFTYPE_STATION) + lbs_send_disconnect_notification(priv); /* report disconnect to upper layer */ netif_stop_queue(priv->dev); @@ -49,141 +44,16 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) priv->currenttxskb = NULL; priv->tx_pending_len = 0; - /* reset SNR/NF/RSSI values */ - memset(priv->SNR, 0x00, sizeof(priv->SNR)); - memset(priv->NF, 0x00, sizeof(priv->NF)); - memset(priv->RSSI, 0x00, sizeof(priv->RSSI)); - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); - memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); - priv->nextSNRNF = 0; - priv->numSNRNF = 0; priv->connect_status = LBS_DISCONNECTED; - /* Clear out associated SSID and BSSID since connection is - * no longer valid. - */ - memset(&priv->curbssparams.bssid, 0, ETH_ALEN); - memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN); - priv->curbssparams.ssid_len = 0; - if (priv->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ lbs_deb_cmd("disconnected, so exit PS mode\n"); - lbs_ps_wakeup(priv, 0); + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); } lbs_deb_leave(LBS_DEB_ASSOC); } -static int lbs_ret_reg_access(struct lbs_private *priv, - u16 type, struct cmd_ds_command *resp) -{ - int ret = 0; - - lbs_deb_enter(LBS_DEB_CMD); - - switch (type) { - case CMD_RET(CMD_MAC_REG_ACCESS): - { - struct cmd_ds_mac_reg_access *reg = &resp->params.macreg; - - priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); - priv->offsetvalue.value = le32_to_cpu(reg->value); - break; - } - - case CMD_RET(CMD_BBP_REG_ACCESS): - { - struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg; - - priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); - priv->offsetvalue.value = reg->value; - break; - } - - case CMD_RET(CMD_RF_REG_ACCESS): - { - struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg; - - priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset); - priv->offsetvalue.value = reg->value; - break; - } - - default: - ret = -1; - } - - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - -static inline int handle_cmd_response(struct lbs_private *priv, - struct cmd_header *cmd_response) -{ - struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response; - int ret = 0; - unsigned long flags; - uint16_t respcmd = le16_to_cpu(resp->command); - - lbs_deb_enter(LBS_DEB_HOST); - - switch (respcmd) { - case CMD_RET(CMD_MAC_REG_ACCESS): - case CMD_RET(CMD_BBP_REG_ACCESS): - case CMD_RET(CMD_RF_REG_ACCESS): - ret = lbs_ret_reg_access(priv, respcmd, resp); - break; - - case CMD_RET(CMD_802_11_SET_AFC): - case CMD_RET(CMD_802_11_GET_AFC): - spin_lock_irqsave(&priv->driver_lock, flags); - memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc, - sizeof(struct cmd_ds_802_11_afc)); - spin_unlock_irqrestore(&priv->driver_lock, flags); - - break; - - case CMD_RET(CMD_802_11_BEACON_STOP): - break; - - case CMD_RET(CMD_802_11_RSSI): - ret = lbs_ret_802_11_rssi(priv, resp); - break; - - case CMD_RET(CMD_802_11_TPC_CFG): - spin_lock_irqsave(&priv->driver_lock, flags); - memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, - sizeof(struct cmd_ds_802_11_tpc_cfg)); - spin_unlock_irqrestore(&priv->driver_lock, flags); - break; - - case CMD_RET(CMD_BT_ACCESS): - spin_lock_irqsave(&priv->driver_lock, flags); - if (priv->cur_cmd->callback_arg) - memcpy((void *)priv->cur_cmd->callback_arg, - &resp->params.bt.addr1, 2 * ETH_ALEN); - spin_unlock_irqrestore(&priv->driver_lock, flags); - break; - case CMD_RET(CMD_FWT_ACCESS): - spin_lock_irqsave(&priv->driver_lock, flags); - if (priv->cur_cmd->callback_arg) - memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt, - sizeof(resp->params.fwt)); - spin_unlock_irqrestore(&priv->driver_lock, flags); - break; - case CMD_RET(CMD_802_11_BEACON_CTRL): - ret = lbs_ret_802_11_bcn_ctrl(priv, resp); - break; - - default: - lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n", - le16_to_cpu(resp->command)); - break; - } - lbs_deb_leave(LBS_DEB_HOST); - return ret; -} - int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) { uint16_t respcmd, curcmd; @@ -242,9 +112,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) del_timer(&priv->command_timer); priv->cmd_timed_out = 0; - /* Store the response code to cur_cmd_retcode. */ - priv->cur_cmd_retcode = result; - if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) { struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1]; u16 action = le16_to_cpu(psmode->action); @@ -261,10 +128,10 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) * ad-hoc mode. It takes place in * lbs_execute_next_command(). */ - if (priv->mode == IW_MODE_ADHOC && - action == CMD_SUBCMD_ENTER_PS) + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR && + action == PS_MODE_ACTION_ENTER_PS) priv->psmode = LBS802_11POWERMODECAM; - } else if (action == CMD_SUBCMD_ENTER_PS) { + } else if (action == PS_MODE_ACTION_ENTER_PS) { priv->needtowakeup = 0; priv->psstate = PS_STATE_AWAKE; @@ -279,11 +146,12 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) spin_unlock_irqrestore(&priv->driver_lock, flags); mutex_unlock(&priv->lock); - lbs_ps_wakeup(priv, 0); + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, + false); mutex_lock(&priv->lock); spin_lock_irqsave(&priv->driver_lock, flags); } - } else if (action == CMD_SUBCMD_EXIT_PS) { + } else if (action == PS_MODE_ACTION_EXIT_PS) { priv->needtowakeup = 0; priv->psstate = PS_STATE_FULL_POWER; lbs_deb_host("CMD_RESP: EXIT_PS command response\n"); @@ -324,8 +192,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) if (priv->cur_cmd && priv->cur_cmd->callback) { ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, resp); - } else - ret = handle_cmd_response(priv, resp); + } spin_lock_irqsave(&priv->driver_lock, flags); @@ -341,32 +208,10 @@ done: return ret; } -static int lbs_send_confirmwake(struct lbs_private *priv) -{ - struct cmd_header cmd; - int ret = 0; - - lbs_deb_enter(LBS_DEB_HOST); - - cmd.command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM); - cmd.size = cpu_to_le16(sizeof(cmd)); - cmd.seqnum = cpu_to_le16(++priv->seqnum); - cmd.result = 0; - - lbs_deb_hex(LBS_DEB_HOST, "wake confirm", (u8 *) &cmd, - sizeof(cmd)); - - ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &cmd, sizeof(cmd)); - if (ret) - lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n"); - - lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); - return ret; -} - int lbs_process_event(struct lbs_private *priv, u32 event) { int ret = 0; + struct cmd_header cmd; lbs_deb_enter(LBS_DEB_CMD); @@ -410,7 +255,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event) if (priv->reset_deep_sleep_wakeup) priv->reset_deep_sleep_wakeup(priv); priv->is_deep_sleep = 0; - lbs_send_confirmwake(priv); + lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd, + sizeof(cmd)); + priv->is_host_sleep_activated = 0; + wake_up_interruptible(&priv->host_sleep_q); break; case MACREG_INT_CODE_DEEP_SLEEP_AWAKE: @@ -441,7 +289,7 @@ int lbs_process_event(struct lbs_private *priv, u32 event) * in lbs_ps_wakeup() */ lbs_deb_cmd("waking up ...\n"); - lbs_ps_wakeup(priv, 0); + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false); } break; diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index de2caac11dd..651a79c8de8 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -1,18 +1,13 @@ -#include <linux/module.h> #include <linux/dcache.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/mm.h> #include <linux/string.h> #include <linux/slab.h> -#include <net/iw_handler.h> -#include <net/lib80211.h> -#include "dev.h" #include "decl.h" -#include "host.h" -#include "debugfs.h" #include "cmd.h" +#include "debugfs.h" static struct dentry *lbs_dir; static char *szStates[] = { @@ -60,51 +55,6 @@ static ssize_t lbs_dev_info(struct file *file, char __user *userbuf, return res; } - -static ssize_t lbs_getscantable(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct lbs_private *priv = file->private_data; - size_t pos = 0; - int numscansdone = 0, res; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - DECLARE_SSID_BUF(ssid); - struct bss_descriptor * iter_bss; - if (!buf) - return -ENOMEM; - - pos += snprintf(buf+pos, len-pos, - "# | ch | rssi | bssid | cap | Qual | SSID\n"); - - mutex_lock(&priv->lock); - list_for_each_entry (iter_bss, &priv->network_list, list) { - u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS); - u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY); - u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); - - pos += snprintf(buf+pos, len-pos, "%02u| %03d | %04d | %pM |", - numscansdone, iter_bss->channel, iter_bss->rssi, - iter_bss->bssid); - pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); - pos += snprintf(buf+pos, len-pos, "%c%c%c |", - ibss ? 'A' : 'I', privacy ? 'P' : ' ', - spectrum_mgmt ? 'S' : ' '); - pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi)); - pos += snprintf(buf+pos, len-pos, " %s\n", - print_ssid(ssid, iter_bss->ssid, - iter_bss->ssid_len)); - - numscansdone++; - } - mutex_unlock(&priv->lock); - - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - - free_page(addr); - return res; -} - static ssize_t lbs_sleepparams_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -174,6 +124,70 @@ out_unlock: return ret; } +static ssize_t lbs_host_sleep_write(struct file *file, + const char __user *user_buf, size_t count, + loff_t *ppos) +{ + struct lbs_private *priv = file->private_data; + ssize_t buf_size, ret; + int host_sleep; + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *)addr; + if (!buf) + return -ENOMEM; + + buf_size = min(count, len - 1); + if (copy_from_user(buf, user_buf, buf_size)) { + ret = -EFAULT; + goto out_unlock; + } + ret = sscanf(buf, "%d", &host_sleep); + if (ret != 1) { + ret = -EINVAL; + goto out_unlock; + } + + if (host_sleep == 0) + ret = lbs_set_host_sleep(priv, 0); + else if (host_sleep == 1) { + if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { + lbs_pr_info("wake parameters not configured"); + ret = -EINVAL; + goto out_unlock; + } + ret = lbs_set_host_sleep(priv, 1); + } else { + lbs_pr_err("invalid option\n"); + ret = -EINVAL; + } + + if (!ret) + ret = count; + +out_unlock: + free_page(addr); + return ret; +} + +static ssize_t lbs_host_sleep_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct lbs_private *priv = file->private_data; + ssize_t ret; + size_t pos = 0; + unsigned long addr = get_zeroed_page(GFP_KERNEL); + char *buf = (char *)addr; + if (!buf) + return -ENOMEM; + + pos += snprintf(buf, len, "%d\n", priv->is_host_sleep_activated); + + ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); + + free_page(addr); + return ret; +} + /* * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the @@ -432,30 +446,24 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf, } - static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + u32 val = 0; + if (!buf) return -ENOMEM; - offval.offset = priv->mac_offset; - offval.value = 0; - - ret = lbs_prepare_and_send_command(priv, - CMD_MAC_REG_ACCESS, 0, - CMD_OPTION_WAITFORRSP, 0, &offval); + ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val); mdelay(10); if (!ret) { - pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n", - priv->mac_offset, priv->offsetvalue.value); - + pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n", + priv->mac_offset, val); ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -493,7 +501,6 @@ static ssize_t lbs_wrmac_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -510,11 +517,7 @@ static ssize_t lbs_wrmac_write(struct file *file, goto out_unlock; } - offval.offset = offset; - offval.value = value; - res = lbs_prepare_and_send_command(priv, - CMD_MAC_REG_ACCESS, 1, - CMD_OPTION_WAITFORRSP, 0, &offval); + res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value); mdelay(10); if (!res) @@ -528,25 +531,20 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + u32 val; + if (!buf) return -ENOMEM; - offval.offset = priv->bbp_offset; - offval.value = 0; - - ret = lbs_prepare_and_send_command(priv, - CMD_BBP_REG_ACCESS, 0, - CMD_OPTION_WAITFORRSP, 0, &offval); + ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val); mdelay(10); if (!ret) { - pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n", - priv->bbp_offset, priv->offsetvalue.value); - + pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n", + priv->bbp_offset, val); ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -585,7 +583,6 @@ static ssize_t lbs_wrbbp_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -602,11 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file, goto out_unlock; } - offval.offset = offset; - offval.value = value; - res = lbs_prepare_and_send_command(priv, - CMD_BBP_REG_ACCESS, 1, - CMD_OPTION_WAITFORRSP, 0, &offval); + res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value); mdelay(10); if (!res) @@ -620,25 +613,20 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { struct lbs_private *priv = file->private_data; - struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + u32 val; + if (!buf) return -ENOMEM; - offval.offset = priv->rf_offset; - offval.value = 0; - - ret = lbs_prepare_and_send_command(priv, - CMD_RF_REG_ACCESS, 0, - CMD_OPTION_WAITFORRSP, 0, &offval); + ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val); mdelay(10); if (!ret) { - pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n", - priv->rf_offset, priv->offsetvalue.value); - + pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n", + priv->rf_offset, val); ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); } free_page(addr); @@ -677,7 +665,6 @@ static ssize_t lbs_wrrf_write(struct file *file, struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; if (!buf) @@ -694,11 +681,7 @@ static ssize_t lbs_wrrf_write(struct file *file, goto out_unlock; } - offval.offset = offset; - offval.value = value; - res = lbs_prepare_and_send_command(priv, - CMD_RF_REG_ACCESS, 1, - CMD_OPTION_WAITFORRSP, 0, &offval); + res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value); mdelay(10); if (!res) @@ -723,10 +706,10 @@ struct lbs_debugfs_files { static const struct lbs_debugfs_files debugfs_files[] = { { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), }, - { "getscantable", 0444, FOPS(lbs_getscantable, - write_file_dummy), }, { "sleepparams", 0644, FOPS(lbs_sleepparams_read, lbs_sleepparams_write), }, + { "hostsleep", 0644, FOPS(lbs_host_sleep_read, + lbs_host_sleep_write), }, }; static const struct lbs_debugfs_files debugfs_events_files[] = { @@ -891,7 +874,7 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, p = buf; - d = (struct debug_data *)file->private_data; + d = file->private_data; for (i = 0; i < num_of_items; i++) { if (d[i].size == 1) @@ -930,7 +913,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, char *p0; char *p1; char *p2; - struct debug_data *d = (struct debug_data *)f->private_data; + struct debug_data *d = f->private_data; pdata = kmalloc(cnt, GFP_KERNEL); if (pdata == NULL) diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 709ffcad22a..1d141fefd76 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -1,3 +1,4 @@ + /** * This file contains declaration referring to * functions defined in other source files @@ -12,6 +13,7 @@ struct lbs_private; struct sk_buff; struct net_device; +struct cmd_ds_command; /* ethtool.c */ @@ -34,11 +36,13 @@ int lbs_start_card(struct lbs_private *priv); void lbs_stop_card(struct lbs_private *priv); void lbs_host_to_card_done(struct lbs_private *priv); +int lbs_rtap_supported(struct lbs_private *priv); + int lbs_set_mac_address(struct net_device *dev, void *addr); void lbs_set_multicast_list(struct net_device *dev); int lbs_suspend(struct lbs_private *priv); -void lbs_resume(struct lbs_private *priv); +int lbs_resume(struct lbs_private *priv); void lbs_queue_event(struct lbs_private *priv, u32 event); void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); @@ -49,5 +53,4 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv); u32 lbs_fw_index_to_data_rate(u8 index); u8 lbs_data_rate_to_fw_index(u32 rate); - #endif diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index ea3f10ef4e0..d00c728cec4 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -172,11 +172,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define MRVDRV_MAX_BSS_DESCRIPTS 16 #define MRVDRV_MAX_REGION_CODE 6 -#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe -#define MRVDRV_MIN_MULTIPLE_DTIM 1 -#define MRVDRV_MAX_MULTIPLE_DTIM 5 -#define MRVDRV_DEFAULT_MULTIPLE_DTIM 1 - #define MRVDRV_DEFAULT_LISTEN_INTERVAL 10 #define MRVDRV_CHANNELS_PER_SCAN 4 @@ -301,19 +296,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define BAND_G (0x02) #define ALL_802_11_BANDS (BAND_B | BAND_G) -/** MACRO DEFINITIONS */ -#define CAL_NF(NF) ((s32)(-(s32)(NF))) -#define CAL_RSSI(SNR, NF) ((s32)((s32)(SNR) + CAL_NF(NF))) -#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) - -#define DEFAULT_BCN_AVG_FACTOR 8 -#define DEFAULT_DATA_AVG_FACTOR 8 -#define AVG_SCALE 100 -#define CAL_AVG_SNR_NF(AVG, SNRNF, N) \ - (((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \ - ((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \ - AVG_SCALE)) / N)) - #define MAX_RATES 14 #define MAX_LEDS 8 diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index a54880e4ad2..3c7e255e18c 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -7,8 +7,8 @@ #define _LBS_DEV_H_ #include "mesh.h" -#include "scan.h" -#include "assoc.h" +#include "defs.h" +#include "host.h" #include <linux/kfifo.h> @@ -29,7 +29,6 @@ struct lbs_private { /* Basic networking */ struct net_device *dev; u32 connect_status; - int infra_open; struct work_struct mcast_work; u32 nr_of_multicastmacaddr; u8 multicastlist[MRVDRV_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; @@ -37,6 +36,9 @@ struct lbs_private { /* CFG80211 */ struct wireless_dev *wdev; bool wiphy_registered; + struct cfg80211_scan_request *scan_req; + u8 assoc_bss[ETH_ALEN]; + u8 disassoc_reason; /* Mesh */ struct net_device *mesh_dev; /* Virtual device */ @@ -49,10 +51,6 @@ struct lbs_private { u8 mesh_ssid_len; #endif - /* Monitor mode */ - struct net_device *rtap_net_dev; - u32 monitormode; - /* Debugfs */ struct dentry *debugfs_dir; struct dentry *debugfs_debug; @@ -66,7 +64,6 @@ struct lbs_private { u32 mac_offset; u32 bbp_offset; u32 rf_offset; - struct lbs_offset_value offsetvalue; /* Power management */ u16 psmode; @@ -75,6 +72,7 @@ struct lbs_private { /* Deep sleep */ int is_deep_sleep; + int deep_sleep_required; int is_auto_deep_sleep_enabled; int wakeup_dev_required; int is_activity_detected; @@ -82,6 +80,11 @@ struct lbs_private { wait_queue_head_t ds_awake_q; struct timer_list auto_deepsleep_timer; + /* Host sleep*/ + int is_host_sleep_configured; + int is_host_sleep_activated; + wait_queue_head_t host_sleep_q; + /* Hardware access */ void *card; u8 fw_ready; @@ -108,12 +111,10 @@ struct lbs_private { struct cmd_ctrl_node *cur_cmd; struct list_head cmdfreeq; /* free command buffers */ struct list_head cmdpendingq; /* pending command buffers */ - wait_queue_head_t cmd_pending; struct timer_list command_timer; int cmd_timed_out; /* Command responses sent from the hardware to the driver */ - int cur_cmd_retcode; u8 resp_idx; u8 resp_buf[2][LBS_UPLD_SIZE]; u32 resp_len[2]; @@ -127,14 +128,10 @@ struct lbs_private { struct workqueue_struct *work_thread; /** Encryption stuff */ - struct lbs_802_11_security secinfo; - struct enc_key wpa_mcast_key; - struct enc_key wpa_unicast_key; - u8 wpa_ie[MAX_WPA_IE_LEN]; - u8 wpa_ie_len; - u16 wep_tx_keyidx; - struct enc_key wep_keys[4]; u8 authtype_auto; + u8 wep_tx_key; + u8 wep_key[4][WLAN_KEY_LEN_WEP104]; + u8 wep_key_len[4]; /* Wake On LAN */ uint32_t wol_criteria; @@ -155,6 +152,7 @@ struct lbs_private { /* NIC/link operation characteristics */ u16 mac_control; u8 radio_on; + u8 cur_rate; u8 channel; s16 txpower_cur; s16 txpower_min; @@ -163,42 +161,6 @@ struct lbs_private { /** Scanning */ struct delayed_work scan_work; int scan_channel; - /* remember which channel was scanned last, != 0 if currently scanning */ - u8 scan_ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 scan_ssid_len; - - /* Associating */ - struct delayed_work assoc_work; - struct current_bss_params curbssparams; - u8 mode; - struct list_head network_list; - struct list_head network_free_list; - struct bss_descriptor *networks; - struct assoc_request * pending_assoc_req; - struct assoc_request * in_progress_assoc_req; - uint16_t enablehwauto; - - /* ADHOC */ - u16 beacon_period; - u8 beacon_enable; - u8 adhoccreate; - - /* WEXT */ - char name[DEV_NAME_LEN]; - u8 nodename[16]; - struct iw_statistics wstats; - u8 cur_rate; -#define MAX_REGION_CHANNEL_NUM 2 - struct region_channel region_channel[MAX_REGION_CHANNEL_NUM]; - - /** Requested Signal Strength*/ - u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG]; - u16 NF[MAX_TYPE_B][MAX_TYPE_AVG]; - u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG]; - u8 rawSNR[DEFAULT_DATA_AVG_FACTOR]; - u8 rawNF[DEFAULT_DATA_AVG_FACTOR]; - u16 nextSNRNF; - u16 numSNRNF; }; extern struct cmd_confirm_sleep confirm_sleep; diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 3804a58d7f4..50193aac679 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -2,13 +2,8 @@ #include <linux/ethtool.h> #include <linux/delay.h> -#include "host.h" #include "decl.h" -#include "defs.h" -#include "dev.h" -#include "wext.h" #include "cmd.h" -#include "mesh.h" static void lbs_ethtool_get_drvinfo(struct net_device *dev, @@ -69,14 +64,11 @@ static void lbs_ethtool_get_wol(struct net_device *dev, { struct lbs_private *priv = dev->ml_priv; - if (priv->wol_criteria == 0xffffffff) { - /* Interface driver didn't configure wake */ - wol->supported = wol->wolopts = 0; - return; - } - wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY; + if (priv->wol_criteria == EHS_REMOVE_WAKEUP) + return; + if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA) wol->wolopts |= WAKE_UCAST; if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA) @@ -91,23 +83,22 @@ static int lbs_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct lbs_private *priv = dev->ml_priv; - uint32_t criteria = 0; if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) return -EOPNOTSUPP; + priv->wol_criteria = 0; if (wol->wolopts & WAKE_UCAST) - criteria |= EHS_WAKE_ON_UNICAST_DATA; + priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA; if (wol->wolopts & WAKE_MCAST) - criteria |= EHS_WAKE_ON_MULTICAST_DATA; + priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA; if (wol->wolopts & WAKE_BCAST) - criteria |= EHS_WAKE_ON_BROADCAST_DATA; + priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA; if (wol->wolopts & WAKE_PHY) - criteria |= EHS_WAKE_ON_MAC_EVENT; + priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT; if (wol->wolopts == 0) - criteria |= EHS_REMOVE_WAKEUP; - - return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL); + priv->wol_criteria |= EHS_REMOVE_WAKEUP; + return 0; } const struct ethtool_ops lbs_ethtool_ops = { diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 3809c0b4946..5eac1351a02 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -94,11 +94,9 @@ #define CMD_802_11_BEACON_CTRL 0x00b0 /* For the IEEE Power Save */ -#define CMD_SUBCMD_ENTER_PS 0x0030 -#define CMD_SUBCMD_EXIT_PS 0x0031 -#define CMD_SUBCMD_SLEEP_CONFIRMED 0x0034 -#define CMD_SUBCMD_FULL_POWERDOWN 0x0035 -#define CMD_SUBCMD_FULL_POWERUP 0x0036 +#define PS_MODE_ACTION_ENTER_PS 0x0030 +#define PS_MODE_ACTION_EXIT_PS 0x0031 +#define PS_MODE_ACTION_SLEEP_CONFIRMED 0x0034 #define CMD_ENABLE_RSN 0x0001 #define CMD_DISABLE_RSN 0x0000 @@ -163,11 +161,6 @@ #define CMD_ACT_SET_TX_FIX_RATE 0x0001 #define CMD_ACT_GET_TX_RATE 0x0002 -/* Define action or option for CMD_802_11_PS_MODE */ -#define CMD_TYPE_CAM 0x0000 -#define CMD_TYPE_MAX_PSP 0x0001 -#define CMD_TYPE_FAST_PSP 0x0002 - /* Options for CMD_802_11_FW_WAKE_METHOD */ #define CMD_WAKE_METHOD_UNCHANGED 0x0000 #define CMD_WAKE_METHOD_COMMAND_INT 0x0001 @@ -326,7 +319,7 @@ struct txpd { u8 pktdelay_2ms; /* reserved */ u8 reserved1; -} __attribute__ ((packed)); +} __packed; /* RxPD Descriptor */ struct rxpd { @@ -339,8 +332,8 @@ struct rxpd { u8 bss_type; /* BSS number */ u8 bss_num; - } __attribute__ ((packed)) bss; - } __attribute__ ((packed)) u; + } __packed bss; + } __packed u; /* SNR */ u8 snr; @@ -366,14 +359,14 @@ struct rxpd { /* Pkt Priority */ u8 priority; u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; struct cmd_header { __le16 command; __le16 size; __le16 seqnum; __le16 result; -} __attribute__ ((packed)); +} __packed; /* Generic structure to hold all key types. */ struct enc_key { @@ -387,7 +380,23 @@ struct enc_key { struct lbs_offset_value { u32 offset; u32 value; -} __attribute__ ((packed)); +} __packed; + +#define MAX_11D_TRIPLETS 83 + +struct mrvl_ie_domain_param_set { + struct mrvl_ie_header header; + + u8 country_code[3]; + struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; +} __packed; + +struct cmd_ds_802_11d_domain_info { + struct cmd_header hdr; + + __le16 action; + struct mrvl_ie_domain_param_set domain; +} __packed; /* * Define data structure for CMD_GET_HW_SPEC @@ -426,7 +435,7 @@ struct cmd_ds_get_hw_spec { /*FW/HW capability */ __le32 fwcapinfo; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_subscribe_event { struct cmd_header hdr; @@ -440,7 +449,7 @@ struct cmd_ds_802_11_subscribe_event { * bump this up a bit. */ uint8_t tlv[128]; -} __attribute__ ((packed)); +} __packed; /* * This scan handle Country Information IE(802.11d compliant) @@ -452,7 +461,7 @@ struct cmd_ds_802_11_scan { uint8_t bsstype; uint8_t bssid[ETH_ALEN]; uint8_t tlvbuffer[0]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_scan_rsp { struct cmd_header hdr; @@ -460,7 +469,7 @@ struct cmd_ds_802_11_scan_rsp { __le16 bssdescriptsize; uint8_t nr_sets; uint8_t bssdesc_and_tlvbuffer[0]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_get_log { struct cmd_header hdr; @@ -478,20 +487,20 @@ struct cmd_ds_802_11_get_log { __le32 fcserror; __le32 txframe; __le32 wepundecryptable; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_mac_control { struct cmd_header hdr; __le16 action; u16 reserved; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_mac_multicast_adr { struct cmd_header hdr; __le16 action; __le16 nr_of_adrs; u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_authenticate { struct cmd_header hdr; @@ -499,14 +508,14 @@ struct cmd_ds_802_11_authenticate { u8 bssid[ETH_ALEN]; u8 authtype; u8 reserved[10]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_deauthenticate { struct cmd_header hdr; u8 macaddr[ETH_ALEN]; __le16 reasoncode; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_associate { struct cmd_header hdr; @@ -517,7 +526,7 @@ struct cmd_ds_802_11_associate { __le16 bcnperiod; u8 dtimperiod; u8 iebuf[512]; /* Enough for required and most optional IEs */ -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_associate_response { struct cmd_header hdr; @@ -526,7 +535,7 @@ struct cmd_ds_802_11_associate_response { __le16 statuscode; __le16 aid; u8 iebuf[512]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_set_wep { struct cmd_header hdr; @@ -540,7 +549,7 @@ struct cmd_ds_802_11_set_wep { /* 40, 128bit or TXWEP */ uint8_t keytype[4]; uint8_t keymaterial[4][16]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_snmp_mib { struct cmd_header hdr; @@ -549,40 +558,33 @@ struct cmd_ds_802_11_snmp_mib { __le16 oid; __le16 bufsize; u8 value[128]; -} __attribute__ ((packed)); - -struct cmd_ds_mac_reg_access { - __le16 action; - __le16 offset; - __le32 value; -} __attribute__ ((packed)); +} __packed; -struct cmd_ds_bbp_reg_access { - __le16 action; - __le16 offset; - u8 value; - u8 reserved[3]; -} __attribute__ ((packed)); +struct cmd_ds_reg_access { + struct cmd_header hdr; -struct cmd_ds_rf_reg_access { __le16 action; __le16 offset; - u8 value; - u8 reserved[3]; -} __attribute__ ((packed)); + union { + u8 bbp_rf; /* for BBP and RF registers */ + __le32 mac; /* for MAC registers */ + } value; +} __packed; struct cmd_ds_802_11_radio_control { struct cmd_header hdr; __le16 action; __le16 control; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_beacon_control { + struct cmd_header hdr; + __le16 action; __le16 beacon_enable; __le16 beacon_period; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_sleep_params { struct cmd_header hdr; @@ -607,7 +609,7 @@ struct cmd_ds_802_11_sleep_params { /* reserved field, should be set to zero */ __le16 reserved; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_rf_channel { struct cmd_header hdr; @@ -617,30 +619,30 @@ struct cmd_ds_802_11_rf_channel { __le16 rftype; /* unused */ __le16 reserved; /* unused */ u8 channellist[32]; /* unused */ -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_rssi { - /* weighting factor */ - __le16 N; + struct cmd_header hdr; - __le16 reserved_0; - __le16 reserved_1; - __le16 reserved_2; -} __attribute__ ((packed)); + /* request: number of beacons (N) to average the SNR and NF over + * response: SNR of most recent beacon + */ + __le16 n_or_snr; -struct cmd_ds_802_11_rssi_rsp { - __le16 SNR; - __le16 noisefloor; - __le16 avgSNR; - __le16 avgnoisefloor; -} __attribute__ ((packed)); + /* The following fields are only set in the response. + * In the request these are reserved and should be set to 0. + */ + __le16 nf; /* most recent beacon noise floor */ + __le16 avg_snr; /* average SNR weighted by N from request */ + __le16 avg_nf; /* average noise floor weighted by N from request */ +} __packed; struct cmd_ds_802_11_mac_address { struct cmd_header hdr; __le16 action; u8 macadd[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_rf_tx_power { struct cmd_header hdr; @@ -649,34 +651,61 @@ struct cmd_ds_802_11_rf_tx_power { __le16 curlevel; s8 maxlevel; s8 minlevel; -} __attribute__ ((packed)); +} __packed; +/* MONITOR_MODE only exists in OLPC v5 firmware */ struct cmd_ds_802_11_monitor_mode { + struct cmd_header hdr; + __le16 action; __le16 mode; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_set_boot2_ver { struct cmd_header hdr; __le16 action; __le16 version; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_fw_wake_method { struct cmd_header hdr; __le16 action; __le16 method; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_ps_mode { + struct cmd_header hdr; + __le16 action; + + /* Interval for keepalive in PS mode: + * 0x0000 = don't change + * 0x001E = firmware default + * 0xFFFF = disable + */ __le16 nullpktinterval; + + /* Number of DTIM intervals to wake up for: + * 0 = don't change + * 1 = firmware default + * 5 = max + */ __le16 multipledtim; + __le16 reserved; __le16 locallisteninterval; -} __attribute__ ((packed)); + + /* AdHoc awake period (FW v9+ only): + * 0 = don't change + * 1 = always awake (IEEE standard behavior) + * 2 - 31 = sleep for (n - 1) periods and awake for 1 period + * 32 - 254 = invalid + * 255 = sleep at each ATIM + */ + __le16 adhoc_awake_period; +} __packed; struct cmd_confirm_sleep { struct cmd_header hdr; @@ -686,7 +715,7 @@ struct cmd_confirm_sleep { __le16 multipledtim; __le16 reserved; __le16 locallisteninterval; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_data_rate { struct cmd_header hdr; @@ -694,14 +723,14 @@ struct cmd_ds_802_11_data_rate { __le16 action; __le16 reserved; u8 rates[MAX_RATES]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_rate_adapt_rateset { struct cmd_header hdr; __le16 action; __le16 enablehwauto; __le16 bitmap; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_ad_hoc_start { struct cmd_header hdr; @@ -718,14 +747,14 @@ struct cmd_ds_802_11_ad_hoc_start { __le16 capability; u8 rates[MAX_RATES]; u8 tlv_memory_size_pad[100]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_ad_hoc_result { struct cmd_header hdr; u8 pad[3]; u8 bssid[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct adhoc_bssdesc { u8 bssid[ETH_ALEN]; @@ -746,7 +775,7 @@ struct adhoc_bssdesc { * Adhoc join command and will cause a binary layout mismatch with * the firmware */ -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_ad_hoc_join { struct cmd_header hdr; @@ -754,18 +783,18 @@ struct cmd_ds_802_11_ad_hoc_join { struct adhoc_bssdesc bss; __le16 failtimeout; /* Reserved on v9 and later */ __le16 probedelay; /* Reserved on v9 and later */ -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_ad_hoc_stop { struct cmd_header hdr; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_enable_rsn { struct cmd_header hdr; __le16 action; __le16 enable; -} __attribute__ ((packed)); +} __packed; struct MrvlIEtype_keyParamSet { /* type ID */ @@ -785,7 +814,7 @@ struct MrvlIEtype_keyParamSet { /* key material of size keylen */ u8 key[32]; -} __attribute__ ((packed)); +} __packed; #define MAX_WOL_RULES 16 @@ -797,7 +826,7 @@ struct host_wol_rule { __le16 reserve; __be32 sig_mask; __be32 signature; -} __attribute__ ((packed)); +} __packed; struct wol_config { uint8_t action; @@ -805,7 +834,7 @@ struct wol_config { uint8_t no_rules_in_cmd; uint8_t result; struct host_wol_rule rule[MAX_WOL_RULES]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_host_sleep { struct cmd_header hdr; @@ -813,7 +842,7 @@ struct cmd_ds_host_sleep { uint8_t gpio; uint16_t gap; struct wol_config wol_conf; -} __attribute__ ((packed)); +} __packed; @@ -822,7 +851,7 @@ struct cmd_ds_802_11_key_material { __le16 action; struct MrvlIEtype_keyParamSet keyParamSet[2]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_eeprom_access { struct cmd_header hdr; @@ -832,7 +861,7 @@ struct cmd_ds_802_11_eeprom_access { /* firmware says it returns a maximum of 20 bytes */ #define LBS_EEPROM_READ_LEN 20 u8 value[LBS_EEPROM_READ_LEN]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_tpc_cfg { struct cmd_header hdr; @@ -843,7 +872,7 @@ struct cmd_ds_802_11_tpc_cfg { int8_t P1; int8_t P2; uint8_t usesnr; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_pa_cfg { @@ -854,16 +883,21 @@ struct cmd_ds_802_11_pa_cfg { int8_t P0; int8_t P1; int8_t P2; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_802_11_led_ctrl { + struct cmd_header hdr; + __le16 action; __le16 numled; u8 data[256]; -} __attribute__ ((packed)); +} __packed; +/* Automatic Frequency Control */ struct cmd_ds_802_11_afc { + struct cmd_header hdr; + __le16 afc_auto; union { struct { @@ -875,24 +909,28 @@ struct cmd_ds_802_11_afc { __le16 carrier_offset; /* signed */ }; }; -} __attribute__ ((packed)); +} __packed; struct cmd_tx_rate_query { __le16 txrate; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_get_tsf { __le64 tsfvalue; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_bt_access { + struct cmd_header hdr; + __le16 action; __le32 id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_fwt_access { + struct cmd_header hdr; + __le16 action; __le32 id; u8 valid; @@ -910,7 +948,7 @@ struct cmd_ds_fwt_access { __le32 snr; __le32 references; u8 prec[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_mesh_config { struct cmd_header hdr; @@ -920,43 +958,15 @@ struct cmd_ds_mesh_config { __le16 type; __le16 length; u8 data[128]; /* last position reserved */ -} __attribute__ ((packed)); +} __packed; struct cmd_ds_mesh_access { struct cmd_header hdr; __le16 action; __le32 data[32]; /* last position reserved */ -} __attribute__ ((packed)); +} __packed; /* Number of stats counters returned by the firmware */ #define MESH_STATS_NUM 8 - -struct cmd_ds_command { - /* command header */ - __le16 command; - __le16 size; - __le16 seqnum; - __le16 result; - - /* command Body */ - union { - struct cmd_ds_802_11_ps_mode psmode; - struct cmd_ds_802_11_monitor_mode monitor; - struct cmd_ds_802_11_rssi rssi; - struct cmd_ds_802_11_rssi_rsp rssirsp; - struct cmd_ds_mac_reg_access macreg; - struct cmd_ds_bbp_reg_access bbpreg; - struct cmd_ds_rf_reg_access rfreg; - - struct cmd_ds_802_11_tpc_cfg tpccfg; - struct cmd_ds_802_11_afc afc; - struct cmd_ds_802_11_led_ctrl ledgpio; - - struct cmd_ds_bt_access bt; - struct cmd_ds_fwt_access fwt; - struct cmd_ds_802_11_beacon_control bcn_ctrl; - } params; -} __attribute__ ((packed)); - #endif diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 64dd345d30f..6e71346a755 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1182,11 +1182,69 @@ static void if_sdio_remove(struct sdio_func *func) lbs_deb_leave(LBS_DEB_SDIO); } +static int if_sdio_suspend(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + int ret; + struct if_sdio_card *card = sdio_get_drvdata(func); + + mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); + + lbs_pr_info("%s: suspend: PM flags = 0x%x\n", + sdio_func_id(func), flags); + + /* If we aren't being asked to wake on anything, we should bail out + * and let the SD stack power down the card. + */ + if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) { + lbs_pr_info("Suspend without wake params -- " + "powering down card."); + return -ENOSYS; + } + + if (!(flags & MMC_PM_KEEP_POWER)) { + lbs_pr_err("%s: cannot remain alive while host is suspended\n", + sdio_func_id(func)); + return -ENOSYS; + } + + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (ret) + return ret; + + ret = lbs_suspend(card->priv); + if (ret) + return ret; + + return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); +} + +static int if_sdio_resume(struct device *dev) +{ + struct sdio_func *func = dev_to_sdio_func(dev); + struct if_sdio_card *card = sdio_get_drvdata(func); + int ret; + + lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func)); + + ret = lbs_resume(card->priv); + + return ret; +} + +static const struct dev_pm_ops if_sdio_pm_ops = { + .suspend = if_sdio_suspend, + .resume = if_sdio_resume, +}; + static struct sdio_driver if_sdio_driver = { .name = "libertas_sdio", .id_table = if_sdio_ids, .probe = if_sdio_probe, .remove = if_sdio_remove, + .drv = { + .pm = &if_sdio_pm_ops, + }, }; /*******************************************************************/ diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index f41594c7ac1..07ece9d26c6 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -433,7 +433,7 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) static int if_usb_reset_device(struct if_usb_card *cardp) { - struct cmd_ds_command *cmd = cardp->ep_out_buf + 4; + struct cmd_header *cmd = cardp->ep_out_buf + 4; int ret; lbs_deb_enter(LBS_DEB_USB); @@ -441,7 +441,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp) *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); cmd->command = cpu_to_le16(CMD_802_11_RESET); - cmd->size = cpu_to_le16(sizeof(struct cmd_header)); + cmd->size = cpu_to_le16(sizeof(cmd)); cmd->result = cpu_to_le16(0); cmd->seqnum = cpu_to_le16(0x5a5a); usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header)); @@ -613,16 +613,14 @@ static void if_usb_receive_fwload(struct urb *urb) return; } - syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); + syncfwheader = kmemdup(skb->data + IPFIELD_ALIGN_OFFSET, + sizeof(struct fwsyncheader), GFP_ATOMIC); if (!syncfwheader) { lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); kfree_skb(skb); return; } - memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET, - sizeof(struct fwsyncheader)); - if (!syncfwheader->cmd) { lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", @@ -1043,6 +1041,12 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) if (priv->psstate != PS_STATE_FULL_POWER) return -1; + if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { + lbs_pr_info("Suspend attempt without " + "configuring wake params!\n"); + return -ENOSYS; + } + ret = lbs_suspend(priv); if (ret) goto out; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index d9b8ee130c4..258967144b9 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -11,20 +11,14 @@ #include <linux/if_arp.h> #include <linux/kthread.h> #include <linux/kfifo.h> -#include <linux/stddef.h> -#include <linux/ieee80211.h> #include <linux/slab.h> -#include <net/iw_handler.h> #include <net/cfg80211.h> #include "host.h" #include "decl.h" #include "dev.h" -#include "wext.h" #include "cfg.h" #include "debugfs.h" -#include "scan.h" -#include "assoc.h" #include "cmd.h" #define DRIVER_RELEASE_VERSION "323.p0" @@ -96,72 +90,6 @@ u8 lbs_data_rate_to_fw_index(u32 rate) } -static int lbs_add_rtap(struct lbs_private *priv); -static void lbs_remove_rtap(struct lbs_private *priv); - - -/** - * Get function for sysfs attribute rtap - */ -static ssize_t lbs_rtap_get(struct device *dev, - struct device_attribute *attr, char * buf) -{ - struct lbs_private *priv = to_net_dev(dev)->ml_priv; - return snprintf(buf, 5, "0x%X\n", priv->monitormode); -} - -/** - * Set function for sysfs attribute rtap - */ -static ssize_t lbs_rtap_set(struct device *dev, - struct device_attribute *attr, const char * buf, size_t count) -{ - int monitor_mode; - struct lbs_private *priv = to_net_dev(dev)->ml_priv; - - sscanf(buf, "%x", &monitor_mode); - if (monitor_mode) { - if (priv->monitormode == monitor_mode) - return strlen(buf); - if (!priv->monitormode) { - if (priv->infra_open || lbs_mesh_open(priv)) - return -EBUSY; - if (priv->mode == IW_MODE_INFRA) - lbs_cmd_80211_deauthenticate(priv, - priv->curbssparams.bssid, - WLAN_REASON_DEAUTH_LEAVING); - else if (priv->mode == IW_MODE_ADHOC) - lbs_adhoc_stop(priv); - lbs_add_rtap(priv); - } - priv->monitormode = monitor_mode; - } else { - if (!priv->monitormode) - return strlen(buf); - priv->monitormode = 0; - lbs_remove_rtap(priv); - - if (priv->currenttxskb) { - dev_kfree_skb_any(priv->currenttxskb); - priv->currenttxskb = NULL; - } - - /* Wake queues, command thread, etc. */ - lbs_host_to_card_done(priv); - } - - lbs_prepare_and_send_command(priv, - CMD_802_11_MONITOR_MODE, CMD_ACT_SET, - CMD_OPTION_WAITFORRSP, 0, &priv->monitormode); - return strlen(buf); -} - -/** - * lbs_rtap attribute to be exported per ethX interface - * through sysfs (/sys/class/net/ethX/lbs_rtap) - */ -static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set ); - /** * @brief This function opens the ethX interface * @@ -177,13 +105,6 @@ static int lbs_dev_open(struct net_device *dev) spin_lock_irq(&priv->driver_lock); - if (priv->monitormode) { - ret = -EBUSY; - goto out; - } - - priv->infra_open = 1; - if (priv->connect_status == LBS_CONNECTED) netif_carrier_on(dev); else @@ -191,7 +112,6 @@ static int lbs_dev_open(struct net_device *dev) if (!priv->tx_pending_len) netif_wake_queue(dev); - out: spin_unlock_irq(&priv->driver_lock); lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); @@ -211,7 +131,6 @@ static int lbs_eth_stop(struct net_device *dev) lbs_deb_enter(LBS_DEB_NET); spin_lock_irq(&priv->driver_lock); - priv->infra_open = 0; netif_stop_queue(dev); spin_unlock_irq(&priv->driver_lock); @@ -238,12 +157,7 @@ static void lbs_tx_timeout(struct net_device *dev) to kick it somehow? */ lbs_host_to_card_done(priv); - /* More often than not, this actually happens because the - firmware has crapped itself -- rather than just a very - busy medium. So send a harmless command, and if/when - _that_ times out, we'll kick it in the head. */ - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, - 0, 0, NULL); + /* FIXME: reset the card */ lbs_deb_leave(LBS_DEB_TX); } @@ -588,12 +502,6 @@ static int lbs_thread(void *data) if (!priv->dnld_sent && !priv->cur_cmd) lbs_execute_next_command(priv); - /* Wake-up command waiters which can't sleep in - * lbs_prepare_and_send_command - */ - if (!list_empty(&priv->cmdpendingq)) - wake_up_all(&priv->cmd_pending); - spin_lock_irq(&priv->driver_lock); if (!priv->dnld_sent && priv->tx_pending_len > 0) { int ret = priv->hw_host_to_card(priv, MVMS_DAT, @@ -619,66 +527,58 @@ static int lbs_thread(void *data) del_timer(&priv->command_timer); del_timer(&priv->auto_deepsleep_timer); - wake_up_all(&priv->cmd_pending); lbs_deb_leave(LBS_DEB_THREAD); return 0; } -static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy, - struct cmd_header *cmd) -{ - lbs_deb_enter(LBS_DEB_FW); - - netif_device_detach(priv->dev); - if (priv->mesh_dev) - netif_device_detach(priv->mesh_dev); - - priv->fw_ready = 0; - lbs_deb_leave(LBS_DEB_FW); - return 0; -} - int lbs_suspend(struct lbs_private *priv) { - struct cmd_header cmd; int ret; lbs_deb_enter(LBS_DEB_FW); - if (priv->wol_criteria == 0xffffffff) { - lbs_pr_info("Suspend attempt without configuring wake params!\n"); - return -EINVAL; + if (priv->is_deep_sleep) { + ret = lbs_set_deep_sleep(priv, 0); + if (ret) { + lbs_pr_err("deep sleep cancellation failed: %d\n", ret); + return ret; + } + priv->deep_sleep_required = 1; } - memset(&cmd, 0, sizeof(cmd)); + ret = lbs_set_host_sleep(priv, 1); - ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd, - sizeof(cmd), lbs_suspend_callback, 0); - if (ret) - lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret); + netif_device_detach(priv->dev); + if (priv->mesh_dev) + netif_device_detach(priv->mesh_dev); lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); return ret; } EXPORT_SYMBOL_GPL(lbs_suspend); -void lbs_resume(struct lbs_private *priv) +int lbs_resume(struct lbs_private *priv) { - lbs_deb_enter(LBS_DEB_FW); + int ret; - priv->fw_ready = 1; + lbs_deb_enter(LBS_DEB_FW); - /* Firmware doesn't seem to give us RX packets any more - until we send it some command. Might as well update */ - lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, - 0, 0, NULL); + ret = lbs_set_host_sleep(priv, 0); netif_device_attach(priv->dev); if (priv->mesh_dev) netif_device_attach(priv->mesh_dev); - lbs_deb_leave(LBS_DEB_FW); + if (priv->deep_sleep_required) { + priv->deep_sleep_required = 0; + ret = lbs_set_deep_sleep(priv, 1); + if (ret) + lbs_pr_err("deep sleep activation failed: %d\n", ret); + } + + lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); + return ret; } EXPORT_SYMBOL_GPL(lbs_resume); @@ -710,6 +610,9 @@ static int lbs_setup_firmware(struct lbs_private *priv) priv->txpower_max = maxlevel; } + /* Send cmd to FW to enable 11D function */ + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1); + lbs_set_mac_control(priv); done: lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); @@ -748,7 +651,6 @@ out: static void auto_deepsleep_timer_fn(unsigned long data) { struct lbs_private *priv = (struct lbs_private *)data; - int ret; lbs_deb_enter(LBS_DEB_CMD); @@ -756,14 +658,15 @@ static void auto_deepsleep_timer_fn(unsigned long data) priv->is_activity_detected = 0; } else { if (priv->is_auto_deep_sleep_enabled && - (!priv->wakeup_dev_required) && - (priv->connect_status != LBS_CONNECTED)) { + (!priv->wakeup_dev_required) && + (priv->connect_status != LBS_CONNECTED)) { + struct cmd_header cmd; + lbs_deb_main("Entering auto deep sleep mode...\n"); - ret = lbs_prepare_and_send_command(priv, - CMD_802_11_DEEP_SLEEP, 0, - 0, 0, NULL); - if (ret) - lbs_pr_err("Enter Deep Sleep command failed\n"); + memset(&cmd, 0, sizeof(cmd)); + cmd.size = cpu_to_le16(sizeof(cmd)); + lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd, + sizeof(cmd)); } } mod_timer(&priv->auto_deepsleep_timer , jiffies + @@ -799,45 +702,27 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv) static int lbs_init_adapter(struct lbs_private *priv) { - size_t bufsize; - int i, ret = 0; + int ret; lbs_deb_enter(LBS_DEB_MAIN); - /* Allocate buffer to store the BSSID list */ - bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor); - priv->networks = kzalloc(bufsize, GFP_KERNEL); - if (!priv->networks) { - lbs_pr_err("Out of memory allocating beacons\n"); - ret = -1; - goto out; - } - - /* Initialize scan result lists */ - INIT_LIST_HEAD(&priv->network_free_list); - INIT_LIST_HEAD(&priv->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) { - list_add_tail(&priv->networks[i].list, - &priv->network_free_list); - } - memset(priv->current_addr, 0xff, ETH_ALEN); priv->connect_status = LBS_DISCONNECTED; - priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - priv->mode = IW_MODE_INFRA; priv->channel = DEFAULT_AD_HOC_CHANNEL; priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; priv->radio_on = 1; - priv->enablehwauto = 1; priv->psmode = LBS802_11POWERMODECAM; priv->psstate = PS_STATE_FULL_POWER; priv->is_deep_sleep = 0; priv->is_auto_deep_sleep_enabled = 0; + priv->deep_sleep_required = 0; priv->wakeup_dev_required = 0; init_waitqueue_head(&priv->ds_awake_q); priv->authtype_auto = 1; - + priv->is_host_sleep_configured = 0; + priv->is_host_sleep_activated = 0; + init_waitqueue_head(&priv->host_sleep_q); mutex_init(&priv->lock); setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, @@ -849,7 +734,6 @@ static int lbs_init_adapter(struct lbs_private *priv) INIT_LIST_HEAD(&priv->cmdpendingq); spin_lock_init(&priv->driver_lock); - init_waitqueue_head(&priv->cmd_pending); /* Allocate the command buffers */ if (lbs_allocate_cmd_buffer(priv)) { @@ -881,8 +765,6 @@ static void lbs_free_adapter(struct lbs_private *priv) kfifo_free(&priv->event_fifo); del_timer(&priv->command_timer); del_timer(&priv->auto_deepsleep_timer); - kfree(priv->networks); - priv->networks = NULL; lbs_deb_leave(LBS_DEB_MAIN); } @@ -919,7 +801,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) lbs_pr_err("cfg80211 init failed\n"); goto done; } - /* TODO? */ + wdev->iftype = NL80211_IFTYPE_STATION; priv = wdev_priv(wdev); priv->wdev = wdev; @@ -929,7 +811,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) goto err_wdev; } - //TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES); dev = alloc_netdev(0, "wlan%d", ether_setup); if (!dev) { dev_err(dmdev, "no memory for network device instance\n"); @@ -945,20 +826,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) dev->netdev_ops = &lbs_netdev_ops; dev->watchdog_timeo = 5 * HZ; dev->ethtool_ops = &lbs_ethtool_ops; -#ifdef WIRELESS_EXT - dev->wireless_handlers = &lbs_handler_def; -#endif dev->flags |= IFF_BROADCAST | IFF_MULTICAST; - - // TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ?? - - priv->card = card; - priv->infra_open = 0; - - priv->rtap_net_dev = NULL; strcpy(dev->name, "wlan%d"); lbs_deb_thread("Starting main thread...\n"); @@ -970,12 +841,11 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) } priv->work_thread = create_singlethread_workqueue("lbs_worker"); - INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); - INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); priv->wol_criteria = 0xffffffff; priv->wol_gpio = 0xff; + priv->wol_gap = 20; goto done; @@ -1004,12 +874,10 @@ void lbs_remove_card(struct lbs_private *priv) lbs_deb_enter(LBS_DEB_MAIN); lbs_remove_mesh(priv); - lbs_remove_rtap(priv); + lbs_scan_deinit(priv); dev = priv->dev; - cancel_delayed_work_sync(&priv->scan_work); - cancel_delayed_work_sync(&priv->assoc_work); cancel_work_sync(&priv->mcast_work); /* worker thread destruction blocks on the in-flight command which @@ -1021,16 +889,18 @@ void lbs_remove_card(struct lbs_private *priv) if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; - lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); + lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } - lbs_send_disconnect_notification(priv); - if (priv->is_deep_sleep) { priv->is_deep_sleep = 0; wake_up_interruptible(&priv->ds_awake_q); } + priv->is_host_sleep_configured = 0; + priv->is_host_sleep_activated = 0; + wake_up_interruptible(&priv->host_sleep_q); + /* Stop the thread servicing the interrupts */ priv->surpriseremoved = 1; kthread_stop(priv->main_thread); @@ -1046,7 +916,7 @@ void lbs_remove_card(struct lbs_private *priv) EXPORT_SYMBOL_GPL(lbs_remove_card); -static int lbs_rtap_supported(struct lbs_private *priv) +int lbs_rtap_supported(struct lbs_private *priv) { if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) return 1; @@ -1078,16 +948,6 @@ int lbs_start_card(struct lbs_private *priv) lbs_init_mesh(priv); - /* - * While rtap isn't related to mesh, only mesh-enabled - * firmware implements the rtap functionality via - * CMD_802_11_MONITOR_MODE. - */ - if (lbs_rtap_supported(priv)) { - if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) - lbs_pr_err("cannot register lbs_rtap attribute\n"); - } - lbs_debugfs_init_one(priv, dev); lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); @@ -1119,9 +979,6 @@ void lbs_stop_card(struct lbs_private *priv) lbs_debugfs_remove_one(priv); lbs_deinit_mesh(priv); - if (lbs_rtap_supported(priv)) - device_remove_file(&dev->dev, &dev_attr_lbs_rtap); - /* Delete the timeout of the currently processing command */ del_timer_sync(&priv->command_timer); del_timer_sync(&priv->auto_deepsleep_timer); @@ -1195,7 +1052,7 @@ static int __init lbs_init_module(void) memset(&confirm_sleep, 0, sizeof(confirm_sleep)); confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE); confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep)); - confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); + confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED); lbs_debugfs_init(); lbs_deb_leave(LBS_DEB_MAIN); return 0; @@ -1208,87 +1065,6 @@ static void __exit lbs_exit_module(void) lbs_deb_leave(LBS_DEB_MAIN); } -/* - * rtap interface support fuctions - */ - -static int lbs_rtap_open(struct net_device *dev) -{ - /* Yes, _stop_ the queue. Because we don't support injection */ - lbs_deb_enter(LBS_DEB_MAIN); - netif_carrier_off(dev); - netif_stop_queue(dev); - lbs_deb_leave(LBS_DEB_LEAVE); - return 0; -} - -static int lbs_rtap_stop(struct net_device *dev) -{ - lbs_deb_enter(LBS_DEB_MAIN); - lbs_deb_leave(LBS_DEB_MAIN); - return 0; -} - -static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - netif_stop_queue(dev); - return NETDEV_TX_BUSY; -} - -static void lbs_remove_rtap(struct lbs_private *priv) -{ - lbs_deb_enter(LBS_DEB_MAIN); - if (priv->rtap_net_dev == NULL) - goto out; - unregister_netdev(priv->rtap_net_dev); - free_netdev(priv->rtap_net_dev); - priv->rtap_net_dev = NULL; -out: - lbs_deb_leave(LBS_DEB_MAIN); -} - -static const struct net_device_ops rtap_netdev_ops = { - .ndo_open = lbs_rtap_open, - .ndo_stop = lbs_rtap_stop, - .ndo_start_xmit = lbs_rtap_hard_start_xmit, -}; - -static int lbs_add_rtap(struct lbs_private *priv) -{ - int ret = 0; - struct net_device *rtap_dev; - - lbs_deb_enter(LBS_DEB_MAIN); - if (priv->rtap_net_dev) { - ret = -EPERM; - goto out; - } - - rtap_dev = alloc_netdev(0, "rtap%d", ether_setup); - if (rtap_dev == NULL) { - ret = -ENOMEM; - goto out; - } - - memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN); - rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP; - rtap_dev->netdev_ops = &rtap_netdev_ops; - rtap_dev->ml_priv = priv; - SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent); - - ret = register_netdev(rtap_dev); - if (ret) { - free_netdev(rtap_dev); - goto out; - } - priv->rtap_net_dev = rtap_dev; - -out: - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); - return ret; -} - module_init(lbs_init_module); module_exit(lbs_exit_module); diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index e385af1f458..194762ab014 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -5,6 +5,7 @@ #include <linux/if_arp.h> #include <linux/kthread.h> #include <linux/kfifo.h> +#include <net/cfg80211.h> #include "mesh.h" #include "decl.h" @@ -314,7 +315,7 @@ static int lbs_mesh_dev_open(struct net_device *dev) spin_lock_irq(&priv->driver_lock); - if (priv->monitormode) { + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { ret = -EBUSY; goto out; } @@ -369,9 +370,6 @@ int lbs_add_mesh(struct lbs_private *priv) SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); -#ifdef WIRELESS_EXT - mesh_dev->wireless_handlers = &mesh_handler_def; -#endif mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; /* Register virtual mesh interface */ ret = register_netdev(mesh_dev); @@ -457,65 +455,189 @@ void lbs_mesh_set_txpd(struct lbs_private *priv, * Mesh command handling */ -int lbs_cmd_bt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf) +/** + * @brief Add or delete Mesh Blinding Table entries + * + * @param priv A pointer to struct lbs_private structure + * @param add TRUE to add the entry, FALSE to delete it + * @param addr1 Destination address to blind or unblind + * + * @return 0 on success, error on failure + */ +int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) { - struct cmd_ds_bt_access *bt_access = &cmd->params.bt; - lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); + struct cmd_ds_bt_access cmd; + int ret = 0; - cmd->command = cpu_to_le16(CMD_BT_ACCESS); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + - sizeof(struct cmd_header)); - cmd->result = 0; - bt_access->action = cpu_to_le16(cmd_action); + lbs_deb_enter(LBS_DEB_CMD); - switch (cmd_action) { - case CMD_ACT_BT_ACCESS_ADD: - memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN); + BUG_ON(addr1 == NULL); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + memcpy(cmd.addr1, addr1, ETH_ALEN); + if (add) { + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD); lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", - bt_access->addr1, 6); - break; - case CMD_ACT_BT_ACCESS_DEL: - memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN); + addr1, ETH_ALEN); + } else { + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL); lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", - bt_access->addr1, 6); - break; - case CMD_ACT_BT_ACCESS_LIST: - bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); - break; - case CMD_ACT_BT_ACCESS_RESET: - break; - case CMD_ACT_BT_ACCESS_SET_INVERT: - bt_access->id = cpu_to_le32(*(u32 *) pdata_buf); - break; - case CMD_ACT_BT_ACCESS_GET_INVERT: - break; - default: - break; + addr1, ETH_ALEN); } - lbs_deb_leave(LBS_DEB_CMD); - return 0; + + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; } -int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf) +/** + * @brief Reset/clear the mesh blinding table + * + * @param priv A pointer to struct lbs_private structure + * + * @return 0 on success, error on failure + */ +int lbs_mesh_bt_reset(struct lbs_private *priv) { - struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt; - lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); + struct cmd_ds_bt_access cmd; + int ret = 0; - cmd->command = cpu_to_le16(CMD_FWT_ACCESS); - cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + - sizeof(struct cmd_header)); - cmd->result = 0; + lbs_deb_enter(LBS_DEB_CMD); - if (pdata_buf) - memcpy(fwt_access, pdata_buf, sizeof(*fwt_access)); - else - memset(fwt_access, 0, sizeof(*fwt_access)); + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET); - fwt_access->action = cpu_to_le16(cmd_action); + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); - lbs_deb_leave(LBS_DEB_CMD); + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief Gets the inverted status of the mesh blinding table + * + * Normally the firmware "blinds" or ignores traffic from mesh nodes in the + * table, but an inverted table allows *only* traffic from nodes listed in + * the table. + * + * @param priv A pointer to struct lbs_private structure + * @param invert On success, TRUE if the blinding table is inverted, + * FALSE if it is not inverted + * + * @return 0 on success, error on failure + */ +int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) +{ + struct cmd_ds_bt_access cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + BUG_ON(inverted == NULL); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT); + + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + if (ret == 0) + *inverted = !!cmd.id; + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief Sets the inverted status of the mesh blinding table + * + * Normally the firmware "blinds" or ignores traffic from mesh nodes in the + * table, but an inverted table allows *only* traffic from nodes listed in + * the table. + * + * @param priv A pointer to struct lbs_private structure + * @param invert TRUE to invert the blinding table (only traffic from + * listed nodes allowed), FALSE to return it + * to normal state (listed nodes ignored) + * + * @return 0 on success, error on failure + */ +int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) +{ + struct cmd_ds_bt_access cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); + cmd.id = !!inverted; + + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief List an entry in the mesh blinding table + * + * @param priv A pointer to struct lbs_private structure + * @param id The ID of the entry to list + * @param addr1 MAC address associated with the table entry + * + * @return 0 on success, error on failure + */ +int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) +{ + struct cmd_ds_bt_access cmd; + int ret = 0; + + lbs_deb_enter(LBS_DEB_CMD); + + BUG_ON(addr1 == NULL); + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.size = cpu_to_le16(sizeof(cmd)); + cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); + cmd.id = cpu_to_le32(id); + + ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); + if (ret == 0) + memcpy(addr1, cmd.addr1, sizeof(cmd.addr1)); + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); + return ret; +} + +/** + * @brief Access the mesh forwarding table + * + * @param priv A pointer to struct lbs_private structure + * @param cmd_action The forwarding table action to perform + * @param cmd The pre-filled FWT_ACCESS command + * + * @return 0 on success and 'cmd' will be filled with the + * firmware's response + */ +int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, + struct cmd_ds_fwt_access *cmd) +{ + int ret; + + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); + + cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS); + cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)); + cmd->hdr.result = 0; + cmd->action = cpu_to_le16(cmd_action); + + ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); + + lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return 0; } diff --git a/drivers/net/wireless/libertas/mesh.h b/drivers/net/wireless/libertas/mesh.h index e2573303a32..afb2e8dead3 100644 --- a/drivers/net/wireless/libertas/mesh.h +++ b/drivers/net/wireless/libertas/mesh.h @@ -8,6 +8,7 @@ #include <net/iw_handler.h> #include <net/lib80211.h> +#include "host.h" #ifdef CONFIG_LIBERTAS_MESH @@ -51,10 +52,15 @@ struct cmd_ds_command; struct cmd_ds_mesh_access; struct cmd_ds_mesh_config; -int lbs_cmd_bt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf); -int lbs_cmd_fwt_access(struct cmd_ds_command *cmd, - u16 cmd_action, void *pdata_buf); +int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1); +int lbs_mesh_bt_reset(struct lbs_private *priv); +int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); +int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); +int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); + +int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, + struct cmd_ds_fwt_access *cmd); + int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, struct cmd_ds_mesh_access *cmd); int lbs_mesh_config_send(struct lbs_private *priv, @@ -70,11 +76,6 @@ void lbs_persist_config_init(struct net_device *net); void lbs_persist_config_remove(struct net_device *net); -/* WEXT handler */ - -extern struct iw_handler_def mesh_handler_def; - - /* Ethtool statistics */ struct ethtool_stats; diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h index d16b26416e8..b3c8ea6d610 100644 --- a/drivers/net/wireless/libertas/radiotap.h +++ b/drivers/net/wireless/libertas/radiotap.h @@ -6,7 +6,7 @@ struct tx_radiotap_hdr { u8 txpower; u8 rts_retries; u8 data_retries; -} __attribute__ ((packed)); +} __packed; #define TX_RADIOTAP_PRESENT ( \ (1 << IEEE80211_RADIOTAP_RATE) | \ @@ -34,7 +34,7 @@ struct rx_radiotap_hdr { u8 flags; u8 rate; u8 antsignal; -} __attribute__ ((packed)); +} __packed; #define RX_RADIOTAP_PRESENT ( \ (1 << IEEE80211_RADIOTAP_FLAGS) | \ diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 7a377f5b766..a4d0bca9ef2 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -4,18 +4,19 @@ #include <linux/etherdevice.h> #include <linux/slab.h> #include <linux/types.h> +#include <net/cfg80211.h> +#include "defs.h" #include "host.h" #include "radiotap.h" #include "decl.h" #include "dev.h" -#include "wext.h" struct eth803hdr { u8 dest_addr[6]; u8 src_addr[6]; u16 h803_len; -} __attribute__ ((packed)); +} __packed; struct rfc1042hdr { u8 llc_dsap; @@ -23,114 +24,22 @@ struct rfc1042hdr { u8 llc_ctrl; u8 snap_oui[3]; u16 snap_type; -} __attribute__ ((packed)); +} __packed; struct rxpackethdr { struct eth803hdr eth803_hdr; struct rfc1042hdr rfc1042_hdr; -} __attribute__ ((packed)); +} __packed; struct rx80211packethdr { struct rxpd rx_pd; void *eth80211_hdr; -} __attribute__ ((packed)); +} __packed; static int process_rxed_802_11_packet(struct lbs_private *priv, struct sk_buff *skb); /** - * @brief This function computes the avgSNR . - * - * @param priv A pointer to struct lbs_private structure - * @return avgSNR - */ -static u8 lbs_getavgsnr(struct lbs_private *priv) -{ - u8 i; - u16 temp = 0; - if (priv->numSNRNF == 0) - return 0; - for (i = 0; i < priv->numSNRNF; i++) - temp += priv->rawSNR[i]; - return (u8) (temp / priv->numSNRNF); - -} - -/** - * @brief This function computes the AvgNF - * - * @param priv A pointer to struct lbs_private structure - * @return AvgNF - */ -static u8 lbs_getavgnf(struct lbs_private *priv) -{ - u8 i; - u16 temp = 0; - if (priv->numSNRNF == 0) - return 0; - for (i = 0; i < priv->numSNRNF; i++) - temp += priv->rawNF[i]; - return (u8) (temp / priv->numSNRNF); - -} - -/** - * @brief This function save the raw SNR/NF to our internel buffer - * - * @param priv A pointer to struct lbs_private structure - * @param prxpd A pointer to rxpd structure of received packet - * @return n/a - */ -static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) -{ - if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR) - priv->numSNRNF++; - priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr; - priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf; - priv->nextSNRNF++; - if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR) - priv->nextSNRNF = 0; -} - -/** - * @brief This function computes the RSSI in received packet. - * - * @param priv A pointer to struct lbs_private structure - * @param prxpd A pointer to rxpd structure of received packet - * @return n/a - */ -static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) -{ - - lbs_deb_enter(LBS_DEB_RX); - - lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf); - lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n", - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); - - priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr; - priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf; - lbs_save_rawSNRNF(priv, p_rx_pd); - - priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE; - priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE; - lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n", - priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); - - priv->RSSI[TYPE_RXPD][TYPE_NOAVG] = - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG], - priv->NF[TYPE_RXPD][TYPE_NOAVG]); - - priv->RSSI[TYPE_RXPD][TYPE_AVG] = - CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, - priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); - - lbs_deb_leave(LBS_DEB_RX); -} - -/** * @brief This function processes received packet and forwards it * to kernel/upper layer * @@ -154,7 +63,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - if (priv->monitormode) + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) return process_rxed_802_11_packet(priv, skb); p_rx_pd = (struct rxpd *) skb->data; @@ -225,13 +134,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) */ skb_pull(skb, hdrchop); - /* Take the data rate from the rxpd structure - * only if the rate is auto - */ - if (priv->enablehwauto) - priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); - - lbs_compute_rssi(priv, p_rx_pd); + priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); dev->stats.rx_bytes += skb->len; @@ -352,20 +255,18 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr)); memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr)); - /* Take the data rate from the rxpd structure - * only if the rate is auto - */ - if (priv->enablehwauto) - priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); - - lbs_compute_rssi(priv, prxpd); + priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; - skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); - netif_rx(skb); + skb->protocol = eth_type_trans(skb, priv->dev); + + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); ret = 0; diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c deleted file mode 100644 index 24cd54b3a80..00000000000 --- a/drivers/net/wireless/libertas/scan.c +++ /dev/null @@ -1,1354 +0,0 @@ -/** - * Functions implementing wlan scan IOCTL and firmware command APIs - * - * IOCTL handlers as well as command preperation and response routines - * for sending scan commands to the firmware. - */ -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/etherdevice.h> -#include <linux/if_arp.h> -#include <asm/unaligned.h> -#include <net/lib80211.h> - -#include "host.h" -#include "dev.h" -#include "scan.h" -#include "assoc.h" -#include "wext.h" -#include "cmd.h" - -//! Approximate amount of data needed to pass a scan result back to iwlist -#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ - + IEEE80211_MAX_SSID_LEN \ - + IW_EV_UINT_LEN \ - + IW_EV_FREQ_LEN \ - + IW_EV_QUAL_LEN \ - + IEEE80211_MAX_SSID_LEN \ - + IW_EV_PARAM_LEN \ - + 40) /* 40 for WPAIE */ - -//! Memory needed to store a max sized channel List TLV for a firmware scan -#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \ - + (MRVDRV_MAX_CHANNELS_PER_SCAN \ - * sizeof(struct chanscanparamset))) - -//! Memory needed to store a max number/size SSID TLV for a firmware scan -#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set)) - -//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max -#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ - + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE) - -//! The maximum number of channels the firmware can scan per command -#define MRVDRV_MAX_CHANNELS_PER_SCAN 14 - -/** - * @brief Number of channels to scan per firmware scan command issuance. - * - * Number restricted to prevent hitting the limit on the amount of scan data - * returned in a single firmware scan command. - */ -#define MRVDRV_CHANNELS_PER_SCAN_CMD 4 - -//! Scan time specified in the channel TLV for each channel for passive scans -#define MRVDRV_PASSIVE_SCAN_CHAN_TIME 100 - -//! Scan time specified in the channel TLV for each channel for active scans -#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) - -static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, - struct cmd_header *resp); - -/*********************************************************************/ -/* */ -/* Misc helper functions */ -/* */ -/*********************************************************************/ - -/** - * @brief Unsets the MSB on basic rates - * - * Scan through an array and unset the MSB for basic data rates. - * - * @param rates buffer of data rates - * @param len size of buffer - */ -static void lbs_unset_basic_rate_flags(u8 *rates, size_t len) -{ - int i; - - for (i = 0; i < len; i++) - rates[i] &= 0x7f; -} - - -static inline void clear_bss_descriptor(struct bss_descriptor *bss) -{ - /* Don't blow away ->list, just BSS data */ - memset(bss, 0, offsetof(struct bss_descriptor, list)); -} - -/** - * @brief Compare two SSIDs - * - * @param ssid1 A pointer to ssid to compare - * @param ssid2 A pointer to ssid to compare - * - * @return 0: ssid is same, otherwise is different - */ -int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2, - uint8_t ssid2_len) -{ - if (ssid1_len != ssid2_len) - return -1; - - return memcmp(ssid1, ssid2, ssid1_len); -} - -static inline int is_same_network(struct bss_descriptor *src, - struct bss_descriptor *dst) -{ - /* A network is only a duplicate if the channel, BSSID, and ESSID - * all match. We treat all <hidden> with the same BSSID and channel - * as one network */ - return ((src->ssid_len == dst->ssid_len) && - (src->channel == dst->channel) && - !compare_ether_addr(src->bssid, dst->bssid) && - !memcmp(src->ssid, dst->ssid, src->ssid_len)); -} - - - -/*********************************************************************/ -/* */ -/* Region channel support */ -/* */ -/*********************************************************************/ - -#define LBS_TX_PWR_DEFAULT 20 /*100mW */ -#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */ -#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */ -#define LBS_TX_PWR_FR_DEFAULT 20 /*100mW */ -#define LBS_TX_PWR_EMEA_DEFAULT 20 /*100mW */ - -/* Format { channel, frequency (MHz), maxtxpower } */ -/* band: 'B/G', region: USA FCC/Canada IC */ -static struct chan_freq_power channel_freq_power_US_BG[] = { - {1, 2412, LBS_TX_PWR_US_DEFAULT}, - {2, 2417, LBS_TX_PWR_US_DEFAULT}, - {3, 2422, LBS_TX_PWR_US_DEFAULT}, - {4, 2427, LBS_TX_PWR_US_DEFAULT}, - {5, 2432, LBS_TX_PWR_US_DEFAULT}, - {6, 2437, LBS_TX_PWR_US_DEFAULT}, - {7, 2442, LBS_TX_PWR_US_DEFAULT}, - {8, 2447, LBS_TX_PWR_US_DEFAULT}, - {9, 2452, LBS_TX_PWR_US_DEFAULT}, - {10, 2457, LBS_TX_PWR_US_DEFAULT}, - {11, 2462, LBS_TX_PWR_US_DEFAULT} -}; - -/* band: 'B/G', region: Europe ETSI */ -static struct chan_freq_power channel_freq_power_EU_BG[] = { - {1, 2412, LBS_TX_PWR_EMEA_DEFAULT}, - {2, 2417, LBS_TX_PWR_EMEA_DEFAULT}, - {3, 2422, LBS_TX_PWR_EMEA_DEFAULT}, - {4, 2427, LBS_TX_PWR_EMEA_DEFAULT}, - {5, 2432, LBS_TX_PWR_EMEA_DEFAULT}, - {6, 2437, LBS_TX_PWR_EMEA_DEFAULT}, - {7, 2442, LBS_TX_PWR_EMEA_DEFAULT}, - {8, 2447, LBS_TX_PWR_EMEA_DEFAULT}, - {9, 2452, LBS_TX_PWR_EMEA_DEFAULT}, - {10, 2457, LBS_TX_PWR_EMEA_DEFAULT}, - {11, 2462, LBS_TX_PWR_EMEA_DEFAULT}, - {12, 2467, LBS_TX_PWR_EMEA_DEFAULT}, - {13, 2472, LBS_TX_PWR_EMEA_DEFAULT} -}; - -/* band: 'B/G', region: Spain */ -static struct chan_freq_power channel_freq_power_SPN_BG[] = { - {10, 2457, LBS_TX_PWR_DEFAULT}, - {11, 2462, LBS_TX_PWR_DEFAULT} -}; - -/* band: 'B/G', region: France */ -static struct chan_freq_power channel_freq_power_FR_BG[] = { - {10, 2457, LBS_TX_PWR_FR_DEFAULT}, - {11, 2462, LBS_TX_PWR_FR_DEFAULT}, - {12, 2467, LBS_TX_PWR_FR_DEFAULT}, - {13, 2472, LBS_TX_PWR_FR_DEFAULT} -}; - -/* band: 'B/G', region: Japan */ -static struct chan_freq_power channel_freq_power_JPN_BG[] = { - {1, 2412, LBS_TX_PWR_JP_DEFAULT}, - {2, 2417, LBS_TX_PWR_JP_DEFAULT}, - {3, 2422, LBS_TX_PWR_JP_DEFAULT}, - {4, 2427, LBS_TX_PWR_JP_DEFAULT}, - {5, 2432, LBS_TX_PWR_JP_DEFAULT}, - {6, 2437, LBS_TX_PWR_JP_DEFAULT}, - {7, 2442, LBS_TX_PWR_JP_DEFAULT}, - {8, 2447, LBS_TX_PWR_JP_DEFAULT}, - {9, 2452, LBS_TX_PWR_JP_DEFAULT}, - {10, 2457, LBS_TX_PWR_JP_DEFAULT}, - {11, 2462, LBS_TX_PWR_JP_DEFAULT}, - {12, 2467, LBS_TX_PWR_JP_DEFAULT}, - {13, 2472, LBS_TX_PWR_JP_DEFAULT}, - {14, 2484, LBS_TX_PWR_JP_DEFAULT} -}; - -/** - * the structure for channel, frequency and power - */ -struct region_cfp_table { - u8 region; - struct chan_freq_power *cfp_BG; - int cfp_no_BG; -}; - -/** - * the structure for the mapping between region and CFP - */ -static struct region_cfp_table region_cfp_table[] = { - {0x10, /*US FCC */ - channel_freq_power_US_BG, - ARRAY_SIZE(channel_freq_power_US_BG), - } - , - {0x20, /*CANADA IC */ - channel_freq_power_US_BG, - ARRAY_SIZE(channel_freq_power_US_BG), - } - , - {0x30, /*EU*/ channel_freq_power_EU_BG, - ARRAY_SIZE(channel_freq_power_EU_BG), - } - , - {0x31, /*SPAIN*/ channel_freq_power_SPN_BG, - ARRAY_SIZE(channel_freq_power_SPN_BG), - } - , - {0x32, /*FRANCE*/ channel_freq_power_FR_BG, - ARRAY_SIZE(channel_freq_power_FR_BG), - } - , - {0x40, /*JAPAN*/ channel_freq_power_JPN_BG, - ARRAY_SIZE(channel_freq_power_JPN_BG), - } - , -/*Add new region here */ -}; - -/** - * @brief This function finds the CFP in - * region_cfp_table based on region and band parameter. - * - * @param region The region code - * @param band The band - * @param cfp_no A pointer to CFP number - * @return A pointer to CFP - */ -static struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no) -{ - int i, end; - - lbs_deb_enter(LBS_DEB_MAIN); - - end = ARRAY_SIZE(region_cfp_table); - - for (i = 0; i < end ; i++) { - lbs_deb_main("region_cfp_table[i].region=%d\n", - region_cfp_table[i].region); - if (region_cfp_table[i].region == region) { - *cfp_no = region_cfp_table[i].cfp_no_BG; - lbs_deb_leave(LBS_DEB_MAIN); - return region_cfp_table[i].cfp_BG; - } - } - - lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL"); - return NULL; -} - -int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band) -{ - int ret = 0; - int i = 0; - - struct chan_freq_power *cfp; - int cfp_no; - - lbs_deb_enter(LBS_DEB_MAIN); - - memset(priv->region_channel, 0, sizeof(priv->region_channel)); - - cfp = lbs_get_region_cfp_table(region, &cfp_no); - if (cfp != NULL) { - priv->region_channel[i].nrcfp = cfp_no; - priv->region_channel[i].CFP = cfp; - } else { - lbs_deb_main("wrong region code %#x in band B/G\n", - region); - ret = -1; - goto out; - } - priv->region_channel[i].valid = 1; - priv->region_channel[i].region = region; - priv->region_channel[i].band = band; - i++; -out: - lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); - return ret; -} - - - - -/*********************************************************************/ -/* */ -/* Main scanning support */ -/* */ -/*********************************************************************/ - -/** - * @brief Create a channel list for the driver to scan based on region info - * - * Only used from lbs_scan_setup_scan_config() - * - * Use the driver region/band information to construct a comprehensive list - * of channels to scan. This routine is used for any scan that is not - * provided a specific channel list to scan. - * - * @param priv A pointer to struct lbs_private structure - * @param scanchanlist Output parameter: resulting channel list to scan - * - * @return void - */ -static int lbs_scan_create_channel_list(struct lbs_private *priv, - struct chanscanparamset *scanchanlist) -{ - struct region_channel *scanregion; - struct chan_freq_power *cfp; - int rgnidx; - int chanidx; - int nextchan; - uint8_t scantype; - - chanidx = 0; - - /* Set the default scan type to the user specified type, will later - * be changed to passive on a per channel basis if restricted by - * regulatory requirements (11d or 11h) - */ - scantype = CMD_SCAN_TYPE_ACTIVE; - - for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) { - if (!priv->region_channel[rgnidx].valid) - continue; - scanregion = &priv->region_channel[rgnidx]; - - for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) { - struct chanscanparamset *chan = &scanchanlist[chanidx]; - - cfp = scanregion->CFP + nextchan; - - if (scanregion->band == BAND_B || scanregion->band == BAND_G) - chan->radiotype = CMD_SCAN_RADIO_TYPE_BG; - - if (scantype == CMD_SCAN_TYPE_PASSIVE) { - chan->maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); - chan->chanscanmode.passivescan = 1; - } else { - chan->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); - chan->chanscanmode.passivescan = 0; - } - - chan->channumber = cfp->channel; - } - } - return chanidx; -} - -/* - * Add SSID TLV of the form: - * - * TLV-ID SSID 00 00 - * length 06 00 - * ssid 4d 4e 54 45 53 54 - */ -static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) -{ - struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; - - ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); - ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); - memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len); - return sizeof(ssid_tlv->header) + priv->scan_ssid_len; -} - -/* - * Add CHANLIST TLV of the form - * - * TLV-ID CHANLIST 01 01 - * length 5b 00 - * channel 1 00 01 00 00 00 64 00 - * radio type 00 - * channel 01 - * scan type 00 - * min scan time 00 00 - * max scan time 64 00 - * channel 2 00 02 00 00 00 64 00 - * channel 3 00 03 00 00 00 64 00 - * channel 4 00 04 00 00 00 64 00 - * channel 5 00 05 00 00 00 64 00 - * channel 6 00 06 00 00 00 64 00 - * channel 7 00 07 00 00 00 64 00 - * channel 8 00 08 00 00 00 64 00 - * channel 9 00 09 00 00 00 64 00 - * channel 10 00 0a 00 00 00 64 00 - * channel 11 00 0b 00 00 00 64 00 - * channel 12 00 0c 00 00 00 64 00 - * channel 13 00 0d 00 00 00 64 00 - * - */ -static int lbs_scan_add_chanlist_tlv(uint8_t *tlv, - struct chanscanparamset *chan_list, - int chan_count) -{ - size_t size = sizeof(struct chanscanparamset) *chan_count; - struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv; - - chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); - memcpy(chan_tlv->chanscanparam, chan_list, size); - chan_tlv->header.len = cpu_to_le16(size); - return sizeof(chan_tlv->header) + size; -} - -/* - * Add RATES TLV of the form - * - * TLV-ID RATES 01 00 - * length 0e 00 - * rates 82 84 8b 96 0c 12 18 24 30 48 60 6c - * - * The rates are in lbs_bg_rates[], but for the 802.11b - * rates the high bit isn't set. - */ -static int lbs_scan_add_rates_tlv(uint8_t *tlv) -{ - int i; - struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; - - rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); - tlv += sizeof(rate_tlv->header); - for (i = 0; i < MAX_RATES; i++) { - *tlv = lbs_bg_rates[i]; - if (*tlv == 0) - break; - /* This code makes sure that the 802.11b rates (1 MBit/s, 2 - MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set. - Note that the values are MBit/s * 2, to mark them as - basic rates so that the firmware likes it better */ - if (*tlv == 0x02 || *tlv == 0x04 || - *tlv == 0x0b || *tlv == 0x16) - *tlv |= 0x80; - tlv++; - } - rate_tlv->header.len = cpu_to_le16(i); - return sizeof(rate_tlv->header) + i; -} - -/* - * Generate the CMD_802_11_SCAN command with the proper tlv - * for a bunch of channels. - */ -static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype, - struct chanscanparamset *chan_list, int chan_count) -{ - int ret = -ENOMEM; - struct cmd_ds_802_11_scan *scan_cmd; - uint8_t *tlv; /* pointer into our current, growing TLV storage area */ - - lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d", - bsstype, chan_list ? chan_list[0].channumber : -1, - chan_count); - - /* create the fixed part for scan command */ - scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); - if (scan_cmd == NULL) - goto out; - - tlv = scan_cmd->tlvbuffer; - /* TODO: do we need to scan for a specific BSSID? - memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */ - scan_cmd->bsstype = bsstype; - - /* add TLVs */ - if (priv->scan_ssid_len) - tlv += lbs_scan_add_ssid_tlv(priv, tlv); - if (chan_list && chan_count) - tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count); - tlv += lbs_scan_add_rates_tlv(tlv); - - /* This is the final data we are about to send */ - scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd); - lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, - sizeof(*scan_cmd)); - lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, - tlv - scan_cmd->tlvbuffer); - - ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr, - le16_to_cpu(scan_cmd->hdr.size), - lbs_ret_80211_scan, 0); - -out: - kfree(scan_cmd); - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} - -/** - * @brief Internal function used to start a scan based on an input config - * - * Use the input user scan configuration information when provided in - * order to send the appropriate scan commands to firmware to populate or - * update the internal driver scan table - * - * @param priv A pointer to struct lbs_private structure - * @param full_scan Do a full-scan (blocking) - * - * @return 0 or < 0 if error - */ -int lbs_scan_networks(struct lbs_private *priv, int full_scan) -{ - int ret = -ENOMEM; - struct chanscanparamset *chan_list; - struct chanscanparamset *curr_chans; - int chan_count; - uint8_t bsstype = CMD_BSS_TYPE_ANY; - int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; - union iwreq_data wrqu; -#ifdef CONFIG_LIBERTAS_DEBUG - struct bss_descriptor *iter; - int i = 0; - DECLARE_SSID_BUF(ssid); -#endif - - lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan); - - /* Cancel any partial outstanding partial scans if this scan - * is a full scan. - */ - if (full_scan && delayed_work_pending(&priv->scan_work)) - cancel_delayed_work(&priv->scan_work); - - /* User-specified bsstype or channel list - TODO: this can be implemented if some user-space application - need the feature. Formerly, it was accessible from debugfs, - but then nowhere used. - if (user_cfg) { - if (user_cfg->bsstype) - bsstype = user_cfg->bsstype; - } */ - - lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype); - - /* Create list of channels to scan */ - chan_list = kzalloc(sizeof(struct chanscanparamset) * - LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); - if (!chan_list) { - lbs_pr_alert("SCAN: chan_list empty\n"); - goto out; - } - - /* We want to scan all channels */ - chan_count = lbs_scan_create_channel_list(priv, chan_list); - - netif_stop_queue(priv->dev); - if (priv->mesh_dev) - netif_stop_queue(priv->mesh_dev); - - /* Prepare to continue an interrupted scan */ - lbs_deb_scan("chan_count %d, scan_channel %d\n", - chan_count, priv->scan_channel); - curr_chans = chan_list; - /* advance channel list by already-scanned-channels */ - if (priv->scan_channel > 0) { - curr_chans += priv->scan_channel; - chan_count -= priv->scan_channel; - } - - /* Send scan command(s) - * numchannels contains the number of channels we should maximally scan - * chan_count is the total number of channels to scan - */ - - while (chan_count) { - int to_scan = min(numchannels, chan_count); - lbs_deb_scan("scanning %d of %d channels\n", - to_scan, chan_count); - ret = lbs_do_scan(priv, bsstype, curr_chans, - to_scan); - if (ret) { - lbs_pr_err("SCAN_CMD failed\n"); - goto out2; - } - curr_chans += to_scan; - chan_count -= to_scan; - - /* somehow schedule the next part of the scan */ - if (chan_count && !full_scan && - !priv->surpriseremoved) { - /* -1 marks just that we're currently scanning */ - if (priv->scan_channel < 0) - priv->scan_channel = to_scan; - else - priv->scan_channel += to_scan; - cancel_delayed_work(&priv->scan_work); - queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(300)); - /* skip over GIWSCAN event */ - goto out; - } - - } - memset(&wrqu, 0, sizeof(union iwreq_data)); - wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); - -#ifdef CONFIG_LIBERTAS_DEBUG - /* Dump the scan table */ - mutex_lock(&priv->lock); - lbs_deb_scan("scan table:\n"); - list_for_each_entry(iter, &priv->network_list, list) - lbs_deb_scan("%02d: BSSID %pM, RSSI %d, SSID '%s'\n", - i++, iter->bssid, iter->rssi, - print_ssid(ssid, iter->ssid, iter->ssid_len)); - mutex_unlock(&priv->lock); -#endif - -out2: - priv->scan_channel = 0; - -out: - if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) - netif_wake_queue(priv->dev); - - if (priv->mesh_dev && lbs_mesh_connected(priv) && - !priv->tx_pending_len) - netif_wake_queue(priv->mesh_dev); - - kfree(chan_list); - - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} - -void lbs_scan_worker(struct work_struct *work) -{ - struct lbs_private *priv = - container_of(work, struct lbs_private, scan_work.work); - - lbs_deb_enter(LBS_DEB_SCAN); - lbs_scan_networks(priv, 0); - lbs_deb_leave(LBS_DEB_SCAN); -} - - -/*********************************************************************/ -/* */ -/* Result interpretation */ -/* */ -/*********************************************************************/ - -/** - * @brief Interpret a BSS scan response returned from the firmware - * - * Parse the various fixed fields and IEs passed back for a a BSS probe - * response or beacon from the scan command. Record information as needed - * in the scan table struct bss_descriptor for that entry. - * - * @param bss Output parameter: Pointer to the BSS Entry - * - * @return 0 or -1 - */ -static int lbs_process_bss(struct bss_descriptor *bss, - uint8_t **pbeaconinfo, int *bytesleft) -{ - struct ieee_ie_fh_param_set *fh; - struct ieee_ie_ds_param_set *ds; - struct ieee_ie_cf_param_set *cf; - struct ieee_ie_ibss_param_set *ibss; - DECLARE_SSID_BUF(ssid); - uint8_t *pos, *end, *p; - uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; - uint16_t beaconsize = 0; - int ret; - - lbs_deb_enter(LBS_DEB_SCAN); - - if (*bytesleft >= sizeof(beaconsize)) { - /* Extract & convert beacon size from the command buffer */ - beaconsize = get_unaligned_le16(*pbeaconinfo); - *bytesleft -= sizeof(beaconsize); - *pbeaconinfo += sizeof(beaconsize); - } - - if (beaconsize == 0 || beaconsize > *bytesleft) { - *pbeaconinfo += *bytesleft; - *bytesleft = 0; - ret = -1; - goto done; - } - - /* Initialize the current working beacon pointer for this BSS iteration */ - pos = *pbeaconinfo; - end = pos + beaconsize; - - /* Advance the return beacon pointer past the current beacon */ - *pbeaconinfo += beaconsize; - *bytesleft -= beaconsize; - - memcpy(bss->bssid, pos, ETH_ALEN); - lbs_deb_scan("process_bss: BSSID %pM\n", bss->bssid); - pos += ETH_ALEN; - - if ((end - pos) < 12) { - lbs_deb_scan("process_bss: Not enough bytes left\n"); - ret = -1; - goto done; - } - - /* - * next 4 fields are RSSI, time stamp, beacon interval, - * and capability information - */ - - /* RSSI is 1 byte long */ - bss->rssi = *pos; - lbs_deb_scan("process_bss: RSSI %d\n", *pos); - pos++; - - /* time stamp is 8 bytes long */ - pos += 8; - - /* beacon interval is 2 bytes long */ - bss->beaconperiod = get_unaligned_le16(pos); - pos += 2; - - /* capability information is 2 bytes long */ - bss->capability = get_unaligned_le16(pos); - lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability); - pos += 2; - - if (bss->capability & WLAN_CAPABILITY_PRIVACY) - lbs_deb_scan("process_bss: WEP enabled\n"); - if (bss->capability & WLAN_CAPABILITY_IBSS) - bss->mode = IW_MODE_ADHOC; - else - bss->mode = IW_MODE_INFRA; - - /* rest of the current buffer are IE's */ - lbs_deb_scan("process_bss: IE len %zd\n", end - pos); - lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos); - - /* process variable IE */ - while (pos <= end - 2) { - if (pos + pos[1] > end) { - lbs_deb_scan("process_bss: error in processing IE, " - "bytes left < IE length\n"); - break; - } - - switch (pos[0]) { - case WLAN_EID_SSID: - bss->ssid_len = min_t(int, IEEE80211_MAX_SSID_LEN, pos[1]); - memcpy(bss->ssid, pos + 2, bss->ssid_len); - lbs_deb_scan("got SSID IE: '%s', len %u\n", - print_ssid(ssid, bss->ssid, bss->ssid_len), - bss->ssid_len); - break; - - case WLAN_EID_SUPP_RATES: - n_basic_rates = min_t(uint8_t, MAX_RATES, pos[1]); - memcpy(bss->rates, pos + 2, n_basic_rates); - got_basic_rates = 1; - lbs_deb_scan("got RATES IE\n"); - break; - - case WLAN_EID_FH_PARAMS: - fh = (struct ieee_ie_fh_param_set *) pos; - memcpy(&bss->phy.fh, fh, sizeof(*fh)); - lbs_deb_scan("got FH IE\n"); - break; - - case WLAN_EID_DS_PARAMS: - ds = (struct ieee_ie_ds_param_set *) pos; - bss->channel = ds->channel; - memcpy(&bss->phy.ds, ds, sizeof(*ds)); - lbs_deb_scan("got DS IE, channel %d\n", bss->channel); - break; - - case WLAN_EID_CF_PARAMS: - cf = (struct ieee_ie_cf_param_set *) pos; - memcpy(&bss->ss.cf, cf, sizeof(*cf)); - lbs_deb_scan("got CF IE\n"); - break; - - case WLAN_EID_IBSS_PARAMS: - ibss = (struct ieee_ie_ibss_param_set *) pos; - bss->atimwindow = ibss->atimwindow; - memcpy(&bss->ss.ibss, ibss, sizeof(*ibss)); - lbs_deb_scan("got IBSS IE\n"); - break; - - case WLAN_EID_EXT_SUPP_RATES: - /* only process extended supported rate if data rate is - * already found. Data rate IE should come before - * extended supported rate IE - */ - lbs_deb_scan("got RATESEX IE\n"); - if (!got_basic_rates) { - lbs_deb_scan("... but ignoring it\n"); - break; - } - - n_ex_rates = pos[1]; - if (n_basic_rates + n_ex_rates > MAX_RATES) - n_ex_rates = MAX_RATES - n_basic_rates; - - p = bss->rates + n_basic_rates; - memcpy(p, pos + 2, n_ex_rates); - break; - - case WLAN_EID_GENERIC: - if (pos[1] >= 4 && - pos[2] == 0x00 && pos[3] == 0x50 && - pos[4] == 0xf2 && pos[5] == 0x01) { - bss->wpa_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN); - memcpy(bss->wpa_ie, pos, bss->wpa_ie_len); - lbs_deb_scan("got WPA IE\n"); - lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, - bss->wpa_ie_len); - } else if (pos[1] >= MARVELL_MESH_IE_LENGTH && - pos[2] == 0x00 && pos[3] == 0x50 && - pos[4] == 0x43 && pos[5] == 0x04) { - lbs_deb_scan("got mesh IE\n"); - bss->mesh = 1; - } else { - lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n", - pos[2], pos[3], - pos[4], pos[5], - pos[1]); - } - break; - - case WLAN_EID_RSN: - lbs_deb_scan("got RSN IE\n"); - bss->rsn_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN); - memcpy(bss->rsn_ie, pos, bss->rsn_ie_len); - lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", - bss->rsn_ie, bss->rsn_ie_len); - break; - - default: - lbs_deb_scan("got IE 0x%04x, len %d\n", - pos[0], pos[1]); - break; - } - - pos += pos[1] + 2; - } - - /* Timestamp */ - bss->last_scanned = jiffies; - lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); - - ret = 0; - -done: - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} - -/** - * @brief Send a scan command for all available channels filtered on a spec - * - * Used in association code and from debugfs - * - * @param priv A pointer to struct lbs_private structure - * @param ssid A pointer to the SSID to scan for - * @param ssid_len Length of the SSID - * - * @return 0-success, otherwise fail - */ -int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid, - uint8_t ssid_len) -{ - DECLARE_SSID_BUF(ssid_buf); - int ret = 0; - - lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n", - print_ssid(ssid_buf, ssid, ssid_len)); - - if (!ssid_len) - goto out; - - memcpy(priv->scan_ssid, ssid, ssid_len); - priv->scan_ssid_len = ssid_len; - - lbs_scan_networks(priv, 1); - if (priv->surpriseremoved) { - ret = -1; - goto out; - } - -out: - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} - - - - -/*********************************************************************/ -/* */ -/* Support for Wireless Extensions */ -/* */ -/*********************************************************************/ - - -#define MAX_CUSTOM_LEN 64 - -static inline char *lbs_translate_scan(struct lbs_private *priv, - struct iw_request_info *info, - char *start, char *stop, - struct bss_descriptor *bss) -{ - struct chan_freq_power *cfp; - char *current_val; /* For rates */ - struct iw_event iwe; /* Temporary buffer */ - int j; -#define PERFECT_RSSI ((uint8_t)50) -#define WORST_RSSI ((uint8_t)0) -#define RSSI_DIFF ((uint8_t)(PERFECT_RSSI - WORST_RSSI)) - uint8_t rssi; - - lbs_deb_enter(LBS_DEB_SCAN); - - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, bss->channel); - if (!cfp) { - lbs_deb_scan("Invalid channel number %d\n", bss->channel); - start = NULL; - goto out; - } - - /* First entry *MUST* be the BSSID */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - - /* SSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IEEE80211_MAX_SSID_LEN); - start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); - - /* Mode */ - iwe.cmd = SIOCGIWMODE; - iwe.u.mode = bss->mode; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); - - /* Frequency */ - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = (long)cfp->freq * 100000; - iwe.u.freq.e = 1; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); - - /* Add quality statistics */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.updated = IW_QUAL_ALL_UPDATED; - iwe.u.qual.level = SCAN_RSSI(bss->rssi); - - rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; - iwe.u.qual.qual = - (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * - (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / - (RSSI_DIFF * RSSI_DIFF); - if (iwe.u.qual.qual > 100) - iwe.u.qual.qual = 100; - - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { - iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; - } else { - iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); - } - - /* Locally created ad-hoc BSSs won't have beacons if this is the - * only station in the adhoc network; so get signal strength - * from receive statistics. - */ - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate - && !lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - bss->ssid, bss->ssid_len)) { - int snr, nf; - snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; - nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; - iwe.u.qual.level = CAL_RSSI(snr, nf); - } - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); - - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (bss->capability & WLAN_CAPABILITY_PRIVACY) { - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - } else { - iwe.u.data.flags = IW_ENCODE_DISABLED; - } - iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); - - current_val = start + iwe_stream_lcp_len(info); - - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = 0; - iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = 0; - - for (j = 0; j < ARRAY_SIZE(bss->rates) && bss->rates[j]; j++) { - /* Bit rate given in 500 kb/s units */ - iwe.u.bitrate.value = bss->rates[j] * 500000; - current_val = iwe_stream_add_value(info, start, current_val, - stop, &iwe, IW_EV_PARAM_LEN); - } - if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate - && !lbs_ssid_cmp(priv->curbssparams.ssid, - priv->curbssparams.ssid_len, - bss->ssid, bss->ssid_len)) { - iwe.u.bitrate.value = 22 * 500000; - current_val = iwe_stream_add_value(info, start, current_val, - stop, &iwe, IW_EV_PARAM_LEN); - } - /* Check if we added any event */ - if ((current_val - start) > iwe_stream_lcp_len(info)) - start = current_val; - - memset(&iwe, 0, sizeof(iwe)); - if (bss->wpa_ie_len) { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = bss->wpa_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - memset(&iwe, 0, sizeof(iwe)); - if (bss->rsn_ie_len) { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = bss->rsn_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - if (bss->mesh) { - char custom[MAX_CUSTOM_LEN]; - char *p = custom; - - iwe.cmd = IWEVCUSTOM; - p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, - &iwe, custom); - } - -out: - lbs_deb_leave_args(LBS_DEB_SCAN, "start %p", start); - return start; -} - - -/** - * @brief Handle Scan Network ioctl - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * - * @return 0 --success, otherwise fail - */ -int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - DECLARE_SSID_BUF(ssid); - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!priv->radio_on) { - ret = -EINVAL; - goto out; - } - - if (!netif_running(dev)) { - ret = -ENETDOWN; - goto out; - } - - /* mac80211 does this: - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_IF_TYPE_xxx) { - ret = -EOPNOTSUPP; - goto out; - } - */ - - if (wrqu->data.length == sizeof(struct iw_scan_req) && - wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - priv->scan_ssid_len = req->essid_len; - memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); - lbs_deb_wext("set_scan, essid '%s'\n", - print_ssid(ssid, priv->scan_ssid, priv->scan_ssid_len)); - } else { - priv->scan_ssid_len = 0; - } - - if (!delayed_work_pending(&priv->scan_work)) - queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(50)); - /* set marker that currently a scan is taking place */ - priv->scan_channel = -1; - - if (priv->surpriseremoved) - ret = -EIO; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - - -/** - * @brief Handle Retrieve scan table ioctl - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param dwrq A pointer to iw_point structure - * @param extra A pointer to extra data buf - * - * @return 0 --success, otherwise fail - */ -int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ -#define SCAN_ITEM_SIZE 128 - struct lbs_private *priv = dev->ml_priv; - int err = 0; - char *ev = extra; - char *stop = ev + dwrq->length; - struct bss_descriptor *iter_bss; - struct bss_descriptor *safe; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* iwlist should wait until the current scan is finished */ - if (priv->scan_channel) - return -EAGAIN; - - /* Update RSSI if current BSS is a locally created ad-hoc BSS */ - if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) { - err = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, - CMD_OPTION_WAITFORRSP, 0, NULL); - if (err) - goto out; - } - - mutex_lock(&priv->lock); - list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { - char *next_ev; - unsigned long stale_time; - - if (stop - ev < SCAN_ITEM_SIZE) { - err = -E2BIG; - break; - } - - /* For mesh device, list only mesh networks */ - if (dev == priv->mesh_dev && !iter_bss->mesh) - continue; - - /* Prune old an old scan result */ - stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; - if (time_after(jiffies, stale_time)) { - list_move_tail(&iter_bss->list, &priv->network_free_list); - clear_bss_descriptor(iter_bss); - continue; - } - - /* Translate to WE format this entry */ - next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss); - if (next_ev == NULL) - continue; - ev = next_ev; - } - mutex_unlock(&priv->lock); - - dwrq->length = (ev - extra); - dwrq->flags = 0; -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err); - return err; -} - - - - -/*********************************************************************/ -/* */ -/* Command execution */ -/* */ -/*********************************************************************/ - - -/** - * @brief This function handles the command response of scan - * - * Called from handle_cmd_response() in cmdrespc. - * - * The response buffer for the scan command has the following - * memory layout: - * - * .-----------------------------------------------------------. - * | header (4 * sizeof(u16)): Standard command response hdr | - * .-----------------------------------------------------------. - * | bufsize (u16) : sizeof the BSS Description data | - * .-----------------------------------------------------------. - * | NumOfSet (u8) : Number of BSS Descs returned | - * .-----------------------------------------------------------. - * | BSSDescription data (variable, size given in bufsize) | - * .-----------------------------------------------------------. - * | TLV data (variable, size calculated using header->size, | - * | bufsize and sizeof the fixed fields above) | - * .-----------------------------------------------------------. - * - * @param priv A pointer to struct lbs_private structure - * @param resp A pointer to cmd_ds_command - * - * @return 0 or -1 - */ -static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, - struct cmd_header *resp) -{ - struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; - struct bss_descriptor *iter_bss; - struct bss_descriptor *safe; - uint8_t *bssinfo; - uint16_t scanrespsize; - int bytesleft; - int idx; - int tlvbufsize; - int ret; - - lbs_deb_enter(LBS_DEB_SCAN); - - /* Prune old entries from scan table */ - list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { - unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; - if (time_before(jiffies, stale_time)) - continue; - list_move_tail (&iter_bss->list, &priv->network_free_list); - clear_bss_descriptor(iter_bss); - } - - if (scanresp->nr_sets > MAX_NETWORK_COUNT) { - lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n", - scanresp->nr_sets, MAX_NETWORK_COUNT); - ret = -1; - goto done; - } - - bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize); - lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); - - scanrespsize = le16_to_cpu(resp->size); - lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets); - - bssinfo = scanresp->bssdesc_and_tlvbuffer; - - /* The size of the TLV buffer is equal to the entire command response - * size (scanrespsize) minus the fixed fields (sizeof()'s), the - * BSS Descriptions (bssdescriptsize as bytesLef) and the command - * response header (sizeof(struct cmd_header)) - */ - tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize) - + sizeof(scanresp->nr_sets) - + sizeof(struct cmd_header)); - - /* - * Process each scan response returned (scanresp->nr_sets). Save - * the information in the newbssentry and then insert into the - * driver scan table either as an update to an existing entry - * or as an addition at the end of the table - */ - for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) { - struct bss_descriptor new; - struct bss_descriptor *found = NULL; - struct bss_descriptor *oldest = NULL; - - /* Process the data fields and IEs returned for this BSS */ - memset(&new, 0, sizeof (struct bss_descriptor)); - if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) { - /* error parsing the scan response, skipped */ - lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); - continue; - } - - /* Try to find this bss in the scan table */ - list_for_each_entry (iter_bss, &priv->network_list, list) { - if (is_same_network(iter_bss, &new)) { - found = iter_bss; - break; - } - - if ((oldest == NULL) || - (iter_bss->last_scanned < oldest->last_scanned)) - oldest = iter_bss; - } - - if (found) { - /* found, clear it */ - clear_bss_descriptor(found); - } else if (!list_empty(&priv->network_free_list)) { - /* Pull one from the free list */ - found = list_entry(priv->network_free_list.next, - struct bss_descriptor, list); - list_move_tail(&found->list, &priv->network_list); - } else if (oldest) { - /* If there are no more slots, expire the oldest */ - found = oldest; - clear_bss_descriptor(found); - list_move_tail(&found->list, &priv->network_list); - } else { - continue; - } - - lbs_deb_scan("SCAN_RESP: BSSID %pM\n", new.bssid); - - /* Copy the locally created newbssentry to the scan table */ - memcpy(found, &new, offsetof(struct bss_descriptor, list)); - } - - ret = 0; - -done: - lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); - return ret; -} diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h deleted file mode 100644 index 8fb1706d752..00000000000 --- a/drivers/net/wireless/libertas/scan.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Interface for the wlan network scan routines - * - * Driver interface functions and type declarations for the scan module - * implemented in scan.c. - */ -#ifndef _LBS_SCAN_H -#define _LBS_SCAN_H - -#include <net/iw_handler.h> - -struct lbs_private; - -#define MAX_NETWORK_COUNT 128 - -/** Chan-freq-TxPower mapping table*/ -struct chan_freq_power { - /** channel Number */ - u16 channel; - /** frequency of this channel */ - u32 freq; - /** Max allowed Tx power level */ - u16 maxtxpower; - /** TRUE:channel unsupported; FLASE:supported*/ - u8 unsupported; -}; - -/** region-band mapping table*/ -struct region_channel { - /** TRUE if this entry is valid */ - u8 valid; - /** region code for US, Japan ... */ - u8 region; - /** band B/G/A, used for BAND_CONFIG cmd */ - u8 band; - /** Actual No. of elements in the array below */ - u8 nrcfp; - /** chan-freq-txpower mapping table*/ - struct chan_freq_power *CFP; -}; - -/** - * @brief Maximum number of channels that can be sent in a setuserscan ioctl - */ -#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 - -int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); - -int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band); - -int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, - u8 ssid_len); - -int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra); -int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int lbs_scan_networks(struct lbs_private *priv, int full_scan); - -void lbs_scan_worker(struct work_struct *work); - -#endif diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index a9bf658659e..8000ca6165d 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -4,13 +4,13 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/sched.h> +#include <net/cfg80211.h> #include "host.h" #include "radiotap.h" #include "decl.h" #include "defs.h" #include "dev.h" -#include "wext.h" /** * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE @@ -111,7 +111,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) p802x_hdr = skb->data; pkt_len = skb->len; - if (dev == priv->rtap_net_dev) { + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data; /* set txpd fields from the radiotap header */ @@ -147,7 +147,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; - if (priv->monitormode) { + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { /* Keep the skb to echo it back once Tx feedback is received from FW */ skb_orphan(skb); @@ -158,6 +158,7 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) free: dev_kfree_skb_any(skb); } + unlock: spin_unlock_irqrestore(&priv->driver_lock, flags); wake_up(&priv->waitq); @@ -179,7 +180,8 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) { struct tx_radiotap_hdr *radiotap_hdr; - if (!priv->monitormode || priv->currenttxskb == NULL) + if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR || + priv->currenttxskb == NULL) return; radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data; @@ -188,7 +190,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) (1 + priv->txretrycount - try_count) : 0; priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb, - priv->rtap_net_dev); + priv->dev); netif_rx(priv->currenttxskb); priv->currenttxskb = NULL; diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index 3e72c86ceca..462fbb4cb74 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -11,7 +11,7 @@ struct ieee_ie_header { u8 id; u8 len; -} __attribute__ ((packed)); +} __packed; struct ieee_ie_cf_param_set { struct ieee_ie_header header; @@ -20,19 +20,19 @@ struct ieee_ie_cf_param_set { u8 cfpperiod; __le16 cfpmaxduration; __le16 cfpdurationremaining; -} __attribute__ ((packed)); +} __packed; struct ieee_ie_ibss_param_set { struct ieee_ie_header header; __le16 atimwindow; -} __attribute__ ((packed)); +} __packed; union ieee_ss_param_set { struct ieee_ie_cf_param_set cf; struct ieee_ie_ibss_param_set ibss; -} __attribute__ ((packed)); +} __packed; struct ieee_ie_fh_param_set { struct ieee_ie_header header; @@ -41,18 +41,18 @@ struct ieee_ie_fh_param_set { u8 hopset; u8 hoppattern; u8 hopindex; -} __attribute__ ((packed)); +} __packed; struct ieee_ie_ds_param_set { struct ieee_ie_header header; u8 channel; -} __attribute__ ((packed)); +} __packed; union ieee_phy_param_set { struct ieee_ie_fh_param_set fh; struct ieee_ie_ds_param_set ds; -} __attribute__ ((packed)); +} __packed; /** TLV type ID definition */ #define PROPRIETARY_TLV_BASE_ID 0x0100 @@ -100,28 +100,28 @@ union ieee_phy_param_set { struct mrvl_ie_header { __le16 type; __le16 len; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_data { struct mrvl_ie_header header; u8 Data[1]; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_rates_param_set { struct mrvl_ie_header header; u8 rates[1]; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_ssid_param_set { struct mrvl_ie_header header; u8 ssid[1]; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_wildcard_ssid_param_set { struct mrvl_ie_header header; u8 MaxSsidlength; u8 ssid[1]; -} __attribute__ ((packed)); +} __packed; struct chanscanmode { #ifdef __BIG_ENDIAN_BITFIELD @@ -133,7 +133,7 @@ struct chanscanmode { u8 disablechanfilt:1; u8 reserved_2_7:6; #endif -} __attribute__ ((packed)); +} __packed; struct chanscanparamset { u8 radiotype; @@ -141,12 +141,12 @@ struct chanscanparamset { struct chanscanmode chanscanmode; __le16 minscantime; __le16 maxscantime; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_chanlist_param_set { struct mrvl_ie_header header; struct chanscanparamset chanscanparam[1]; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_cf_param_set { struct mrvl_ie_header header; @@ -154,86 +154,86 @@ struct mrvl_ie_cf_param_set { u8 cfpperiod; __le16 cfpmaxduration; __le16 cfpdurationremaining; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_ds_param_set { struct mrvl_ie_header header; u8 channel; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_rsn_param_set { struct mrvl_ie_header header; u8 rsnie[1]; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_tsf_timestamp { struct mrvl_ie_header header; __le64 tsftable[1]; -} __attribute__ ((packed)); +} __packed; /* v9 and later firmware only */ struct mrvl_ie_auth_type { struct mrvl_ie_header header; __le16 auth; -} __attribute__ ((packed)); +} __packed; /** Local Power capability */ struct mrvl_ie_power_capability { struct mrvl_ie_header header; s8 minpower; s8 maxpower; -} __attribute__ ((packed)); +} __packed; /* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */ struct mrvl_ie_thresholds { struct mrvl_ie_header header; u8 value; u8 freq; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_beacons_missed { struct mrvl_ie_header header; u8 beaconmissed; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_num_probes { struct mrvl_ie_header header; __le16 numprobes; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_bcast_probe { struct mrvl_ie_header header; __le16 bcastprobe; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_num_ssid_probe { struct mrvl_ie_header header; __le16 numssidprobe; -} __attribute__ ((packed)); +} __packed; struct led_pin { u8 led; u8 pin; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_ledgpio { struct mrvl_ie_header header; struct led_pin ledpin[1]; -} __attribute__ ((packed)); +} __packed; struct led_bhv { uint8_t firmwarestate; uint8_t led; uint8_t ledstate; uint8_t ledarg; -} __attribute__ ((packed)); +} __packed; struct mrvl_ie_ledbhv { struct mrvl_ie_header header; struct led_bhv ledbhv[1]; -} __attribute__ ((packed)); +} __packed; /* Meant to be packed as the value member of a struct ieee80211_info_element. * Note that the len member of the ieee80211_info_element varies depending on @@ -248,12 +248,12 @@ struct mrvl_meshie_val { uint8_t mesh_capability; uint8_t mesh_id_len; uint8_t mesh_id[IEEE80211_MAX_SSID_LEN]; -} __attribute__ ((packed)); +} __packed; struct mrvl_meshie { u8 id, len; struct mrvl_meshie_val val; -} __attribute__ ((packed)); +} __packed; struct mrvl_mesh_defaults { __le32 bootflag; @@ -261,6 +261,6 @@ struct mrvl_mesh_defaults { uint8_t reserved; __le16 channel; struct mrvl_meshie meshie; -} __attribute__ ((packed)); +} __packed; #endif diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c deleted file mode 100644 index f96a96031a5..00000000000 --- a/drivers/net/wireless/libertas/wext.c +++ /dev/null @@ -1,2353 +0,0 @@ -/** - * This file contains ioctl functions - */ -#include <linux/ctype.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> -#include <linux/bitops.h> - -#include <net/lib80211.h> -#include <net/iw_handler.h> - -#include "host.h" -#include "radiotap.h" -#include "decl.h" -#include "defs.h" -#include "dev.h" -#include "wext.h" -#include "scan.h" -#include "assoc.h" -#include "cmd.h" - - -static inline void lbs_postpone_association_work(struct lbs_private *priv) -{ - if (priv->surpriseremoved) - return; - cancel_delayed_work(&priv->assoc_work); - queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2); -} - -static inline void lbs_do_association_work(struct lbs_private *priv) -{ - if (priv->surpriseremoved) - return; - cancel_delayed_work(&priv->assoc_work); - queue_delayed_work(priv->work_thread, &priv->assoc_work, 0); -} - -static inline void lbs_cancel_association_work(struct lbs_private *priv) -{ - cancel_delayed_work(&priv->assoc_work); - kfree(priv->pending_assoc_req); - priv->pending_assoc_req = NULL; -} - -void lbs_send_disconnect_notification(struct lbs_private *priv) -{ - union iwreq_data wrqu; - - memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); -} - -static void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str) -{ - union iwreq_data iwrq; - u8 buf[50]; - - lbs_deb_enter(LBS_DEB_WEXT); - - memset(&iwrq, 0, sizeof(union iwreq_data)); - memset(buf, 0, sizeof(buf)); - - snprintf(buf, sizeof(buf) - 1, "%s", str); - - iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN; - - /* Send Event to upper layer */ - lbs_deb_wext("event indication string %s\n", (char *)buf); - lbs_deb_wext("event indication length %d\n", iwrq.data.length); - lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str); - - wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf); - - lbs_deb_leave(LBS_DEB_WEXT); -} - -/** - * @brief This function handles MIC failure event. - * - * @param priv A pointer to struct lbs_private structure - * @para event the event id - * @return n/a - */ -void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) -{ - char buf[50]; - - lbs_deb_enter(LBS_DEB_CMD); - memset(buf, 0, sizeof(buf)); - - sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication "); - - if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) - strcat(buf, "unicast "); - else - strcat(buf, "multicast "); - - lbs_send_iwevcustom_event(priv, buf); - lbs_deb_leave(LBS_DEB_CMD); -} - -/** - * @brief Find the channel frequency power info with specific channel - * - * @param priv A pointer to struct lbs_private structure - * @param band it can be BAND_A, BAND_G or BAND_B - * @param channel the channel for looking - * @return A pointer to struct chan_freq_power structure or NULL if not find. - */ -struct chan_freq_power *lbs_find_cfp_by_band_and_channel( - struct lbs_private *priv, - u8 band, - u16 channel) -{ - struct chan_freq_power *cfp = NULL; - struct region_channel *rc; - int i, j; - - for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) { - rc = &priv->region_channel[j]; - - if (!rc->valid || !rc->CFP) - continue; - if (rc->band != band) - continue; - for (i = 0; i < rc->nrcfp; i++) { - if (rc->CFP[i].channel == channel) { - cfp = &rc->CFP[i]; - break; - } - } - } - - if (!cfp && channel) - lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find " - "cfp by band %d / channel %d\n", band, channel); - - return cfp; -} - -/** - * @brief Find the channel frequency power info with specific frequency - * - * @param priv A pointer to struct lbs_private structure - * @param band it can be BAND_A, BAND_G or BAND_B - * @param freq the frequency for looking - * @return A pointer to struct chan_freq_power structure or NULL if not find. - */ -static struct chan_freq_power *find_cfp_by_band_and_freq( - struct lbs_private *priv, - u8 band, - u32 freq) -{ - struct chan_freq_power *cfp = NULL; - struct region_channel *rc; - int i, j; - - for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) { - rc = &priv->region_channel[j]; - - if (!rc->valid || !rc->CFP) - continue; - if (rc->band != band) - continue; - for (i = 0; i < rc->nrcfp; i++) { - if (rc->CFP[i].freq == freq) { - cfp = &rc->CFP[i]; - break; - } - } - } - - if (!cfp && freq) - lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by " - "band %d / freq %d\n", band, freq); - - return cfp; -} - -/** - * @brief Copy active data rates based on adapter mode and status - * - * @param priv A pointer to struct lbs_private structure - * @param rate The buf to return the active rates - */ -static void copy_active_data_rates(struct lbs_private *priv, u8 *rates) -{ - lbs_deb_enter(LBS_DEB_WEXT); - - if ((priv->connect_status != LBS_CONNECTED) && - !lbs_mesh_connected(priv)) - memcpy(rates, lbs_bg_rates, MAX_RATES); - else - memcpy(rates, priv->curbssparams.rates, MAX_RATES); - - lbs_deb_leave(LBS_DEB_WEXT); -} - -static int lbs_get_name(struct net_device *dev, struct iw_request_info *info, - char *cwrq, char *extra) -{ - - lbs_deb_enter(LBS_DEB_WEXT); - - /* We could add support for 802.11n here as needed. Jean II */ - snprintf(cwrq, IFNAMSIZ, "IEEE 802.11b/g"); - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, - struct iw_freq *fwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - struct chan_freq_power *cfp; - - lbs_deb_enter(LBS_DEB_WEXT); - - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, - priv->channel); - - if (!cfp) { - if (priv->channel) - lbs_deb_wext("invalid channel %d\n", - priv->channel); - return -EINVAL; - } - - fwrq->m = (long)cfp->freq * 100000; - fwrq->e = 1; - - lbs_deb_wext("freq %u\n", fwrq->m); - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, - struct sockaddr *awrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (priv->connect_status == LBS_CONNECTED) { - memcpy(awrq->sa_data, priv->curbssparams.bssid, ETH_ALEN); - } else { - memset(awrq->sa_data, 0, ETH_ALEN); - } - awrq->sa_family = ARPHRD_ETHER; - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* - * Check the size of the string - */ - - if (dwrq->length > 16) { - return -E2BIG; - } - - mutex_lock(&priv->lock); - memset(priv->nodename, 0, sizeof(priv->nodename)); - memcpy(priv->nodename, extra, dwrq->length); - mutex_unlock(&priv->lock); - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - dwrq->length = strlen(priv->nodename); - memcpy(extra, priv->nodename, dwrq->length); - extra[dwrq->length] = '\0'; - - dwrq->flags = 1; /* active */ - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -#ifdef CONFIG_LIBERTAS_MESH -static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* Use nickname to indicate that mesh is on */ - - if (lbs_mesh_connected(priv)) { - strncpy(extra, "Mesh", 12); - extra[12] = '\0'; - dwrq->length = strlen(extra); - } - - else { - extra[0] = '\0'; - dwrq->length = 0; - } - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} -#endif - -static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - u32 val = vwrq->value; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (vwrq->disabled) - val = MRVDRV_RTS_MAX_VALUE; - - if (val > MRVDRV_RTS_MAX_VALUE) /* min rts value is 0 */ - return -EINVAL; - - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, (u16) val); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u16 val = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val); - if (ret) - goto out; - - vwrq->value = val; - vwrq->disabled = val > MRVDRV_RTS_MAX_VALUE; /* min rts value is 0 */ - vwrq->fixed = 1; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u32 val = vwrq->value; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (vwrq->disabled) - val = MRVDRV_FRAG_MAX_VALUE; - - if (val < MRVDRV_FRAG_MIN_VALUE || val > MRVDRV_FRAG_MAX_VALUE) - return -EINVAL; - - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, (u16) val); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u16 val = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val); - if (ret) - goto out; - - vwrq->value = val; - vwrq->disabled = ((val < MRVDRV_FRAG_MIN_VALUE) - || (val > MRVDRV_FRAG_MAX_VALUE)); - vwrq->fixed = 1; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_mode(struct net_device *dev, - struct iw_request_info *info, u32 * uwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - *uwrq = priv->mode; - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -#ifdef CONFIG_LIBERTAS_MESH -static int mesh_wlan_get_mode(struct net_device *dev, - struct iw_request_info *info, u32 * uwrq, - char *extra) -{ - lbs_deb_enter(LBS_DEB_WEXT); - - *uwrq = IW_MODE_REPEAT; - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} -#endif - -static int lbs_get_txpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - s16 curlevel = 0; - int ret = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!priv->radio_on) { - lbs_deb_wext("tx power off\n"); - vwrq->value = 0; - vwrq->disabled = 1; - goto out; - } - - ret = lbs_get_tx_power(priv, &curlevel, NULL, NULL); - if (ret) - goto out; - - lbs_deb_wext("tx power level %d dbm\n", curlevel); - priv->txpower_cur = curlevel; - - vwrq->value = curlevel; - vwrq->fixed = 1; - vwrq->disabled = 0; - vwrq->flags = IW_TXPOW_DBM; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u16 slimit = 0, llimit = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) - return -EOPNOTSUPP; - - /* The MAC has a 4-bit Total_Tx_Count register - Total_Tx_Count = 1 + Tx_Retry_Count */ -#define TX_RETRY_MIN 0 -#define TX_RETRY_MAX 14 - if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX) - return -EINVAL; - - /* Add 1 to convert retry count to try count */ - if (vwrq->flags & IW_RETRY_SHORT) - slimit = (u16) (vwrq->value + 1); - else if (vwrq->flags & IW_RETRY_LONG) - llimit = (u16) (vwrq->value + 1); - else - slimit = llimit = (u16) (vwrq->value + 1); /* set both */ - - if (llimit) { - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT, - llimit); - if (ret) - goto out; - } - - if (slimit) { - /* txretrycount follows the short retry limit */ - priv->txretrycount = slimit; - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT, - slimit); - if (ret) - goto out; - } - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u16 val = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - vwrq->disabled = 0; - - if (vwrq->flags & IW_RETRY_LONG) { - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_LONG_RETRY_LIMIT, &val); - if (ret) - goto out; - - /* Subtract 1 to convert try count to retry count */ - vwrq->value = val - 1; - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; - } else { - ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_SHORT_RETRY_LIMIT, &val); - if (ret) - goto out; - - /* txretry count follows the short retry limit */ - priv->txretrycount = val; - /* Subtract 1 to convert try count to retry count */ - vwrq->value = val - 1; - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; - } - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static inline void sort_channels(struct iw_freq *freq, int num) -{ - int i, j; - struct iw_freq temp; - - for (i = 0; i < num; i++) - for (j = i + 1; j < num; j++) - if (freq[i].i > freq[j].i) { - temp.i = freq[i].i; - temp.m = freq[i].m; - - freq[i].i = freq[j].i; - freq[i].m = freq[j].m; - - freq[j].i = temp.i; - freq[j].m = temp.m; - } -} - -/* data rate listing - MULTI_BANDS: - abg a b b/g - Infra G(12) A(8) B(4) G(12) - Adhoc A+B(12) A(8) B(4) B(4) - - non-MULTI_BANDS: - b b/g - Infra B(4) G(12) - Adhoc B(4) B(4) - */ -/** - * @brief Get Range Info - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 --success, otherwise fail - */ -static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - int i, j; - struct lbs_private *priv = dev->ml_priv; - struct iw_range *range = (struct iw_range *)extra; - struct chan_freq_power *cfp; - u8 rates[MAX_RATES + 1]; - - lbs_deb_enter(LBS_DEB_WEXT); - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - range->min_nwid = 0; - range->max_nwid = 0; - - memset(rates, 0, sizeof(rates)); - copy_active_data_rates(priv, rates); - range->num_bitrates = strnlen(rates, IW_MAX_BITRATES); - for (i = 0; i < range->num_bitrates; i++) - range->bitrate[i] = rates[i] * 500000; - range->num_bitrates = i; - lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, - range->num_bitrates); - - range->num_frequency = 0; - - range->scan_capa = IW_SCAN_CAPA_ESSID; - - for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES) - && (j < ARRAY_SIZE(priv->region_channel)); j++) { - cfp = priv->region_channel[j].CFP; - for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES) - && priv->region_channel[j].valid - && cfp - && (i < priv->region_channel[j].nrcfp); i++) { - range->freq[range->num_frequency].i = - (long)cfp->channel; - range->freq[range->num_frequency].m = - (long)cfp->freq * 100000; - range->freq[range->num_frequency].e = 1; - cfp++; - range->num_frequency++; - } - } - - lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n", - IW_MAX_FREQUENCIES, range->num_frequency); - - range->num_channels = range->num_frequency; - - sort_channels(&range->freq[0], range->num_frequency); - - /* - * Set an indication of the max TCP throughput in bit/s that we can - * expect using this interface - */ - if (i > 2) - range->throughput = 5000 * 1000; - else - range->throughput = 1500 * 1000; - - range->min_rts = MRVDRV_RTS_MIN_VALUE; - range->max_rts = MRVDRV_RTS_MAX_VALUE; - range->min_frag = MRVDRV_FRAG_MIN_VALUE; - range->max_frag = MRVDRV_FRAG_MAX_VALUE; - - range->encoding_size[0] = 5; - range->encoding_size[1] = 13; - range->num_encoding_sizes = 2; - range->max_encoding_tokens = 4; - - /* - * Right now we support only "iwconfig ethX power on|off" - */ - range->pm_capa = IW_POWER_ON; - - /* - * Minimum version we recommend - */ - range->we_version_source = 15; - - /* - * Version we are compiled with - */ - range->we_version_compiled = WIRELESS_EXT; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - - range->min_retry = TX_RETRY_MIN; - range->max_retry = TX_RETRY_MAX; - - /* - * Set the qual, level and noise range values - */ - range->max_qual.qual = 100; - range->max_qual.level = 0; - range->max_qual.noise = 0; - range->max_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - - range->avg_qual.qual = 70; - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 0; - range->avg_qual.noise = 0; - range->avg_qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - - range->sensitivity = 0; - - /* Setup the supported power level ranges */ - memset(range->txpower, 0, sizeof(range->txpower)); - range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE; - range->txpower[0] = priv->txpower_min; - range->txpower[1] = priv->txpower_max; - range->num_txpower = 2; - - range->event_capa[0] = (IW_EVENT_CAPA_K_0 | - IW_EVENT_CAPA_MASK(SIOCGIWAP) | - IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); - range->event_capa[1] = IW_EVENT_CAPA_K_1; - - if (priv->fwcapinfo & FW_CAPINFO_WPA) { - range->enc_capa = IW_ENC_CAPA_WPA - | IW_ENC_CAPA_WPA2 - | IW_ENC_CAPA_CIPHER_TKIP - | IW_ENC_CAPA_CIPHER_CCMP; - } - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!(priv->fwcapinfo & FW_CAPINFO_PS)) { - if (vwrq->disabled) - return 0; - else - return -EINVAL; - } - - /* PS is currently supported only in Infrastructure mode - * Remove this check if it is to be supported in IBSS mode also - */ - - if (vwrq->disabled) { - priv->psmode = LBS802_11POWERMODECAM; - if (priv->psstate != PS_STATE_FULL_POWER) { - lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); - } - - return 0; - } - - if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - lbs_deb_wext( - "setting power timeout is not supported\n"); - return -EINVAL; - } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { - vwrq->value = vwrq->value / 1000; - if (!priv->enter_deep_sleep) { - lbs_pr_err("deep sleep feature is not implemented " - "for this interface driver\n"); - return -EINVAL; - } - - if (priv->connect_status == LBS_CONNECTED) { - if ((priv->is_auto_deep_sleep_enabled) && - (vwrq->value == -1000)) { - lbs_exit_auto_deep_sleep(priv); - return 0; - } else { - lbs_pr_err("can't use deep sleep cmd in " - "connected state\n"); - return -EINVAL; - } - } - - if ((vwrq->value < 0) && (vwrq->value != -1000)) { - lbs_pr_err("unknown option\n"); - return -EINVAL; - } - - if (vwrq->value > 0) { - if (!priv->is_auto_deep_sleep_enabled) { - priv->is_activity_detected = 0; - priv->auto_deep_sleep_timeout = vwrq->value; - lbs_enter_auto_deep_sleep(priv); - } else { - priv->auto_deep_sleep_timeout = vwrq->value; - lbs_deb_debugfs("auto deep sleep: " - "already enabled\n"); - } - return 0; - } else { - if (priv->is_auto_deep_sleep_enabled) { - lbs_exit_auto_deep_sleep(priv); - /* Try to exit deep sleep if auto */ - /*deep sleep disabled */ - ret = lbs_set_deep_sleep(priv, 0); - } - if (vwrq->value == 0) - ret = lbs_set_deep_sleep(priv, 1); - else if (vwrq->value == -1000) - ret = lbs_set_deep_sleep(priv, 0); - return ret; - } - } - - if (priv->psmode != LBS802_11POWERMODECAM) { - return 0; - } - - priv->psmode = LBS802_11POWERMODEMAX_PSP; - - if (priv->connect_status == LBS_CONNECTED) { - lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP); - } - - lbs_deb_leave(LBS_DEB_WEXT); - - return 0; -} - -static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - vwrq->value = 0; - vwrq->flags = 0; - vwrq->disabled = priv->psmode == LBS802_11POWERMODECAM - || priv->connect_status == LBS_DISCONNECTED; - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) -{ - enum { - POOR = 30, - FAIR = 60, - GOOD = 80, - VERY_GOOD = 90, - EXCELLENT = 95, - PERFECT = 100 - }; - struct lbs_private *priv = dev->ml_priv; - u32 rssi_qual; - u32 tx_qual; - u32 quality = 0; - int ret, stats_valid = 0; - u8 rssi; - u32 tx_retries; - struct cmd_ds_802_11_get_log log; - - lbs_deb_enter(LBS_DEB_WEXT); - - priv->wstats.status = priv->mode; - - /* If we're not associated, all quality values are meaningless */ - if ((priv->connect_status != LBS_CONNECTED) && - !lbs_mesh_connected(priv)) - goto out; - - /* Quality by RSSI */ - priv->wstats.qual.level = - CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], - priv->NF[TYPE_BEACON][TYPE_NOAVG]); - - if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { - priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; - } else { - priv->wstats.qual.noise = - CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]); - } - - lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level); - lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise); - - rssi = priv->wstats.qual.level - priv->wstats.qual.noise; - if (rssi < 15) - rssi_qual = rssi * POOR / 10; - else if (rssi < 20) - rssi_qual = (rssi - 15) * (FAIR - POOR) / 5 + POOR; - else if (rssi < 30) - rssi_qual = (rssi - 20) * (GOOD - FAIR) / 5 + FAIR; - else if (rssi < 40) - rssi_qual = (rssi - 30) * (VERY_GOOD - GOOD) / - 10 + GOOD; - else - rssi_qual = (rssi - 40) * (PERFECT - VERY_GOOD) / - 10 + VERY_GOOD; - quality = rssi_qual; - - /* Quality by TX errors */ - priv->wstats.discard.retries = dev->stats.tx_errors; - - memset(&log, 0, sizeof(log)); - log.hdr.size = cpu_to_le16(sizeof(log)); - ret = lbs_cmd_with_response(priv, CMD_802_11_GET_LOG, &log); - if (ret) - goto out; - - tx_retries = le32_to_cpu(log.retry); - - if (tx_retries > 75) - tx_qual = (90 - tx_retries) * POOR / 15; - else if (tx_retries > 70) - tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR; - else if (tx_retries > 65) - tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; - else if (tx_retries > 50) - tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / - 15 + GOOD; - else - tx_qual = (50 - tx_retries) * - (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; - quality = min(quality, tx_qual); - - priv->wstats.discard.code = le32_to_cpu(log.wepundecryptable); - priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = le32_to_cpu(log.ackfailure); - - /* Calculate quality */ - priv->wstats.qual.qual = min_t(u8, quality, 100); - priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - stats_valid = 1; - - /* update stats asynchronously for future calls */ - ret = lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, - 0, 0, NULL); - if (ret) - lbs_pr_err("RSSI command failed\n"); -out: - if (!stats_valid) { - priv->wstats.miss.beacon = 0; - priv->wstats.discard.retries = 0; - priv->wstats.qual.qual = 0; - priv->wstats.qual.level = 0; - priv->wstats.qual.noise = 0; - priv->wstats.qual.updated = IW_QUAL_ALL_UPDATED; - priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID | - IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; - } - - lbs_deb_leave(LBS_DEB_WEXT); - return &priv->wstats; - - -} - -static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info, - struct iw_freq *fwrq, char *extra) -{ - int ret = -EINVAL; - struct lbs_private *priv = dev->ml_priv; - struct chan_freq_power *cfp; - struct assoc_request * assoc_req; - - lbs_deb_enter(LBS_DEB_WEXT); - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - goto out; - } - - /* If setting by frequency, convert to a channel */ - if (fwrq->e == 1) { - long f = fwrq->m / 100000; - - cfp = find_cfp_by_band_and_freq(priv, 0, f); - if (!cfp) { - lbs_deb_wext("invalid freq %ld\n", f); - goto out; - } - - fwrq->e = 0; - fwrq->m = (int) cfp->channel; - } - - /* Setting by channel number */ - if (fwrq->m > 1000 || fwrq->e > 0) { - goto out; - } - - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m); - if (!cfp) { - goto out; - } - - assoc_req->channel = fwrq->m; - ret = 0; - -out: - if (ret == 0) { - set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags); - lbs_postpone_association_work(priv); - } else { - lbs_cancel_association_work(priv); - } - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -#ifdef CONFIG_LIBERTAS_MESH -static int lbs_mesh_set_freq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *fwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - struct chan_freq_power *cfp; - int ret = -EINVAL; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* If setting by frequency, convert to a channel */ - if (fwrq->e == 1) { - long f = fwrq->m / 100000; - - cfp = find_cfp_by_band_and_freq(priv, 0, f); - if (!cfp) { - lbs_deb_wext("invalid freq %ld\n", f); - goto out; - } - - fwrq->e = 0; - fwrq->m = (int) cfp->channel; - } - - /* Setting by channel number */ - if (fwrq->m > 1000 || fwrq->e > 0) { - goto out; - } - - cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m); - if (!cfp) { - goto out; - } - - if (fwrq->m != priv->channel) { - lbs_deb_wext("mesh channel change forces eth disconnect\n"); - if (priv->mode == IW_MODE_INFRA) - lbs_cmd_80211_deauthenticate(priv, - priv->curbssparams.bssid, - WLAN_REASON_DEAUTH_LEAVING); - else if (priv->mode == IW_MODE_ADHOC) - lbs_adhoc_stop(priv); - } - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m); - lbs_update_channel(priv); - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} -#endif - -static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - u8 new_rate = 0; - int ret = -EINVAL; - u8 rates[MAX_RATES + 1]; - - lbs_deb_enter(LBS_DEB_WEXT); - - lbs_deb_wext("vwrq->value %d\n", vwrq->value); - lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed); - - if (vwrq->fixed && vwrq->value == -1) - goto out; - - /* Auto rate? */ - priv->enablehwauto = !vwrq->fixed; - - if (vwrq->value == -1) - priv->cur_rate = 0; - else { - if (vwrq->value % 100000) - goto out; - - new_rate = vwrq->value / 500000; - priv->cur_rate = new_rate; - /* the rest is only needed for lbs_set_data_rate() */ - memset(rates, 0, sizeof(rates)); - copy_active_data_rates(priv, rates); - if (!memchr(rates, new_rate, sizeof(rates))) { - lbs_pr_alert("fixed data rate 0x%X out of range\n", - new_rate); - goto out; - } - if (priv->fwrelease < 0x09000000) { - ret = lbs_set_power_adapt_cfg(priv, 0, - POW_ADAPT_DEFAULT_P0, - POW_ADAPT_DEFAULT_P1, - POW_ADAPT_DEFAULT_P2); - if (ret) - goto out; - } - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, - TPC_DEFAULT_P2, 1); - if (ret) - goto out; - } - - /* Try the newer command first (Firmware Spec 5.1 and above) */ - ret = lbs_cmd_802_11_rate_adapt_rateset(priv, CMD_ACT_SET); - - /* Fallback to older version */ - if (ret) - ret = lbs_set_data_rate(priv, new_rate); - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (priv->connect_status == LBS_CONNECTED) { - vwrq->value = priv->cur_rate * 500000; - - if (priv->enablehwauto) - vwrq->fixed = 0; - else - vwrq->fixed = 1; - - } else { - vwrq->fixed = 0; - vwrq->value = 0; - } - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_set_mode(struct net_device *dev, - struct iw_request_info *info, u32 * uwrq, char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - struct assoc_request * assoc_req; - - lbs_deb_enter(LBS_DEB_WEXT); - - if ( (*uwrq != IW_MODE_ADHOC) - && (*uwrq != IW_MODE_INFRA) - && (*uwrq != IW_MODE_AUTO)) { - lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq); - ret = -EINVAL; - goto out; - } - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - lbs_cancel_association_work(priv); - } else { - assoc_req->mode = *uwrq; - set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); - lbs_postpone_association_work(priv); - lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq); - } - mutex_unlock(&priv->lock); - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - - -/** - * @brief Get Encryption key - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 --success, otherwise fail - */ -static int lbs_get_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, u8 * extra) -{ - struct lbs_private *priv = dev->ml_priv; - int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - lbs_deb_enter(LBS_DEB_WEXT); - - lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n", - dwrq->flags, index, dwrq->length, priv->wep_tx_keyidx); - - dwrq->flags = 0; - - /* Authentication method */ - switch (priv->secinfo.auth_mode) { - case IW_AUTH_ALG_OPEN_SYSTEM: - dwrq->flags = IW_ENCODE_OPEN; - break; - - case IW_AUTH_ALG_SHARED_KEY: - case IW_AUTH_ALG_LEAP: - dwrq->flags = IW_ENCODE_RESTRICTED; - break; - default: - dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN; - break; - } - - memset(extra, 0, 16); - - mutex_lock(&priv->lock); - - /* Default to returning current transmit key */ - if (index < 0) - index = priv->wep_tx_keyidx; - - if ((priv->wep_keys[index].len) && priv->secinfo.wep_enabled) { - memcpy(extra, priv->wep_keys[index].key, - priv->wep_keys[index].len); - dwrq->length = priv->wep_keys[index].len; - - dwrq->flags |= (index + 1); - /* Return WEP enabled */ - dwrq->flags &= ~IW_ENCODE_DISABLED; - } else if ((priv->secinfo.WPAenabled) - || (priv->secinfo.WPA2enabled)) { - /* return WPA enabled */ - dwrq->flags &= ~IW_ENCODE_DISABLED; - dwrq->flags |= IW_ENCODE_NOKEY; - } else { - dwrq->flags |= IW_ENCODE_DISABLED; - } - - mutex_unlock(&priv->lock); - - lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n", - extra[0], extra[1], extra[2], - extra[3], extra[4], extra[5], dwrq->length); - - lbs_deb_wext("return flags 0x%x\n", dwrq->flags); - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -/** - * @brief Set Encryption key (internal) - * - * @param priv A pointer to private card structure - * @param key_material A pointer to key material - * @param key_length length of key material - * @param index key index to set - * @param set_tx_key Force set TX key (1 = yes, 0 = no) - * @return 0 --success, otherwise fail - */ -static int lbs_set_wep_key(struct assoc_request *assoc_req, - const char *key_material, - u16 key_length, - u16 index, - int set_tx_key) -{ - int ret = 0; - struct enc_key *pkey; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* Paranoid validation of key index */ - if (index > 3) { - ret = -EINVAL; - goto out; - } - - /* validate max key length */ - if (key_length > KEY_LEN_WEP_104) { - ret = -EINVAL; - goto out; - } - - pkey = &assoc_req->wep_keys[index]; - - if (key_length > 0) { - memset(pkey, 0, sizeof(struct enc_key)); - pkey->type = KEY_TYPE_ID_WEP; - - /* Standardize the key length */ - pkey->len = (key_length > KEY_LEN_WEP_40) ? - KEY_LEN_WEP_104 : KEY_LEN_WEP_40; - memcpy(pkey->key, key_material, key_length); - } - - if (set_tx_key) { - /* Ensure the chosen key is valid */ - if (!pkey->len) { - lbs_deb_wext("key not set, so cannot enable it\n"); - ret = -EINVAL; - goto out; - } - assoc_req->wep_tx_keyidx = index; - } - - assoc_req->secinfo.wep_enabled = 1; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int validate_key_index(u16 def_index, u16 raw_index, - u16 *out_index, u16 *is_default) -{ - if (!out_index || !is_default) - return -EINVAL; - - /* Verify index if present, otherwise use default TX key index */ - if (raw_index > 0) { - if (raw_index > 4) - return -EINVAL; - *out_index = raw_index - 1; - } else { - *out_index = def_index; - *is_default = 1; - } - return 0; -} - -static void disable_wep(struct assoc_request *assoc_req) -{ - int i; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* Set Open System auth mode */ - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - - /* Clear WEP keys and mark WEP as disabled */ - assoc_req->secinfo.wep_enabled = 0; - for (i = 0; i < 4; i++) - assoc_req->wep_keys[i].len = 0; - - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); - - lbs_deb_leave(LBS_DEB_WEXT); -} - -static void disable_wpa(struct assoc_request *assoc_req) -{ - lbs_deb_enter(LBS_DEB_WEXT); - - memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct enc_key)); - assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST; - set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); - - memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct enc_key)); - assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST; - set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); - - assoc_req->secinfo.WPAenabled = 0; - assoc_req->secinfo.WPA2enabled = 0; - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - - lbs_deb_leave(LBS_DEB_WEXT); -} - -/** - * @brief Set Encryption key - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 --success, otherwise fail - */ -static int lbs_set_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - struct assoc_request * assoc_req; - u16 is_default = 0, index = 0, set_tx_key = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - goto out; - } - - if (dwrq->flags & IW_ENCODE_DISABLED) { - disable_wep (assoc_req); - disable_wpa (assoc_req); - goto out; - } - - ret = validate_key_index(assoc_req->wep_tx_keyidx, - (dwrq->flags & IW_ENCODE_INDEX), - &index, &is_default); - if (ret) { - ret = -EINVAL; - goto out; - } - - /* If WEP isn't enabled, or if there is no key data but a valid - * index, set the TX key. - */ - if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default)) - set_tx_key = 1; - - ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); - if (ret) - goto out; - - if (dwrq->length) - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); - if (set_tx_key) - set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); - - if (dwrq->flags & IW_ENCODE_RESTRICTED) { - priv->authtype_auto = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; - } else if (dwrq->flags & IW_ENCODE_OPEN) { - priv->authtype_auto = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } - -out: - if (ret == 0) { - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - lbs_postpone_association_work(priv); - } else { - lbs_cancel_association_work(priv); - } - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -/** - * @brief Get Extended Encryption key (WPA/802.1x and WEP) - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 on success, otherwise failure - */ -static int lbs_get_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra) -{ - int ret = -EINVAL; - struct lbs_private *priv = dev->ml_priv; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int index, max_key_len; - - lbs_deb_enter(LBS_DEB_WEXT); - - max_key_len = dwrq->length - sizeof(*ext); - if (max_key_len < 0) - goto out; - - index = dwrq->flags & IW_ENCODE_INDEX; - if (index) { - if (index < 1 || index > 4) - goto out; - index--; - } else { - index = priv->wep_tx_keyidx; - } - - if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && - ext->alg != IW_ENCODE_ALG_WEP) { - if (index != 0 || priv->mode != IW_MODE_INFRA) - goto out; - } - - dwrq->flags = index + 1; - memset(ext, 0, sizeof(*ext)); - - if ( !priv->secinfo.wep_enabled - && !priv->secinfo.WPAenabled - && !priv->secinfo.WPA2enabled) { - ext->alg = IW_ENCODE_ALG_NONE; - ext->key_len = 0; - dwrq->flags |= IW_ENCODE_DISABLED; - } else { - u8 *key = NULL; - - if ( priv->secinfo.wep_enabled - && !priv->secinfo.WPAenabled - && !priv->secinfo.WPA2enabled) { - /* WEP */ - ext->alg = IW_ENCODE_ALG_WEP; - ext->key_len = priv->wep_keys[index].len; - key = &priv->wep_keys[index].key[0]; - } else if ( !priv->secinfo.wep_enabled - && (priv->secinfo.WPAenabled || - priv->secinfo.WPA2enabled)) { - /* WPA */ - struct enc_key * pkey = NULL; - - if ( priv->wpa_mcast_key.len - && (priv->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED)) - pkey = &priv->wpa_mcast_key; - else if ( priv->wpa_unicast_key.len - && (priv->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED)) - pkey = &priv->wpa_unicast_key; - - if (pkey) { - if (pkey->type == KEY_TYPE_ID_AES) { - ext->alg = IW_ENCODE_ALG_CCMP; - } else { - ext->alg = IW_ENCODE_ALG_TKIP; - } - ext->key_len = pkey->len; - key = &pkey->key[0]; - } else { - ext->alg = IW_ENCODE_ALG_TKIP; - ext->key_len = 0; - } - } else { - goto out; - } - - if (ext->key_len > max_key_len) { - ret = -E2BIG; - goto out; - } - - if (ext->key_len) - memcpy(ext->key, key, ext->key_len); - else - dwrq->flags |= IW_ENCODE_NOKEY; - dwrq->flags |= IW_ENCODE_ENABLED; - } - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -/** - * @brief Set Encryption key Extended (WPA/802.1x and WEP) - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param vwrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 --success, otherwise fail - */ -static int lbs_set_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int alg = ext->alg; - struct assoc_request * assoc_req; - - lbs_deb_enter(LBS_DEB_WEXT); - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - goto out; - } - - if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) { - disable_wep (assoc_req); - disable_wpa (assoc_req); - } else if (alg == IW_ENCODE_ALG_WEP) { - u16 is_default = 0, index, set_tx_key = 0; - - ret = validate_key_index(assoc_req->wep_tx_keyidx, - (dwrq->flags & IW_ENCODE_INDEX), - &index, &is_default); - if (ret) - goto out; - - /* If WEP isn't enabled, or if there is no key data but a valid - * index, or if the set-TX-key flag was passed, set the TX key. - */ - if ( !assoc_req->secinfo.wep_enabled - || (dwrq->length == 0 && !is_default) - || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) - set_tx_key = 1; - - /* Copy key to driver */ - ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index, - set_tx_key); - if (ret) - goto out; - - if (dwrq->flags & IW_ENCODE_RESTRICTED) { - priv->authtype_auto = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; - } else if (dwrq->flags & IW_ENCODE_OPEN) { - priv->authtype_auto = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } - - /* Mark the various WEP bits as modified */ - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - if (dwrq->length) - set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); - if (set_tx_key) - set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); - } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { - struct enc_key * pkey; - - /* validate key length */ - if (((alg == IW_ENCODE_ALG_TKIP) - && (ext->key_len != KEY_LEN_WPA_TKIP)) - || ((alg == IW_ENCODE_ALG_CCMP) - && (ext->key_len != KEY_LEN_WPA_AES))) { - lbs_deb_wext("invalid size %d for key of alg " - "type %d\n", - ext->key_len, - alg); - ret = -EINVAL; - goto out; - } - - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - pkey = &assoc_req->wpa_mcast_key; - set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); - } else { - pkey = &assoc_req->wpa_unicast_key; - set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); - } - - memset(pkey, 0, sizeof (struct enc_key)); - memcpy(pkey->key, ext->key, ext->key_len); - pkey->len = ext->key_len; - if (pkey->len) - pkey->flags |= KEY_INFO_WPA_ENABLED; - - /* Do this after zeroing key structure */ - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - pkey->flags |= KEY_INFO_WPA_MCAST; - } else { - pkey->flags |= KEY_INFO_WPA_UNICAST; - } - - if (alg == IW_ENCODE_ALG_TKIP) { - pkey->type = KEY_TYPE_ID_TKIP; - } else if (alg == IW_ENCODE_ALG_CCMP) { - pkey->type = KEY_TYPE_ID_AES; - } - - /* If WPA isn't enabled yet, do that now */ - if ( assoc_req->secinfo.WPAenabled == 0 - && assoc_req->secinfo.WPA2enabled == 0) { - assoc_req->secinfo.WPAenabled = 1; - assoc_req->secinfo.WPA2enabled = 1; - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - } - - /* Only disable wep if necessary: can't waste time here. */ - if (priv->mac_control & CMD_ACT_MAC_WEP_ENABLE) - disable_wep(assoc_req); - } - -out: - if (ret == 0) { - /* 802.1x and WPA rekeying must happen as quickly as possible, - * especially during the 4-way handshake; thus if in - * infrastructure mode, and either (a) 802.1x is enabled or - * (b) WPA is being used, set the key right away. - */ - if (assoc_req->mode == IW_MODE_INFRA && - ((assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_802_1X) || - (assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_PSK) || - assoc_req->secinfo.WPAenabled || - assoc_req->secinfo.WPA2enabled)) { - lbs_do_association_work(priv); - } else - lbs_postpone_association_work(priv); - } else { - lbs_cancel_association_work(priv); - } - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - - -static int lbs_set_genie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - struct assoc_request * assoc_req; - - lbs_deb_enter(LBS_DEB_WEXT); - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - goto out; - } - - if (dwrq->length > MAX_WPA_IE_LEN || - (dwrq->length && extra == NULL)) { - ret = -EINVAL; - goto out; - } - - if (dwrq->length) { - memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length); - assoc_req->wpa_ie_len = dwrq->length; - } else { - memset(&assoc_req->wpa_ie[0], 0, sizeof(priv->wpa_ie)); - assoc_req->wpa_ie_len = 0; - } - -out: - if (ret == 0) { - set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags); - lbs_postpone_association_work(priv); - } else { - lbs_cancel_association_work(priv); - } - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_genie(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, - char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (priv->wpa_ie_len == 0) { - dwrq->length = 0; - goto out; - } - - if (dwrq->length < priv->wpa_ie_len) { - ret = -E2BIG; - goto out; - } - - dwrq->length = priv->wpa_ie_len; - memcpy(extra, &priv->wpa_ie[0], priv->wpa_ie_len); - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - - -static int lbs_set_auth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *dwrq, - char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - struct assoc_request * assoc_req; - int ret = 0; - int updated = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - mutex_lock(&priv->lock); - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - goto out; - } - - switch (dwrq->flags & IW_AUTH_INDEX) { - case IW_AUTH_PRIVACY_INVOKED: - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - case IW_AUTH_TKIP_COUNTERMEASURES: - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_DROP_UNENCRYPTED: - /* - * libertas does not use these parameters - */ - break; - - case IW_AUTH_KEY_MGMT: - assoc_req->secinfo.key_mgmt = dwrq->value; - updated = 1; - break; - - case IW_AUTH_WPA_VERSION: - if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) { - assoc_req->secinfo.WPAenabled = 0; - assoc_req->secinfo.WPA2enabled = 0; - disable_wpa (assoc_req); - } - if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) { - assoc_req->secinfo.WPAenabled = 1; - assoc_req->secinfo.wep_enabled = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } - if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) { - assoc_req->secinfo.WPA2enabled = 1; - assoc_req->secinfo.wep_enabled = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } - updated = 1; - break; - - case IW_AUTH_80211_AUTH_ALG: - if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) { - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; - } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) { - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } else if (dwrq->value & IW_AUTH_ALG_LEAP) { - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP; - } else { - ret = -EINVAL; - } - updated = 1; - break; - - case IW_AUTH_WPA_ENABLED: - if (dwrq->value) { - if (!assoc_req->secinfo.WPAenabled && - !assoc_req->secinfo.WPA2enabled) { - assoc_req->secinfo.WPAenabled = 1; - assoc_req->secinfo.WPA2enabled = 1; - assoc_req->secinfo.wep_enabled = 0; - assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; - } - } else { - assoc_req->secinfo.WPAenabled = 0; - assoc_req->secinfo.WPA2enabled = 0; - disable_wpa (assoc_req); - } - updated = 1; - break; - - default: - ret = -EOPNOTSUPP; - break; - } - -out: - if (ret == 0) { - if (updated) - set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - lbs_postpone_association_work(priv); - } else if (ret != -EOPNOTSUPP) { - lbs_cancel_association_work(priv); - } - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_auth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *dwrq, - char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - switch (dwrq->flags & IW_AUTH_INDEX) { - case IW_AUTH_KEY_MGMT: - dwrq->value = priv->secinfo.key_mgmt; - break; - - case IW_AUTH_WPA_VERSION: - dwrq->value = 0; - if (priv->secinfo.WPAenabled) - dwrq->value |= IW_AUTH_WPA_VERSION_WPA; - if (priv->secinfo.WPA2enabled) - dwrq->value |= IW_AUTH_WPA_VERSION_WPA2; - if (!dwrq->value) - dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED; - break; - - case IW_AUTH_80211_AUTH_ALG: - dwrq->value = priv->secinfo.auth_mode; - break; - - case IW_AUTH_WPA_ENABLED: - if (priv->secinfo.WPAenabled && priv->secinfo.WPA2enabled) - dwrq->value = 1; - break; - - default: - ret = -EOPNOTSUPP; - } - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - - -static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int ret = 0; - struct lbs_private *priv = dev->ml_priv; - s16 dbm = (s16) vwrq->value; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (vwrq->disabled) { - lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0); - goto out; - } - - if (vwrq->fixed == 0) { - /* User requests automatic tx power control, however there are - * many auto tx settings. For now use firmware defaults until - * we come up with a good way to expose these to the user. */ - if (priv->fwrelease < 0x09000000) { - ret = lbs_set_power_adapt_cfg(priv, 1, - POW_ADAPT_DEFAULT_P0, - POW_ADAPT_DEFAULT_P1, - POW_ADAPT_DEFAULT_P2); - if (ret) - goto out; - } - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, - TPC_DEFAULT_P2, 1); - if (ret) - goto out; - dbm = priv->txpower_max; - } else { - /* Userspace check in iwrange if it should use dBm or mW, - * therefore this should never happen... Jean II */ - if ((vwrq->flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) { - ret = -EOPNOTSUPP; - goto out; - } - - /* Validate requested power level against firmware allowed - * levels */ - if (priv->txpower_min && (dbm < priv->txpower_min)) { - ret = -EINVAL; - goto out; - } - - if (priv->txpower_max && (dbm > priv->txpower_max)) { - ret = -EINVAL; - goto out; - } - if (priv->fwrelease < 0x09000000) { - ret = lbs_set_power_adapt_cfg(priv, 0, - POW_ADAPT_DEFAULT_P0, - POW_ADAPT_DEFAULT_P1, - POW_ADAPT_DEFAULT_P2); - if (ret) - goto out; - } - ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, - TPC_DEFAULT_P2, 1); - if (ret) - goto out; - } - - /* If the radio was off, turn it on */ - if (!priv->radio_on) { - ret = lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 1); - if (ret) - goto out; - } - - lbs_deb_wext("txpower set %d dBm\n", dbm); - - ret = lbs_set_tx_power(priv, dbm); - -out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - /* - * Note : if dwrq->flags != 0, we should get the relevant SSID from - * the SSID list... - */ - - /* - * Get the current SSID - */ - if (priv->connect_status == LBS_CONNECTED) { - memcpy(extra, priv->curbssparams.ssid, - priv->curbssparams.ssid_len); - } else { - memset(extra, 0, 32); - } - /* - * If none, we may want to get the one that was set - */ - - dwrq->length = priv->curbssparams.ssid_len; - - dwrq->flags = 1; /* active */ - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len = 0; - struct assoc_request * assoc_req; - int in_ssid_len = dwrq->length; - DECLARE_SSID_BUF(ssid_buf); - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!priv->radio_on) { - ret = -EINVAL; - goto out; - } - - /* Check the size of the string */ - if (in_ssid_len > IEEE80211_MAX_SSID_LEN) { - ret = -E2BIG; - goto out; - } - - memset(&ssid, 0, sizeof(ssid)); - - if (!dwrq->flags || !in_ssid_len) { - /* "any" SSID requested; leave SSID blank */ - } else { - /* Specific SSID requested */ - memcpy(&ssid, extra, in_ssid_len); - ssid_len = in_ssid_len; - } - - if (!ssid_len) { - lbs_deb_wext("requested any SSID\n"); - } else { - lbs_deb_wext("requested SSID '%s'\n", - print_ssid(ssid_buf, ssid, ssid_len)); - } - -out: - mutex_lock(&priv->lock); - if (ret == 0) { - /* Get or create the current association request */ - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - ret = -ENOMEM; - } else { - /* Copy the SSID to the association request */ - memcpy(&assoc_req->ssid, &ssid, IEEE80211_MAX_SSID_LEN); - assoc_req->ssid_len = ssid_len; - set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); - lbs_postpone_association_work(priv); - } - } - - /* Cancel the association request if there was an error */ - if (ret != 0) { - lbs_cancel_association_work(priv); - } - - mutex_unlock(&priv->lock); - - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} - -#ifdef CONFIG_LIBERTAS_MESH -static int lbs_mesh_get_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - - lbs_deb_enter(LBS_DEB_WEXT); - - memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len); - - dwrq->length = priv->mesh_ssid_len; - - dwrq->flags = 1; /* active */ - - lbs_deb_leave(LBS_DEB_WEXT); - return 0; -} - -static int lbs_mesh_set_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - int ret = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!priv->radio_on) { - ret = -EINVAL; - goto out; - } - - /* Check the size of the string */ - if (dwrq->length > IEEE80211_MAX_SSID_LEN) { - ret = -E2BIG; - goto out; - } - - if (!dwrq->flags || !dwrq->length) { - ret = -EINVAL; - goto out; - } else { - /* Specific SSID requested */ - memcpy(priv->mesh_ssid, extra, dwrq->length); - priv->mesh_ssid_len = dwrq->length; - } - - lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, - priv->channel); - out: - lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); - return ret; -} -#endif - -/** - * @brief Connect to the AP or Ad-hoc Network with specific bssid - * - * @param dev A pointer to net_device structure - * @param info A pointer to iw_request_info structure - * @param awrq A pointer to iw_param structure - * @param extra A pointer to extra data buf - * @return 0 --success, otherwise fail - */ -static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, - struct sockaddr *awrq, char *extra) -{ - struct lbs_private *priv = dev->ml_priv; - struct assoc_request * assoc_req; - int ret = 0; - - lbs_deb_enter(LBS_DEB_WEXT); - - if (!priv->radio_on) - return -EINVAL; - - if (awrq->sa_family != ARPHRD_ETHER) - return -EINVAL; - - lbs_deb_wext("ASSOC: WAP: sa_data %pM\n", awrq->sa_data); - - mutex_lock(&priv->lock); - - /* Get or create the current association request */ - assoc_req = lbs_get_association_request(priv); - if (!assoc_req) { - lbs_cancel_association_work(priv); - ret = -ENOMEM; - } else { - /* Copy the BSSID to the association request */ - memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN); - set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags); - lbs_postpone_association_work(priv); - } - - mutex_unlock(&priv->lock); - - return ret; -} - -/* - * iwconfig settable callbacks - */ -static const iw_handler lbs_handler[] = { - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) lbs_get_name, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) lbs_set_freq, /* SIOCSIWFREQ */ - (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ - (iw_handler) lbs_set_mode, /* SIOCSIWMODE */ - (iw_handler) lbs_get_mode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ - (iw_handler) NULL, /* SIOCSIWPRIV */ - (iw_handler) NULL, /* SIOCGIWPRIV */ - (iw_handler) NULL, /* SIOCSIWSTATS */ - (iw_handler) NULL, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ - (iw_handler) lbs_set_wap, /* SIOCSIWAP */ - (iw_handler) lbs_get_wap, /* SIOCGIWAP */ - (iw_handler) NULL, /* SIOCSIWMLME */ - (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ - (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ - (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ - (iw_handler) lbs_set_essid, /* SIOCSIWESSID */ - (iw_handler) lbs_get_essid, /* SIOCGIWESSID */ - (iw_handler) lbs_set_nick, /* SIOCSIWNICKN */ - (iw_handler) lbs_get_nick, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ - (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ - (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ - (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ - (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ - (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ - (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ - (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ - (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ - (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ - (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ - (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ - (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ - (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ - (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ - (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ - (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ - (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ - (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ -}; -struct iw_handler_def lbs_handler_def = { - .num_standard = ARRAY_SIZE(lbs_handler), - .standard = (iw_handler *) lbs_handler, - .get_wireless_stats = lbs_get_wireless_stats, -}; - -#ifdef CONFIG_LIBERTAS_MESH -static const iw_handler mesh_wlan_handler[] = { - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) lbs_get_name, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */ - (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ - (iw_handler) NULL, /* SIOCSIWMODE */ - (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ - (iw_handler) NULL, /* SIOCSIWPRIV */ - (iw_handler) NULL, /* SIOCGIWPRIV */ - (iw_handler) NULL, /* SIOCSIWSTATS */ - (iw_handler) NULL, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ - (iw_handler) NULL, /* SIOCSIWAP */ - (iw_handler) NULL, /* SIOCGIWAP */ - (iw_handler) NULL, /* SIOCSIWMLME */ - (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ - (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ - (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ - (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */ - (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ - (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ - (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ - (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ - (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ - (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ - (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ - (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ - (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ - (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ - (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ - (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ - (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ - (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ - (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ - (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ - (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ - (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ - (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ -}; - -struct iw_handler_def mesh_handler_def = { - .num_standard = ARRAY_SIZE(mesh_wlan_handler), - .standard = (iw_handler *) mesh_wlan_handler, - .get_wireless_stats = lbs_get_wireless_stats, -}; -#endif diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h deleted file mode 100644 index f3f19fe8c6c..00000000000 --- a/drivers/net/wireless/libertas/wext.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * This file contains definition for IOCTL call. - */ -#ifndef _LBS_WEXT_H_ -#define _LBS_WEXT_H_ - -void lbs_send_disconnect_notification(struct lbs_private *priv); -void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event); - -struct chan_freq_power *lbs_find_cfp_by_band_and_channel( - struct lbs_private *priv, - u8 band, - u16 channel); - -extern struct iw_handler_def lbs_handler_def; - -#endif diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index c445500ffc6..b172f5d87a3 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -538,7 +538,8 @@ static void if_usb_receive_fwload(struct urb *urb) return; } - syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); + syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader), + GFP_ATOMIC); if (!syncfwheader) { lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); kfree_skb(skb); @@ -546,8 +547,6 @@ static void if_usb_receive_fwload(struct urb *urb) return; } - memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader)); - if (!syncfwheader->cmd) { lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h index fbbaaae7a1a..ad77b92d0b4 100644 --- a/drivers/net/wireless/libertas_tf/libertas_tf.h +++ b/drivers/net/wireless/libertas_tf/libertas_tf.h @@ -253,6 +253,9 @@ struct lbtf_private { u8 fw_ready; u8 surpriseremoved; struct sk_buff_head bc_ps_buf; + + /* Most recently reported noise in dBm */ + s8 noise; }; /* 802.11-related definitions */ @@ -316,7 +319,7 @@ struct cmd_header { __le16 size; __le16 seqnum; __le16 result; -} __attribute__ ((packed)); +} __packed; struct cmd_ctrl_node { struct list_head list; @@ -369,7 +372,7 @@ struct cmd_ds_get_hw_spec { /*FW/HW capability */ __le32 fwcapinfo; -} __attribute__ ((packed)); +} __packed; struct cmd_ds_mac_control { struct cmd_header hdr; diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 817fffc0de4..9278b3c8ee3 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -525,6 +525,22 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, lbtf_deb_leave(LBTF_DEB_MACOPS); } +static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct lbtf_private *priv = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = priv->noise; + + return 0; +} + static const struct ieee80211_ops lbtf_ops = { .tx = lbtf_op_tx, .start = lbtf_op_start, @@ -535,6 +551,7 @@ static const struct ieee80211_ops lbtf_ops = { .prepare_multicast = lbtf_op_prepare_multicast, .configure_filter = lbtf_op_configure_filter, .bss_info_changed = lbtf_op_bss_info_changed, + .get_survey = lbtf_op_get_survey, }; int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) @@ -555,6 +572,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) stats.freq = priv->cur_freq; stats.band = IEEE80211_BAND_2GHZ; stats.signal = prxpd->snr; + priv->noise = prxpd->nf; /* Marvell rate index has a hole at value 4 */ if (prxpd->rx_rate > 4) --prxpd->rx_rate; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6f8cb3ee6fe..01ad7f77383 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -317,7 +317,7 @@ struct hwsim_radiotap_hdr { u8 rt_rate; __le16 rt_channel; __le16 rt_chbitmask; -} __attribute__ ((packed)); +} __packed; static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, @@ -486,8 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, struct ieee80211_rx_status rx_status; if (data->idle) { - printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n", - wiphy_name(hw->wiphy)); + wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n"); return false; } @@ -576,7 +575,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int mac80211_hwsim_start(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *data = hw->priv; - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); + wiphy_debug(hw->wiphy, "%s\n", __func__); data->started = 1; return 0; } @@ -587,16 +586,15 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) struct mac80211_hwsim_data *data = hw->priv; data->started = 0; del_timer(&data->beacon_timer); - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); + wiphy_debug(hw->wiphy, "%s\n", __func__); } static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", - wiphy_name(hw->wiphy), __func__, vif->type, - vif->addr); + wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", + __func__, vif->type, vif->addr); hwsim_set_magic(vif); return 0; } @@ -605,9 +603,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n", - wiphy_name(hw->wiphy), __func__, vif->type, - vif->addr); + wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", + __func__, vif->type, vif->addr); hwsim_check_magic(vif); hwsim_clear_magic(vif); } @@ -670,13 +667,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) [IEEE80211_SMPS_DYNAMIC] = "dynamic", }; - printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", - wiphy_name(hw->wiphy), __func__, - conf->channel->center_freq, - hwsim_chantypes[conf->channel_type], - !!(conf->flags & IEEE80211_CONF_IDLE), - !!(conf->flags & IEEE80211_CONF_PS), - smps_modes[conf->smps_mode]); + wiphy_debug(hw->wiphy, + "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", + __func__, + conf->channel->center_freq, + hwsim_chantypes[conf->channel_type], + !!(conf->flags & IEEE80211_CONF_IDLE), + !!(conf->flags & IEEE80211_CONF_PS), + smps_modes[conf->smps_mode]); data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); @@ -696,7 +694,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, { struct mac80211_hwsim_data *data = hw->priv; - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); + wiphy_debug(hw->wiphy, "%s\n", __func__); data->rx_filter = 0; if (*total_flags & FIF_PROMISC_IN_BSS) @@ -717,26 +715,23 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, hwsim_check_magic(vif); - printk(KERN_DEBUG "%s:%s(changed=0x%x)\n", - wiphy_name(hw->wiphy), __func__, changed); + wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed); if (changed & BSS_CHANGED_BSSID) { - printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n", - wiphy_name(hw->wiphy), __func__, - info->bssid); + wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", + __func__, info->bssid); memcpy(vp->bssid, info->bssid, ETH_ALEN); } if (changed & BSS_CHANGED_ASSOC) { - printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n", - wiphy_name(hw->wiphy), info->assoc, info->aid); + wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n", + info->assoc, info->aid); vp->assoc = info->assoc; vp->aid = info->aid; } if (changed & BSS_CHANGED_BEACON_INT) { - printk(KERN_DEBUG " %s: BCNINT: %d\n", - wiphy_name(hw->wiphy), info->beacon_int); + wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; if (WARN_ON(!data->beacon_int)) data->beacon_int = 1; @@ -746,31 +741,28 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - printk(KERN_DEBUG " %s: ERP_CTS_PROT: %d\n", - wiphy_name(hw->wiphy), info->use_cts_prot); + wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n", + info->use_cts_prot); } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - printk(KERN_DEBUG " %s: ERP_PREAMBLE: %d\n", - wiphy_name(hw->wiphy), info->use_short_preamble); + wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n", + info->use_short_preamble); } if (changed & BSS_CHANGED_ERP_SLOT) { - printk(KERN_DEBUG " %s: ERP_SLOT: %d\n", - wiphy_name(hw->wiphy), info->use_short_slot); + wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot); } if (changed & BSS_CHANGED_HT) { - printk(KERN_DEBUG " %s: HT: op_mode=0x%x, chantype=%s\n", - wiphy_name(hw->wiphy), - info->ht_operation_mode, - hwsim_chantypes[info->channel_type]); + wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n", + info->ht_operation_mode, + hwsim_chantypes[info->channel_type]); } if (changed & BSS_CHANGED_BASIC_RATES) { - printk(KERN_DEBUG " %s: BASIC_RATES: 0x%llx\n", - wiphy_name(hw->wiphy), - (unsigned long long) info->basic_rates); + wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", + (unsigned long long) info->basic_rates); } } @@ -824,10 +816,11 @@ static int mac80211_hwsim_conf_tx( struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d " - "aifs=%d)\n", - wiphy_name(hw->wiphy), __func__, queue, - params->txop, params->cw_min, params->cw_max, params->aifs); + wiphy_debug(hw->wiphy, + "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n", + __func__, queue, + params->txop, params->cw_min, + params->cw_max, params->aifs); return 0; } @@ -837,8 +830,7 @@ static int mac80211_hwsim_get_survey( { struct ieee80211_conf *conf = &hw->conf; - printk(KERN_DEBUG "%s:%s (idx=%d)\n", - wiphy_name(hw->wiphy), __func__, idx); + wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx); if (idx != 0) return -ENOENT; @@ -1108,8 +1100,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) if (!vp->assoc) return; - printk(KERN_DEBUG "%s:%s: send PS-Poll to %pM for aid %d\n", - wiphy_name(data->hw->wiphy), __func__, vp->bssid, vp->aid); + wiphy_debug(data->hw->wiphy, + "%s: send PS-Poll to %pM for aid %d\n", + __func__, vp->bssid, vp->aid); skb = dev_alloc_skb(sizeof(*pspoll)); if (!skb) @@ -1137,8 +1130,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, if (!vp->assoc) return; - printk(KERN_DEBUG "%s:%s: send data::nullfunc to %pM ps=%d\n", - wiphy_name(data->hw->wiphy), __func__, vp->bssid, ps); + wiphy_debug(data->hw->wiphy, + "%s: send data::nullfunc to %pM ps=%d\n", + __func__, vp->bssid, ps); skb = dev_alloc_skb(sizeof(*hdr)); if (!skb) @@ -1291,6 +1285,11 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->n_addresses = 2; hw->wiphy->addresses = data->addresses; + if (fake_hw_scan) { + hw->wiphy->max_scan_ssids = 255; + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + } + hw->channel_change_time = 1; hw->queues = 4; hw->wiphy->interface_modes = @@ -1468,9 +1467,8 @@ static int __init init_mac80211_hwsim(void) break; } - printk(KERN_DEBUG "%s: hwaddr %pM registered\n", - wiphy_name(hw->wiphy), - hw->wiphy->perm_addr); + wiphy_debug(hw->wiphy, "hwaddr %pm registered\n", + hw->wiphy->perm_addr); data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 808adb90909..d761ed2d8af 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -86,7 +86,7 @@ struct rxd_ops { void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); void (*rxd_refill)(void *rxd, dma_addr_t addr, int len); int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status, - __le16 *qos); + __le16 *qos, s8 *noise); }; struct mwl8k_device_info { @@ -109,7 +109,7 @@ struct mwl8k_rx_queue { dma_addr_t rxd_dma; struct { struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(dma) + DEFINE_DMA_UNMAP_ADDR(dma); } *buf; }; @@ -207,6 +207,9 @@ struct mwl8k_priv { /* Tasklet to perform RX. */ struct tasklet_struct poll_rx_task; + + /* Most recently reported noise in dBm */ + s8 noise; }; /* Per interface specific private data */ @@ -314,13 +317,15 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_STADB 0x1123 -static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) +static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) { + u16 command = le16_to_cpu(cmd); + #define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\ snprintf(buf, bufsize, "%s", #x);\ return buf;\ } while (0) - switch (cmd & ~0x8000) { + switch (command & ~0x8000) { MWL8K_CMDNAME(CODE_DNLD); MWL8K_CMDNAME(GET_HW_SPEC); MWL8K_CMDNAME(SET_HW_SPEC); @@ -426,7 +431,7 @@ struct mwl8k_cmd_pkt { __u8 macid; __le16 result; char payload[0]; -} __attribute__((packed)); +} __packed; /* * Firmware loading. @@ -632,7 +637,7 @@ struct mwl8k_dma_data { __le16 fwlen; struct ieee80211_hdr wh; char data[0]; -} __attribute__((packed)); +} __packed; /* Routines to add/remove DMA header from skb. */ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos) @@ -711,7 +716,7 @@ struct mwl8k_rxd_8366_ap { __u8 rx_status; __u8 channel; __u8 rx_ctrl; -} __attribute__((packed)); +} __packed; #define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80 #define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40 @@ -739,7 +744,7 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) static int mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, - __le16 *qos) + __le16 *qos, s8 *noise) { struct mwl8k_rxd_8366_ap *rxd = _rxd; @@ -750,6 +755,7 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; + *noise = -rxd->noise_floor; if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { status->flag |= RX_FLAG_HT; @@ -806,7 +812,7 @@ struct mwl8k_rxd_sta { __u8 rx_ctrl; __u8 rx_status; __u8 pad2[2]; -} __attribute__((packed)); +} __packed; #define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000 #define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3) @@ -837,7 +843,7 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) static int mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, - __le16 *qos) + __le16 *qos, s8 *noise) { struct mwl8k_rxd_sta *rxd = _rxd; u16 rate_info; @@ -851,6 +857,7 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, memset(status, 0, sizeof(*status)); status->signal = -rxd->rssi; + *noise = -rxd->noise_level; status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); @@ -903,16 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); if (rxq->rxd == NULL) { - printk(KERN_ERR "%s: failed to alloc RX descriptors\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); return -ENOMEM; } memset(rxq->rxd, 0, size); rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); if (rxq->buf == NULL) { - printk(KERN_ERR "%s: failed to alloc RX skbuff list\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); return -ENOMEM; } @@ -963,7 +968,7 @@ static int rxq_refill(struct ieee80211_hw *hw, int index, int limit) if (rxq->tail == MWL8K_RX_DESCS) rxq->tail = 0; rxq->buf[rx].skb = skb; - pci_unmap_addr_set(&rxq->buf[rx], dma, addr); + dma_unmap_addr_set(&rxq->buf[rx], dma, addr); rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size); priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ); @@ -984,9 +989,9 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index) for (i = 0; i < MWL8K_RX_DESCS; i++) { if (rxq->buf[i].skb != NULL) { pci_unmap_single(priv->pdev, - pci_unmap_addr(&rxq->buf[i], dma), + dma_unmap_addr(&rxq->buf[i], dma), MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); - pci_unmap_addr_set(&rxq->buf[i], dma, 0); + dma_unmap_addr_set(&rxq->buf[i], dma, 0); kfree_skb(rxq->buf[i].skb); rxq->buf[i].skb = NULL; @@ -1053,16 +1058,17 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size); - pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos); + pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos, + &priv->noise); if (pkt_len < 0) break; rxq->buf[rxq->head].skb = NULL; pci_unmap_single(priv->pdev, - pci_unmap_addr(&rxq->buf[rxq->head], dma), + dma_unmap_addr(&rxq->buf[rxq->head], dma), MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); - pci_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); + dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0); rxq->head++; if (rxq->head == MWL8K_RX_DESCS) @@ -1120,7 +1126,7 @@ struct mwl8k_tx_desc { __le16 rate_info; __u8 peer_id; __u8 tx_frag_cnt; -} __attribute__((packed)); +} __packed; #define MWL8K_TX_DESCS 128 @@ -1139,16 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); if (txq->txd == NULL) { - printk(KERN_ERR "%s: failed to alloc TX descriptors\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); return -ENOMEM; } memset(txq->txd, 0, size); txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); if (txq->skb == NULL) { - printk(KERN_ERR "%s: failed to alloc TX skbuff list\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); return -ENOMEM; } @@ -1204,11 +1208,12 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw) unused++; } - printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d " - "fw_owned=%d drv_owned=%d unused=%d\n", - wiphy_name(hw->wiphy), i, - txq->len, txq->head, txq->tail, - fw_owned, drv_owned, unused); + wiphy_err(hw->wiphy, + "txq[%d] len=%d head=%d tail=%d " + "fw_owned=%d drv_owned=%d unused=%d\n", + i, + txq->len, txq->head, txq->tail, + fw_owned, drv_owned, unused); } } @@ -1252,25 +1257,23 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) if (timeout) { WARN_ON(priv->pending_tx_pkts); if (retry) { - printk(KERN_NOTICE "%s: tx rings drained\n", - wiphy_name(hw->wiphy)); + wiphy_notice(hw->wiphy, "tx rings drained\n"); } break; } if (priv->pending_tx_pkts < oldcount) { - printk(KERN_NOTICE "%s: waiting for tx rings " - "to drain (%d -> %d pkts)\n", - wiphy_name(hw->wiphy), oldcount, - priv->pending_tx_pkts); + wiphy_notice(hw->wiphy, + "waiting for tx rings to drain (%d -> %d pkts)\n", + oldcount, priv->pending_tx_pkts); retry = 1; continue; } priv->tx_wait = NULL; - printk(KERN_ERR "%s: tx rings stuck for %d ms\n", - wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS); + wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", + MWL8K_TX_WAIT_TIMEOUT_MS); mwl8k_dump_tx_rings(hw); rc = -ETIMEDOUT; @@ -1421,8 +1424,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(priv->pdev, dma)) { - printk(KERN_DEBUG "%s: failed to dma map skb, " - "dropping TX frame.\n", wiphy_name(hw->wiphy)); + wiphy_debug(hw->wiphy, + "failed to dma map skb, dropping TX frame.\n"); dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1538,7 +1541,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) unsigned long timeout = 0; u8 buf[32]; - cmd->result = 0xffff; + cmd->result = (__force __le16) 0xffff; dma_size = le16_to_cpu(cmd->length); dma_addr = pci_map_single(priv->pdev, cmd, dma_size, PCI_DMA_BIDIRECTIONAL); @@ -1570,10 +1573,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) PCI_DMA_BIDIRECTIONAL); if (!timeout) { - printk(KERN_ERR "%s: Command %s timeout after %u ms\n", - wiphy_name(hw->wiphy), - mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), - MWL8K_CMD_TIMEOUT_MS); + wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", + mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), + MWL8K_CMD_TIMEOUT_MS); rc = -ETIMEDOUT; } else { int ms; @@ -1582,15 +1584,14 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) rc = cmd->result ? -EINVAL : 0; if (rc) - printk(KERN_ERR "%s: Command %s error 0x%x\n", - wiphy_name(hw->wiphy), - mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), - le16_to_cpu(cmd->result)); + wiphy_err(hw->wiphy, "command %s error 0x%x\n", + mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), + le16_to_cpu(cmd->result)); else if (ms > 2000) - printk(KERN_NOTICE "%s: Command %s took %d ms\n", - wiphy_name(hw->wiphy), - mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), - ms); + wiphy_notice(hw->wiphy, "command %s took %d ms\n", + mwl8k_cmd_name(cmd->code, + buf, sizeof(buf)), + ms); } return rc; @@ -1666,7 +1667,7 @@ struct mwl8k_cmd_get_hw_spec_sta { __le32 caps2; __le32 num_tx_desc_per_queue; __le32 total_rxd; -} __attribute__((packed)); +} __packed; #define MWL8K_CAP_MAX_AMSDU 0x20000000 #define MWL8K_CAP_GREENFIELD 0x08000000 @@ -1810,7 +1811,7 @@ struct mwl8k_cmd_get_hw_spec_ap { __le32 wcbbase1; __le32 wcbbase2; __le32 wcbbase3; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) { @@ -1842,22 +1843,22 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) priv->sta_macids_supported = 0x00000000; off = le32_to_cpu(cmd->wcbbase0) & 0xffff; - iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off); + iowrite32(priv->txq[0].txd_dma, priv->sram + off); off = le32_to_cpu(cmd->rxwrptr) & 0xffff; - iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off); + iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); off = le32_to_cpu(cmd->rxrdptr) & 0xffff; - iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off); + iowrite32(priv->rxq[0].rxd_dma, priv->sram + off); off = le32_to_cpu(cmd->wcbbase1) & 0xffff; - iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off); + iowrite32(priv->txq[1].txd_dma, priv->sram + off); off = le32_to_cpu(cmd->wcbbase2) & 0xffff; - iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off); + iowrite32(priv->txq[2].txd_dma, priv->sram + off); off = le32_to_cpu(cmd->wcbbase3) & 0xffff; - iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off); + iowrite32(priv->txq[3].txd_dma, priv->sram + off); } kfree(cmd); @@ -1883,7 +1884,7 @@ struct mwl8k_cmd_set_hw_spec { __le32 flags; __le32 num_tx_desc_per_queue; __le32 total_rxd; -} __attribute__((packed)); +} __packed; #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 @@ -1985,7 +1986,7 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti, struct mwl8k_cmd_get_stat { struct mwl8k_cmd_pkt header; __le32 stats[64]; -} __attribute__((packed)); +} __packed; #define MWL8K_STAT_ACK_FAILURE 9 #define MWL8K_STAT_RTS_FAILURE 12 @@ -2029,7 +2030,7 @@ struct mwl8k_cmd_radio_control { __le16 action; __le16 control; __le16 radio_on; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force) @@ -2092,7 +2093,7 @@ struct mwl8k_cmd_rf_tx_power { __le16 current_level; __le16 reserved; __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) { @@ -2121,7 +2122,7 @@ struct mwl8k_cmd_rf_antenna { struct mwl8k_cmd_pkt header; __le16 antenna; __le16 mode; -} __attribute__((packed)); +} __packed; #define MWL8K_RF_ANTENNA_RX 1 #define MWL8K_RF_ANTENNA_TX 2 @@ -2182,7 +2183,7 @@ static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw, */ struct mwl8k_cmd_set_pre_scan { struct mwl8k_cmd_pkt header; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw) { @@ -2209,7 +2210,7 @@ struct mwl8k_cmd_set_post_scan { struct mwl8k_cmd_pkt header; __le32 isibss; __u8 bssid[ETH_ALEN]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac) @@ -2240,7 +2241,7 @@ struct mwl8k_cmd_set_rf_channel { __le16 action; __u8 current_channel; __le32 channel_flags; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, struct ieee80211_conf *conf) @@ -2293,7 +2294,7 @@ struct mwl8k_cmd_update_set_aid { __u8 bssid[ETH_ALEN]; __le16 protection_mode; __u8 supp_rates[14]; -} __attribute__((packed)); +} __packed; static void legacy_rate_mask_to_array(u8 *rates, u32 mask) { @@ -2364,7 +2365,7 @@ struct mwl8k_cmd_set_rate { /* Bitmap for supported MCS codes. */ __u8 mcs_set[16]; __u8 reserved[16]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -2397,7 +2398,7 @@ struct mwl8k_cmd_finalize_join { struct mwl8k_cmd_pkt header; __le32 sleep_interval; /* Number of beacon periods to sleep */ __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN]; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame, int framelen, int dtim) @@ -2436,7 +2437,7 @@ struct mwl8k_cmd_set_rts_threshold { struct mwl8k_cmd_pkt header; __le16 action; __le16 threshold; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh) @@ -2466,7 +2467,7 @@ struct mwl8k_cmd_set_slot { struct mwl8k_cmd_pkt header; __le16 action; __u8 short_slot; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time) { @@ -2528,7 +2529,7 @@ struct mwl8k_cmd_set_edca_params { __u8 txq; } sta; }; -} __attribute__((packed)); +} __packed; #define MWL8K_SET_EDCA_CW 0x01 #define MWL8K_SET_EDCA_TXOP 0x02 @@ -2579,7 +2580,7 @@ mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum, struct mwl8k_cmd_set_wmm_mode { struct mwl8k_cmd_pkt header; __le16 action; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable) { @@ -2612,7 +2613,7 @@ struct mwl8k_cmd_mimo_config { __le32 action; __u8 rx_antenna_map; __u8 tx_antenna_map; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx) { @@ -2652,7 +2653,7 @@ struct mwl8k_cmd_use_fixed_rate_sta { __le32 rate_type; __le32 reserved1; __le32 reserved2; -} __attribute__((packed)); +} __packed; #define MWL8K_USE_AUTO_RATE 0x0002 #define MWL8K_UCAST_RATE 0 @@ -2694,7 +2695,7 @@ struct mwl8k_cmd_use_fixed_rate_ap { u8 multicast_rate; u8 multicast_rate_type; u8 management_rate; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt) @@ -2724,7 +2725,7 @@ mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt) struct mwl8k_cmd_enable_sniffer { struct mwl8k_cmd_pkt header; __le32 action; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable) { @@ -2757,7 +2758,7 @@ struct mwl8k_cmd_set_mac_addr { } mbss; __u8 mac_addr[ETH_ALEN]; }; -} __attribute__((packed)); +} __packed; #define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0 #define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1 @@ -2812,7 +2813,7 @@ struct mwl8k_cmd_set_rate_adapt_mode { struct mwl8k_cmd_pkt header; __le16 action; __le16 mode; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode) { @@ -2840,7 +2841,7 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode) struct mwl8k_cmd_bss_start { struct mwl8k_cmd_pkt header; __le32 enable; -} __attribute__((packed)); +} __packed; static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int enable) @@ -2885,7 +2886,7 @@ struct mwl8k_cmd_set_new_stn { __u8 add_qos_info; __u8 is_qos_sta; __le32 fw_sta_ptr; -} __attribute__((packed)); +} __packed; #define MWL8K_STA_ACTION_ADD 0 #define MWL8K_STA_ACTION_REMOVE 2 @@ -2978,7 +2979,7 @@ struct ewc_ht_info { __le16 control1; __le16 control2; __le16 control3; -} __attribute__((packed)); +} __packed; struct peer_capability_info { /* Peer type - AP vs. STA. */ @@ -3007,7 +3008,7 @@ struct peer_capability_info { __u8 pad2; __u8 station_id; __le16 amsdu_enabled; -} __attribute__((packed)); +} __packed; struct mwl8k_cmd_update_stadb { struct mwl8k_cmd_pkt header; @@ -3022,7 +3023,7 @@ struct mwl8k_cmd_update_stadb { /* Peer info - valid during add/update. */ struct peer_capability_info peer_info; -} __attribute__((packed)); +} __packed; #define MWL8K_STA_DB_MODIFY_ENTRY 1 #define MWL8K_STA_DB_DEL_ENTRY 2 @@ -3052,7 +3053,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT; p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability); p->ht_support = sta->ht_cap.ht_supported; - p->ht_caps = sta->ht_cap.cap; + p->ht_caps = cpu_to_le16(sta->ht_cap.cap); p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) | ((sta->ht_cap.ampdu_density & 7) << 2); if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) @@ -3190,8 +3191,8 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int rc; if (!priv->radio_on) { - printk(KERN_DEBUG "%s: dropped TX frame since radio " - "disabled\n", wiphy_name(hw->wiphy)); + wiphy_debug(hw->wiphy, + "dropped TX frame since radio disabled\n"); dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -3209,8 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw) rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); if (rc) { - printk(KERN_ERR "%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to register irq handler\n"); return -EIO; } @@ -3297,9 +3297,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, * mode. (Sniffer mode is only used on STA firmware.) */ if (priv->sniffer_enabled) { - printk(KERN_INFO "%s: unable to create STA " - "interface due to sniffer mode being enabled\n", - wiphy_name(hw->wiphy)); + wiphy_info(hw->wiphy, + "unable to create STA interface because sniffer mode is enabled\n"); return -EINVAL; } @@ -3581,9 +3580,8 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw, */ if (!list_empty(&priv->vif_list)) { if (net_ratelimit()) - printk(KERN_INFO "%s: not enabling sniffer " - "mode because STA interface is active\n", - wiphy_name(hw->wiphy)); + wiphy_info(hw->wiphy, + "not enabling sniffer mode because STA interface is active\n"); return 0; } @@ -3763,6 +3761,22 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw, return mwl8k_cmd_get_stat(hw, stats); } +static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct mwl8k_priv *priv = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = priv->noise; + + return 0; +} + static int mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, @@ -3794,6 +3808,7 @@ static const struct ieee80211_ops mwl8k_ops = { .sta_remove = mwl8k_sta_remove, .conf_tx = mwl8k_conf_tx, .get_stats = mwl8k_get_stats, + .get_survey = mwl8k_get_survey, .ampdu_action = mwl8k_ampdu_action, }; @@ -3911,8 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, priv->sram = pci_iomap(pdev, 0, 0x10000); if (priv->sram == NULL) { - printk(KERN_ERR "%s: Cannot map device SRAM\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot map device sram\n"); goto err_iounmap; } @@ -3924,8 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, if (priv->regs == NULL) { priv->regs = pci_iomap(pdev, 2, 0x10000); if (priv->regs == NULL) { - printk(KERN_ERR "%s: Cannot map device registers\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot map device registers\n"); goto err_iounmap; } } @@ -3937,16 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, /* Ask userland hotplug daemon for the device firmware */ rc = mwl8k_request_firmware(priv); if (rc) { - printk(KERN_ERR "%s: Firmware files not found\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "firmware files not found\n"); goto err_stop_firmware; } /* Load firmware into hardware */ rc = mwl8k_load_firmware(hw); if (rc) { - printk(KERN_ERR "%s: Cannot start firmware\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot start firmware\n"); goto err_stop_firmware; } @@ -3957,9 +3968,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, if (priv->ap_fw) { priv->rxd_ops = priv->device_info->ap_rxd_ops; if (priv->rxd_ops == NULL) { - printk(KERN_ERR "%s: Driver does not have AP " - "firmware image support for this hardware\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, + "Driver does not have AP firmware image support for this hardware\n"); goto err_stop_firmware; } } else { @@ -4037,8 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = request_irq(priv->pdev->irq, mwl8k_interrupt, IRQF_SHARED, MWL8K_NAME, hw); if (rc) { - printk(KERN_ERR "%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "failed to register irq handler\n"); goto err_free_queues; } @@ -4058,8 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = mwl8k_cmd_get_hw_spec_sta(hw); } if (rc) { - printk(KERN_ERR "%s: Cannot initialise firmware\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot initialise firmware\n"); goto err_free_irq; } @@ -4073,15 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, /* Turn radio off */ rc = mwl8k_cmd_radio_disable(hw); if (rc) { - printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot disable\n"); goto err_free_irq; } /* Clear MAC address */ rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); if (rc) { - printk(KERN_ERR "%s: Cannot clear MAC address\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot clear mac address\n"); goto err_free_irq; } @@ -4091,17 +4098,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, rc = ieee80211_register_hw(hw); if (rc) { - printk(KERN_ERR "%s: Cannot register device\n", - wiphy_name(hw->wiphy)); + wiphy_err(hw->wiphy, "cannot register device\n"); goto err_free_queues; } - printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", - wiphy_name(hw->wiphy), priv->device_info->part_name, - priv->hw_rev, hw->wiphy->perm_addr, - priv->ap_fw ? "AP" : "STA", - (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, - (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); + wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n", + priv->device_info->part_name, + priv->hw_rev, hw->wiphy->perm_addr, + priv->ap_fw ? "AP" : "STA", + (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, + (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); return 0; diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index 8c4169c227a..09fae2f0ea0 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c @@ -117,9 +117,8 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_MONITOR: if (priv->broken_monitor && !force_monitor) { - printk(KERN_WARNING "%s: Monitor mode support is " - "buggy in this firmware, not enabling\n", - wiphy_name(wiphy)); + wiphy_warn(wiphy, + "Monitor mode support is buggy in this firmware, not enabling\n"); err = -EINVAL; } break; diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c index 3e1947d097c..259d7585398 100644 --- a/drivers/net/wireless/orinoco/fw.c +++ b/drivers/net/wireless/orinoco/fw.c @@ -49,7 +49,7 @@ struct orinoco_fw_header { __le32 pri_offset; /* Offset to primary plug data */ __le32 compat_offset; /* Offset to compatibility data*/ char signature[0]; /* FW signature length headersize-20 */ -} __attribute__ ((packed)); +} __packed; /* Check the range of various header entries. Return a pointer to a * description of the problem, or NULL if everything checks out. */ diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h index 9ca34e722b4..d9f18c11682 100644 --- a/drivers/net/wireless/orinoco/hermes.h +++ b/drivers/net/wireless/orinoco/hermes.h @@ -205,7 +205,7 @@ struct hermes_tx_descriptor { u8 retry_count; u8 tx_rate; __le16 tx_control; -} __attribute__ ((packed)); +} __packed; #define HERMES_TXSTAT_RETRYERR (0x0001) #define HERMES_TXSTAT_AGEDERR (0x0002) @@ -254,7 +254,7 @@ struct hermes_tallies_frame { /* Those last are probably not available in very old firmwares */ __le16 RxDiscards_WEPICVError; __le16 RxDiscards_WEPExcluded; -} __attribute__ ((packed)); +} __packed; /* Grabbed from wlan-ng - Thanks Mark... - Jean II * This is the result of a scan inquiry command */ @@ -271,7 +271,7 @@ struct prism2_scan_apinfo { u8 rates[10]; /* Bit rate supported */ __le16 proberesp_rate; /* Data rate of the response frame */ __le16 atim; /* ATIM window time, Kus (hostscan only) */ -} __attribute__ ((packed)); +} __packed; /* Same stuff for the Lucent/Agere card. * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */ @@ -285,7 +285,7 @@ struct agere_scan_apinfo { /* bits: 0-ess, 1-ibss, 4-privacy [wep] */ __le16 essid_len; /* ESSID length */ u8 essid[32]; /* ESSID of the network */ -} __attribute__ ((packed)); +} __packed; /* Moustafa: Scan structure for Symbol cards */ struct symbol_scan_apinfo { @@ -303,7 +303,7 @@ struct symbol_scan_apinfo { __le16 basic_rates; /* Basic rates bitmask */ u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */ u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */ -} __attribute__ ((packed)); +} __packed; union hermes_scan_info { struct agere_scan_apinfo a; @@ -343,7 +343,7 @@ struct agere_ext_scan_info { __le16 beacon_interval; __le16 capabilities; u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000) #define HERMES_LINKSTATUS_CONNECTED (0x0001) @@ -355,7 +355,7 @@ struct agere_ext_scan_info { struct hermes_linkstatus { __le16 linkstatus; /* Link status */ -} __attribute__ ((packed)); +} __packed; struct hermes_response { u16 status, resp0, resp1, resp2; @@ -365,11 +365,11 @@ struct hermes_response { struct hermes_idstring { __le16 len; __le16 val[16]; -} __attribute__ ((packed)); +} __packed; struct hermes_multicast { u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; /* Timeouts */ #define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c index 6da85e75fce..2b2b9a1a979 100644 --- a/drivers/net/wireless/orinoco/hermes_dld.c +++ b/drivers/net/wireless/orinoco/hermes_dld.c @@ -65,10 +65,10 @@ struct dblock { __le32 addr; /* adapter address where to write the block */ __le16 len; /* length of the data only, in bytes */ char data[0]; /* data to be written */ -} __attribute__ ((packed)); +} __packed; /* - * Plug Data References are located in in the image after the last data + * Plug Data References are located in the image after the last data * block. They refer to areas in the adapter memory where the plug data * items with matching ID should be written. */ @@ -77,7 +77,7 @@ struct pdr { __le32 addr; /* adapter address where to write the data */ __le32 len; /* expected length of the data, in bytes */ char next[0]; /* next PDR starts here */ -} __attribute__ ((packed)); +} __packed; /* * Plug Data Items are located in the EEPROM read from the adapter by @@ -88,7 +88,7 @@ struct pdi { __le16 len; /* length of ID and data, in words */ __le16 id; /* record ID */ char data[0]; /* plug data */ -} __attribute__ ((packed)); +} __packed; /*** FW data block access functions ***/ @@ -317,7 +317,7 @@ static const struct { \ __le16 len; \ __le16 id; \ u8 val[length]; \ -} __attribute__ ((packed)) default_pdr_data_##pid = { \ +} __packed default_pdr_data_##pid = { \ cpu_to_le16((sizeof(default_pdr_data_##pid)/ \ sizeof(__le16)) - 1), \ cpu_to_le16(pid), \ diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 6fbd7885012..077baa86756 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -45,7 +45,7 @@ static const struct { /* Firmware version encoding */ struct comp_id { u16 id, variant, major, minor; -} __attribute__ ((packed)); +} __packed; static inline fwtype_t determine_firmware_type(struct comp_id *nic_id) { @@ -995,7 +995,7 @@ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx, u8 tx_mic[MIC_KEYLEN]; u8 rx_mic[MIC_KEYLEN]; u8 tsc[ORINOCO_SEQ_LEN]; - } __attribute__ ((packed)) buf; + } __packed buf; hermes_t *hw = &priv->hw; int ret; int err; @@ -1326,7 +1326,7 @@ int orinoco_hw_disassociate(struct orinoco_private *priv, struct { u8 addr[ETH_ALEN]; __le16 reason_code; - } __attribute__ ((packed)) buf; + } __packed buf; /* Currently only supported by WPA enabled Agere fw */ if (!priv->has_wpa) diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index ca71f08709b..e8e2d0f4763 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -172,7 +172,7 @@ struct hermes_txexc_data { __le16 frame_ctl; __le16 duration_id; u8 addr1[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; /* Rx frame header except compatibility 802.3 header */ struct hermes_rx_descriptor { @@ -196,7 +196,7 @@ struct hermes_rx_descriptor { /* Data length */ __le16 data_len; -} __attribute__ ((packed)); +} __packed; struct orinoco_rx_data { struct hermes_rx_descriptor *desc; @@ -390,7 +390,7 @@ int orinoco_process_xmit_skb(struct sk_buff *skb, struct header_struct { struct ethhdr eth; /* 802.3 header */ u8 encap[6]; /* 802.2 header */ - } __attribute__ ((packed)) hdr; + } __packed hdr; int len = skb->len + sizeof(encaps_hdr) - (2 * ETH_ALEN); if (skb_headroom(skb) < ENCAPS_OVERHEAD) { @@ -1170,7 +1170,7 @@ static void orinoco_join_ap(struct work_struct *work) struct join_req { u8 bssid[ETH_ALEN]; __le16 channel; - } __attribute__ ((packed)) req; + } __packed req; const int atom_len = offsetof(struct prism2_scan_apinfo, atim); struct prism2_scan_apinfo *atom = NULL; int offset = 4; @@ -1410,7 +1410,7 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) struct { __le16 len; __le16 type; - } __attribute__ ((packed)) info; + } __packed info; int len, type; int err; diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index a6da86e0a70..255710ef082 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h @@ -32,7 +32,7 @@ struct orinoco_key { __le16 len; /* always stored as little-endian */ char data[ORINOCO_MAX_KEY_SIZE]; -} __attribute__ ((packed)); +} __packed; #define TKIP_KEYLEN 16 #define MIC_KEYLEN 8 diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index 78f089baa8c..a38a7bd25f1 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -90,7 +90,7 @@ struct header_struct { /* SNAP */ u8 oui[3]; __be16 ethertype; -} __attribute__ ((packed)); +} __packed; struct ez_usb_fw { u16 size; @@ -222,7 +222,7 @@ struct ezusb_packet { __le16 hermes_len; __le16 hermes_rid; u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* Table of devices that work or may work with this driver */ static struct usb_device_id ezusb_table[] = { @@ -356,12 +356,10 @@ static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv, { struct request_context *ctx; - ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); + ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); if (!ctx) return NULL; - memset(ctx, 0, sizeof(*ctx)); - ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC); if (!ctx->buf) { kfree(ctx); @@ -1504,16 +1502,16 @@ static inline void ezusb_delete(struct ezusb_priv *upriv) ezusb_ctx_complete(list_entry(item, struct request_context, list)); - if (upriv->read_urb->status == -EINPROGRESS) + if (upriv->read_urb && upriv->read_urb->status == -EINPROGRESS) printk(KERN_ERR PFX "Some URB in progress\n"); mutex_unlock(&upriv->mtx); - kfree(upriv->read_urb->transfer_buffer); - if (upriv->bap_buf != NULL) - kfree(upriv->bap_buf); - if (upriv->read_urb != NULL) + if (upriv->read_urb) { + kfree(upriv->read_urb->transfer_buffer); usb_free_urb(upriv->read_urb); + } + kfree(upriv->bap_buf); if (upriv->dev) { struct orinoco_private *priv = ndev_priv(upriv->dev); orinoco_if_del(priv); diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 5775124e2ae..cf7be1eb612 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -128,7 +128,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) } else { struct { __le16 qual, signal, noise, unused; - } __attribute__ ((packed)) cq; + } __packed cq; err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_COMMSQUALITY, &cq); @@ -993,11 +993,9 @@ static int orinoco_ioctl_set_genie(struct net_device *dev, return -EINVAL; if (wrqu->data.length) { - buf = kmalloc(wrqu->data.length, GFP_KERNEL); + buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - - memcpy(buf, extra, wrqu->data.length); } else buf = NULL; diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 187e263b045..d687cb7f2a5 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -149,16 +149,15 @@ static int p54_generate_band(struct ieee80211_hw *dev, continue; if (list->channels[i].data != CHAN_HAS_ALL) { - printk(KERN_ERR "%s:%s%s%s is/are missing for " - "channel:%d [%d MHz].\n", - wiphy_name(dev->wiphy), - (list->channels[i].data & CHAN_HAS_CAL ? "" : - " [iqauto calibration data]"), - (list->channels[i].data & CHAN_HAS_LIMIT ? "" : - " [output power limits]"), - (list->channels[i].data & CHAN_HAS_CURVE ? "" : - " [curve data]"), - list->channels[i].index, list->channels[i].freq); + wiphy_err(dev->wiphy, + "%s%s%s is/are missing for channel:%d [%d MHz].\n", + (list->channels[i].data & CHAN_HAS_CAL ? "" : + " [iqauto calibration data]"), + (list->channels[i].data & CHAN_HAS_LIMIT ? "" : + " [output power limits]"), + (list->channels[i].data & CHAN_HAS_CURVE ? "" : + " [curve data]"), + list->channels[i].index, list->channels[i].freq); continue; } @@ -168,9 +167,8 @@ static int p54_generate_band(struct ieee80211_hw *dev, } if (j == 0) { - printk(KERN_ERR "%s: Disabling totally damaged %s band.\n", - wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ? - "2 GHz" : "5 GHz"); + wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n", + (band == IEEE80211_BAND_2GHZ) ? 2 : 5); ret = -ENODATA; goto err_out; @@ -244,9 +242,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) if ((priv->iq_autocal_len != priv->curve_data->entries) || (priv->iq_autocal_len != priv->output_limit->entries)) - printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. " - "You may not be able to use all channels.\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, + "Unsupported or damaged EEPROM detected. " + "You may not be able to use all channels.\n"); max_channel_num = max_t(unsigned int, priv->output_limit->entries, priv->iq_autocal_len); @@ -419,15 +417,14 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, int i; if (len != (entry_size * num_entries)) { - printk(KERN_ERR "%s: unknown rssi calibration data packing " - " type:(%x) len:%d.\n", - wiphy_name(dev->wiphy), type, len); + wiphy_err(dev->wiphy, + "unknown rssi calibration data packing type:(%x) len:%d.\n", + type, len); print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len); - printk(KERN_ERR "%s: please report this issue.\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "please report this issue.\n"); return; } @@ -445,15 +442,14 @@ static void p54_parse_default_country(struct ieee80211_hw *dev, struct pda_country *country; if (len != sizeof(*country)) { - printk(KERN_ERR "%s: found possible invalid default country " - "eeprom entry. (entry size: %d)\n", - wiphy_name(dev->wiphy), len); + wiphy_err(dev->wiphy, + "found possible invalid default country eeprom entry. (entry size: %d)\n", + len); print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, data, len); - printk(KERN_ERR "%s: please report this issue.\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "please report this issue.\n"); return; } @@ -478,8 +474,8 @@ static int p54_convert_output_limits(struct ieee80211_hw *dev, return -EINVAL; if (data[0] != 0) { - printk(KERN_ERR "%s: unknown output power db revision:%x\n", - wiphy_name(dev->wiphy), data[0]); + wiphy_err(dev->wiphy, "unknown output power db revision:%x\n", + data[0]); return -EINVAL; } @@ -587,10 +583,9 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) err = p54_convert_rev1(dev, curve_data); break; default: - printk(KERN_ERR "%s: unknown curve data " - "revision %d\n", - wiphy_name(dev->wiphy), - curve_data->cal_method_rev); + wiphy_err(dev->wiphy, + "unknown curve data revision %d\n", + curve_data->cal_method_rev); err = -ENODEV; break; } @@ -599,13 +594,13 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) } break; case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: - priv->iq_autocal = kmalloc(data_len, GFP_KERNEL); + priv->iq_autocal = kmemdup(entry->data, data_len, + GFP_KERNEL); if (!priv->iq_autocal) { err = -ENOMEM; goto err; } - memcpy(priv->iq_autocal, entry->data, data_len); priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); break; case PDR_DEFAULT_COUNTRY: @@ -672,8 +667,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { - printk(KERN_ERR "%s: not all required entries found in eeprom!\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, + "not all required entries found in eeprom!\n"); err = -EINVAL; goto err; } @@ -699,15 +694,15 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { u8 perm_addr[ETH_ALEN]; - printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n", - wiphy_name(dev->wiphy)); + wiphy_warn(dev->wiphy, + "invalid hwaddr! using randomly generated mac addr\n"); random_ether_addr(perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr); } - printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n", - wiphy_name(dev->wiphy), dev->wiphy->perm_addr, priv->version, - p54_rf_chips[priv->rxhw]); + wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n", + dev->wiphy->perm_addr, priv->version, + p54_rf_chips[priv->rxhw]); return 0; @@ -719,8 +714,7 @@ err: priv->output_limit = NULL; priv->curve_data = NULL; - printk(KERN_ERR "%s: eeprom parse failed!\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "eeprom parse failed!\n"); return err; } EXPORT_SYMBOL_GPL(p54_parse_eeprom); diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index c43a5d461ab..47006bca485 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -62,16 +62,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) case FW_LM20: case FW_LM87: { char *iftype = (char *)bootrec->data; - printk(KERN_INFO "%s: p54 detected a LM%c%c " - "firmware\n", - wiphy_name(priv->hw->wiphy), - iftype[2], iftype[3]); + wiphy_info(priv->hw->wiphy, + "p54 detected a LM%c%c firmware\n", + iftype[2], iftype[3]); break; } case FW_FMAC: default: - printk(KERN_ERR "%s: unsupported firmware\n", - wiphy_name(priv->hw->wiphy)); + wiphy_err(priv->hw->wiphy, + "unsupported firmware\n"); return -ENODEV; } break; @@ -125,15 +124,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) } if (fw_version) - printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n", - wiphy_name(priv->hw->wiphy), fw_version, - priv->fw_var >> 8, priv->fw_var & 0xff); + wiphy_info(priv->hw->wiphy, + "fw rev %s - softmac protocol %x.%x\n", + fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); if (priv->fw_var < 0x500) - printk(KERN_INFO "%s: you are using an obsolete firmware. " - "visit http://wireless.kernel.org/en/users/Drivers/p54 " - "and grab one for \"kernel >= 2.6.28\"!\n", - wiphy_name(priv->hw->wiphy)); + wiphy_info(priv->hw->wiphy, + "you are using an obsolete firmware. " + "visit http://wireless.kernel.org/en/users/Drivers/p54 " + "and grab one for \"kernel >= 2.6.28\"!\n"); if (priv->fw_var >= 0x300) { /* Firmware supports QoS, use it! */ @@ -152,13 +151,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) priv->hw->queues = P54_QUEUE_AC_NUM; } - printk(KERN_INFO "%s: cryptographic accelerator " - "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy), - (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : - "no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP | - BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no", - (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ? - "YES" : "no"); + wiphy_info(priv->hw->wiphy, + "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n", + (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no", + (priv->privacy_caps & + (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL)) + ? "YES" : "no", + (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) + ? "YES" : "no"); if (priv->rx_keycache_size) { /* @@ -247,8 +247,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf, if (!wait_for_completion_interruptible_timeout( &priv->eeprom_comp, HZ)) { - printk(KERN_ERR "%s: device does not respond!\n", - wiphy_name(priv->hw->wiphy)); + wiphy_err(priv->hw->wiphy, "device does not respond!\n"); ret = -EBUSY; } priv->eeprom = NULL; @@ -523,9 +522,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) return 0; err: - printk(KERN_ERR "%s: frequency change to channel %d failed.\n", - wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel( - priv->hw->conf.channel->center_freq)); + wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", + ieee80211_frequency_to_channel( + priv->hw->conf.channel->center_freq)); dev_kfree_skb_any(skb); return -EINVAL; @@ -676,8 +675,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len, break; default: - printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n", - wiphy_name(priv->hw->wiphy), algo); + wiphy_err(priv->hw->wiphy, + "invalid cryptographic algorithm: %d\n", algo); dev_kfree_skb(skb); return -EINVAL; } diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index 9575ac03363..ea91f5cce6b 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c @@ -57,8 +57,8 @@ static void p54_update_leds(struct work_struct *work) err = p54_set_leds(priv); if (err && net_ratelimit()) - printk(KERN_ERR "%s: failed to update LEDs (%d).\n", - wiphy_name(priv->hw->wiphy), err); + wiphy_err(priv->hw->wiphy, + "failed to update leds (%d).\n", err); if (rerun) ieee80211_queue_delayed_work(priv->hw, &priv->led_work, @@ -102,8 +102,8 @@ static int p54_register_led(struct p54_common *priv, err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); if (err) - printk(KERN_ERR "%s: Failed to register %s LED.\n", - wiphy_name(priv->hw->wiphy), name); + wiphy_err(priv->hw->wiphy, + "failed to register %s led.\n", name); else led->registered = 1; diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index c072f41747c..47db439b63b 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -507,6 +507,22 @@ out_unlock: return ret; } +static int p54_get_survey(struct ieee80211_hw *dev, int idx, + struct survey_info *survey) +{ + struct p54_common *priv = dev->priv; + struct ieee80211_conf *conf = &dev->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = clamp_t(s8, priv->noise, -128, 127); + + return 0; +} + static const struct ieee80211_ops p54_ops = { .tx = p54_tx_80211, .start = p54_start, @@ -523,6 +539,7 @@ static const struct ieee80211_ops p54_ops = { .configure_filter = p54_configure_filter, .conf_tx = p54_conf_tx, .get_stats = p54_get_stats, + .get_survey = p54_get_survey, }; struct ieee80211_hw *p54_init_common(size_t priv_data_len) diff --git a/drivers/net/wireless/p54/net2280.h b/drivers/net/wireless/p54/net2280.h index 4915d9d5420..e3ed893b5aa 100644 --- a/drivers/net/wireless/p54/net2280.h +++ b/drivers/net/wireless/p54/net2280.h @@ -232,7 +232,7 @@ struct net2280_regs { #define GPIO2_INTERRUPT 2 #define GPIO1_INTERRUPT 1 #define GPIO0_INTERRUPT 0 -} __attribute__ ((packed)); +} __packed; /* usb control, BAR0 + 0x0080 */ struct net2280_usb_regs { @@ -296,7 +296,7 @@ struct net2280_usb_regs { #define FORCE_IMMEDIATE 7 #define OUR_USB_ADDRESS 0 __le32 ourconfig; -} __attribute__ ((packed)); +} __packed; /* pci control, BAR0 + 0x0100 */ struct net2280_pci_regs { @@ -323,7 +323,7 @@ struct net2280_pci_regs { #define PCI_ARBITER_CLEAR 2 #define PCI_EXTERNAL_ARBITER 1 #define PCI_HOST_MODE 0 -} __attribute__ ((packed)); +} __packed; /* dma control, BAR0 + 0x0180 ... array of four structs like this, * for channels 0..3. see also struct net2280_dma: descriptor @@ -364,7 +364,7 @@ struct net2280_dma_regs { /* [11.7] */ __le32 dmaaddr; __le32 dmadesc; u32 _unused1; -} __attribute__ ((packed)); +} __packed; /* dedicated endpoint registers, BAR0 + 0x0200 */ @@ -374,7 +374,7 @@ struct net2280_dep_regs { /* [11.8] */ /* offset 0x0204, 0x0214, 0x224, 0x234, 0x244 */ __le32 dep_rsp; u32 _unused[2]; -} __attribute__ ((packed)); +} __packed; /* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs * like this, for ep0 then the configurable endpoints A..F @@ -437,16 +437,16 @@ struct net2280_ep_regs { /* [11.9] */ __le32 ep_avail; __le32 ep_data; u32 _unused0[2]; -} __attribute__ ((packed)); +} __packed; struct net2280_reg_write { __le16 port; __le32 addr; __le32 val; -} __attribute__ ((packed)); +} __packed; struct net2280_reg_read { __le16 port; __le32 addr; -} __attribute__ ((packed)); +} __packed; #endif /* NET2280_H */ diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index a5ea89cde8c..822f8dc26e9 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -466,8 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev) P54P_READ(dev_int); if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { - printk(KERN_ERR "%s: Cannot boot firmware!\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "cannot boot firmware!\n"); p54p_stop(dev); return -ETIMEDOUT; } diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h index 2feead617a3..ee9bc62a4fa 100644 --- a/drivers/net/wireless/p54/p54pci.h +++ b/drivers/net/wireless/p54/p54pci.h @@ -65,7 +65,7 @@ struct p54p_csr { u8 unused_6[1924]; u8 cardbus_cis[0x800]; u8 direct_mem_win[0x1000]; -} __attribute__ ((packed)); +} __packed; /* usb backend only needs the register defines above */ #ifndef P54USB_H @@ -74,7 +74,7 @@ struct p54p_desc { __le32 device_addr; __le16 len; __le16 flags; -} __attribute__ ((packed)); +} __packed; struct p54p_ring_control { __le32 host_idx[4]; @@ -83,7 +83,7 @@ struct p54p_ring_control { struct p54p_desc tx_data[32]; struct p54p_desc rx_mgmt[4]; struct p54p_desc tx_mgmt[4]; -} __attribute__ ((packed)); +} __packed; #define P54P_READ(r) (__force __le32)__raw_readl(&priv->map->r) #define P54P_WRITE(r, val) __raw_writel((__force u32)(__le32)(val), &priv->map->r) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index c8f09da1f84..087bf0698a5 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -697,9 +697,7 @@ static int __devexit p54spi_remove(struct spi_device *spi) static struct spi_driver p54spi_driver = { .driver = { - /* use cx3110x name because board-n800.c uses that for the - * SPI port */ - .name = "cx3110x", + .name = "p54spi", .bus = &spi_bus_type, .owner = THIS_MODULE, }, @@ -733,3 +731,4 @@ module_exit(p54spi_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); MODULE_ALIAS("spi:cx3110x"); +MODULE_ALIAS("spi:p54spi"); diff --git a/drivers/net/wireless/p54/p54spi.h b/drivers/net/wireless/p54/p54spi.h index 7fbe8d8fc67..dfaa62aaeb0 100644 --- a/drivers/net/wireless/p54/p54spi.h +++ b/drivers/net/wireless/p54/p54spi.h @@ -96,7 +96,7 @@ struct p54s_dma_regs { __le16 cmd; __le16 len; __le32 addr; -} __attribute__ ((packed)); +} __packed; struct p54s_tx_info { struct list_head tx_list; diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 73073259f50..ad595958b7d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -69,7 +69,8 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/ {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/ - {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ + /* {USB_DEVICE(0x0cde, 0x0006)}, * Medion MD40900 already listed above, + * just noting it here for clarity */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ @@ -434,10 +435,9 @@ static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) u8 *buf; int ret; - buf = kmalloc(4, GFP_KERNEL); + buf = kmemdup(p54u_romboot_3887, 4, GFP_KERNEL); if (!buf) return -ENOMEM; - memcpy(buf, p54u_romboot_3887, 4); ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4); kfree(buf); diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h index e935b79f7f7..ed4034ade59 100644 --- a/drivers/net/wireless/p54/p54usb.h +++ b/drivers/net/wireless/p54/p54usb.h @@ -70,12 +70,12 @@ struct net2280_tx_hdr { __le16 len; __le16 follower; /* ? */ u8 padding[8]; -} __attribute__((packed)); +} __packed; struct lm87_tx_hdr { __le32 device_addr; __le32 chksum; -} __attribute__((packed)); +} __packed; /* Some flags for the isl hardware registers controlling DMA inside the * chip */ @@ -103,7 +103,7 @@ struct x2_header { __le32 fw_load_addr; __le32 fw_length; __le32 crc; -} __attribute__((packed)); +} __packed; /* pipes 3 and 4 are not used by the driver */ #define P54U_PIPE_NUMBER 9 diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 4e6891099d4..427b46f558e 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -38,8 +38,8 @@ static void p54_dump_tx_queue(struct p54_common *priv) u32 largest_hole = 0, free; spin_lock_irqsave(&priv->tx_queue.lock, flags); - printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n", - wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue)); + wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n", + skb_queue_len(&priv->tx_queue)); prev_addr = priv->rx_start; skb_queue_walk(&priv->tx_queue, skb) { @@ -48,21 +48,23 @@ static void p54_dump_tx_queue(struct p54_common *priv) hdr = (void *) skb->data; free = range->start_addr - prev_addr; - printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x " - "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} " - "mem:{start:%04x end:%04x, free:%d}]\n", - wiphy_name(priv->hw->wiphy), i++, skb, skb->len, - le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len), - le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type), - range->start_addr, range->end_addr, free); + wiphy_debug(priv->hw->wiphy, + "| [%02d] => [skb:%p skb_len:0x%04x " + "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} " + "mem:{start:%04x end:%04x, free:%d}]\n", + i++, skb, skb->len, + le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len), + le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type), + range->start_addr, range->end_addr, free); prev_addr = range->end_addr; largest_hole = max(largest_hole, free); } free = priv->rx_end - prev_addr; largest_hole = max(largest_hole, free); - printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n", - wiphy_name(priv->hw->wiphy), free, largest_hole); + wiphy_debug(priv->hw->wiphy, + "\\ --- [free: %d], largest free block: %d ---\n", + free, largest_hole); spin_unlock_irqrestore(&priv->tx_queue.lock, flags); } #endif /* P54_MM_DEBUG */ @@ -538,8 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) case P54_TRAP_BEACON_TX: break; case P54_TRAP_RADAR: - printk(KERN_INFO "%s: radar (freq:%d MHz)\n", - wiphy_name(priv->hw->wiphy), freq); + wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq); break; case P54_TRAP_NO_BEACON: if (priv->vif) @@ -558,8 +559,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) wiphy_rfkill_set_hw_state(priv->hw->wiphy, false); break; default: - printk(KERN_INFO "%s: received event:%x freq:%d\n", - wiphy_name(priv->hw->wiphy), event, freq); + wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n", + event, freq); break; } } @@ -584,8 +585,9 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb) p54_rx_eeprom_readback(priv, skb); break; default: - printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", - wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type)); + wiphy_debug(priv->hw->wiphy, + "not handling 0x%02x type control frame\n", + le16_to_cpu(hdr->type)); break; } return 0; diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 8d1190c0f06..77cd65db850 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -2067,7 +2067,7 @@ send_simple_event(islpci_private *priv, const char *str) memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL); if (!memptr) return; - BUG_ON(n > IW_CUSTOM_MAX); + BUG_ON(n >= IW_CUSTOM_MAX); wrqu.data.pointer = memptr; wrqu.data.length = n; strcpy(memptr, str); @@ -2101,7 +2101,7 @@ struct ieee80211_beacon_phdr { u8 timestamp[8]; u16 beacon_int; u16 capab_info; -} __attribute__ ((packed)); +} __packed; #define WLAN_EID_GENERIC 0xdd static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 }; @@ -2751,14 +2751,9 @@ prism54_hostapd(struct net_device *ndev, struct iw_point *p) p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = kmalloc(p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - kfree(param); - return -EFAULT; - } + param = memdup_user(p->pointer, p->length); + if (IS_ERR(param)) + return PTR_ERR(param); switch (param->cmd) { case PRISM2_SET_ENCRYPTION: diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h index b7534c2869c..59e31258d45 100644 --- a/drivers/net/wireless/prism54/isl_oid.h +++ b/drivers/net/wireless/prism54/isl_oid.h @@ -29,20 +29,20 @@ struct obj_ssid { u8 length; char octets[33]; -} __attribute__ ((packed)); +} __packed; struct obj_key { u8 type; /* dot11_priv_t */ u8 length; char key[32]; -} __attribute__ ((packed)); +} __packed; struct obj_mlme { u8 address[6]; u16 id; u16 state; u16 code; -} __attribute__ ((packed)); +} __packed; struct obj_mlmeex { u8 address[6]; @@ -51,12 +51,12 @@ struct obj_mlmeex { u16 code; u16 size; u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct obj_buffer { u32 size; u32 addr; /* 32bit bus address */ -} __attribute__ ((packed)); +} __packed; struct obj_bss { u8 address[6]; @@ -77,17 +77,17 @@ struct obj_bss { short rates; short basic_rates; int:16; /* padding */ -} __attribute__ ((packed)); +} __packed; struct obj_bsslist { u32 nr; struct obj_bss bsslist[0]; -} __attribute__ ((packed)); +} __packed; struct obj_frequencies { u16 nr; u16 mhz[0]; -} __attribute__ ((packed)); +} __packed; struct obj_attachment { char type; @@ -95,7 +95,7 @@ struct obj_attachment { short id; short size; char data[0]; -} __attribute__((packed)); +} __packed; /* * in case everything's ok, the inlined function below will be diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h index 54f9a4b7bf9..6ca30a5b7bf 100644 --- a/drivers/net/wireless/prism54/islpci_eth.h +++ b/drivers/net/wireless/prism54/islpci_eth.h @@ -34,13 +34,13 @@ struct rfmon_header { __le16 unk3; u8 rssi; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct rx_annex_header { u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; struct rfmon_header rfmon; -} __attribute__ ((packed)); +} __packed; /* wlan-ng (and hopefully others) AVS header, version one. Fields in * network byte order. */ diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h index 0b27e50fe0d..0db93db9b67 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.h +++ b/drivers/net/wireless/prism54/islpci_mgt.h @@ -101,7 +101,7 @@ typedef struct { u8 device_id; u8 flags; u32 length; -} __attribute__ ((packed)) +} __packed pimfor_header_t; /* A received and interrupt-processed management frame, either for diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index abff8934db1..9c38fc331dc 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -97,7 +97,6 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev); static const struct iw_handler_def ray_handler_def; /***** Prototypes for raylink functions **************************************/ -static int asc_to_int(char a); static void authenticate(ray_dev_t *local); static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type); static void authenticate_timeout(u_long); @@ -1717,24 +1716,6 @@ static void authenticate_timeout(u_long data) } /*===========================================================================*/ -static int asc_to_int(char a) -{ - if (a < '0') - return -1; - if (a <= '9') - return (a - '0'); - if (a < 'A') - return -1; - if (a <= 'F') - return (10 + a - 'A'); - if (a < 'a') - return -1; - if (a <= 'f') - return (10 + a - 'a'); - return -1; -} - -/*===========================================================================*/ static int parse_addr(char *in_str, UCHAR *out) { int len; @@ -1754,14 +1735,14 @@ static int parse_addr(char *in_str, UCHAR *out) i = 5; while (j > 0) { - if ((k = asc_to_int(in_str[j--])) != -1) + if ((k = hex_to_bin(in_str[j--])) != -1) out[i] = k; else return 0; if (j == 0) break; - if ((k = asc_to_int(in_str[j--])) != -1) + if ((k = hex_to_bin(in_str[j--])) != -1) out[i] += k << 4; else return 0; diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 4bd61ee627c..719573bbbf8 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -238,19 +238,19 @@ struct ndis_80211_auth_request { u8 bssid[6]; u8 padding[2]; __le32 flags; -} __attribute__((packed)); +} __packed; struct ndis_80211_pmkid_candidate { u8 bssid[6]; u8 padding[2]; __le32 flags; -} __attribute__((packed)); +} __packed; struct ndis_80211_pmkid_cand_list { __le32 version; __le32 num_candidates; struct ndis_80211_pmkid_candidate candidate_list[0]; -} __attribute__((packed)); +} __packed; struct ndis_80211_status_indication { __le32 status_type; @@ -260,19 +260,19 @@ struct ndis_80211_status_indication { struct ndis_80211_auth_request auth_request[0]; struct ndis_80211_pmkid_cand_list cand_list; } u; -} __attribute__((packed)); +} __packed; struct ndis_80211_ssid { __le32 length; u8 essid[NDIS_802_11_LENGTH_SSID]; -} __attribute__((packed)); +} __packed; struct ndis_80211_conf_freq_hop { __le32 length; __le32 hop_pattern; __le32 hop_set; __le32 dwell_time; -} __attribute__((packed)); +} __packed; struct ndis_80211_conf { __le32 length; @@ -280,7 +280,7 @@ struct ndis_80211_conf { __le32 atim_window; __le32 ds_config; struct ndis_80211_conf_freq_hop fh_config; -} __attribute__((packed)); +} __packed; struct ndis_80211_bssid_ex { __le32 length; @@ -295,25 +295,25 @@ struct ndis_80211_bssid_ex { u8 rates[NDIS_802_11_LENGTH_RATES_EX]; __le32 ie_length; u8 ies[0]; -} __attribute__((packed)); +} __packed; struct ndis_80211_bssid_list_ex { __le32 num_items; struct ndis_80211_bssid_ex bssid[0]; -} __attribute__((packed)); +} __packed; struct ndis_80211_fixed_ies { u8 timestamp[8]; __le16 beacon_interval; __le16 capabilities; -} __attribute__((packed)); +} __packed; struct ndis_80211_wep_key { __le32 size; __le32 index; __le32 length; u8 material[32]; -} __attribute__((packed)); +} __packed; struct ndis_80211_key { __le32 size; @@ -323,14 +323,14 @@ struct ndis_80211_key { u8 padding[6]; u8 rsc[8]; u8 material[32]; -} __attribute__((packed)); +} __packed; struct ndis_80211_remove_key { __le32 size; __le32 index; u8 bssid[6]; u8 padding[2]; -} __attribute__((packed)); +} __packed; struct ndis_config_param { __le32 name_offs; @@ -338,7 +338,7 @@ struct ndis_config_param { __le32 type; __le32 value_offs; __le32 value_length; -} __attribute__((packed)); +} __packed; struct ndis_80211_assoc_info { __le32 length; @@ -358,12 +358,12 @@ struct ndis_80211_assoc_info { } resp_ie; __le32 resp_ie_length; __le32 offset_resp_ies; -} __attribute__((packed)); +} __packed; struct ndis_80211_auth_encr_pair { __le32 auth_mode; __le32 encr_mode; -} __attribute__((packed)); +} __packed; struct ndis_80211_capability { __le32 length; @@ -371,7 +371,7 @@ struct ndis_80211_capability { __le32 num_pmkids; __le32 num_auth_encr_pair; struct ndis_80211_auth_encr_pair auth_encr_pair[0]; -} __attribute__((packed)); +} __packed; struct ndis_80211_bssid_info { u8 bssid[6]; @@ -520,8 +520,9 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); -static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, - int dbm); +static int rndis_set_tx_power(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, + int mbm); static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, @@ -1856,20 +1857,25 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed) return 0; } -static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, - int dbm) +static int rndis_set_tx_power(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, + int mbm) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; - netdev_dbg(usbdev->net, "%s(): type:0x%x dbm:%i\n", - __func__, type, dbm); + netdev_dbg(usbdev->net, "%s(): type:0x%x mbm:%i\n", + __func__, type, mbm); + + if (mbm < 0 || (mbm % 100)) + return -ENOTSUPP; /* Device doesn't support changing txpower after initialization, only * turn off/on radio. Support 'auto' mode and setting same dBm that is * currently used. */ - if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) { + if (type == NL80211_TX_POWER_AUTOMATIC || + MBM_TO_DBM(mbm) == get_bcm4320_power_dbm(priv)) { if (!priv->radio_on) disassociate(usbdev, true); /* turn on radio */ @@ -2495,8 +2501,7 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); - struct ndis_80211_assoc_info *info; - u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32]; + struct ndis_80211_assoc_info *info = NULL; u8 bssid[ETH_ALEN]; int resp_ie_len, req_ie_len; u8 *req_ie, *resp_ie; @@ -2515,23 +2520,43 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) resp_ie = NULL; if (priv->infra_mode == NDIS_80211_INFRA_INFRA) { - memset(assoc_buf, 0, sizeof(assoc_buf)); - info = (void *)assoc_buf; + info = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); + if (!info) { + /* No memory? Try resume work later */ + set_bit(WORK_LINK_UP, &priv->work_pending); + queue_work(priv->workqueue, &priv->work); + return; + } - /* Get association info IEs from device and send them back to - * userspace. */ - ret = get_association_info(usbdev, info, sizeof(assoc_buf)); + /* Get association info IEs from device. */ + ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); if (!ret) { req_ie_len = le32_to_cpu(info->req_ie_length); if (req_ie_len > 0) { offset = le32_to_cpu(info->offset_req_ies); + + if (offset > CONTROL_BUFFER_SIZE) + offset = CONTROL_BUFFER_SIZE; + req_ie = (u8 *)info + offset; + + if (offset + req_ie_len > CONTROL_BUFFER_SIZE) + req_ie_len = + CONTROL_BUFFER_SIZE - offset; } resp_ie_len = le32_to_cpu(info->resp_ie_length); if (resp_ie_len > 0) { offset = le32_to_cpu(info->offset_resp_ies); + + if (offset > CONTROL_BUFFER_SIZE) + offset = CONTROL_BUFFER_SIZE; + resp_ie = (u8 *)info + offset; + + if (offset + resp_ie_len > CONTROL_BUFFER_SIZE) + resp_ie_len = + CONTROL_BUFFER_SIZE - offset; } } } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC)) @@ -2563,6 +2588,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); + if (info != NULL) + kfree(info); + priv->connected = true; memcpy(priv->bssid, bssid, ETH_ALEN); diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index ad2c98af7e9..5063e01410e 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -586,9 +586,11 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, u8 vgc_level) { - rt2400pci_bbp_write(rt2x00dev, 13, vgc_level); - qual->vgc_level = vgc_level; - qual->vgc_level_reg = vgc_level; + if (qual->vgc_level_reg != vgc_level) { + rt2400pci_bbp_write(rt2x00dev, 13, vgc_level); + qual->vgc_level = vgc_level; + qual->vgc_level_reg = vgc_level; + } } static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev, @@ -877,7 +879,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF); + int mask = (state == STATE_RADIO_IRQ_OFF) || + (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; /* @@ -978,7 +981,9 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: rt2400pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: @@ -1076,9 +1081,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - u32 word; u32 reg; /* @@ -1091,9 +1093,15 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00queue_map_txskb(rt2x00dev, entry->skb); - rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); - rt2x00_desc_write(entry_priv->desc, 1, word); + /* + * Write the TX descriptor for the beacon. + */ + rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* * Enable beaconing again. @@ -1230,23 +1238,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) +static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg; - - /* - * Get the interrupt sources & saved to local variable. - * Write register value back to clear pending interrupts. - */ - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); - - if (!reg) - return IRQ_NONE; - - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - return IRQ_HANDLED; + u32 reg = rt2x00dev->irqvalue[0]; /* * Handle interrupts, walk through all bits @@ -1284,9 +1279,40 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) rt2400pci_txdone(rt2x00dev, QID_AC_BK); + /* Enable interrupts again. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_ON_ISR); return IRQ_HANDLED; } +static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) +{ + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg; + + /* + * Get the interrupt sources & saved to local variable. + * Write register value back to clear pending interrupts. + */ + rt2x00pci_register_read(rt2x00dev, CSR7, ®); + rt2x00pci_register_write(rt2x00dev, CSR7, reg); + + if (!reg) + return IRQ_NONE; + + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return IRQ_HANDLED; + + /* Store irqvalues for use in the interrupt thread. */ + rt2x00dev->irqvalue[0] = reg; + + /* Disable interrupts, will be enabled again in the interrupt thread. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); + + return IRQ_WAKE_THREAD; +} + /* * Device probe functions. */ @@ -1396,8 +1422,8 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Check if the BBP tuning should be enabled. */ - if (!rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) - __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); + if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); return 0; } @@ -1563,7 +1589,8 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { .remove_interface = rt2x00mac_remove_interface, .config = rt2x00mac_config, .configure_filter = rt2x00mac_configure_filter, - .set_tim = rt2x00mac_set_tim, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, .get_stats = rt2x00mac_get_stats, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2400pci_conf_tx, @@ -1574,6 +1601,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .irq_handler = rt2400pci_interrupt, + .irq_handler_thread = rt2400pci_interrupt_thread, .probe_hw = rt2400pci_probe_hw, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize, @@ -1585,7 +1613,6 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .reset_tuner = rt2400pci_reset_tuner, .link_tuner = rt2400pci_link_tuner, .write_tx_desc = rt2400pci_write_tx_desc, - .write_tx_data = rt2x00pci_write_tx_data, .write_beacon = rt2400pci_write_beacon, .kick_tx_queue = rt2400pci_kick_tx_queue, .kill_tx_queue = rt2400pci_kill_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 41da3d218c6..c2a555d5376 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -626,6 +626,7 @@ static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, { if (qual->vgc_level_reg != vgc_level) { rt2500pci_bbp_write(rt2x00dev, 17, vgc_level); + qual->vgc_level = vgc_level; qual->vgc_level_reg = vgc_level; } } @@ -700,13 +701,10 @@ dynamic_cca_tune: * R17 is inside the dynamic tuning range, * start tuning the link based on the false cca counter. */ - if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) { + if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg); - qual->vgc_level = qual->vgc_level_reg; - } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) { + else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg); - qual->vgc_level = qual->vgc_level_reg; - } } /* @@ -1035,7 +1033,8 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF); + int mask = (state == STATE_RADIO_IRQ_OFF) || + (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; /* @@ -1136,7 +1135,9 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: rt2500pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: @@ -1233,9 +1234,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct queue_entry_priv_pci *entry_priv = entry->priv_data; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - u32 word; u32 reg; /* @@ -1248,9 +1246,15 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00queue_map_txskb(rt2x00dev, entry->skb); - rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); - rt2x00_desc_write(entry_priv->desc, 1, word); + /* + * Write the TX descriptor for the beacon. + */ + rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* * Enable beaconing again. @@ -1366,23 +1370,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) +static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg; - - /* - * Get the interrupt sources & saved to local variable. - * Write register value back to clear pending interrupts. - */ - rt2x00pci_register_read(rt2x00dev, CSR7, ®); - rt2x00pci_register_write(rt2x00dev, CSR7, reg); - - if (!reg) - return IRQ_NONE; - - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - return IRQ_HANDLED; + u32 reg = rt2x00dev->irqvalue[0]; /* * Handle interrupts, walk through all bits @@ -1420,9 +1411,41 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) rt2500pci_txdone(rt2x00dev, QID_AC_BK); + /* Enable interrupts again. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_ON_ISR); + return IRQ_HANDLED; } +static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) +{ + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg; + + /* + * Get the interrupt sources & saved to local variable. + * Write register value back to clear pending interrupts. + */ + rt2x00pci_register_read(rt2x00dev, CSR7, ®); + rt2x00pci_register_write(rt2x00dev, CSR7, reg); + + if (!reg) + return IRQ_NONE; + + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return IRQ_HANDLED; + + /* Store irqvalues for use in the interrupt thread. */ + rt2x00dev->irqvalue[0] = reg; + + /* Disable interrupts, will be enabled again in the interrupt thread. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); + + return IRQ_WAKE_THREAD; +} + /* * Device probe functions. */ @@ -1554,9 +1577,8 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * Check if the BBP tuning should be enabled. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - - if (rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) - __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); + if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); /* * Read the RSSI <-> dBm offset information. @@ -1861,7 +1883,8 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { .remove_interface = rt2x00mac_remove_interface, .config = rt2x00mac_config, .configure_filter = rt2x00mac_configure_filter, - .set_tim = rt2x00mac_set_tim, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, .get_stats = rt2x00mac_get_stats, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2x00mac_conf_tx, @@ -1872,6 +1895,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .irq_handler = rt2500pci_interrupt, + .irq_handler_thread = rt2500pci_interrupt_thread, .probe_hw = rt2500pci_probe_hw, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize, @@ -1883,7 +1907,6 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .reset_tuner = rt2500pci_reset_tuner, .link_tuner = rt2500pci_link_tuner, .write_tx_desc = rt2500pci_write_tx_desc, - .write_tx_data = rt2x00pci_write_tx_data, .write_beacon = rt2500pci_write_beacon, .kick_tx_queue = rt2500pci_kick_tx_queue, .kill_tx_queue = rt2500pci_kill_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9ae96a626e6..cdaf93f4826 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -345,12 +345,20 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_crypto *crypto, struct ieee80211_key_conf *key) { - int timeout; u32 mask; u16 reg; + enum cipher curr_cipher; if (crypto->cmd == SET_KEY) { /* + * Disallow to set WEP key other than with index 0, + * it is known that not work at least on some hardware. + * SW crypto will be used in that case. + */ + if (key->alg == ALG_WEP && key->keyidx != 0) + return -EOPNOTSUPP; + + /* * Pairwise key will always be entry 0, but this * could collide with a shared key on the same * position... @@ -358,6 +366,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, mask = TXRX_CSR0_KEY_ID.bit_mask; rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); + curr_cipher = rt2x00_get_field16(reg, TXRX_CSR0_ALGORITHM); reg &= mask; if (reg && reg == mask) @@ -366,19 +375,17 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID); key->hw_key_idx += reg ? ffz(reg) : 0; - /* - * The encryption key doesn't fit within the CSR cache, - * this means we should allocate it separately and use - * rt2x00usb_vendor_request() to send the key to the hardware. + * Hardware requires that all keys use the same cipher + * (e.g. TKIP-only, AES-only, but not TKIP+AES). + * If this is not the first key, compare the cipher with the + * first one and fall back to SW crypto if not the same. */ - reg = KEY_ENTRY(key->hw_key_idx); - timeout = REGISTER_TIMEOUT32(sizeof(crypto->key)); - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, reg, - crypto->key, - sizeof(crypto->key), - timeout); + if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher) + return -EOPNOTSUPP; + + rt2500usb_register_multiwrite(rt2x00dev, KEY_ENTRY(key->hw_key_idx), + crypto->key, sizeof(crypto->key)); /* * The driver does not support the IV/EIV generation @@ -818,6 +825,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); + rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, CIPHER_NONE); rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0); rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); @@ -1005,7 +1013,9 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: @@ -1034,7 +1044,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); + __le32 *txd = (__le32 *) skb->data; u32 word; /* @@ -1080,6 +1090,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * Register descriptor details in skb frame descriptor. */ + skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = txd; skbdesc->desc_len = TXD_DESC_SIZE; } @@ -1108,9 +1119,20 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); /* - * Take the descriptor in front of the skb into account. + * Add space for the descriptor in front of the skb. */ skb_push(entry->skb, TXD_DESC_SIZE); + memset(entry->skb->data, 0, TXD_DESC_SIZE); + + /* + * Write the TX descriptor for the beacon. + */ + rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* * USB devices cannot blindly pass the skb->len as the @@ -1460,13 +1482,6 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); /* - * Check if the BBP tuning should be disabled. - */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) - __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); - - /* * Read the RSSI <-> dBm offset information. */ rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &eeprom); @@ -1732,7 +1747,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); } - __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); /* * Set the rssi offset. @@ -1752,6 +1767,8 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { .configure_filter = rt2x00mac_configure_filter, .set_tim = rt2x00mac_set_tim, .set_key = rt2x00mac_set_key, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, .get_stats = rt2x00mac_get_stats, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2x00mac_conf_tx, @@ -1767,8 +1784,8 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .rfkill_poll = rt2500usb_rfkill_poll, .link_stats = rt2500usb_link_stats, .reset_tuner = rt2500usb_reset_tuner, + .watchdog = rt2x00usb_watchdog, .write_tx_desc = rt2500usb_write_tx_desc, - .write_tx_data = rt2x00usb_write_tx_data, .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2aa03751c34..ed4ebcdde7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -63,7 +63,6 @@ */ #define REV_RT2860C 0x0100 #define REV_RT2860D 0x0101 -#define REV_RT2870D 0x0101 #define REV_RT2872E 0x0200 #define REV_RT3070E 0x0200 #define REV_RT3070F 0x0201 @@ -75,7 +74,7 @@ * Signal information. * Default offset is required for RSSI <-> dBm conversion. */ -#define DEFAULT_RSSI_OFFSET 120 /* FIXME */ +#define DEFAULT_RSSI_OFFSET 120 /* * Register layout information. @@ -99,6 +98,21 @@ */ /* + * E2PROM_CSR: PCI EEPROM control register. + * RELOAD: Write 1 to reload eeprom content. + * TYPE: 0: 93c46, 1:93c66. + * LOAD_STATUS: 1:loading, 0:done. + */ +#define E2PROM_CSR 0x0004 +#define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001) +#define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002) +#define E2PROM_CSR_DATA_IN FIELD32(0x00000004) +#define E2PROM_CSR_DATA_OUT FIELD32(0x00000008) +#define E2PROM_CSR_TYPE FIELD32(0x00000030) +#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) +#define E2PROM_CSR_RELOAD FIELD32(0x00000080) + +/* * OPT_14: Unknown register used by rt3xxx devices. */ #define OPT_14_CSR 0x0114 @@ -322,6 +336,39 @@ #define RX_DRX_IDX 0x029c /* + * USB_DMA_CFG + * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns. + * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes. + * PHY_CLEAR: phy watch dog enable. + * TX_CLEAR: Clear USB DMA TX path. + * TXOP_HALT: Halt TXOP count down when TX buffer is full. + * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation. + * RX_BULK_EN: Enable USB DMA Rx. + * TX_BULK_EN: Enable USB DMA Tx. + * EP_OUT_VALID: OUT endpoint data valid. + * RX_BUSY: USB DMA RX FSM busy. + * TX_BUSY: USB DMA TX FSM busy. + */ +#define USB_DMA_CFG 0x02a0 +#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff) +#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00) +#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000) +#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000) +#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000) +#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000) +#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000) +#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000) +#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000) +#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000) +#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000) + +/* + * US_CYC_CNT + */ +#define US_CYC_CNT 0x02a4 +#define US_CYC_CNT_CLOCK_CYCLE FIELD32(0x000000ff) + +/* * PBF_SYS_CTRL * HOST_RAM_WRITE: enable Host program ram write selection */ @@ -672,14 +719,20 @@ #define TBTT_TIMER 0x1124 /* - * INT_TIMER_CFG: + * INT_TIMER_CFG: timer configuration + * PRE_TBTT_TIMER: leadtime to tbtt for pretbtt interrupt in units of 1/16 TU + * GP_TIMER: period of general purpose timer in units of 1/16 TU */ #define INT_TIMER_CFG 0x1128 +#define INT_TIMER_CFG_PRE_TBTT_TIMER FIELD32(0x0000ffff) +#define INT_TIMER_CFG_GP_TIMER FIELD32(0xffff0000) /* * INT_TIMER_EN: GP-timer and pre-tbtt Int enable */ #define INT_TIMER_EN 0x112c +#define INT_TIMER_EN_PRE_TBTT_TIMER FIELD32(0x00000001) +#define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) /* * CH_IDLE_STA: channel idle time @@ -756,6 +809,18 @@ #define EDCA_TID_AC_MAP 0x1310 /* + * TX_PWR_CFG: + */ +#define TX_PWR_CFG_RATE0 FIELD32(0x0000000f) +#define TX_PWR_CFG_RATE1 FIELD32(0x000000f0) +#define TX_PWR_CFG_RATE2 FIELD32(0x00000f00) +#define TX_PWR_CFG_RATE3 FIELD32(0x0000f000) +#define TX_PWR_CFG_RATE4 FIELD32(0x000f0000) +#define TX_PWR_CFG_RATE5 FIELD32(0x00f00000) +#define TX_PWR_CFG_RATE6 FIELD32(0x0f000000) +#define TX_PWR_CFG_RATE7 FIELD32(0xf0000000) + +/* * TX_PWR_CFG_0: */ #define TX_PWR_CFG_0 0x1314 @@ -1370,17 +1435,17 @@ struct mac_wcid_entry { u8 mac[6]; u8 reserved[2]; -} __attribute__ ((packed)); +} __packed; struct hw_key_entry { u8 key[16]; u8 tx_mic[8]; u8 rx_mic[8]; -} __attribute__ ((packed)); +} __packed; struct mac_iveiv_entry { u8 iv[8]; -} __attribute__ ((packed)); +} __packed; /* * MAC_WCID_ATTRIBUTE: @@ -1389,6 +1454,10 @@ struct mac_iveiv_entry { #define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e) #define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070) #define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380) +#define MAC_WCID_ATTRIBUTE_CIPHER_EXT FIELD32(0x00000400) +#define MAC_WCID_ATTRIBUTE_BSS_IDX_EXT FIELD32(0x00000800) +#define MAC_WCID_ATTRIBUTE_WAPI_MCBC FIELD32(0x00008000) +#define MAC_WCID_ATTRIBUTE_WAPI_KEY_IDX FIELD32(0xff000000) /* * SHARED_KEY_MODE: @@ -1510,7 +1579,9 @@ struct mac_iveiv_entry { */ /* - * BBP 1: TX Antenna + * 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 */ #define BBP1_TX_POWER FIELD8(0x07) #define BBP1_TX_ANTENNA FIELD8(0x18) @@ -1800,9 +1871,15 @@ struct mac_iveiv_entry { #define EEPROM_TXPOWER_A_2 FIELD16(0xff00) /* - * EEPROM TXpower byrate: 20MHZ power + * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode */ #define EEPROM_TXPOWER_BYRATE 0x006f +#define EEPROM_TXPOWER_BYRATE_SIZE 9 + +#define EEPROM_TXPOWER_BYRATE_RATE0 FIELD16(0x000f) +#define EEPROM_TXPOWER_BYRATE_RATE1 FIELD16(0x00f0) +#define EEPROM_TXPOWER_BYRATE_RATE2 FIELD16(0x0f00) +#define EEPROM_TXPOWER_BYRATE_RATE3 FIELD16(0xf000) /* * EEPROM BBP. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index db4250d1c8b..b66e0fd8f0f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1,9 +1,9 @@ /* + Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com> Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> Based on the original rt2800pci.c and rt2800usb.c. - Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> @@ -33,21 +33,14 @@ Abstract: rt2800 generic device routines. */ +#include <linux/crc-ccitt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include "rt2x00.h" -#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) -#include "rt2x00usb.h" -#endif #include "rt2800lib.h" #include "rt2800.h" -#include "rt2800usb.h" - -MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); -MODULE_DESCRIPTION("rt2800 library"); -MODULE_LICENSE("GPL"); /* * Register access. @@ -107,8 +100,7 @@ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBP_CSR_CFG_REGNUM, word); rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1); rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 0); - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) - rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); + rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); } @@ -136,8 +128,7 @@ static void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, BBP_CSR_CFG_REGNUM, word); rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1); rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 1); - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) - rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); + rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); @@ -282,9 +273,162 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); -void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) +static bool rt2800_check_firmware_crc(const u8 *data, const size_t len) +{ + u16 fw_crc; + u16 crc; + + /* + * The last 2 bytes in the firmware array are the crc checksum itself, + * this means that we should never pass those 2 bytes to the crc + * algorithm. + */ + fw_crc = (data[len - 2] << 8 | data[len - 1]); + + /* + * Use the crc ccitt algorithm. + * This will return the same value as the legacy driver which + * used bit ordering reversion on the both the firmware bytes + * before input input as well as on the final output. + * Obviously using crc ccitt directly is much more efficient. + */ + crc = crc_ccitt(~0, data, len - 2); + + /* + * There is a small difference between the crc-itu-t + bitrev and + * the crc-ccitt crc calculation. In the latter method the 2 bytes + * will be swapped, use swab16 to convert the crc to the correct + * value. + */ + crc = swab16(crc); + + return fw_crc == crc; +} + +int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len) +{ + size_t offset = 0; + size_t fw_len; + bool multiple; + + /* + * PCI(e) & SOC devices require firmware with a length + * of 8kb. USB devices require firmware files with a length + * of 4kb. Certain USB chipsets however require different firmware, + * which Ralink only provides attached to the original firmware + * file. Thus for USB devices, firmware files have a length + * which is a multiple of 4kb. + */ + if (rt2x00_is_usb(rt2x00dev)) { + fw_len = 4096; + multiple = true; + } else { + fw_len = 8192; + multiple = true; + } + + /* + * Validate the firmware length + */ + if (len != fw_len && (!multiple || (len % fw_len) != 0)) + return FW_BAD_LENGTH; + + /* + * Check if the chipset requires one of the upper parts + * of the firmware. + */ + if (rt2x00_is_usb(rt2x00dev) && + !rt2x00_rt(rt2x00dev, RT2860) && + !rt2x00_rt(rt2x00dev, RT2872) && + !rt2x00_rt(rt2x00dev, RT3070) && + ((len / fw_len) == 1)) + return FW_BAD_VERSION; + + /* + * 8kb firmware files must be checked as if it were + * 2 separate firmware files. + */ + while (offset < len) { + if (!rt2800_check_firmware_crc(data + offset, fw_len)) + return FW_BAD_CRC; + + offset += fw_len; + } + + return FW_OK; +} +EXPORT_SYMBOL_GPL(rt2800_check_firmware); + +int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len) +{ + unsigned int i; + u32 reg; + + /* + * Wait for stable hardware. + */ + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (reg && reg != ~0) + break; + msleep(1); + } + + if (i == REGISTER_BUSY_COUNT) { + ERROR(rt2x00dev, "Unstable hardware.\n"); + return -EBUSY; + } + + if (rt2x00_is_pci(rt2x00dev)) + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); + + /* + * Disable DMA, will be reenabled later when enabling + * the radio. + */ + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + /* + * Write firmware to the device. + */ + rt2800_drv_write_firmware(rt2x00dev, data, len); + + /* + * Wait for device to stabilize. + */ + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); + if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) + break; + msleep(1); + } + + if (i == REGISTER_BUSY_COUNT) { + ERROR(rt2x00dev, "PBF system register not ready.\n"); + return -EBUSY; + } + + /* + * Initialize firmware. + */ + rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); + rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + msleep(1); + + return 0; +} +EXPORT_SYMBOL_GPL(rt2800_load_firmware); + +void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) { - __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE); u32 word; /* @@ -336,9 +480,53 @@ void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) } EXPORT_SYMBOL_GPL(rt2800_write_txwi); -void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc) +static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) { - __le32 *rxwi = (__le32 *) skb->data; + int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); + int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); + int rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2); + u16 eeprom; + u8 offset0; + u8 offset1; + u8 offset2; + + if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) { + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); + offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); + offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom); + offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_OFFSET2); + } else { + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &eeprom); + offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET0); + offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A_OFFSET1); + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom); + offset2 = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_OFFSET2); + } + + /* + * Convert the value from the descriptor into the RSSI value + * If the value in the descriptor is 0, it is considered invalid + * and the default (extremely low) rssi value is assumed + */ + rssi0 = (rssi0) ? (-12 - offset0 - rt2x00dev->lna_gain - rssi0) : -128; + rssi1 = (rssi1) ? (-12 - offset1 - rt2x00dev->lna_gain - rssi1) : -128; + rssi2 = (rssi2) ? (-12 - offset2 - rt2x00dev->lna_gain - rssi2) : -128; + + /* + * mac80211 only accepts a single RSSI value. Calculating the + * average doesn't deliver a fair answer either since -60:-60 would + * be considered equally good as -50:-70 while the second is the one + * which gives less energy... + */ + rssi0 = max(rssi0, rssi1); + return max(rssi0, rssi2); +} + +void rt2800_process_rxwi(struct queue_entry *entry, + struct rxdone_entry_desc *rxdesc) +{ + __le32 *rxwi = (__le32 *) entry->skb->data; u32 word; rt2x00_desc_read(rxwi, 0, &word); @@ -369,17 +557,93 @@ void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc) rt2x00_desc_read(rxwi, 2, &word); - rxdesc->rssi = - (rt2x00_get_field32(word, RXWI_W2_RSSI0) + - rt2x00_get_field32(word, RXWI_W2_RSSI1)) / 2; + /* + * Convert descriptor AGC value to RSSI value. + */ + rxdesc->rssi = rt2800_agc_to_rssi(entry->queue->rt2x00dev, word); /* * Remove RXWI descriptor from start of buffer. */ - skb_pull(skb, RXWI_DESC_SIZE); + skb_pull(entry->skb, RXWI_DESC_SIZE); } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); +void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + unsigned int beacon_base; + u32 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, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + /* + * Add space for the TXWI in front of the skb. + */ + skb_push(entry->skb, TXWI_DESC_SIZE); + memset(entry->skb, 0, TXWI_DESC_SIZE); + + /* + * Register descriptor details in skb frame descriptor. + */ + skbdesc->flags |= SKBDESC_DESC_IN_SKB; + skbdesc->desc = entry->skb->data; + skbdesc->desc_len = TXWI_DESC_SIZE; + + /* + * Add the TXWI for the beacon to the skb. + */ + rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); + + /* + * Write entire beacon with TXWI to register. + */ + beacon_base = HW_BEACON_OFFSET(entry->entry_idx); + rt2800_register_multiwrite(rt2x00dev, beacon_base, + entry->skb->data, entry->skb->len); + + /* + * Enable beaconing again. + */ + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + /* + * Clean up beacon skb. + */ + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; +} +EXPORT_SYMBOL_GPL(rt2800_write_beacon); + +static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, + unsigned int beacon_base) +{ + int i; + + /* + * For the Beacon base registers we only need to clear + * the whole TXWI which (when set to 0) will invalidate + * the entire beacon. + */ + for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32)) + rt2800_register_write(rt2x00dev, beacon_base + i, 0); +} + #ifdef CONFIG_RT2X00_LIB_DEBUGFS const struct rt2x00debug rt2800_rt2x00debug = { .owner = THIS_MODULE, @@ -502,15 +766,28 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); - rt2800_register_read(rt2x00dev, offset, ®); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, - !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, - (crypto->cmd == SET_KEY) * crypto->cipher); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, - (crypto->cmd == SET_KEY) * crypto->bssidx); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); - rt2800_register_write(rt2x00dev, offset, reg); + if (crypto->cmd == SET_KEY) { + rt2800_register_read(rt2x00dev, offset, ®); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, + !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); + /* + * Both the cipher as the BSS Idx numbers are split in a main + * value of 3 bits, and a extended field for adding one additional + * bit to the value. + */ + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, + (crypto->cipher & 0x7)); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT, + (crypto->cipher & 0x8) >> 3); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, + (crypto->bssidx & 0x7)); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, + (crypto->bssidx & 0x8) >> 3); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); + rt2800_register_write(rt2x00dev, offset, reg); + } else { + rt2800_register_write(rt2x00dev, offset, 0); + } offset = MAC_IVEIV_ENTRY(key->hw_key_idx); @@ -668,19 +945,14 @@ EXPORT_SYMBOL_GPL(rt2800_config_filter); void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags) { - unsigned int beacon_base; u32 reg; if (flags & CONFIG_UPDATE_TYPE) { /* * Clear current synchronisation setup. - * For the Beacon base registers we only need to clear - * the first byte since that byte contains the VALID and OWNER - * bits which (when set to 0) will invalidate the entire beacon. */ - beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); - rt2800_register_write(rt2x00dev, beacon_base, 0); - + rt2800_clear_beacon(rt2x00dev, + HW_BEACON_OFFSET(intf->beacon->entry_idx)); /* * Enable synchronisation. */ @@ -688,8 +960,18 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, - (conf->sync == TSF_SYNC_BEACON)); + (conf->sync == TSF_SYNC_ADHOC || + conf->sync == TSF_SYNC_AP_NONE)); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + /* + * Enable pre tbtt interrupt for beaconing modes + */ + rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, + (conf->sync == TSF_SYNC_AP_NONE)); + rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); + } if (flags & CONFIG_UPDATE_MAC) { @@ -703,8 +985,8 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, if (flags & CONFIG_UPDATE_BSSID) { reg = le32_to_cpu(conf->bssid[1]); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 0); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); conf->bssid[1] = cpu_to_le32(reg); rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, @@ -762,14 +1044,12 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) switch ((int)ant->tx) { case 1: rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); - if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) - rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); break; case 2: rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); break; case 3: - /* Do nothing */ + rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); break; } @@ -1016,66 +1296,115 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, } static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, - const int txpower) + const int max_txpower) { + u8 txpower; + u8 max_value = (u8)max_txpower; + u16 eeprom; + int i; u32 reg; - u32 value = TXPOWER_G_TO_DEV(txpower); u8 r1; + u32 offset; + /* + * set to normal tx power mode: +/- 0dBm + */ rt2800_bbp_read(rt2x00dev, 1, &r1); - rt2x00_set_field8(®, BBP1_TX_POWER, 0); + rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); rt2800_bbp_write(rt2x00dev, 1, r1); - rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); - rt2x00_set_field32(®, TX_PWR_CFG_0_1MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_2MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_55MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_11MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_6MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_9MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_12MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_0_18MBS, value); - rt2800_register_write(rt2x00dev, TX_PWR_CFG_0, reg); - - rt2800_register_read(rt2x00dev, TX_PWR_CFG_1, ®); - rt2x00_set_field32(®, TX_PWR_CFG_1_24MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_36MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_48MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_54MBS, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_MCS0, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_MCS1, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_MCS2, value); - rt2x00_set_field32(®, TX_PWR_CFG_1_MCS3, value); - rt2800_register_write(rt2x00dev, TX_PWR_CFG_1, reg); - - rt2800_register_read(rt2x00dev, TX_PWR_CFG_2, ®); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS4, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS5, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS6, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS7, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS8, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS9, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS10, value); - rt2x00_set_field32(®, TX_PWR_CFG_2_MCS11, value); - rt2800_register_write(rt2x00dev, TX_PWR_CFG_2, reg); - - rt2800_register_read(rt2x00dev, TX_PWR_CFG_3, ®); - rt2x00_set_field32(®, TX_PWR_CFG_3_MCS12, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_MCS13, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_MCS14, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_MCS15, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN1, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN2, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN3, value); - rt2x00_set_field32(®, TX_PWR_CFG_3_UKNOWN4, value); - rt2800_register_write(rt2x00dev, TX_PWR_CFG_3, reg); - - rt2800_register_read(rt2x00dev, TX_PWR_CFG_4, ®); - rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN5, value); - rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN6, value); - rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN7, value); - rt2x00_set_field32(®, TX_PWR_CFG_4_UKNOWN8, value); - rt2800_register_write(rt2x00dev, TX_PWR_CFG_4, reg); + /* + * 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) { + /* just to be safe */ + if (offset > TX_PWR_CFG_4) + break; + + rt2800_register_read(rt2x00dev, offset, ®); + + /* read the next four txpower values */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, + &eeprom); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE0); + rt2x00_set_field32(®, TX_PWR_CFG_RATE0, + min(txpower, max_value)); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE1); + rt2x00_set_field32(®, TX_PWR_CFG_RATE1, + min(txpower, max_value)); + + /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, + * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, + * TX_PWR_CFG_4: unknown */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE2); + rt2x00_set_field32(®, TX_PWR_CFG_RATE2, + min(txpower, max_value)); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE3); + rt2x00_set_field32(®, TX_PWR_CFG_RATE3, + min(txpower, max_value)); + + /* 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, + * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, + * TX_PWR_CFG_4: unknown */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE0); + rt2x00_set_field32(®, TX_PWR_CFG_RATE4, + min(txpower, max_value)); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE1); + rt2x00_set_field32(®, TX_PWR_CFG_RATE5, + min(txpower, max_value)); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE2); + rt2x00_set_field32(®, TX_PWR_CFG_RATE6, + min(txpower, max_value)); + + /* 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 */ + txpower = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_BYRATE_RATE3); + rt2x00_set_field32(®, TX_PWR_CFG_RATE7, + min(txpower, max_value)); + + rt2800_register_write(rt2x00dev, offset, reg); + + /* next TX_PWR_CFG register */ + offset += 4; + } } static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, @@ -1212,6 +1541,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) u32 reg; u16 eeprom; unsigned int i; + int ret; rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); @@ -1221,59 +1551,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - if (rt2x00_is_usb(rt2x00dev)) { - /* - * Wait until BBP and RF are ready. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); - return -EBUSY; - } - - rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, - reg & ~0x00002000); - } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) { - /* - * Reset DMA indexes - */ - rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - } - - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - if (rt2x00_is_usb(rt2x00dev)) { - rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); -#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) - rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, - USB_MODE_RESET, REGISTER_TIMEOUT); -#endif - } - - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + ret = rt2800_drv_init_registers(rt2x00dev); + if (ret) + return ret; rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®); rt2x00_set_field32(®, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */ @@ -1295,7 +1575,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, 1600); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, 0); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); @@ -1328,7 +1608,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) } else { rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); } - rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg); } else if (rt2x00_rt(rt2x00dev, RT3070)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); @@ -1339,6 +1618,10 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); } + } else if (rt2800_is_305x_soc(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 { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); @@ -1546,23 +1829,20 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) /* * Clear all beacons - * For the Beacon base registers we only need to clear - * the first byte since that byte contains the VALID and OWNER - * bits which (when set to 0) will invalidate the entire beacon. - */ - rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0); - rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); + */ + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6); + rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7); if (rt2x00_is_usb(rt2x00dev)) { - rt2800_register_read(rt2x00dev, USB_CYC_CFG, ®); - rt2x00_set_field32(®, USB_CYC_CFG_CLOCK_CYCLE, 30); - rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg); + rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); + rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30); + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); } rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); @@ -1617,6 +1897,13 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, TX_STA_CNT1, ®); rt2800_register_read(rt2x00dev, TX_STA_CNT2, ®); + /* + * Setup leadtime for pre tbtt interrupt to 6ms + */ + rt2800_register_read(rt2x00dev, INT_TIMER_CFG, ®); + rt2x00_set_field32(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); + rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg); + return 0; } EXPORT_SYMBOL_GPL(rt2800_init_registers); @@ -1706,8 +1993,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 82, 0x62); rt2800_bbp_write(rt2x00dev, 83, 0x6a); - if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) || - rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D)) + if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); else rt2800_bbp_write(rt2x00dev, 84, 0x99); @@ -2013,8 +2299,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) + 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); @@ -2147,7 +2432,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); } else if (rt2x00_rt(rt2x00dev, RT2860) || - rt2x00_rt(rt2x00dev, RT2870) || rt2x00_rt(rt2x00dev, RT2872)) { /* * There is a max of 2 RX streams for RT28x0 series @@ -2169,6 +2453,8 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); + rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0); + rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); } @@ -2176,6 +2462,10 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); if ((word & 0x00ff) == 0x00ff) { rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); + rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); + EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); + } + if ((word & 0xff00) == 0xff00) { rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, LED_MODE_TXRX_ACTIVITY); rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); @@ -2183,7 +2473,7 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); - EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); + EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); } /* @@ -2251,7 +2541,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); if (!rt2x00_rt(rt2x00dev, RT2860) && - !rt2x00_rt(rt2x00dev, RT2870) && !rt2x00_rt(rt2x00dev, RT2872) && !rt2x00_rt(rt2x00dev, RT2883) && !rt2x00_rt(rt2x00dev, RT3070) && @@ -2484,13 +2773,26 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_PS_NULLFUNC_STACK; + IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_AMPDU_AGGREGATION; SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); + /* + * As rt2800 has a global fallback table we cannot specify + * more then one tx rate per frame but since the hw will + * try several rates (based on the fallback table) we should + * still initialize max_rates to the maximum number of rates + * we are going to try. Otherwise mac80211 will truncate our + * reported tx rates and the rc algortihm will end up with + * incorrect data. + */ + rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rate_tries = 1; + rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); /* @@ -2528,16 +2830,19 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) else spec->ht.ht_supported = false; - /* - * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes - * reception problems with HT40 capable 11n APs - */ spec->ht.cap = + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_TX_STBC | - IEEE80211_HT_CAP_RX_STBC; + IEEE80211_HT_CAP_SGI_40; + + if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) + spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; + + spec->ht.cap |= + rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) << + IEEE80211_HT_CAP_RX_STBC_SHIFT; + spec->ht.ampdu_factor = 3; spec->ht.ampdu_density = 4; spec->ht.mcs.tx_params = @@ -2591,8 +2896,8 @@ EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode); /* * IEEE80211 stack callback functions. */ -static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, - u32 *iv32, u16 *iv16) +void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, + u16 *iv16) { struct rt2x00_dev *rt2x00dev = hw->priv; struct mac_iveiv_entry iveiv_entry; @@ -2605,8 +2910,9 @@ static void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16)); memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32)); } +EXPORT_SYMBOL_GPL(rt2800_get_tkip_seq); -static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { struct rt2x00_dev *rt2x00dev = hw->priv; u32 reg; @@ -2642,9 +2948,10 @@ static int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value) return 0; } +EXPORT_SYMBOL_GPL(rt2800_set_rts_threshold); -static int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, - const struct ieee80211_tx_queue_params *params) +int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, + const struct ieee80211_tx_queue_params *params) { struct rt2x00_dev *rt2x00dev = hw->priv; struct data_queue *queue; @@ -2709,8 +3016,9 @@ static int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, return 0; } +EXPORT_SYMBOL_GPL(rt2800_conf_tx); -static u64 rt2800_get_tsf(struct ieee80211_hw *hw) +u64 rt2800_get_tsf(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; u64 tsf; @@ -2723,23 +3031,37 @@ static u64 rt2800_get_tsf(struct ieee80211_hw *hw) return tsf; } +EXPORT_SYMBOL_GPL(rt2800_get_tsf); -const struct ieee80211_ops rt2800_mac80211_ops = { - .tx = rt2x00mac_tx, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, - .remove_interface = rt2x00mac_remove_interface, - .config = rt2x00mac_config, - .configure_filter = rt2x00mac_configure_filter, - .set_tim = rt2x00mac_set_tim, - .set_key = rt2x00mac_set_key, - .get_stats = rt2x00mac_get_stats, - .get_tkip_seq = rt2800_get_tkip_seq, - .set_rts_threshold = rt2800_set_rts_threshold, - .bss_info_changed = rt2x00mac_bss_info_changed, - .conf_tx = rt2800_conf_tx, - .get_tsf = rt2800_get_tsf, - .rfkill_poll = rt2x00mac_rfkill_poll, -}; -EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); +int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ + int ret = 0; + + switch (action) { + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + /* we don't support RX aggregation yet */ + ret = -ENOTSUPP; + break; + case IEEE80211_AMPDU_TX_START: + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_STOP: + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + break; + default: + WARNING((struct rt2x00_dev *)hw->priv, "Unknown AMPDU action\n"); + } + + return ret; +} +EXPORT_SYMBOL_GPL(rt2800_ampdu_action); + +MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); +MODULE_VERSION(DRV_VERSION); +MODULE_DESCRIPTION("Ralink RT2800 library"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 94de999e229..091641e3c5e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -40,13 +40,17 @@ struct rt2800_ops { int (*regbusy_read)(struct rt2x00_dev *rt2x00dev, const unsigned int offset, const struct rt2x00_field32 field, u32 *reg); + + int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len); + int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); }; static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 *value) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_read(rt2x00dev, offset, value); } @@ -55,7 +59,7 @@ static inline void rt2800_register_read_lock(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 *value) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_read_lock(rt2x00dev, offset, value); } @@ -64,7 +68,7 @@ static inline void rt2800_register_write(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 value) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_write(rt2x00dev, offset, value); } @@ -73,7 +77,7 @@ static inline void rt2800_register_write_lock(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 value) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_write_lock(rt2x00dev, offset, value); } @@ -82,7 +86,7 @@ static inline void rt2800_register_multiread(struct rt2x00_dev *rt2x00dev, const unsigned int offset, void *value, const u32 length) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_multiread(rt2x00dev, offset, value, length); } @@ -92,7 +96,7 @@ static inline void rt2800_register_multiwrite(struct rt2x00_dev *rt2x00dev, const void *value, const u32 length) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; rt2800ops->register_multiwrite(rt2x00dev, offset, value, length); } @@ -102,17 +106,39 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev, const struct rt2x00_field32 field, u32 *reg) { - const struct rt2800_ops *rt2800ops = rt2x00dev->priv; + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); } +static inline int rt2800_drv_write_firmware(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len) +{ + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; + + return rt2800ops->drv_write_firmware(rt2x00dev, data, len); +} + +static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev) +{ + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; + + return rt2800ops->drv_init_registers(rt2x00dev); +} + void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1); -void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc); -void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc); +int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len); +int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len); + +void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc); +void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); + +void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); extern const struct rt2x00debug rt2800_rt2x00debug; @@ -148,6 +174,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev); int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev); int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev); -extern const struct ieee80211_ops rt2800_mac80211_ops; +void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32, + u16 *iv16); +int rt2800_set_rts_threshold(struct ieee80211_hw *hw, u32 value); +int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, + const struct ieee80211_tx_queue_params *params); +u64 rt2800_get_tsf(struct ieee80211_hw *hw); +int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); #endif /* RT2800LIB_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b2f23272c3a..39b3846fa34 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -31,7 +31,6 @@ Supported chipsets: RT2800E & RT2800ED. */ -#include <linux/crc-ccitt.h> #include <linux/delay.h> #include <linux/etherdevice.h> #include <linux/init.h> @@ -51,7 +50,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 1; +static int modparam_nohwcrypt = 0; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -139,8 +138,18 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) eeprom.data = rt2x00dev; eeprom.register_read = rt2800pci_eepromregister_read; eeprom.register_write = rt2800pci_eepromregister_write; - eeprom.width = !rt2x00_get_field32(reg, E2PROM_CSR_TYPE) ? - PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; + switch (rt2x00_get_field32(reg, E2PROM_CSR_TYPE)) + { + case 0: + eeprom.width = PCI_EEPROM_WIDTH_93C46; + break; + case 1: + eeprom.width = PCI_EEPROM_WIDTH_93C66; + break; + default: + eeprom.width = PCI_EEPROM_WIDTH_93C86; + break; + } eeprom.reg_data_in = 0; eeprom.reg_data_out = 0; eeprom.reg_data_clock = 0; @@ -182,82 +191,14 @@ static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) return FIRMWARE_RT2860; } -static int rt2800pci_check_firmware(struct rt2x00_dev *rt2x00dev, +static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len) { - u16 fw_crc; - u16 crc; - - /* - * Only support 8kb firmware files. - */ - if (len != 8192) - return FW_BAD_LENGTH; - - /* - * The last 2 bytes in the firmware array are the crc checksum itself, - * this means that we should never pass those 2 bytes to the crc - * algorithm. - */ - fw_crc = (data[len - 2] << 8 | data[len - 1]); - - /* - * Use the crc ccitt algorithm. - * This will return the same value as the legacy driver which - * used bit ordering reversion on the both the firmware bytes - * before input input as well as on the final output. - * Obviously using crc ccitt directly is much more efficient. - */ - crc = crc_ccitt(~0, data, len - 2); - - /* - * There is a small difference between the crc-itu-t + bitrev and - * the crc-ccitt crc calculation. In the latter method the 2 bytes - * will be swapped, use swab16 to convert the crc to the correct - * value. - */ - crc = swab16(crc); - - return (fw_crc == crc) ? FW_OK : FW_BAD_CRC; -} - -static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev, - const u8 *data, const size_t len) -{ - unsigned int i; u32 reg; - /* - * Wait for stable hardware. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); - return -EBUSY; - } - - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); /* - * Disable DMA, will be reenabled later when enabling - * the radio. - */ - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - /* * enable Host program ram write selection */ reg = 0; @@ -268,34 +209,11 @@ static int rt2800pci_load_firmware(struct rt2x00_dev *rt2x00dev, * Write firmware to device. */ rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, - data, len); + data, len); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001); - /* - * Wait for device to stabilize. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); - if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "PBF system register not ready.\n"); - return -EBUSY; - } - - /* - * Disable interrupts - */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF); - - /* - * Initialize BBP R/W access agent - */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); @@ -412,7 +330,8 @@ static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev, static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_ON); + int mask = (state == STATE_RADIO_IRQ_ON) || + (state == STATE_RADIO_IRQ_ON_ISR); u32 reg; /* @@ -446,6 +365,38 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); } +static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + + /* + * Reset DMA indexes + */ + rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); + rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); + + rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); + rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + + return 0; +} + static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; @@ -465,7 +416,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Send signal to firmware during boot time. */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); /* * Enable RX. @@ -589,7 +540,9 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: rt2800pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: @@ -613,18 +566,12 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static int rt2800pci_write_tx_data(struct queue_entry* entry, - struct txentry_desc *txdesc) +static void rt2800pci_write_tx_data(struct queue_entry* entry, + struct txentry_desc *txdesc) { - int ret; - - ret = rt2x00pci_write_tx_data(entry, txdesc); - if (ret) - return ret; + __le32 *txwi = (__le32 *) entry->skb->data; - rt2800_write_txwi(entry->skb, txdesc); - - return 0; + rt2800_write_txwi(txwi, txdesc); } @@ -684,49 +631,6 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * TX data initialization */ -static void rt2800pci_write_beacon(struct queue_entry *entry, - struct txentry_desc *txdesc) -{ - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - unsigned int beacon_base; - u32 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, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - /* - * Add the TXWI for the beacon to the skb. - */ - rt2800_write_txwi(entry->skb, txdesc); - skb_push(entry->skb, TXWI_DESC_SIZE); - - /* - * Write entire beacon with TXWI to register. - */ - beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2800_register_multiwrite(rt2x00dev, beacon_base, - entry->skb->data, entry->skb->len); - - /* - * Enable beaconing again. - */ - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - /* - * Clean up beacon skb. - */ - dev_kfree_skb_any(entry->skb); - entry->skb = NULL; -} - static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { @@ -812,7 +716,7 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, /* * Process the RXWI structure that is at the start of the buffer. */ - rt2800_process_rxwi(entry->skb, rxdesc); + rt2800_process_rxwi(entry, rxdesc); /* * Set RX IDX in register to inform hardware that we have handled @@ -832,29 +736,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) struct txdone_entry_desc txdesc; u32 word; u32 reg; - u32 old_reg; int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; u16 mcs, real_mcs; + int i; /* - * During each loop we will compare the freshly read - * TX_STA_FIFO register value with the value read from - * the previous loop. If the 2 values are equal then - * we should stop processing because the chance it - * quite big that the device has been unplugged and - * we risk going into an endless loop. + * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO + * at most X times and also stop processing once the TX_STA_FIFO_VALID + * flag is not set anymore. + * + * The legacy drivers use X=TX_RING_SIZE but state in a comment + * that the TX_STA_FIFO stack has a size of 16. We stick to our + * tx ring size for now. */ - old_reg = 0; - - while (1) { + for (i = 0; i < TX_ENTRIES; i++) { rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) break; - if (old_reg == reg) - break; - old_reg = reg; - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); @@ -880,8 +779,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) /* Check if we got a match by looking at WCID/ACK/PID * fields */ - txwi = (__le32 *)(entry->skb->data - - rt2x00dev->ops->extra_tx_headroom); + txwi = (__le32 *) entry->skb->data; rt2x00_desc_read(txwi, 1, &word); tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); @@ -923,8 +821,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) txdesc.retry = 7; } - __set_bit(TXDONE_FALLBACK, &txdesc.flags); - + /* + * the frame was retried at least once + * -> hw used fallback rates + */ + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); rt2x00lib_txdone(entry, &txdesc); } @@ -938,6 +840,48 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } +static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) +{ + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg = rt2x00dev->irqvalue[0]; + + /* + * 1 - Pre TBTT interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) + rt2x00lib_pretbtt(rt2x00dev); + + /* + * 2 - Beacondone interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) + rt2x00lib_beacondone(rt2x00dev); + + /* + * 3 - Rx ring done interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) + rt2x00pci_rxdone(rt2x00dev); + + /* + * 4 - Tx done interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) + rt2800pci_txdone(rt2x00dev); + + /* + * 5 - Auto wakeup interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) + rt2800pci_wakeup(rt2x00dev); + + /* Enable interrupts again. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_ON_ISR); + + return IRQ_HANDLED; +} + static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; @@ -953,19 +897,15 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* - * 1 - Rx ring done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) - rt2x00pci_rxdone(rt2x00dev); + /* Store irqvalue for use in the interrupt thread. */ + rt2x00dev->irqvalue[0] = reg; - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800pci_txdone(rt2x00dev); + /* Disable interrupts, will be enabled again in the interrupt thread. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) - rt2800pci_wakeup(rt2x00dev); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } /* @@ -986,24 +926,10 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) return rt2800_validate_eeprom(rt2x00dev); } -static const struct rt2800_ops rt2800pci_rt2800_ops = { - .register_read = rt2x00pci_register_read, - .register_read_lock = rt2x00pci_register_read, /* same for PCI */ - .register_write = rt2x00pci_register_write, - .register_write_lock = rt2x00pci_register_write, /* same for PCI */ - - .register_multiread = rt2x00pci_register_multiread, - .register_multiwrite = rt2x00pci_register_multiwrite, - - .regbusy_read = rt2x00pci_regbusy_read, -}; - static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - rt2x00dev->priv = (void *)&rt2800pci_rt2800_ops; - /* * Allocate eeprom data. */ @@ -1030,6 +956,12 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags); /* + * This device has a pre tbtt interrupt and thus fetches + * a new beacon directly prior to transmission. + */ + __set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags); + + /* * This device requires firmware. */ if (!rt2x00_is_soc(rt2x00dev)) @@ -1038,6 +970,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); /* * Set the rssi offset. @@ -1047,12 +980,46 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) return 0; } +static const struct ieee80211_ops rt2800pci_mac80211_ops = { + .tx = rt2x00mac_tx, + .start = rt2x00mac_start, + .stop = rt2x00mac_stop, + .add_interface = rt2x00mac_add_interface, + .remove_interface = rt2x00mac_remove_interface, + .config = rt2x00mac_config, + .configure_filter = rt2x00mac_configure_filter, + .set_key = rt2x00mac_set_key, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, + .get_stats = rt2x00mac_get_stats, + .get_tkip_seq = rt2800_get_tkip_seq, + .set_rts_threshold = rt2800_set_rts_threshold, + .bss_info_changed = rt2x00mac_bss_info_changed, + .conf_tx = rt2800_conf_tx, + .get_tsf = rt2800_get_tsf, + .rfkill_poll = rt2x00mac_rfkill_poll, + .ampdu_action = rt2800_ampdu_action, +}; + +static const struct rt2800_ops rt2800pci_rt2800_ops = { + .register_read = rt2x00pci_register_read, + .register_read_lock = rt2x00pci_register_read, /* same for PCI */ + .register_write = rt2x00pci_register_write, + .register_write_lock = rt2x00pci_register_write, /* same for PCI */ + .register_multiread = rt2x00pci_register_multiread, + .register_multiwrite = rt2x00pci_register_multiwrite, + .regbusy_read = rt2x00pci_regbusy_read, + .drv_write_firmware = rt2800pci_write_firmware, + .drv_init_registers = rt2800pci_init_registers, +}; + static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .irq_handler = rt2800pci_interrupt, + .irq_handler_thread = rt2800pci_interrupt_thread, .probe_hw = rt2800pci_probe_hw, .get_firmware_name = rt2800pci_get_firmware_name, - .check_firmware = rt2800pci_check_firmware, - .load_firmware = rt2800pci_load_firmware, + .check_firmware = rt2800_check_firmware, + .load_firmware = rt2800_load_firmware, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize, .get_entry_state = rt2800pci_get_entry_state, @@ -1064,7 +1031,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800pci_write_tx_data, - .write_beacon = rt2800pci_write_beacon, + .write_beacon = rt2800_write_beacon, .kick_tx_queue = rt2800pci_kick_tx_queue, .kill_tx_queue = rt2800pci_kill_tx_queue, .fill_rxdone = rt2800pci_fill_rxdone, @@ -1110,7 +1077,8 @@ static const struct rt2x00_ops rt2800pci_ops = { .tx = &rt2800pci_queue_tx, .bcn = &rt2800pci_queue_bcn, .lib = &rt2800pci_rt2x00_ops, - .hw = &rt2800_mac80211_ops, + .drv = &rt2800pci_rt2800_ops, + .hw = &rt2800pci_mac80211_ops, #ifdef CONFIG_RT2X00_LIB_DEBUGFS .debugfs = &rt2800_rt2x00debug, #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index afc8e7da27c..5a8dda9b5b5 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -35,25 +35,6 @@ #define RT2800PCI_H /* - * PCI registers. - */ - -/* - * E2PROM_CSR: EEPROM control register. - * RELOAD: Write 1 to reload eeprom content. - * TYPE: 0: 93c46, 1:93c66. - * LOAD_STATUS: 1:loading, 0:done. - */ -#define E2PROM_CSR 0x0004 -#define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001) -#define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002) -#define E2PROM_CSR_DATA_IN FIELD32(0x00000004) -#define E2PROM_CSR_DATA_OUT FIELD32(0x00000008) -#define E2PROM_CSR_TYPE FIELD32(0x00000030) -#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) -#define E2PROM_CSR_RELOAD FIELD32(0x00000080) - -/* * Queue register offset macros */ #define TX_QUEUE_REG_OFFSET 0x10 diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 0f8b84b7224..5a2dfe87c6b 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -28,7 +28,6 @@ Supported chipsets: RT2800U. */ -#include <linux/crc-ccitt.h> #include <linux/delay.h> #include <linux/etherdevice.h> #include <linux/init.h> @@ -45,7 +44,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 1; +static int modparam_nohwcrypt = 0; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -57,84 +56,10 @@ static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) return FIRMWARE_RT2870; } -static bool rt2800usb_check_crc(const u8 *data, const size_t len) -{ - u16 fw_crc; - u16 crc; - - /* - * The last 2 bytes in the firmware array are the crc checksum itself, - * this means that we should never pass those 2 bytes to the crc - * algorithm. - */ - fw_crc = (data[len - 2] << 8 | data[len - 1]); - - /* - * Use the crc ccitt algorithm. - * This will return the same value as the legacy driver which - * used bit ordering reversion on the both the firmware bytes - * before input input as well as on the final output. - * Obviously using crc ccitt directly is much more efficient. - */ - crc = crc_ccitt(~0, data, len - 2); - - /* - * There is a small difference between the crc-itu-t + bitrev and - * the crc-ccitt crc calculation. In the latter method the 2 bytes - * will be swapped, use swab16 to convert the crc to the correct - * value. - */ - crc = swab16(crc); - - return fw_crc == crc; -} - -static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev, +static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len) { - size_t offset = 0; - - /* - * Firmware files: - * There are 2 variations of the rt2870 firmware. - * a) size: 4kb - * b) size: 8kb - * Note that (b) contains 2 separate firmware blobs of 4k - * within the file. The first blob is the same firmware as (a), - * but the second blob is for the additional chipsets. - */ - if (len != 4096 && len != 8192) - return FW_BAD_LENGTH; - - /* - * Check if we need the upper 4kb firmware data or not. - */ - if ((len == 4096) && - !rt2x00_rt(rt2x00dev, RT2860) && - !rt2x00_rt(rt2x00dev, RT2872) && - !rt2x00_rt(rt2x00dev, RT3070)) - return FW_BAD_VERSION; - - /* - * 8kb firmware files must be checked as if it were - * 2 separate firmware files. - */ - while (offset < len) { - if (!rt2800usb_check_crc(data + offset, 4096)) - return FW_BAD_CRC; - - offset += 4096; - } - - return FW_OK; -} - -static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, - const u8 *data, const size_t len) -{ - unsigned int i; int status; - u32 reg; u32 offset; u32 length; @@ -152,28 +77,10 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, } /* - * Wait for stable hardware. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); - return -EBUSY; - } - - /* * Write firmware to device. */ - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, - FIRMWARE_IMAGE_BASE, - data + offset, length, - REGISTER_TIMEOUT32(length)); + rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, + data + offset, length); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); @@ -196,7 +103,7 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, /* * Send signal to firmware during boot time. */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || @@ -206,28 +113,6 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, udelay(10); } - /* - * Wait for device to stabilize. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); - if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY)) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "PBF system register not ready.\n"); - return -EBUSY; - } - - /* - * Initialize firmware. - */ - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); - msleep(1); - return 0; } @@ -246,6 +131,44 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); } +static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + int i; + + /* + * Wait until BBP and RF are ready. + */ + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (reg && reg != ~0) + break; + msleep(1); + } + + if (i == REGISTER_BUSY_COUNT) { + ERROR(rt2x00dev, "Unstable hardware.\n"); + return -EBUSY; + } + + rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); + rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); + + rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, + USB_MODE_RESET, REGISTER_TIMEOUT); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + + return 0; +} + static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; @@ -371,7 +294,9 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: @@ -395,25 +320,29 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ +static void rt2800usb_write_tx_data(struct queue_entry* entry, + struct txentry_desc *txdesc) +{ + __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); + + rt2800_write_txwi(txwi, txdesc); +} + + static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE); + __le32 *txi = (__le32 *) skb->data; u32 word; /* - * Initialize TXWI descriptor - */ - rt2800_write_txwi(skb, txdesc); - - /* * Initialize TXINFO descriptor */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len + TXWI_DESC_SIZE); + skb->len - TXINFO_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); @@ -426,6 +355,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * Register descriptor details in skb frame descriptor. */ + skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = txi; skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; } @@ -433,51 +363,6 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * TX data initialization */ -static void rt2800usb_write_beacon(struct queue_entry *entry, - struct txentry_desc *txdesc) -{ - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - unsigned int beacon_base; - u32 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, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - /* - * Add the TXWI for the beacon to the skb. - */ - rt2800_write_txwi(entry->skb, txdesc); - skb_push(entry->skb, TXWI_DESC_SIZE); - - /* - * Write entire beacon with descriptor to register. - */ - beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, beacon_base, - entry->skb->data, entry->skb->len, - REGISTER_TIMEOUT32(entry->skb->len)); - - /* - * Enable beaconing again. - */ - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - /* - * Clean up the beacon skb. - */ - dev_kfree_skb(entry->skb); - entry->skb = NULL; -} - static int rt2800usb_get_tx_data_len(struct queue_entry *entry) { int length; @@ -568,7 +453,7 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, /* * Process the RXWI structure. */ - rt2800_process_rxwi(entry->skb, rxdesc); + rt2800_process_rxwi(entry, rxdesc); } /* @@ -585,24 +470,10 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) return rt2800_validate_eeprom(rt2x00dev); } -static const struct rt2800_ops rt2800usb_rt2800_ops = { - .register_read = rt2x00usb_register_read, - .register_read_lock = rt2x00usb_register_read_lock, - .register_write = rt2x00usb_register_write, - .register_write_lock = rt2x00usb_register_write_lock, - - .register_multiread = rt2x00usb_register_multiread, - .register_multiwrite = rt2x00usb_register_multiwrite, - - .regbusy_read = rt2x00usb_regbusy_read, -}; - static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; - rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops; - /* * Allocate eeprom data. */ @@ -635,6 +506,8 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); /* * Set the rssi offset. @@ -644,11 +517,45 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) return 0; } +static const struct ieee80211_ops rt2800usb_mac80211_ops = { + .tx = rt2x00mac_tx, + .start = rt2x00mac_start, + .stop = rt2x00mac_stop, + .add_interface = rt2x00mac_add_interface, + .remove_interface = rt2x00mac_remove_interface, + .config = rt2x00mac_config, + .configure_filter = rt2x00mac_configure_filter, + .set_tim = rt2x00mac_set_tim, + .set_key = rt2x00mac_set_key, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, + .get_stats = rt2x00mac_get_stats, + .get_tkip_seq = rt2800_get_tkip_seq, + .set_rts_threshold = rt2800_set_rts_threshold, + .bss_info_changed = rt2x00mac_bss_info_changed, + .conf_tx = rt2800_conf_tx, + .get_tsf = rt2800_get_tsf, + .rfkill_poll = rt2x00mac_rfkill_poll, + .ampdu_action = rt2800_ampdu_action, +}; + +static const struct rt2800_ops rt2800usb_rt2800_ops = { + .register_read = rt2x00usb_register_read, + .register_read_lock = rt2x00usb_register_read_lock, + .register_write = rt2x00usb_register_write, + .register_write_lock = rt2x00usb_register_write_lock, + .register_multiread = rt2x00usb_register_multiread, + .register_multiwrite = rt2x00usb_register_multiwrite, + .regbusy_read = rt2x00usb_regbusy_read, + .drv_write_firmware = rt2800usb_write_firmware, + .drv_init_registers = rt2800usb_init_registers, +}; + static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .probe_hw = rt2800usb_probe_hw, .get_firmware_name = rt2800usb_get_firmware_name, - .check_firmware = rt2800usb_check_firmware, - .load_firmware = rt2800usb_load_firmware, + .check_firmware = rt2800_check_firmware, + .load_firmware = rt2800_load_firmware, .initialize = rt2x00usb_initialize, .uninitialize = rt2x00usb_uninitialize, .clear_entry = rt2x00usb_clear_entry, @@ -657,9 +564,10 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_stats = rt2800_link_stats, .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, + .watchdog = rt2x00usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2x00usb_write_tx_data, - .write_beacon = rt2800usb_write_beacon, + .write_tx_data = rt2800usb_write_tx_data, + .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, .kill_tx_queue = rt2x00usb_kill_tx_queue, @@ -706,7 +614,8 @@ static const struct rt2x00_ops rt2800usb_ops = { .tx = &rt2800usb_queue_tx, .bcn = &rt2800usb_queue_bcn, .lib = &rt2800usb_rt2x00_ops, - .hw = &rt2800_mac80211_ops, + .drv = &rt2800usb_rt2800_ops, + .hw = &rt2800usb_mac80211_ops, #ifdef CONFIG_RT2X00_LIB_DEBUGFS .debugfs = &rt2800_rt2x00debug, #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index 2bca6a71a7f..0722badccf8 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h @@ -32,43 +32,6 @@ #define RT2800USB_H /* - * USB registers. - */ - -/* - * USB_DMA_CFG - * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns. - * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes. - * PHY_CLEAR: phy watch dog enable. - * TX_CLEAR: Clear USB DMA TX path. - * TXOP_HALT: Halt TXOP count down when TX buffer is full. - * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation. - * RX_BULK_EN: Enable USB DMA Rx. - * TX_BULK_EN: Enable USB DMA Tx. - * EP_OUT_VALID: OUT endpoint data valid. - * RX_BUSY: USB DMA RX FSM busy. - * TX_BUSY: USB DMA TX FSM busy. - */ -#define USB_DMA_CFG 0x02a0 -#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff) -#define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00) -#define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000) -#define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000) -#define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000) -#define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000) -#define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000) -#define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000) -#define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000) -#define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000) -#define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000) - -/* - * USB_CYC_CFG - */ -#define USB_CYC_CFG 0x02a4 -#define USB_CYC_CFG_CLOCK_CYCLE FIELD32(0x000000ff) - -/* * 8051 firmware image. */ #define FIRMWARE_RT2870 "rt2870.bin" diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6c1ff4c15c8..c21af38cc5a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -39,6 +39,7 @@ #include <net/mac80211.h> #include "rt2x00debug.h" +#include "rt2x00dump.h" #include "rt2x00leds.h" #include "rt2x00reg.h" #include "rt2x00queue.h" @@ -159,6 +160,7 @@ struct avg_val { enum rt2x00_chip_intf { RT2X00_CHIP_INTF_PCI, + RT2X00_CHIP_INTF_PCIE, RT2X00_CHIP_INTF_USB, RT2X00_CHIP_INTF_SOC, }; @@ -175,8 +177,7 @@ struct rt2x00_chip { #define RT2570 0x2570 #define RT2661 0x2661 #define RT2573 0x2573 -#define RT2860 0x2860 /* 2.4GHz PCI/CB */ -#define RT2870 0x2870 +#define RT2860 0x2860 /* 2.4GHz */ #define RT2872 0x2872 /* WSOC */ #define RT2883 0x2883 /* WSOC */ #define RT3070 0x3070 @@ -331,6 +332,11 @@ struct link { * Work structure for scheduling periodic link tuning. */ struct delayed_work work; + + /* + * Work structure for scheduling periodic watchdog monitoring. + */ + struct delayed_work watchdog_work; }; /* @@ -509,6 +515,11 @@ struct rt2x00lib_ops { irq_handler_t irq_handler; /* + * Threaded Interrupt handlers. + */ + irq_handler_t irq_handler_thread; + + /* * Device init handlers. */ int (*probe_hw) (struct rt2x00_dev *rt2x00dev); @@ -542,6 +553,7 @@ struct rt2x00lib_ops { struct link_qual *qual); void (*link_tuner) (struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); + void (*watchdog) (struct rt2x00_dev *rt2x00dev); /* * TX control handlers @@ -549,8 +561,8 @@ struct rt2x00lib_ops { void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc); - int (*write_tx_data) (struct queue_entry *entry, - struct txentry_desc *txdesc); + void (*write_tx_data) (struct queue_entry *entry, + struct txentry_desc *txdesc); void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); int (*get_tx_data_len) (struct queue_entry *entry); @@ -609,6 +621,7 @@ struct rt2x00_ops { const struct data_queue_desc *bcn; const struct data_queue_desc *atim; const struct rt2x00lib_ops *lib; + const void *drv; const struct ieee80211_ops *hw; #ifdef CONFIG_RT2X00_LIB_DEBUGFS const struct rt2x00debug *debugfs; @@ -627,6 +640,7 @@ enum rt2x00_flags { DEVICE_STATE_INITIALIZED, DEVICE_STATE_STARTED, DEVICE_STATE_ENABLED_RADIO, + DEVICE_STATE_SCANNING, /* * Driver requirements @@ -645,6 +659,9 @@ enum rt2x00_flags { CONFIG_SUPPORT_HW_CRYPTO, DRIVER_SUPPORT_CONTROL_FILTERS, DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, + DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, + DRIVER_SUPPORT_LINK_TUNING, + DRIVER_SUPPORT_WATCHDOG, /* * Driver configuration @@ -654,7 +671,6 @@ enum rt2x00_flags { CONFIG_EXTERNAL_LNA_A, CONFIG_EXTERNAL_LNA_BG, CONFIG_DOUBLE_ANTENNA, - CONFIG_DISABLE_LINK_TUNING, CONFIG_CHANNEL_HT40, }; @@ -862,9 +878,10 @@ struct rt2x00_dev { const struct firmware *fw; /* - * Driver specific data. + * Interrupt values, stored between interrupt service routine + * and interrupt thread routine. */ - void *priv; + u32 irqvalue[2]; }; /* @@ -978,7 +995,13 @@ static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev, static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev) { - return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); + return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI) || + rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); +} + +static inline bool rt2x00_is_pcie(struct rt2x00_dev *rt2x00dev) +{ + return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); } static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev) @@ -999,6 +1022,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); /** + * rt2x00queue_unmap_skb - Unmap a skb from DMA. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @skb: The skb to unmap. + */ +void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); + +/** * rt2x00queue_get_queue - Convert queue index to queue pointer * @rt2x00dev: Pointer to &struct rt2x00_dev. * @queue: rt2x00 queue index (see &enum data_queue_qid). @@ -1015,9 +1045,30 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index); /* + * Debugfs handlers. + */ +/** + * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @type: The type of frame that is being dumped. + * @skb: The skb containing the frame to be dumped. + */ +#ifdef CONFIG_RT2X00_LIB_DEBUGFS +void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + enum rt2x00_dump_type type, struct sk_buff *skb); +#else +static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + enum rt2x00_dump_type type, + struct sk_buff *skb) +{ +} +#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ + +/* * Interrupt context handlers. */ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, @@ -1047,6 +1098,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, #else #define rt2x00mac_set_key NULL #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw); +void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw); int rt2x00mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 098315a271c..953dc4f2c6a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -41,10 +41,12 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, switch (type) { case NL80211_IFTYPE_ADHOC: + conf.sync = TSF_SYNC_ADHOC; + break; case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_WDS: - conf.sync = TSF_SYNC_BEACON; + conf.sync = TSF_SYNC_AP_NONE; break; case NL80211_IFTYPE_STATION: conf.sync = TSF_SYNC_INFRA; @@ -170,23 +172,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, unsigned int ieee80211_flags) { struct rt2x00lib_conf libconf; + u16 hw_value; memset(&libconf, 0, sizeof(libconf)); libconf.conf = conf; if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { - if (conf_is_ht40(conf)) + if (conf_is_ht40(conf)) { __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); - else + hw_value = rt2x00ht_center_channel(rt2x00dev, conf); + } else { __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); + hw_value = conf->channel->hw_value; + } memcpy(&libconf.rf, - &rt2x00dev->spec.channels[conf->channel->hw_value], + &rt2x00dev->spec.channels[hw_value], sizeof(libconf.rf)); memcpy(&libconf.channel, - &rt2x00dev->spec.channels_info[conf->channel->hw_value], + &rt2x00dev->spec.channels_info[hw_value], sizeof(libconf.channel)); } diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index e9fe93fd804..b0498e7e7aa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -211,6 +211,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) skb_queue_purge(&intf->frame_dump_skbqueue); } +EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame); static int rt2x00debug_file_open(struct inode *inode, struct file *file) { diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 3ae468c4d76..585e8166f22 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -70,6 +70,11 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); /* + * Start watchdog monitoring. + */ + rt2x00link_start_watchdog(rt2x00dev); + + /* * Start the TX queues. */ ieee80211_wake_queues(rt2x00dev->hw); @@ -89,6 +94,11 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00queue_stop_queues(rt2x00dev); /* + * Stop watchdog monitoring. + */ + rt2x00link_stop_watchdog(rt2x00dev); + + /* * Disable RX. */ rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); @@ -168,10 +178,32 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) /* * Interrupt context handlers. */ -static void rt2x00lib_beacondone_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) +static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) { - struct rt2x00_intf *intf = vif_to_intf(vif); + struct rt2x00_dev *rt2x00dev = data; + struct sk_buff *skb; + + /* + * Only AP mode interfaces do broad- and multicast buffering + */ + if (vif->type != NL80211_IFTYPE_AP) + return; + + /* + * Send out buffered broad- and multicast frames + */ + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + while (skb) { + rt2x00mac_tx(rt2x00dev->hw, skb); + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + } +} + +static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rt2x00_dev *rt2x00dev = data; if (vif->type != NL80211_IFTYPE_AP && vif->type != NL80211_IFTYPE_ADHOC && @@ -179,9 +211,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac, vif->type != NL80211_IFTYPE_WDS) return; - spin_lock(&intf->lock); - intf->delayed_flags |= DELAYED_UPDATE_BEACON; - spin_unlock(&intf->lock); + rt2x00queue_update_beacon(rt2x00dev, vif, true); } void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) @@ -189,14 +219,37 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return; - ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, - rt2x00lib_beacondone_iter, - rt2x00dev); + /* send buffered bc/mc frames out for every bssid */ + ieee80211_iterate_active_interfaces(rt2x00dev->hw, + rt2x00lib_bc_buffer_iter, + rt2x00dev); + /* + * Devices with pre tbtt interrupt don't need to update the beacon + * here as they will fetch the next beacon directly prior to + * transmission. + */ + if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags)) + return; - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); + /* fetch next beacon */ + ieee80211_iterate_active_interfaces(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); +void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) +{ + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + /* fetch next beacon */ + ieee80211_iterate_active_interfaces(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); +} +EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); + void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc) { @@ -216,6 +269,16 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00queue_unmap_skb(rt2x00dev, entry->skb); /* + * Remove the extra tx headroom from the skb. + */ + skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom); + + /* + * Signal that the TX descriptor is no longer in the skb. + */ + skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; + + /* * Remove L2 padding which was added during */ if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) @@ -224,7 +287,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * If the IV/EIV data was stripped from the frame before it was * passed to the hardware, we should now reinsert it again because - * mac80211 will expect the the same data to be present it the + * mac80211 will expect the same data to be present it the * frame as it was passed to us. */ if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) @@ -241,8 +304,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, */ success = test_bit(TXDONE_SUCCESS, &txdesc->flags) || - test_bit(TXDONE_UNKNOWN, &txdesc->flags) || - test_bit(TXDONE_FALLBACK, &txdesc->flags); + test_bit(TXDONE_UNKNOWN, &txdesc->flags); /* * Update TX statistics. @@ -264,11 +326,22 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * Frame was send with retries, hardware tried * different rates to send out the frame, at each - * retry it lowered the rate 1 step. + * retry it lowered the rate 1 step except when the + * lowest rate was used. */ for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) { tx_info->status.rates[i].idx = rate_idx - i; tx_info->status.rates[i].flags = rate_flags; + + if (rate_idx - i == 0) { + /* + * The lowest rate (index 0) was used until the + * number of max retries was reached. + */ + tx_info->status.rates[i].count = retry_rates - i; + i++; + break; + } tx_info->status.rates[i].count = 1; } if (i < (IEEE80211_TX_MAX_RATES - 1)) @@ -281,6 +354,21 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00dev->low_level_stats.dot11ACKFailureCount++; } + /* + * Every single frame has it's own tx status, hence report + * every frame as ampdu of size 1. + * + * TODO: if we can find out how many frames were aggregated + * by the hw we could provide the real ampdu_len to mac80211 + * which would allow the rc algorithm to better decide on + * which rates are suitable. + */ + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + tx_info->status.ampdu_len = 1; + tx_info->status.ampdu_ack_len = success ? 1 : 0; + } + if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { if (success) rt2x00dev->low_level_stats.dot11RTSSuccessCount++; @@ -295,9 +383,17 @@ void rt2x00lib_txdone(struct queue_entry *entry, * send the status report back. */ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); + /* + * Only PCI and SOC devices process the tx status in process + * context. Hence use ieee80211_tx_status for PCI and SOC + * devices and stick to ieee80211_tx_status_irqsafe for USB. + */ + if (rt2x00_is_usb(rt2x00dev)) + ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); + else + ieee80211_tx_status(rt2x00dev->hw, entry->skb); else - dev_kfree_skb_irq(entry->skb); + dev_kfree_skb_any(entry->skb); /* * Make this entry available for reuse. @@ -444,7 +540,16 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, */ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); - ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); + + /* + * Currently only PCI and SOC devices handle rx interrupts in process + * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni + * for PCI and SOC devices. + */ + if (rt2x00_is_usb(rt2x00dev)) + ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); + else + ieee80211_rx_ni(rt2x00dev->hw, entry->skb); /* * Replace the skb with the freshly allocated one. @@ -854,6 +959,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) BIT(NL80211_IFTYPE_WDS); /* + * Initialize configuration work. + */ + INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); + + /* * Let the driver probe the device to detect the capabilities. */ retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); @@ -863,11 +973,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) } /* - * Initialize configuration work. - */ - INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); - - /* * Allocate queue array. */ retval = rt2x00queue_allocate(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index ed303b423e4..5d6e0b83151 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h @@ -20,7 +20,12 @@ /* Module: rt2x00dump - Abstract: Data structures for the rt2x00debug & userspace. + Abstract: + Data structures for the rt2x00debug & userspace. + + The declarations in this file can be used by both rt2x00 + and userspace and therefore should be kept together in + this file. */ #ifndef RT2X00DUMP_H @@ -111,7 +116,7 @@ struct rt2x00dump_hdr { __le16 chip_rt; __le16 chip_rf; - __le32 chip_rev; + __le16 chip_rev; __le16 type; __u8 queue_index; diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 5a407602ce3..c004cd3a884 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -44,11 +44,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, txdesc->mpdu_density = 0; txdesc->ba_size = 7; /* FIXME: What value is needed? */ - txdesc->stbc = 0; /* FIXME: What value is needed? */ - txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); - if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - txdesc->mcs |= 0x08; + txdesc->stbc = + (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; + + /* + * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the + * mcs rate to be used + */ + if (txrate->flags & IEEE80211_TX_RC_MCS) { + txdesc->mcs = txrate->idx; + } else { + txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); + if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + txdesc->mcs |= 0x08; + } + /* * Convert flags @@ -84,3 +95,31 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, else txdesc->txop = TXOP_HTTXOP; } + +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf) +{ + struct hw_mode_spec *spec = &rt2x00dev->spec; + int center_channel; + u16 i; + + /* + * Initialize center channel to current channel. + */ + center_channel = spec->channels[conf->channel->hw_value].channel; + + /* + * Adjust center channel to HT40+ and HT40- operation. + */ + if (conf_is_ht40_plus(conf)) + center_channel += 2; + else if (conf_is_ht40_minus(conf)) + center_channel -= (center_channel == 14) ? 1 : 2; + + for (i = 0; i < spec->num_channels; i++) + if (spec->channels[i].channel == center_channel) + return i; + + WARN_ON(1); + return conf->channel->hw_value; +} diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index be2e37fb407..dc5c6574aaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -27,11 +27,10 @@ #ifndef RT2X00LIB_H #define RT2X00LIB_H -#include "rt2x00dump.h" - /* * Interval defines */ +#define WATCHDOG_INTERVAL round_jiffies_relative(HZ) #define LINK_TUNE_INTERVAL round_jiffies_relative(HZ) /* @@ -107,13 +106,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry); /** - * rt2x00queue_unmap_skb - Unmap a skb from DMA. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to unmap. - */ -void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); - -/** * rt2x00queue_free_skb - free a skb * @rt2x00dev: Pointer to &struct rt2x00_dev. * @skb: The skb to free. @@ -266,11 +258,30 @@ void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev); void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna); /** - * rt2x00link_register - Initialize link tuning functionality + * rt2x00link_start_watchdog - Start periodic watchdog monitoring + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * This start the watchdog periodic work, this work will + *be executed periodically until &rt2x00link_stop_watchdog has + * been called. + */ +void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00link_stop_watchdog - Stop periodic watchdog monitoring * @rt2x00dev: Pointer to &struct rt2x00_dev. * - * Initialize work structure and all link tuning related - * parameters. This will not start the link tuning process itself. + * After this function completed the watchdog monitoring will not + * be running until &rt2x00link_start_watchdog is called. + */ +void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00link_register - Initialize link tuning & watchdog functionality + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * + * Initialize work structure and all link tuning and watchdog related + * parameters. This will not start the periodic work itself. */ void rt2x00link_register(struct rt2x00_dev *rt2x00dev); @@ -296,8 +307,6 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2X00_LIB_DEBUGFS void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); -void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, - enum rt2x00_dump_type type, struct sk_buff *skb); void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, struct rxdone_entry_desc *rxdesc); #else @@ -309,12 +318,6 @@ static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) { } -static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, - enum rt2x00_dump_type type, - struct sk_buff *skb) -{ -} - static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, struct rxdone_entry_desc *rxdesc) { @@ -384,12 +387,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc, const struct rt2x00_rate *hwrate); + +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf); #else static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc, const struct rt2x00_rate *hwrate) { } + +static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf) +{ + return conf->channel->hw_value; +} #endif /* CONFIG_RT2X00_LIB_HT */ /* diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 0efbf5a6c25..666cef3f847 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -271,11 +271,20 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) /* * Link tuning should only be performed when - * an active sta or master interface exists. - * Single monitor mode interfaces should never have - * work with link tuners. + * an active sta interface exists. AP interfaces + * don't need link tuning and monitor mode interfaces + * should never have to work with link tuners. */ - if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) + if (!rt2x00dev->intf_sta_count) + return; + + /** + * While scanning, link tuning is disabled. By default + * the most sensitive settings will be used to make sure + * that all beacons and probe responses will be recieved + * during the scan. + */ + if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) return; rt2x00link_reset_tuner(rt2x00dev, false); @@ -293,6 +302,7 @@ void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) { struct link_qual *qual = &rt2x00dev->link.qual; + u8 vgc_level = qual->vgc_level_reg; if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return; @@ -309,6 +319,13 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) memset(qual, 0, sizeof(*qual)); /* + * Restore the VGC level as stored in the registers, + * the driver can use this to determine if the register + * must be updated during reset or not. + */ + qual->vgc_level_reg = vgc_level; + + /* * Reset the link tuner. */ rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual); @@ -338,7 +355,8 @@ static void rt2x00link_tuner(struct work_struct *work) * When the radio is shutting down we should * immediately cease all link tuning. */ - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || + test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) return; /* @@ -359,10 +377,11 @@ static void rt2x00link_tuner(struct work_struct *work) qual->rssi = link->avg_rssi.avg; /* - * Only perform the link tuning when Link tuning - * has been enabled (This could have been disabled from the EEPROM). + * Check if link tuning is supported by the hardware, some hardware + * do not support link tuning at all, while other devices can disable + * the feature from the EEPROM. */ - if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) + if (test_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags)) rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); /* @@ -388,7 +407,45 @@ static void rt2x00link_tuner(struct work_struct *work) &link->work, LINK_TUNE_INTERVAL); } +void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) +{ + struct link *link = &rt2x00dev->link; + + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || + !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) + return; + + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->watchdog_work, WATCHDOG_INTERVAL); +} + +void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) +{ + cancel_delayed_work_sync(&rt2x00dev->link.watchdog_work); +} + +static void rt2x00link_watchdog(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, link.watchdog_work.work); + struct link *link = &rt2x00dev->link; + + /* + * When the radio is shutting down we should + * immediately cease the watchdog monitoring. + */ + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + rt2x00dev->ops->lib->watchdog(rt2x00dev); + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->watchdog_work, WATCHDOG_INTERVAL); +} + void rt2x00link_register(struct rt2x00_dev *rt2x00dev) { + INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index abbd857ec75..235e037e650 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -273,16 +273,24 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, mutex_init(&intf->beacon_skb_mutex); intf->beacon = entry; - if (vif->type == NL80211_IFTYPE_AP) - memcpy(&intf->bssid, vif->addr, ETH_ALEN); - memcpy(&intf->mac, vif->addr, ETH_ALEN); - /* * The MAC adddress must be configured after the device * has been initialized. Otherwise the device can reset * the MAC registers. + * The BSSID address must only be configured in AP mode, + * however we should not send an empty BSSID address for + * STA interfaces at this time, since this can cause + * invalid behavior in the device. */ - rt2x00lib_config_intf(rt2x00dev, intf, vif->type, intf->mac, NULL); + memcpy(&intf->mac, vif->addr, ETH_ALEN); + if (vif->type == NL80211_IFTYPE_AP) { + memcpy(&intf->bssid, vif->addr, ETH_ALEN); + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, + intf->mac, intf->bssid); + } else { + rt2x00lib_config_intf(rt2x00dev, intf, vif->type, + intf->mac, NULL); + } /* * Some filters depend on the current working mode. We can force @@ -346,9 +354,11 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) /* * Some configuration parameters (e.g. channel and antenna values) can * only be set when the radio is enabled, but do require the RX to - * be off. + * be off. During this period we should keep link tuning enabled, + * if for any reason the link tuner must be reset, this will be + * handled by rt2x00lib_config(). */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); /* * When we've just turned on the radio, we want to reprogram @@ -366,7 +376,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ - rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); return 0; } @@ -430,12 +440,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); +static void rt2x00mac_set_tim_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rt2x00_intf *intf = vif_to_intf(vif); + + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_ADHOC && + vif->type != NL80211_IFTYPE_MESH_POINT && + vif->type != NL80211_IFTYPE_WDS) + return; + + spin_lock(&intf->lock); + intf->delayed_flags |= DELAYED_UPDATE_BEACON; + spin_unlock(&intf->lock); +} + int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { struct rt2x00_dev *rt2x00dev = hw->priv; - rt2x00lib_beacondone(rt2x00dev); + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return 0; + + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00mac_set_tim_iter, + rt2x00dev); + + /* queue work to upodate the beacon template */ + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); return 0; } EXPORT_SYMBOL_GPL(rt2x00mac_set_tim); @@ -539,6 +573,22 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, EXPORT_SYMBOL_GPL(rt2x00mac_set_key); #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + __set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); + rt2x00link_stop_tuner(rt2x00dev); +} +EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start); + +void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + __clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags); + rt2x00link_start_tuner(rt2x00dev); +} +EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete); + int rt2x00mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { @@ -562,7 +612,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, { struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_intf *intf = vif_to_intf(vif); - int update_bssid = 0; /* * mac80211 might be calling this function while we are trying @@ -577,10 +626,8 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, * conf->bssid can be NULL if coming from the internal * beacon update routine. */ - if (changes & BSS_CHANGED_BSSID) { - update_bssid = 1; + if (changes & BSS_CHANGED_BSSID) memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN); - } spin_unlock(&intf->lock); @@ -592,7 +639,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, */ if (changes & BSS_CHANGED_BSSID) rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, - update_bssid ? bss_conf->bssid : NULL); + bss_conf->bssid); /* * Update the beacon. diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index f71eee67f97..19b262e1ddb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -60,34 +60,6 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); -/* - * TX data handlers. - */ -int rt2x00pci_write_tx_data(struct queue_entry *entry, - struct txentry_desc *txdesc) -{ - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - - /* - * This should not happen, we already checked the entry - * was ours. When the hardware disagrees there has been - * a queue corruption! - */ - if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) { - ERROR(rt2x00dev, - "Corrupt queue %d, accessing entry which is not ours.\n" - "Please file bug report to %s.\n", - entry->queue->qid, DRV_PROJECT); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); - -/* - * TX/RX data handlers. - */ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue = rt2x00dev->rx; @@ -181,8 +153,10 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) /* * Register interrupt handler. */ - status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler, - IRQF_SHARED, rt2x00dev->name, rt2x00dev); + status = request_threaded_irq(rt2x00dev->irq, + rt2x00dev->ops->lib->irq_handler, + rt2x00dev->ops->lib->irq_handler_thread, + IRQF_SHARED, rt2x00dev->name, rt2x00dev); if (status) { ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", rt2x00dev->irq, status); @@ -305,7 +279,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) rt2x00dev->irq = pci_dev->irq; rt2x00dev->name = pci_name(pci_dev); - rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); + if (pci_dev->is_pcie) + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); + else + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); retval = rt2x00pci_alloc_reg(rt2x00dev); if (retval) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 51bcef3839c..b854d62ff99 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -86,16 +86,6 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, u32 *reg); /** - * rt2x00pci_write_tx_data - Initialize data for TX operation - * @entry: The entry where the frame is located - * - * This function will initialize the DMA and skb descriptor - * to prepare the entry for the actual TX operation. - */ -int rt2x00pci_write_tx_data(struct queue_entry *entry, - struct txentry_desc *txdesc); - -/** * struct queue_entry_priv_pci: Per entry PCI specific information * * @desc: Pointer to device descriptor diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 20dbdd6fb90..a3401d30105 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -100,21 +100,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - /* - * If device has requested headroom, we should make sure that - * is also mapped to the DMA so it can be used for transfering - * additional descriptor information to the hardware. - */ - skb_push(skb, rt2x00dev->ops->extra_tx_headroom); - skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); - - /* - * Restore data pointer to original location again. - */ - skb_pull(skb, rt2x00dev->ops->extra_tx_headroom); - skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; } EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); @@ -130,16 +117,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) } if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { - /* - * Add headroom to the skb length, it has been removed - * by the driver, but it was actually mapped to DMA. - */ - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, - skb->len + rt2x00dev->ops->extra_tx_headroom, + dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, DMA_TO_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; } } +EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) { @@ -370,13 +353,18 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Check if more fragments are pending */ - if (ieee80211_has_morefrags(hdr->frame_control) || - (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)) { + if (ieee80211_has_morefrags(hdr->frame_control)) { __set_bit(ENTRY_TXD_BURST, &txdesc->flags); __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); } /* + * Check if more frames (!= fragments) are pending + */ + if (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES) + __set_bit(ENTRY_TXD_BURST, &txdesc->flags); + + /* * 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 @@ -416,12 +404,51 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); } +static int rt2x00queue_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + + /* + * This should not happen, we already checked the entry + * was ours. When the hardware disagrees there has been + * a queue corruption! + */ + if (unlikely(rt2x00dev->ops->lib->get_entry_state && + rt2x00dev->ops->lib->get_entry_state(entry))) { + ERROR(rt2x00dev, + "Corrupt queue %d, accessing entry which is not ours.\n" + "Please file bug report to %s.\n", + entry->queue->qid, DRV_PROJECT); + return -EINVAL; + } + + /* + * Add the requested extra tx headroom in front of the skb. + */ + skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom); + memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom); + + /* + * Call the driver's write_tx_data function, if it exists. + */ + if (rt2x00dev->ops->lib->write_tx_data) + rt2x00dev->ops->lib->write_tx_data(entry, txdesc); + + /* + * Map the skb to DMA. + */ + if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) + rt2x00queue_map_txskb(rt2x00dev, entry->skb); + + return 0; +} + static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { struct data_queue *queue = entry->queue; struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - enum rt2x00_dump_type dump_type; rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); @@ -429,9 +456,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, * All processing on the frame has been completed, this means * it is now ready to be dumped to userspace through debugfs. */ - dump_type = (txdesc->queue == QID_BEACON) ? - DUMP_FRAME_BEACON : DUMP_FRAME_TX; - rt2x00debug_dump_frame(rt2x00dev, dump_type, entry->skb); + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); } static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, @@ -530,16 +555,12 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * call failed. Since we always return NETDEV_TX_OK to mac80211, * this frame will simply be dropped. */ - if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry, - &txdesc))) { + if (unlikely(rt2x00queue_write_tx_data(entry, &txdesc))) { clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); entry->skb = NULL; return -EIO; } - if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) - rt2x00queue_map_txskb(queue->rt2x00dev, skb); - set_bit(ENTRY_DATA_PENDING, &entry->flags); rt2x00queue_index_inc(queue, Q_INDEX); @@ -595,11 +616,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, skbdesc->entry = intf->beacon; /* - * Write TX descriptor into reserved room in front of the beacon. - */ - rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); - - /* * Send beacon to hardware and enable beacon genaration.. */ rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); @@ -672,9 +688,11 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) if (index == Q_INDEX) { queue->length++; + queue->last_index = jiffies; } else if (index == Q_INDEX_DONE) { queue->length--; queue->count++; + queue->last_index_done = jiffies; } spin_unlock_irqrestore(&queue->lock, irqflags); @@ -688,6 +706,8 @@ static void rt2x00queue_reset(struct data_queue *queue) queue->count = 0; queue->length = 0; + queue->last_index = jiffies; + queue->last_index_done = jiffies; memset(queue->index, 0, sizeof(queue->index)); spin_unlock_irqrestore(&queue->lock, irqflags); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index f79170849ad..191e7775a9c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -213,9 +213,16 @@ struct rxdone_entry_desc { /** * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc * + * Every txdone report has to contain the basic result of the + * transmission, either &TXDONE_UNKNOWN, &TXDONE_SUCCESS or + * &TXDONE_FAILURE. The flag &TXDONE_FALLBACK can be used in + * conjunction with all of these flags but should only be set + * if retires > 0. The flag &TXDONE_EXCESSIVE_RETRY can only be used + * in conjunction with &TXDONE_FAILURE. + * * @TXDONE_UNKNOWN: Hardware could not determine success of transmission. * @TXDONE_SUCCESS: Frame was successfully send - * @TXDONE_FALLBACK: Frame was successfully send using a fallback rate. + * @TXDONE_FALLBACK: Hardware used fallback rates for retries * @TXDONE_FAILURE: Frame was not successfully send * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the * frame transmission failed due to excessive retries. @@ -439,6 +446,8 @@ struct data_queue { enum data_queue_qid qid; spinlock_t lock; + unsigned long last_index; + unsigned long last_index_done; unsigned int count; unsigned short limit; unsigned short threshold; @@ -592,6 +601,15 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** + * rt2x00queue_timeout - Check if a timeout occured for this queue + * @queue: Queue to check. + */ +static inline int rt2x00queue_timeout(struct data_queue *queue) +{ + return time_after(queue->last_index, queue->last_index_done + (HZ / 10)); +} + +/** * _rt2x00_desc_read - Read a word from the hardware descriptor. * @desc: Base descriptor address * @word: Word index from where the descriptor should be read. diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index b9fe94873ee..cef94621cef 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -63,7 +63,8 @@ enum led_mode { enum tsf_sync { TSF_SYNC_NONE = 0, TSF_SYNC_INFRA = 1, - TSF_SYNC_BEACON = 2, + TSF_SYNC_ADHOC = 2, + TSF_SYNC_AP_NONE = 3, }; /* @@ -88,6 +89,8 @@ enum dev_state { STATE_RADIO_RX_OFF_LINK, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, + STATE_RADIO_IRQ_ON_ISR, + STATE_RADIO_IRQ_OFF_ISR, }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index bd1546ba7ad..ff3a36622d1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -113,26 +113,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, const u16 offset, void *buffer, const u16 buffer_length, const int timeout) { - int status; - - mutex_lock(&rt2x00dev->csr_mutex); - - status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, - requesttype, offset, buffer, - buffer_length, timeout); - - mutex_unlock(&rt2x00dev->csr_mutex); - - return status; -} -EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); - -int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, - const u8 request, const u8 requesttype, - const u16 offset, const void *buffer, - const u16 buffer_length, - const int timeout) -{ int status = 0; unsigned char *tb; u16 off, len, bsize; @@ -157,7 +137,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, return status; } -EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff); +EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, const unsigned int offset, @@ -216,48 +196,28 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) rt2x00lib_txdone(entry, &txdesc); } -int rt2x00usb_write_tx_data(struct queue_entry *entry, - struct txentry_desc *txdesc) +static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb *entry_priv = entry->priv_data; u32 length; - /* - * Add the descriptor in front of the skb. - */ - skb_push(entry->skb, entry->queue->desc_size); - memset(entry->skb->data, 0, entry->queue->desc_size); - - /* - * USB devices cannot blindly pass the skb->len as the - * length of the data to usb_fill_bulk_urb. Pass the skb - * to the driver to determine what the length should be. - */ - length = rt2x00dev->ops->lib->get_tx_data_len(entry); - - usb_fill_bulk_urb(entry_priv->urb, usb_dev, - usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), - entry->skb->data, length, - rt2x00usb_interrupt_txdone, entry); - - /* - * Make sure the skb->data pointer points to the frame, not the - * descriptor. - */ - skb_pull(entry->skb, entry->queue->desc_size); + if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { + /* + * USB devices cannot blindly pass the skb->len as the + * length of the data to usb_fill_bulk_urb. Pass the skb + * to the driver to determine what the length should be. + */ + length = rt2x00dev->ops->lib->get_tx_data_len(entry); - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); + usb_fill_bulk_urb(entry_priv->urb, usb_dev, + usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), + entry->skb->data, length, + rt2x00usb_interrupt_txdone, entry); -static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) -{ - struct queue_entry_priv_usb *entry_priv = entry->priv_data; - - if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + } } void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, @@ -332,6 +292,56 @@ void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); +static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) +{ + struct queue_entry_priv_usb *entry_priv; + unsigned short threshold = queue->threshold; + + WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); + + /* + * Temporarily disable the TX queue, this will force mac80211 + * to use the other queues until this queue has been restored. + * + * Set the queue threshold to the queue limit. This prevents the + * queue from being enabled during the txdone handler. + */ + queue->threshold = queue->limit; + ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); + + /* + * Reset all currently uploaded TX frames. + */ + while (!rt2x00queue_empty(queue)) { + entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data; + usb_kill_urb(entry_priv->urb); + + /* + * We need a short delay here to wait for + * the URB to be canceled and invoked the tx_done handler. + */ + udelay(200); + } + + /* + * The queue has been reset, and mac80211 is allowed to use the + * queue again. + */ + queue->threshold = threshold; + ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); +} + +void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + tx_queue_for_each(rt2x00dev, queue) { + if (rt2x00queue_timeout(queue)) + rt2x00usb_watchdog_reset_tx(queue); + } +} +EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); + /* * RX data handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 621d0f82925..d3d3ddc4087 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -167,25 +167,6 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, const u16 buffer_length, const int timeout); /** - * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered) - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @request: USB vendor command (See &enum rt2x00usb_vendor_request) - * @requesttype: Request type &USB_VENDOR_REQUEST_* - * @offset: Register start offset to perform action on - * @buffer: Buffer where information will be read/written to by device - * @buffer_length: Size of &buffer - * @timeout: Operation timeout - * - * This function is used to transfer register data in blocks larger - * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons. - */ -int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, - const u8 request, const u8 requesttype, - const u16 offset, const void *buffer, - const u16 buffer_length, - const int timeout); - -/** * rt2x00usb_vendor_request_sw - Send single register command to device * @rt2x00dev: Pointer to &struct rt2x00_dev * @request: USB vendor command (See &enum rt2x00usb_vendor_request) @@ -370,16 +351,6 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); /** - * rt2x00usb_write_tx_data - Initialize URB for TX operation - * @entry: The entry where the frame is located - * - * This function will initialize the URB and skb descriptor - * to prepare the entry for the actual TX operation. - */ -int rt2x00usb_write_tx_data(struct queue_entry *entry, - struct txentry_desc *txdesc); - -/** * struct queue_entry_priv_usb: Per entry USB specific information * * @urb: Urb structure used for device communication. @@ -428,6 +399,16 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid qid); +/** + * rt2x00usb_watchdog - Watchdog for USB communication + * @rt2x00dev: Pointer to &struct rt2x00_dev + * + * Check the health of the USB communication and determine + * if timeouts have occured. If this is the case, this function + * will reset all communication to restore functionality again. + */ +void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev); + /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 6a74baf4e93..e539c6cb636 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -931,6 +931,9 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev, u32 reg; rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, libconf->conf->long_frame_max_tx_count); rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, @@ -1619,7 +1622,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF); + int mask = (state == STATE_RADIO_IRQ_OFF) || + (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; /* @@ -1736,7 +1740,9 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: rt61pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: @@ -1874,6 +1880,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); /* + * Write the TX descriptor for the beacon. + */ + rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); + + /* * Write entire beacon with descriptor to register. */ beacon_base = HW_BEACON_OFFSET(entry->entry_idx); @@ -2039,29 +2055,24 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) struct txdone_entry_desc txdesc; u32 word; u32 reg; - u32 old_reg; int type; int index; + int i; /* - * During each loop we will compare the freshly read - * STA_CSR4 register value with the value read from - * the previous loop. If the 2 values are equal then - * we should stop processing because the chance is - * quite big that the device has been unplugged and - * we risk going into an endless loop. + * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO + * at most X times and also stop processing once the TX_STA_FIFO_VALID + * flag is not set anymore. + * + * The legacy drivers use X=TX_RING_SIZE but state in a comment + * that the TX_STA_FIFO stack has a size of 16. We stick to our + * tx ring size for now. */ - old_reg = 0; - - while (1) { + for (i = 0; i < TX_ENTRIES; i++) { rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) break; - if (old_reg == reg) - break; - old_reg = reg; - /* * Skip this entry when it contains an invalid * queue identication number. @@ -2120,6 +2131,13 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) } txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); + /* + * the frame was retried at least once + * -> hw used fallback rates + */ + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); + rt2x00lib_txdone(entry, &txdesc); } } @@ -2132,27 +2150,11 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } -static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) +static irqreturn_t rt61pci_interrupt_thread(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg_mcu; - u32 reg; - - /* - * Get the interrupt sources & saved to local variable. - * Write register value back to clear pending interrupts. - */ - rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); - rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); - - rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - - if (!reg && !reg_mcu) - return IRQ_NONE; - - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - return IRQ_HANDLED; + u32 reg = rt2x00dev->irqvalue[0]; + u32 reg_mcu = rt2x00dev->irqvalue[1]; /* * Handle interrupts, walk through all bits @@ -2185,9 +2187,51 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP)) rt61pci_wakeup(rt2x00dev); + /* + * 5 - Beacon done interrupt. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) + rt2x00lib_beacondone(rt2x00dev); + + /* Enable interrupts again. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_ON_ISR); return IRQ_HANDLED; } + +static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) +{ + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg_mcu; + u32 reg; + + /* + * Get the interrupt sources & saved to local variable. + * Write register value back to clear pending interrupts. + */ + rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); + rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); + + rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + + if (!reg && !reg_mcu) + return IRQ_NONE; + + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return IRQ_HANDLED; + + /* Store irqvalues for use in the interrupt thread. */ + rt2x00dev->irqvalue[0] = reg; + rt2x00dev->irqvalue[1] = reg_mcu; + + /* Disable interrupts, will be enabled again in the interrupt thread. */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); + return IRQ_WAKE_THREAD; +} + /* * Device probe functions. */ @@ -2577,6 +2621,18 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) EEPROM_MAC_ADDR_0)); /* + * As rt61 has a global fallback table we cannot specify + * more then one tx rate per frame but since the hw will + * try several rates (based on the fallback table) we should + * still initialize max_rates to the maximum number of rates + * we are going to try. Otherwise mac80211 will truncate our + * reported tx rates and the rc algortihm will end up with + * incorrect data. + */ + rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rate_tries = 1; + + /* * Initialize hw_mode information. */ spec->supported_bands = SUPPORT_BAND_2GHZ; @@ -2657,6 +2713,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); /* * Set the rssi offset. @@ -2748,8 +2805,9 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { .remove_interface = rt2x00mac_remove_interface, .config = rt2x00mac_config, .configure_filter = rt2x00mac_configure_filter, - .set_tim = rt2x00mac_set_tim, .set_key = rt2x00mac_set_key, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, .get_stats = rt2x00mac_get_stats, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt61pci_conf_tx, @@ -2759,6 +2817,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .irq_handler = rt61pci_interrupt, + .irq_handler_thread = rt61pci_interrupt_thread, .probe_hw = rt61pci_probe_hw, .get_firmware_name = rt61pci_get_firmware_name, .check_firmware = rt61pci_check_firmware, @@ -2773,7 +2832,6 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .reset_tuner = rt61pci_reset_tuner, .link_tuner = rt61pci_link_tuner, .write_tx_desc = rt61pci_write_tx_desc, - .write_tx_data = rt2x00pci_write_tx_data, .write_beacon = rt61pci_write_beacon, .kick_tx_queue = rt61pci_kick_tx_queue, .kill_tx_queue = rt61pci_kill_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index df80f1af22a..e2e728ab0b2 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -153,13 +153,13 @@ struct hw_key_entry { u8 key[16]; u8 tx_mic[8]; u8 rx_mic[8]; -} __attribute__ ((packed)); +} __packed; struct hw_pairwise_ta_entry { u8 address[6]; u8 cipher; u8 reserved; -} __attribute__ ((packed)); +} __packed; /* * Other on-chip shared memory space. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6e0d82efe92..aa9de18fd41 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -270,7 +270,6 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, { struct hw_key_entry key_entry; struct rt2x00_field32 field; - int timeout; u32 mask; u32 reg; @@ -306,12 +305,8 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, sizeof(key_entry.rx_mic)); reg = SHARED_KEY_ENTRY(key->hw_key_idx); - timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, reg, - &key_entry, - sizeof(key_entry), - timeout); + rt2x00usb_register_multiwrite(rt2x00dev, reg, + &key_entry, sizeof(key_entry)); /* * The cipher types are stored over 2 registers. @@ -372,7 +367,6 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, { struct hw_pairwise_ta_entry addr_entry; struct hw_key_entry key_entry; - int timeout; u32 mask; u32 reg; @@ -407,17 +401,11 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, sizeof(key_entry.rx_mic)); reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); - timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, reg, - &key_entry, - sizeof(key_entry), - timeout); + rt2x00usb_register_multiwrite(rt2x00dev, reg, + &key_entry, sizeof(key_entry)); /* * Send the address and cipher type to the hardware register. - * This data fits within the CSR cache size, so we can use - * rt2x00usb_register_multiwrite() directly. */ memset(&addr_entry, 0, sizeof(addr_entry)); memcpy(&addr_entry, crypto->address, ETH_ALEN); @@ -828,6 +816,9 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev, u32 reg; rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); + rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, libconf->conf->long_frame_max_tx_count); rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, @@ -1092,11 +1083,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, /* * Write firmware to device. */ - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, - FIRMWARE_IMAGE_BASE, - data, len, - REGISTER_TIMEOUT32(len)); + rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len); /* * Send firmware request to device to load firmware, @@ -1413,7 +1400,9 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_toggle_rx(rt2x00dev, state); break; case STATE_RADIO_IRQ_ON: + case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: + case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: @@ -1442,7 +1431,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); + __le32 *txd = (__le32 *) skb->data; u32 word; /* @@ -1505,6 +1494,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * Register descriptor details in skb frame descriptor. */ + skbdesc->flags |= SKBDESC_DESC_IN_SKB; skbdesc->desc = txd; skbdesc->desc_len = TXD_DESC_SIZE; } @@ -1528,18 +1518,27 @@ static void rt73usb_write_beacon(struct queue_entry *entry, rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); /* - * Take the descriptor in front of the skb into account. + * Add space for the descriptor in front of the skb. */ skb_push(entry->skb, TXD_DESC_SIZE); + memset(entry->skb->data, 0, TXD_DESC_SIZE); + + /* + * Write the TX descriptor for the beacon. + */ + rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + + /* + * Dump beacon to userspace through debugfs. + */ + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); /* * Write entire beacon with descriptor to register. */ beacon_base = HW_BEACON_OFFSET(entry->entry_idx); - rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, - USB_VENDOR_REQUEST_OUT, beacon_base, - entry->skb->data, entry->skb->len, - REGISTER_TIMEOUT32(entry->skb->len)); + rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, + entry->skb->data, entry->skb->len); /* * Enable beaconing again. @@ -2138,6 +2137,8 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); /* * Set the rssi offset. @@ -2231,6 +2232,8 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { .configure_filter = rt2x00mac_configure_filter, .set_tim = rt2x00mac_set_tim, .set_key = rt2x00mac_set_key, + .sw_scan_start = rt2x00mac_sw_scan_start, + .sw_scan_complete = rt2x00mac_sw_scan_complete, .get_stats = rt2x00mac_get_stats, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt73usb_conf_tx, @@ -2251,8 +2254,8 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .link_stats = rt73usb_link_stats, .reset_tuner = rt73usb_reset_tuner, .link_tuner = rt73usb_link_tuner, + .watchdog = rt2x00usb_watchdog, .write_tx_desc = rt73usb_write_tx_desc, - .write_tx_data = rt2x00usb_write_tx_data, .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 7abe7eb1455..44d5b2bebd3 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -108,13 +108,13 @@ struct hw_key_entry { u8 key[16]; u8 tx_mic[8]; u8 rx_mic[8]; -} __attribute__ ((packed)); +} __packed; struct hw_pairwise_ta_entry { u8 address[6]; u8 cipher; u8 reserved; -} __attribute__ ((packed)); +} __packed; /* * Since NULL frame won't be that long (256 byte), diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h index 4baf0cf0826..30523314da4 100644 --- a/drivers/net/wireless/rtl818x/rtl8180.h +++ b/drivers/net/wireless/rtl818x/rtl8180.h @@ -36,7 +36,7 @@ struct rtl8180_tx_desc { u8 agc; u8 flags2; u32 reserved[2]; -} __attribute__ ((packed)); +} __packed; struct rtl8180_rx_desc { __le32 flags; @@ -45,7 +45,7 @@ struct rtl8180_rx_desc { __le32 rx_buf; __le64 tsft; }; -} __attribute__ ((packed)); +} __packed; struct rtl8180_tx_ring { struct rtl8180_tx_desc *desc; diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 515817de290..1d8178563d7 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -103,6 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) { struct rtl8180_priv *priv = dev->priv; unsigned int count = 32; + u8 signal, agc, sq; while (count--) { struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; @@ -130,10 +131,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) skb_put(skb, flags & 0xFFF); rx_status.antenna = (flags2 >> 15) & 1; - /* TODO: improve signal/rssi reporting */ - rx_status.signal = (flags2 >> 8) & 0x7F; - /* XXX: is this correct? */ rx_status.rate_idx = (flags >> 20) & 0xF; + agc = (flags2 >> 17) & 0x7F; + if (priv->r8185) { + if (rx_status.rate_idx > 3) + signal = 90 - clamp_t(u8, agc, 25, 90); + else + signal = 95 - clamp_t(u8, agc, 30, 95); + } else { + sq = flags2 & 0xff; + signal = priv->rf->calc_rssi(agc, sq); + } + rx_status.signal = signal; rx_status.freq = dev->conf.channel->center_freq; rx_status.band = dev->conf.channel->band; rx_status.mactime = le64_to_cpu(entry->tsft); @@ -352,7 +361,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) /* check success of reset */ if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { - printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "reset timeout!\n"); return -ETIMEDOUT; } @@ -436,8 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) &priv->rx_ring_dma); if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { - printk(KERN_ERR "%s: Cannot allocate RX ring\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "cannot allocate rx ring\n"); return -ENOMEM; } @@ -494,8 +502,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); if (!ring || (unsigned long)ring & 0xFF) { - printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n", - wiphy_name(dev->wiphy), prio); + wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n", + prio); return -ENOMEM; } @@ -560,8 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) ret = request_irq(priv->pdev->irq, rtl8180_interrupt, IRQF_SHARED, KBUILD_MODNAME, dev); if (ret) { - printk(KERN_ERR "%s: failed to register IRQ handler\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "failed to register irq handler\n"); goto err_free_rings; } @@ -671,7 +678,7 @@ static u64 rtl8180_get_tsf(struct ieee80211_hw *dev) (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; } -void rtl8180_beacon_work(struct work_struct *work) +static void rtl8180_beacon_work(struct work_struct *work) { struct rtl8180_vif *vif_priv = container_of(work, struct rtl8180_vif, beacon_work.work); @@ -1098,9 +1105,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, goto err_iounmap; } - printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", - wiphy_name(dev->wiphy), mac_addr, - chip_name, priv->rf->name); + wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", + mac_addr, chip_name, priv->rf->name); return 0; diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c index 947ee55f18b..5cab9dfa8c0 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c @@ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) rtl8180_write_phy(dev, 0x10, ant); } +static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq) +{ + if (agc > 60) + return 65; + + /* TODO(?): just return agc (or agc + 5) to avoid mult / div */ + return 65 * agc / 60; +} + static void grf5101_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = { .name = "GCT", .init = grf5101_rf_init, .stop = grf5101_rf_stop, - .set_chan = grf5101_rf_set_channel + .set_chan = grf5101_rf_set_channel, + .calc_rssi = grf5101_rf_calc_rssi, }; diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c index 6c825fd7f3b..16c4655181c 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.c @@ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) rtl8180_write_phy(dev, 0x10, ant); } +static u8 max2820_rf_calc_rssi(u8 agc, u8 sq) +{ + bool odd; + + odd = !!(agc & 1); + + agc >>= 1; + if (odd) + agc += 76; + else + agc += 66; + + /* TODO: change addends above to avoid mult / div below */ + return 65 * agc / 100; +} + static void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = { .name = "Maxim", .init = max2820_rf_init, .stop = max2820_rf_stop, - .set_chan = max2820_rf_set_channel + .set_chan = max2820_rf_set_channel, + .calc_rssi = max2820_rf_calc_rssi, }; diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c index 4d2be0d9672..69e4d4745da 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c @@ -50,7 +50,10 @@ static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) udelay(10); for (i = 15; i >= 0; i--) { - u16 reg = reg80 | !!(bangdata & (1 << i)); + u16 reg = reg80; + + if (bangdata & (1 << i)) + reg |= 1; if (i & 1) rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c index cea4e0ccb92..d064fcc5ec0 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c @@ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) } +static u8 sa2400_rf_rssi_map[] = { + 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, + 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, + 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, + 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, + 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, + 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, + 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, + 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, + 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, + 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, +}; + +static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq) +{ + if (sq == 0x80) + return 1; + + if (sq > 78) + return 32; + + /* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */ + return 65 * sa2400_rf_rssi_map[sq] / 100; +} + static void sa2400_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { @@ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = { .name = "Philips", .init = sa2400_rf_init, .stop = sa2400_rf_stop, - .set_chan = sa2400_rf_set_channel + .set_chan = sa2400_rf_set_channel, + .calc_rssi = sa2400_rf_calc_rssi, }; diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index 6bb32112e65..98878160a65 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h @@ -47,7 +47,7 @@ struct rtl8187_rx_hdr { u8 agc; u8 reserved; __le64 mac_time; -} __attribute__((packed)); +} __packed; struct rtl8187b_rx_hdr { __le32 flags; @@ -59,7 +59,7 @@ struct rtl8187b_rx_hdr { __le16 snr_long2end; s8 pwdb_g12; u8 fot; -} __attribute__((packed)); +} __packed; /* {rtl8187,rtl8187b}_tx_info is in skb */ @@ -68,7 +68,7 @@ struct rtl8187_tx_hdr { __le16 rts_duration; __le16 len; __le32 retry; -} __attribute__((packed)); +} __packed; struct rtl8187b_tx_hdr { __le32 flags; @@ -80,7 +80,7 @@ struct rtl8187b_tx_hdr { __le32 unused_3; __le32 retry; __le32 unused_4[2]; -} __attribute__((packed)); +} __packed; enum { DEVICE_RTL8187, diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 891b8490e34..5738a55c1b0 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) } while (--i); if (!i) { - printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "reset timeout!\n"); return -ETIMEDOUT; } @@ -589,8 +589,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) } while (--i); if (!i) { - printk(KERN_ERR "%s: eeprom reset timeout!\n", - wiphy_name(dev->wiphy)); + wiphy_err(dev->wiphy, "eeprom reset timeout!\n"); return -ETIMEDOUT; } @@ -1527,9 +1526,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, mutex_init(&priv->conf_mutex); skb_queue_head_init(&priv->b_tx_status.queue); - printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", - wiphy_name(dev->wiphy), mac_addr, - chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); + wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n", + mac_addr, chip_name, priv->asic_rev, priv->rf->name, + priv->rfkill_mask); #ifdef CONFIG_RTL8187_LEDS eeprom_93cx6_read(&eeprom, 0x3F, ®); diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index a09819386a1..fd96f911232 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c @@ -366,8 +366,8 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev) rtl8225_write(dev, 0x02, 0x044d); msleep(100); if (!(rtl8225_read(dev, 6) & (1 << 7))) - printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", - wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); + wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", + rtl8225_read(dev, 6)); } rtl8225_write(dev, 0x0, 0x127); @@ -735,8 +735,8 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev) rtl8225_write(dev, 0x02, 0x044D); msleep(100); if (!(rtl8225_read(dev, 6) & (1 << 7))) - printk(KERN_WARNING "%s: RF Calibration Failed! %x\n", - wiphy_name(dev->wiphy), rtl8225_read(dev, 6)); + wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", + rtl8225_read(dev, 6)); } msleep(200); diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h index 8522490d2e2..1615f63b02f 100644 --- a/drivers/net/wireless/rtl818x/rtl818x.h +++ b/drivers/net/wireless/rtl818x/rtl818x.h @@ -185,7 +185,7 @@ struct rtl818x_csr { u8 reserved_22[4]; __le16 TALLY_CNT; u8 TALLY_SEL; -} __attribute__((packed)); +} __packed; struct rtl818x_rf_ops { char *name; @@ -193,6 +193,7 @@ struct rtl818x_rf_ops { void (*stop)(struct ieee80211_hw *); void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *); + u8 (*calc_rssi)(u8 agc, u8 sq); }; /** diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 337fc7bec5a..2f98058be45 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -41,7 +41,7 @@ config WL1251_SDIO config WL1271 tristate "TI wl1271 support" - depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS + depends on WL12XX && GENERIC_HARDIRQS depends on INET select FW_LOADER select CRC7 @@ -65,7 +65,7 @@ config WL1271_SPI config WL1271_SDIO tristate "TI wl1271 SDIO support" - depends on WL1271 && MMC && ARM + depends on WL1271 && MMC ---help--- This module adds support for the SDIO interface of adapters using TI wl1271 chipset. Select this if your platform is using diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 27ddd2be0a9..078b4398ac1 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ wl1271_event.o wl1271_tx.o wl1271_rx.o \ wl1271_ps.o wl1271_acx.o wl1271_boot.o \ - wl1271_init.o wl1271_debugfs.o + wl1271_init.o wl1271_debugfs.o wl1271_scan.o wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o obj-$(CONFIG_WL1271) += wl1271.o diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 4f5f02a26e6..6b942a28e6a 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h @@ -381,6 +381,9 @@ struct wl1251 { u32 chip_id; char fw_ver[21]; + + /* Most recently reported noise in dBm */ + s8 noise; }; int wl1251_plt_start(struct wl1251 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h index 26160c45784..842df310d92 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl12xx/wl1251_acx.h @@ -60,7 +60,7 @@ struct acx_error_counter { /* the number of missed sequence numbers in the squentially */ /* values of frames seq numbers */ u32 seq_num_miss; -} __attribute__ ((packed)); +} __packed; struct acx_revision { struct acx_header header; @@ -89,7 +89,7 @@ struct acx_revision { * bits 24 - 31: Chip ID - The WiLink chip ID. */ u32 hw_version; -} __attribute__ ((packed)); +} __packed; enum wl1251_psm_mode { /* Active mode */ @@ -111,7 +111,7 @@ struct acx_sleep_auth { /* 2 - ELP mode: Deep / Max sleep*/ u8 sleep_auth; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum { HOSTIF_PCI_MASTER_HOST_INDIRECT, @@ -159,7 +159,7 @@ struct acx_data_path_params { * complete ring until an interrupt is generated. */ u32 tx_complete_timeout; -} __attribute__ ((packed)); +} __packed; struct acx_data_path_params_resp { @@ -180,7 +180,7 @@ struct acx_data_path_params_resp { u32 tx_control_addr; u32 tx_complete_addr; -} __attribute__ ((packed)); +} __packed; #define TX_MSDU_LIFETIME_MIN 0 #define TX_MSDU_LIFETIME_MAX 3000 @@ -197,7 +197,7 @@ struct acx_rx_msdu_lifetime { * firmware discards the MSDU. */ u32 lifetime; -} __attribute__ ((packed)); +} __packed; /* * RX Config Options Table @@ -285,7 +285,7 @@ struct acx_rx_config { u32 config_options; u32 filter_options; -} __attribute__ ((packed)); +} __packed; enum { QOS_AC_BE = 0, @@ -325,13 +325,13 @@ struct acx_tx_queue_qos_config { /* Lowest memory blocks guaranteed for this queue */ u16 low_threshold; -} __attribute__ ((packed)); +} __packed; struct acx_packet_detection { struct acx_header header; u32 threshold; -} __attribute__ ((packed)); +} __packed; enum acx_slot_type { @@ -349,7 +349,7 @@ struct acx_slot { u8 wone_index; /* Reserved */ u8 slot_time; u8 reserved[6]; -} __attribute__ ((packed)); +} __packed; #define ADDRESS_GROUP_MAX (8) @@ -362,7 +362,7 @@ struct acx_dot11_grp_addr_tbl { u8 num_groups; u8 pad[2]; u8 mac_table[ADDRESS_GROUP_MAX_LEN]; -} __attribute__ ((packed)); +} __packed; #define RX_TIMEOUT_PS_POLL_MIN 0 @@ -388,7 +388,7 @@ struct acx_rx_timeout { * from an UPSD enabled queue. */ u16 upsd_timeout; -} __attribute__ ((packed)); +} __packed; #define RTS_THRESHOLD_MIN 0 #define RTS_THRESHOLD_MAX 4096 @@ -399,7 +399,7 @@ struct acx_rts_threshold { u16 threshold; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_beacon_filter_option { struct acx_header header; @@ -415,7 +415,7 @@ struct acx_beacon_filter_option { */ u8 max_num_beacons; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; /* * ACXBeaconFilterEntry (not 221) @@ -461,7 +461,7 @@ struct acx_beacon_filter_ie_table { u8 num_ie; u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; #define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ #define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */ @@ -494,7 +494,7 @@ struct acx_bt_wlan_coex { */ u8 enable; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; #define PTA_ANTENNA_TYPE_DEF (0) #define PTA_BT_HP_MAXTIME_DEF (2000) @@ -648,7 +648,7 @@ struct acx_bt_wlan_coex_param { /* range: 0 - 20 default: 1 */ u8 bt_hp_respected_num; -} __attribute__ ((packed)); +} __packed; #define CCA_THRSH_ENABLE_ENERGY_D 0x140A #define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF @@ -660,7 +660,7 @@ struct acx_energy_detection { u16 rx_cca_threshold; u8 tx_energy_detection; u8 pad; -} __attribute__ ((packed)); +} __packed; #define BCN_RX_TIMEOUT_DEF_VALUE 10000 #define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000 @@ -679,14 +679,14 @@ struct acx_beacon_broadcast { /* Consecutive PS Poll failures before updating the host */ u8 ps_poll_threshold; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_event_mask { struct acx_header header; u32 event_mask; u32 high_event_mask; /* Unused */ -} __attribute__ ((packed)); +} __packed; #define CFG_RX_FCS BIT(2) #define CFG_RX_ALL_GOOD BIT(3) @@ -729,7 +729,7 @@ struct acx_fw_gen_frame_rates { u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */ u8 tx_mgt_frame_rate; u8 tx_mgt_frame_mod; -} __attribute__ ((packed)); +} __packed; /* STA MAC */ struct acx_dot11_station_id { @@ -737,28 +737,28 @@ struct acx_dot11_station_id { u8 mac[ETH_ALEN]; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_feature_config { struct acx_header header; u32 options; u32 data_flow_options; -} __attribute__ ((packed)); +} __packed; struct acx_current_tx_power { struct acx_header header; u8 current_tx_power; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct acx_dot11_default_key { struct acx_header header; u8 id; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; struct acx_tsf_info { struct acx_header header; @@ -769,7 +769,7 @@ struct acx_tsf_info { u32 last_TBTT_lsb; u8 last_dtim_count; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; enum acx_wake_up_event { WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/ @@ -785,7 +785,7 @@ struct acx_wake_up_condition { u8 wake_up_event; /* Only one bit can be set */ u8 listen_interval; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_aid { struct acx_header header; @@ -795,7 +795,7 @@ struct acx_aid { */ u16 aid; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; enum acx_preamble_type { ACX_PREAMBLE_LONG = 0, @@ -811,7 +811,7 @@ struct acx_preamble { */ u8 preamble; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum acx_ctsprotect_type { CTSPROTECT_DISABLE = 0, @@ -822,11 +822,11 @@ struct acx_ctsprotect { struct acx_header header; u8 ctsprotect; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct acx_tx_statistics { u32 internal_desc_overflow; -} __attribute__ ((packed)); +} __packed; struct acx_rx_statistics { u32 out_of_mem; @@ -837,14 +837,14 @@ struct acx_rx_statistics { u32 xfr_hint_trig; u32 path_reset; u32 reset_counter; -} __attribute__ ((packed)); +} __packed; struct acx_dma_statistics { u32 rx_requested; u32 rx_errors; u32 tx_requested; u32 tx_errors; -} __attribute__ ((packed)); +} __packed; struct acx_isr_statistics { /* host command complete */ @@ -903,7 +903,7 @@ struct acx_isr_statistics { /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ u32 low_rssi; -} __attribute__ ((packed)); +} __packed; struct acx_wep_statistics { /* WEP address keys configured */ @@ -925,7 +925,7 @@ struct acx_wep_statistics { /* WEP decrypt interrupts */ u32 interrupt; -} __attribute__ ((packed)); +} __packed; #define ACX_MISSED_BEACONS_SPREAD 10 @@ -985,12 +985,12 @@ struct acx_pwr_statistics { /* the number of beacons in awake mode */ u32 rcvd_awake_beacons; -} __attribute__ ((packed)); +} __packed; struct acx_mic_statistics { u32 rx_pkts; u32 calc_failure; -} __attribute__ ((packed)); +} __packed; struct acx_aes_statistics { u32 encrypt_fail; @@ -999,7 +999,7 @@ struct acx_aes_statistics { u32 decrypt_packets; u32 encrypt_interrupt; u32 decrypt_interrupt; -} __attribute__ ((packed)); +} __packed; struct acx_event_statistics { u32 heart_beat; @@ -1010,7 +1010,7 @@ struct acx_event_statistics { u32 oom_late; u32 phy_transmit_error; u32 tx_stuck; -} __attribute__ ((packed)); +} __packed; struct acx_ps_statistics { u32 pspoll_timeouts; @@ -1020,7 +1020,7 @@ struct acx_ps_statistics { u32 pspoll_max_apturn; u32 pspoll_utilization; u32 upsd_utilization; -} __attribute__ ((packed)); +} __packed; struct acx_rxpipe_statistics { u32 rx_prep_beacon_drop; @@ -1028,7 +1028,7 @@ struct acx_rxpipe_statistics { u32 beacon_buffer_thres_host_int_trig_rx_data; u32 missed_beacon_host_int_trig_rx_data; u32 tx_xfr_host_int_trig_rx_data; -} __attribute__ ((packed)); +} __packed; struct acx_statistics { struct acx_header header; @@ -1044,7 +1044,7 @@ struct acx_statistics { struct acx_event_statistics event; struct acx_ps_statistics ps; struct acx_rxpipe_statistics rxpipe; -} __attribute__ ((packed)); +} __packed; #define ACX_MAX_RATE_CLASSES 8 #define ACX_RATE_MASK_UNSPECIFIED 0 @@ -1063,7 +1063,7 @@ struct acx_rate_policy { u32 rate_class_cnt; struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES]; -} __attribute__ ((packed)); +} __packed; struct wl1251_acx_memory { __le16 num_stations; /* number of STAs to be supported. */ @@ -1082,7 +1082,7 @@ struct wl1251_acx_memory { u8 tx_min_mem_block_num; u8 num_ssid_profiles; __le16 debug_buffer_size; -} __attribute__ ((packed)); +} __packed; #define ACX_RX_DESC_MIN 1 @@ -1094,7 +1094,7 @@ struct wl1251_acx_rx_queue_config { u8 type; u8 priority; __le32 dma_address; -} __attribute__ ((packed)); +} __packed; #define ACX_TX_DESC_MIN 1 #define ACX_TX_DESC_MAX 127 @@ -1103,7 +1103,7 @@ struct wl1251_acx_tx_queue_config { u8 num_descs; u8 pad[2]; u8 attributes; -} __attribute__ ((packed)); +} __packed; #define MAX_TX_QUEUE_CONFIGS 5 #define MAX_TX_QUEUES 4 @@ -1113,7 +1113,7 @@ struct wl1251_acx_config_memory { struct wl1251_acx_memory mem_config; struct wl1251_acx_rx_queue_config rx_queue_config; struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS]; -} __attribute__ ((packed)); +} __packed; struct wl1251_acx_mem_map { struct acx_header header; @@ -1147,7 +1147,7 @@ struct wl1251_acx_mem_map { /* Number of blocks FW allocated for RX packets */ u32 num_rx_mem_blocks; -} __attribute__ ((packed)); +} __packed; struct wl1251_acx_wr_tbtt_and_dtim { @@ -1164,7 +1164,7 @@ struct wl1251_acx_wr_tbtt_and_dtim { */ u8 dtim; u8 padding; -} __attribute__ ((packed)); +} __packed; struct wl1251_acx_ac_cfg { struct acx_header header; @@ -1194,7 +1194,7 @@ struct wl1251_acx_ac_cfg { /* The TX Op Limit (in microseconds) for the access class. */ u16 txop_limit; -} __attribute__ ((packed)); +} __packed; enum wl1251_acx_channel_type { @@ -1245,7 +1245,7 @@ struct wl1251_acx_tid_cfg { /* not supported */ u32 apsdconf[2]; -} __attribute__ ((packed)); +} __packed; /************************************************************************* diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 2545123931e..65e0416be5b 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -225,7 +225,7 @@ static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag) int wl1251_boot_run_firmware(struct wl1251 *wl) { int loop, ret; - u32 chip_id, interrupt; + u32 chip_id, acx_intr; wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); @@ -242,15 +242,15 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) loop = 0; while (loop++ < INIT_LOOP) { udelay(INIT_LOOP_DELAY); - interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); + acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - if (interrupt == 0xffffffff) { + if (acx_intr == 0xffffffff) { wl1251_error("error reading hardware complete " "init indication"); return -EIO; } /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) { + else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) { wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, WL1251_ACX_INTR_INIT_COMPLETE); break; diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h index 4ad67cae94d..a9e4991369b 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h @@ -106,7 +106,7 @@ struct wl1251_cmd_header { u16 status; /* payload */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct wl1251_command { struct wl1251_cmd_header header; @@ -175,8 +175,8 @@ struct cmd_read_write_memory { #define WL1251_SCAN_NUM_PROBES 3 struct wl1251_scan_parameters { - u32 rx_config_options; - u32 rx_filter_options; + __le32 rx_config_options; + __le32 rx_filter_options; /* * Scan options: @@ -186,7 +186,7 @@ struct wl1251_scan_parameters { * bit 2: voice mode, 0 for normal scan. * bit 3: scan priority, 1 for high priority. */ - u16 scan_options; + __le16 scan_options; /* Number of channels to scan */ u8 num_channels; @@ -195,17 +195,17 @@ struct wl1251_scan_parameters { u8 num_probe_requests; /* Rate and modulation for probe requests */ - u16 tx_rate; + __le16 tx_rate; u8 tid_trigger; u8 ssid_len; u8 ssid[32]; -} __attribute__ ((packed)); +} __packed; struct wl1251_scan_ch_parameters { - u32 min_duration; /* in TU */ - u32 max_duration; /* in TU */ + __le32 min_duration; /* in TU */ + __le32 max_duration; /* in TU */ u32 bssid_lsb; u16 bssid_msb; @@ -218,7 +218,7 @@ struct wl1251_scan_ch_parameters { u8 tx_power_att; u8 channel; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; /* SCAN parameters */ #define SCAN_MAX_NUM_OF_CHANNELS 16 @@ -228,7 +228,7 @@ struct wl1251_cmd_scan { struct wl1251_scan_parameters params; struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; -} __attribute__ ((packed)); +} __packed; enum { BSS_TYPE_IBSS = 0, @@ -276,14 +276,14 @@ struct cmd_join { u8 tx_mgt_frame_rate; /* OBSOLETE */ u8 tx_mgt_frame_mod; /* OBSOLETE */ u8 reserved; -} __attribute__ ((packed)); +} __packed; struct cmd_enabledisable_path { struct wl1251_cmd_header header; u8 channel; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; #define WL1251_MAX_TEMPLATE_SIZE 300 @@ -292,7 +292,7 @@ struct wl1251_cmd_packet_template { __le16 size; u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define TIM_ELE_ID 5 #define PARTIAL_VBM_MAX 251 @@ -304,7 +304,7 @@ struct wl1251_tim { u8 dtim_period; u8 bitmap_ctrl; u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ -} __attribute__ ((packed)); +} __packed; /* Virtual Bit Map update */ struct wl1251_cmd_vbm_update { @@ -312,7 +312,7 @@ struct wl1251_cmd_vbm_update { __le16 len; u8 padding[2]; struct wl1251_tim tim; -} __attribute__ ((packed)); +} __packed; enum wl1251_cmd_ps_mode { STATION_ACTIVE_MODE, @@ -333,7 +333,7 @@ struct wl1251_cmd_ps_params { u8 hang_over_period; u16 null_data_rate; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct wl1251_cmd_trigger_scan_to { struct wl1251_cmd_header header; @@ -411,7 +411,7 @@ struct wl1251_cmd_set_keys { u8 key[MAX_KEY_SIZE]; u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; -} __attribute__ ((packed)); +} __packed; #endif /* __WL1251_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h index be0ac54d624..f48a2b66bc5 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.h +++ b/drivers/net/wireless/wl12xx/wl1251_event.h @@ -82,7 +82,7 @@ struct event_debug_report { u32 report_1; u32 report_2; u32 report_3; -} __attribute__ ((packed)); +} __packed; struct event_mailbox { u32 events_vector; @@ -112,7 +112,7 @@ struct event_mailbox { struct event_debug_report report; u8 average_snr_level; u8 padding[19]; -} __attribute__ ((packed)); +} __packed; int wl1251_event_unmask(struct wl1251 *wl); void wl1251_event_mbox_config(struct wl1251 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 00b24282fc7..861a5f33761 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -124,7 +124,7 @@ static int wl1251_fetch_nvs(struct wl1251 *wl) } wl->nvs_len = fw->size; - wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL); + wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL); if (!wl->nvs) { wl1251_error("could not allocate memory for the nvs file"); @@ -132,8 +132,6 @@ static int wl1251_fetch_nvs(struct wl1251 *wl) goto out; } - memcpy(wl->nvs, fw->data, wl->nvs_len); - ret = 0; out: @@ -413,6 +411,7 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int wl1251_op_start(struct ieee80211_hw *hw) { struct wl1251 *wl = hw->priv; + struct wiphy *wiphy = hw->wiphy; int ret = 0; wl1251_debug(DEBUG_MAC80211, "mac80211 start"); @@ -446,6 +445,10 @@ static int wl1251_op_start(struct ieee80211_hw *hw) wl1251_info("firmware booted (%s)", wl->fw_ver); + /* update hw/fw version info in wiphy struct */ + wiphy->hw_version = wl->chip_id; + strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version)); + out: if (ret < 0) wl1251_power_off(wl); @@ -1174,6 +1177,22 @@ out: return ret; } +static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct wl1251 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = wl->noise; + + return 0; +} + /* can't be const, mac80211 writes to this */ static struct ieee80211_supported_band wl1251_band_2ghz = { .channels = wl1251_channels, @@ -1195,6 +1214,7 @@ static const struct ieee80211_ops wl1251_ops = { .bss_info_changed = wl1251_op_bss_info_changed, .set_rts_threshold = wl1251_op_set_rts_threshold, .conf_tx = wl1251_op_conf_tx, + .get_survey = wl1251_op_get_survey, }; static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data) @@ -1419,5 +1439,4 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw); MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); -MODULE_ALIAS("spi:wl1251"); MODULE_FIRMWARE(WL1251_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index 851515836a7..1b6294b3b99 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c @@ -74,6 +74,12 @@ static void wl1251_rx_status(struct wl1251 *wl, status->signal = desc->rssi; + /* + * FIXME: guessing that snr needs to be divided by two, otherwise + * the values don't make any sense + */ + wl->noise = desc->rssi - desc->snr / 2; + status->freq = ieee80211_channel_to_frequency(desc->channel); status->flag |= RX_FLAG_TSFT; diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h index 563a3fde40f..da4e53406a0 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.h +++ b/drivers/net/wireless/wl12xx/wl1251_rx.h @@ -117,7 +117,7 @@ struct wl1251_rx_descriptor { s8 rssi; /* in dB */ u8 rcpi; /* in dB */ u8 snr; /* in dB */ -} __attribute__ ((packed)); +} __packed; void wl1251_rx(struct wl1251 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index c561332e700..b901b613565 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c @@ -37,11 +37,17 @@ #define SDIO_DEVICE_ID_TI_WL1251 0x9066 #endif +struct wl1251_sdio { + struct sdio_func *func; + u32 elp_val; +}; + static struct wl12xx_platform_data *wl12xx_board_data; static struct sdio_func *wl_to_func(struct wl1251 *wl) { - return wl->if_priv; + struct wl1251_sdio *wl_sdio = wl->if_priv; + return wl_sdio->func; } static void wl1251_sdio_interrupt(struct sdio_func *func) @@ -90,10 +96,17 @@ static void wl1251_sdio_write(struct wl1251 *wl, int addr, static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) { int ret = 0; - struct sdio_func *func = wl_to_func(wl); - + struct wl1251_sdio *wl_sdio = wl->if_priv; + struct sdio_func *func = wl_sdio->func; + + /* + * The hardware only supports RAW (read after write) access for + * reading, regular sdio_readb won't work here (it interprets + * the unused bits of CMD52 as write data even if we send read + * request). + */ sdio_claim_host(func); - *val = sdio_readb(func, addr, &ret); + *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret); sdio_release_host(func); if (ret) @@ -103,7 +116,8 @@ static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) { int ret = 0; - struct sdio_func *func = wl_to_func(wl); + struct wl1251_sdio *wl_sdio = wl->if_priv; + struct sdio_func *func = wl_sdio->func; sdio_claim_host(func); sdio_writeb(func, val, addr, &ret); @@ -111,6 +125,8 @@ static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) if (ret) wl1251_error("sdio_writeb failed (%d)", ret); + else + wl_sdio->elp_val = val; } static void wl1251_sdio_reset(struct wl1251 *wl) @@ -197,6 +213,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, int ret; struct wl1251 *wl; struct ieee80211_hw *hw; + struct wl1251_sdio *wl_sdio; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) @@ -204,6 +221,12 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl = hw->priv; + wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); + if (wl_sdio == NULL) { + ret = -ENOMEM; + goto out_free_hw; + } + sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) @@ -213,7 +236,8 @@ static int wl1251_sdio_probe(struct sdio_func *func, sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); - wl->if_priv = func; + wl_sdio->func = func; + wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; wl->set_power = wl1251_sdio_set_power; @@ -259,6 +283,8 @@ disable: sdio_disable_func(func); release: sdio_release_host(func); + kfree(wl_sdio); +out_free_hw: wl1251_free_hw(wl); return ret; } @@ -266,9 +292,11 @@ release: static void __devexit wl1251_sdio_remove(struct sdio_func *func) { struct wl1251 *wl = sdio_get_drvdata(func); + struct wl1251_sdio *wl_sdio = wl->if_priv; if (wl->irq) free_irq(wl->irq, wl); + kfree(wl_sdio); wl1251_free_hw(wl); sdio_claim_host(func); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index e81474203a2..27fdfaaeb07 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -345,3 +345,4 @@ module_exit(wl1251_spi_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); +MODULE_ALIAS("spi:wl1251"); diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c index c8223185efd..a38ec199187 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/drivers/net/wireless/wl12xx/wl1251_tx.c @@ -117,7 +117,7 @@ static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr) frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; tx_hdr->frag_threshold = cpu_to_le16(frag_threshold); - payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH; + payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH; if (payload_len > frag_threshold) { mem_blocks_per_frag = @@ -191,11 +191,13 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, if (control->control.hw_key && control->control.hw_key->alg == ALG_TKIP) { int hdrlen; - u16 fc; + __le16 fc; + u16 length; u8 *pos; - fc = *(u16 *)(skb->data + sizeof(*tx_hdr)); - tx_hdr->length += WL1251_TKIP_IV_SPACE; + fc = *(__le16 *)(skb->data + sizeof(*tx_hdr)); + length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE; + tx_hdr->length = cpu_to_le16(length); hdrlen = ieee80211_hdrlen(fc); diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h index 55856c6bb97..f40eeb37f5a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.h +++ b/drivers/net/wireless/wl12xx/wl1251_tx.h @@ -109,12 +109,12 @@ struct tx_control { unsigned xfer_pad:1; unsigned reserved:7; -} __attribute__ ((packed)); +} __packed; struct tx_double_buffer_desc { /* Length of payload, including headers. */ - u16 length; + __le16 length; /* * A bit mask that specifies the initial rate to be used @@ -133,10 +133,10 @@ struct tx_double_buffer_desc { * 0x0800 - 48Mbits * 0x1000 - 54Mbits */ - u16 rate; + __le16 rate; /* Time in us that a packet can spend in the target */ - u32 expiry_time; + __le32 expiry_time; /* index of the TX queue used for this packet */ u8 xmit_queue; @@ -150,13 +150,13 @@ struct tx_double_buffer_desc { * The FW should cut the packet into fragments * of this size. */ - u16 frag_threshold; + __le16 frag_threshold; /* Numbers of HW queue blocks to be allocated */ u8 num_mem_blocks; u8 reserved; -} __attribute__ ((packed)); +} __packed; enum { TX_SUCCESS = 0, @@ -208,7 +208,7 @@ struct tx_result { /* See done_1 */ u8 done_2; -} __attribute__ ((packed)); +} __packed; static inline int wl1251_tx_get_queue(int queue) { diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 6f1b6b5640c..dd3cee6ea5b 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -33,6 +33,7 @@ #include <net/mac80211.h> #include "wl1271_conf.h" +#include "wl1271_ini.h" #define DRIVER_NAME "wl1271" #define DRIVER_PREFIX DRIVER_NAME ": " @@ -116,33 +117,6 @@ enum { #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) -/* NVS data structure */ -#define WL1271_NVS_SECTION_SIZE 468 - -#define WL1271_NVS_GENERAL_PARAMS_SIZE 57 -#define WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED \ - (WL1271_NVS_GENERAL_PARAMS_SIZE + 1) -#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE 17 -#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED \ - (WL1271_NVS_STAT_RADIO_PARAMS_SIZE + 1) -#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE 65 -#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED \ - (WL1271_NVS_DYN_RADIO_PARAMS_SIZE + 1) -#define WL1271_NVS_FEM_COUNT 2 -#define WL1271_NVS_INI_SPARE_SIZE 124 - -struct wl1271_nvs_file { - /* NVS section */ - u8 nvs[WL1271_NVS_SECTION_SIZE]; - - /* INI section */ - u8 general_params[WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED]; - u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED]; - u8 dyn_radio_params[WL1271_NVS_FEM_COUNT] - [WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED]; - u8 ini_spare[WL1271_NVS_INI_SPARE_SIZE]; -} __attribute__ ((packed)); - /* * Enable/disable 802.11a support for WL1273 */ @@ -317,7 +291,7 @@ struct wl1271_fw_status { __le32 tx_released_blks[NUM_TX_QUEUES]; __le32 fw_localtime; __le32 padding[2]; -} __attribute__ ((packed)); +} __packed; struct wl1271_rx_mem_pool_addr { u32 addr; @@ -325,12 +299,11 @@ struct wl1271_rx_mem_pool_addr { }; struct wl1271_scan { + struct cfg80211_scan_request *req; + bool *scanned_ch; u8 state; u8 ssid[IW_ESSID_MAX_SIZE+1]; size_t ssid_len; - u8 active; - u8 high_prio; - u8 probe_requests; }; struct wl1271_if_operations { @@ -368,13 +341,14 @@ struct wl1271 { #define WL1271_FLAG_JOINED (2) #define WL1271_FLAG_GPIO_POWER (3) #define WL1271_FLAG_TX_QUEUE_STOPPED (4) -#define WL1271_FLAG_SCANNING (5) -#define WL1271_FLAG_IN_ELP (6) -#define WL1271_FLAG_PSM (7) -#define WL1271_FLAG_PSM_REQUESTED (8) -#define WL1271_FLAG_IRQ_PENDING (9) -#define WL1271_FLAG_IRQ_RUNNING (10) -#define WL1271_FLAG_IDLE (11) +#define WL1271_FLAG_IN_ELP (5) +#define WL1271_FLAG_PSM (6) +#define WL1271_FLAG_PSM_REQUESTED (7) +#define WL1271_FLAG_IRQ_PENDING (8) +#define WL1271_FLAG_IRQ_RUNNING (9) +#define WL1271_FLAG_IDLE (10) +#define WL1271_FLAG_IDLE_REQUESTED (11) +#define WL1271_FLAG_PSPOLL_FAILURE (12) unsigned long flags; struct wl1271_partition_set part; @@ -421,6 +395,7 @@ struct wl1271 { /* Pending TX frames */ struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; + int tx_frames_cnt; /* Security sequence number counters */ u8 tx_security_last_seq; @@ -468,6 +443,10 @@ struct wl1271 { struct completion *elp_compl; struct delayed_work elp_work; + struct delayed_work pspoll_work; + + /* counter for ps-poll delivery failures */ + int ps_poll_failures; /* retry counter for PSM entries */ u8 psm_entry_retry; @@ -496,6 +475,9 @@ struct wl1271 { bool sg_enabled; struct list_head list; + + /* Most recently reported noise in dBm */ + s8 noise; }; int wl1271_plt_start(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index e19e2f8f1e5..bb245f05af4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -1075,8 +1075,7 @@ out: return ret; } -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, - u8 version) +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) { struct wl1271_acx_arp_filter *acx; int ret; @@ -1089,17 +1088,11 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, goto out; } - acx->version = version; + acx->version = ACX_IPV4_VERSION; acx->enable = enable; - if (enable == true) { - if (version == ACX_IPV4_VERSION) - memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE); - else if (version == ACX_IPV6_VERSION) - memcpy(acx->address, address, sizeof(acx->address)); - else - wl1271_error("Invalid IP version"); - } + if (enable == true) + memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, acx, sizeof(*acx)); @@ -1266,3 +1259,29 @@ out: kfree(acx); return ret; } + +int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) +{ + struct wl1271_acx_fw_tsf_information *tsf_info; + int ret; + + tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); + if (!tsf_info) { + ret = -ENOMEM; + goto out; + } + + ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, + tsf_info, sizeof(*tsf_info)); + if (ret < 0) { + wl1271_warning("acx tsf info interrogate failed"); + goto out; + } + + *mactime = le32_to_cpu(tsf_info->current_tsf_low) | + ((u64) le32_to_cpu(tsf_info->current_tsf_high) << 32); + +out: + kfree(tsf_info); + return ret; +} diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 420e7e2fc02..4235bc56f75 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -75,7 +75,7 @@ struct acx_header { /* payload length (not including headers */ __le16 len; -} __attribute__ ((packed)); +} __packed; struct acx_error_counter { struct acx_header header; @@ -98,7 +98,7 @@ struct acx_error_counter { /* the number of missed sequence numbers in the squentially */ /* values of frames seq numbers */ __le32 seq_num_miss; -} __attribute__ ((packed)); +} __packed; struct acx_revision { struct acx_header header; @@ -127,7 +127,7 @@ struct acx_revision { * bits 24 - 31: Chip ID - The WiLink chip ID. */ __le32 hw_version; -} __attribute__ ((packed)); +} __packed; enum wl1271_psm_mode { /* Active mode */ @@ -149,7 +149,7 @@ struct acx_sleep_auth { /* 2 - ELP mode: Deep / Max sleep*/ u8 sleep_auth; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum { HOSTIF_PCI_MASTER_HOST_INDIRECT, @@ -187,7 +187,7 @@ struct acx_rx_msdu_lifetime { * firmware discards the MSDU. */ __le32 lifetime; -} __attribute__ ((packed)); +} __packed; /* * RX Config Options Table @@ -275,13 +275,13 @@ struct acx_rx_config { __le32 config_options; __le32 filter_options; -} __attribute__ ((packed)); +} __packed; struct acx_packet_detection { struct acx_header header; __le32 threshold; -} __attribute__ ((packed)); +} __packed; enum acx_slot_type { @@ -299,7 +299,7 @@ struct acx_slot { u8 wone_index; /* Reserved */ u8 slot_time; u8 reserved[6]; -} __attribute__ ((packed)); +} __packed; #define ACX_MC_ADDRESS_GROUP_MAX (8) @@ -312,21 +312,21 @@ struct acx_dot11_grp_addr_tbl { u8 num_groups; u8 pad[2]; u8 mac_table[ADDRESS_GROUP_MAX_LEN]; -} __attribute__ ((packed)); +} __packed; struct acx_rx_timeout { struct acx_header header; __le16 ps_poll_timeout; __le16 upsd_timeout; -} __attribute__ ((packed)); +} __packed; struct acx_rts_threshold { struct acx_header header; __le16 threshold; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_beacon_filter_option { struct acx_header header; @@ -342,7 +342,7 @@ struct acx_beacon_filter_option { */ u8 max_num_beacons; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; /* * ACXBeaconFilterEntry (not 221) @@ -383,21 +383,21 @@ struct acx_beacon_filter_ie_table { u8 num_ie; u8 pad[3]; u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; -} __attribute__ ((packed)); +} __packed; struct acx_conn_monit_params { struct acx_header header; __le32 synch_fail_thold; /* number of beacons missed */ __le32 bss_lose_timeout; /* number of TU's from synch fail */ -} __attribute__ ((packed)); +} __packed; struct acx_bt_wlan_coex { struct acx_header header; u8 enable; u8 pad[3]; -} __attribute__ ((packed)); +} __packed; struct acx_bt_wlan_coex_param { struct acx_header header; @@ -405,7 +405,7 @@ struct acx_bt_wlan_coex_param { __le32 params[CONF_SG_PARAMS_MAX]; u8 param_idx; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct acx_dco_itrim_params { struct acx_header header; @@ -413,7 +413,7 @@ struct acx_dco_itrim_params { u8 enable; u8 padding[3]; __le32 timeout; -} __attribute__ ((packed)); +} __packed; struct acx_energy_detection { struct acx_header header; @@ -422,7 +422,7 @@ struct acx_energy_detection { __le16 rx_cca_threshold; u8 tx_energy_detection; u8 pad; -} __attribute__ ((packed)); +} __packed; struct acx_beacon_broadcast { struct acx_header header; @@ -436,14 +436,14 @@ struct acx_beacon_broadcast { /* Consecutive PS Poll failures before updating the host */ u8 ps_poll_threshold; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_event_mask { struct acx_header header; __le32 event_mask; __le32 high_event_mask; /* Unused */ -} __attribute__ ((packed)); +} __packed; #define CFG_RX_FCS BIT(2) #define CFG_RX_ALL_GOOD BIT(3) @@ -488,14 +488,14 @@ struct acx_feature_config { __le32 options; __le32 data_flow_options; -} __attribute__ ((packed)); +} __packed; struct acx_current_tx_power { struct acx_header header; u8 current_tx_power; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct acx_wake_up_condition { struct acx_header header; @@ -503,7 +503,7 @@ struct acx_wake_up_condition { u8 wake_up_event; /* Only one bit can be set */ u8 listen_interval; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; struct acx_aid { struct acx_header header; @@ -513,7 +513,7 @@ struct acx_aid { */ __le16 aid; u8 pad[2]; -} __attribute__ ((packed)); +} __packed; enum acx_preamble_type { ACX_PREAMBLE_LONG = 0, @@ -529,7 +529,7 @@ struct acx_preamble { */ u8 preamble; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum acx_ctsprotect_type { CTSPROTECT_DISABLE = 0, @@ -540,11 +540,11 @@ struct acx_ctsprotect { struct acx_header header; u8 ctsprotect; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct acx_tx_statistics { __le32 internal_desc_overflow; -} __attribute__ ((packed)); +} __packed; struct acx_rx_statistics { __le32 out_of_mem; @@ -555,14 +555,14 @@ struct acx_rx_statistics { __le32 xfr_hint_trig; __le32 path_reset; __le32 reset_counter; -} __attribute__ ((packed)); +} __packed; struct acx_dma_statistics { __le32 rx_requested; __le32 rx_errors; __le32 tx_requested; __le32 tx_errors; -} __attribute__ ((packed)); +} __packed; struct acx_isr_statistics { /* host command complete */ @@ -621,7 +621,7 @@ struct acx_isr_statistics { /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ __le32 low_rssi; -} __attribute__ ((packed)); +} __packed; struct acx_wep_statistics { /* WEP address keys configured */ @@ -643,7 +643,7 @@ struct acx_wep_statistics { /* WEP decrypt interrupts */ __le32 interrupt; -} __attribute__ ((packed)); +} __packed; #define ACX_MISSED_BEACONS_SPREAD 10 @@ -703,12 +703,12 @@ struct acx_pwr_statistics { /* the number of beacons in awake mode */ __le32 rcvd_awake_beacons; -} __attribute__ ((packed)); +} __packed; struct acx_mic_statistics { __le32 rx_pkts; __le32 calc_failure; -} __attribute__ ((packed)); +} __packed; struct acx_aes_statistics { __le32 encrypt_fail; @@ -717,7 +717,7 @@ struct acx_aes_statistics { __le32 decrypt_packets; __le32 encrypt_interrupt; __le32 decrypt_interrupt; -} __attribute__ ((packed)); +} __packed; struct acx_event_statistics { __le32 heart_beat; @@ -728,7 +728,7 @@ struct acx_event_statistics { __le32 oom_late; __le32 phy_transmit_error; __le32 tx_stuck; -} __attribute__ ((packed)); +} __packed; struct acx_ps_statistics { __le32 pspoll_timeouts; @@ -738,7 +738,7 @@ struct acx_ps_statistics { __le32 pspoll_max_apturn; __le32 pspoll_utilization; __le32 upsd_utilization; -} __attribute__ ((packed)); +} __packed; struct acx_rxpipe_statistics { __le32 rx_prep_beacon_drop; @@ -746,7 +746,7 @@ struct acx_rxpipe_statistics { __le32 beacon_buffer_thres_host_int_trig_rx_data; __le32 missed_beacon_host_int_trig_rx_data; __le32 tx_xfr_host_int_trig_rx_data; -} __attribute__ ((packed)); +} __packed; struct acx_statistics { struct acx_header header; @@ -762,7 +762,7 @@ struct acx_statistics { struct acx_event_statistics event; struct acx_ps_statistics ps; struct acx_rxpipe_statistics rxpipe; -} __attribute__ ((packed)); +} __packed; struct acx_rate_class { __le32 enabled_rates; @@ -780,7 +780,7 @@ struct acx_rate_policy { __le32 rate_class_cnt; struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES]; -} __attribute__ ((packed)); +} __packed; struct acx_ac_cfg { struct acx_header header; @@ -790,7 +790,7 @@ struct acx_ac_cfg { u8 aifsn; u8 reserved; __le16 tx_op_limit; -} __attribute__ ((packed)); +} __packed; struct acx_tid_config { struct acx_header header; @@ -801,19 +801,19 @@ struct acx_tid_config { u8 ack_policy; u8 padding[3]; __le32 apsd_conf[2]; -} __attribute__ ((packed)); +} __packed; struct acx_frag_threshold { struct acx_header header; __le16 frag_threshold; u8 padding[2]; -} __attribute__ ((packed)); +} __packed; struct acx_tx_config_options { struct acx_header header; __le16 tx_compl_timeout; /* msec */ __le16 tx_compl_threshold; /* number of packets */ -} __attribute__ ((packed)); +} __packed; #define ACX_RX_MEM_BLOCKS 70 #define ACX_TX_MIN_MEM_BLOCKS 40 @@ -828,7 +828,7 @@ struct wl1271_acx_config_memory { u8 num_stations; u8 num_ssid_profiles; __le32 total_tx_descriptors; -} __attribute__ ((packed)); +} __packed; struct wl1271_acx_mem_map { struct acx_header header; @@ -872,7 +872,7 @@ struct wl1271_acx_mem_map { u8 *rx_cbuf; __le32 rx_ctrl; __le32 tx_ctrl; -} __attribute__ ((packed)); +} __packed; struct wl1271_acx_rx_config_opt { struct acx_header header; @@ -882,7 +882,7 @@ struct wl1271_acx_rx_config_opt { __le16 timeout; u8 queue_type; u8 reserved; -} __attribute__ ((packed)); +} __packed; struct wl1271_acx_bet_enable { @@ -891,7 +891,7 @@ struct wl1271_acx_bet_enable { u8 enable; u8 max_consecutive; u8 padding[2]; -} __attribute__ ((packed)); +} __packed; #define ACX_IPV4_VERSION 4 #define ACX_IPV6_VERSION 6 @@ -905,7 +905,7 @@ struct wl1271_acx_arp_filter { requests directed to this IP address will pass through. For IPv4, the first four bytes are used. */ -} __attribute__((packed)); +} __packed; struct wl1271_acx_pm_config { struct acx_header header; @@ -913,14 +913,14 @@ struct wl1271_acx_pm_config { __le32 host_clk_settling_time; u8 host_fast_wakeup_support; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; struct wl1271_acx_keep_alive_mode { struct acx_header header; u8 enabled; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum { ACX_KEEP_ALIVE_NO_TX = 0, @@ -940,7 +940,7 @@ struct wl1271_acx_keep_alive_config { u8 tpl_validation; u8 trigger; u8 padding; -} __attribute__ ((packed)); +} __packed; enum { WL1271_ACX_TRIG_TYPE_LEVEL = 0, @@ -993,6 +993,17 @@ struct wl1271_acx_rssi_snr_avg_weights { u8 snr_data; }; +struct wl1271_acx_fw_tsf_information { + struct acx_header header; + + __le32 current_tsf_high; + __le32 current_tsf_low; + __le32 last_bttt_high; + __le32 last_tbtt_low; + u8 last_dtim_count; + u8 padding[3]; +} __packed; + enum { ACX_WAKE_UP_CONDITIONS = 0x0002, ACX_MEM_CFG = 0x0003, @@ -1106,13 +1117,13 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl); int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); int wl1271_acx_smart_reflex(struct wl1271 *wl); int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, - u8 version); +int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); int wl1271_acx_pm_config(struct wl1271 *wl); int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, s16 thold, u8 hyst); int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); +int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 1a36d8a2196..f36430b0336 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -414,7 +414,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) PS_REPORT_EVENT_ID | JOIN_EVENT_COMPLETE_ID | DISCONNECT_EVENT_COMPLETE_ID | - RSSI_SNR_TRIGGER_0_EVENT_ID; + RSSI_SNR_TRIGGER_0_EVENT_ID | + PSPOLL_DELIVERY_FAILURE_EVENT_ID | + SOFT_GEMINI_SENSE_EVENT_ID; ret = wl1271_event_unmask(wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 19393e236e2..ce503ddd5a4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -104,100 +104,6 @@ out: return ret; } -static int wl1271_cmd_cal_channel_tune(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_channel_tune *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_CHANNEL_TUNE; - - cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4; - /* set up any channel, 7 is in the middle of the range */ - cmd->channel = 7; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_CHANNEL_TUNE failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_update_ref_point *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT; - - /* FIXME: still waiting for the correct values */ - cmd->ref_power = 0; - cmd->ref_detector = 0; - - cmd->sub_band = WL1271_PD_REFERENCE_POINT_BAND_B_G; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal_p2g(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_p2g *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_P2G_CAL; - - cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_P2G_CAL failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal(struct wl1271 *wl) -{ - /* - * FIXME: we must make sure that we're not sleeping when calibration - * is done - */ - int ret; - - wl1271_notice("performing tx calibration"); - - ret = wl1271_cmd_cal_channel_tune(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_cal_update_ref_point(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_cal_p2g(wl); - if (ret < 0) - return ret; - - return ret; -} - int wl1271_cmd_general_parms(struct wl1271 *wl) { struct wl1271_general_parms_cmd *gen_parms; @@ -212,8 +118,8 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; - memcpy(gen_parms->params, wl->nvs->general_params, - WL1271_NVS_GENERAL_PARAMS_SIZE); + memcpy(&gen_parms->general_params, &wl->nvs->general_params, + sizeof(struct wl1271_ini_general_params)); ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); if (ret < 0) @@ -226,7 +132,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) int wl1271_cmd_radio_parms(struct wl1271 *wl) { struct wl1271_radio_parms_cmd *radio_parms; - struct conf_radio_parms *rparam = &wl->conf.init.radioparam; + struct wl1271_ini_general_params *gp = &wl->nvs->general_params; int ret; if (!wl->nvs) @@ -238,13 +144,20 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; - memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params, - WL1271_NVS_STAT_RADIO_PARAMS_SIZE); - memcpy(radio_parms->dyn_radio_params, - wl->nvs->dyn_radio_params[rparam->fem], - WL1271_NVS_DYN_RADIO_PARAMS_SIZE); - - /* FIXME: current NVS is missing 5GHz parameters */ + /* 2.4GHz parameters */ + memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2, + sizeof(struct wl1271_ini_band_params_2)); + memcpy(&radio_parms->dyn_params_2, + &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, + sizeof(struct wl1271_ini_fem_params_2)); + + /* 5GHz parameters */ + memcpy(&radio_parms->static_params_5, + &wl->nvs->stat_radio_params_5, + sizeof(struct wl1271_ini_band_params_5)); + memcpy(&radio_parms->dyn_params_5, + &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, + sizeof(struct wl1271_ini_fem_params_5)); wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", radio_parms, sizeof(*radio_parms)); @@ -288,20 +201,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) { - static bool do_cal = true; struct wl1271_cmd_join *join; int ret, i; u8 *bssid; - /* FIXME: remove when we get calibration from the factory */ - if (do_cal) { - ret = wl1271_cmd_cal(wl); - if (ret < 0) - wl1271_warning("couldn't calibrate"); - else - do_cal = false; - } - join = kzalloc(sizeof(*join), GFP_KERNEL); if (!join) { ret = -ENOMEM; @@ -329,12 +232,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) join->channel = wl->channel; join->ssid_len = wl->ssid_len; memcpy(join->ssid, wl->ssid, wl->ssid_len); - join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH; - - /* increment the session counter */ - wl->session_counter++; - if (wl->session_counter >= SESSION_COUNTER_MAX) - wl->session_counter = 0; join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; @@ -517,7 +414,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) ps_params->send_null_data = send; ps_params->retries = 5; ps_params->hang_over_period = 1; - ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */ + ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set); ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, sizeof(*ps_params), 0); @@ -566,140 +463,6 @@ out: return ret; } -int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 active_scan, - u8 high_prio, u8 band, u8 probe_requests) -{ - - struct wl1271_cmd_trigger_scan_to *trigger = NULL; - struct wl1271_cmd_scan *params = NULL; - struct ieee80211_channel *channels; - u32 rate; - int i, j, n_ch, ret; - u16 scan_options = 0; - u8 ieee_band; - - if (band == WL1271_SCAN_BAND_2_4_GHZ) { - ieee_band = IEEE80211_BAND_2GHZ; - rate = wl->conf.tx.basic_rate; - } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) { - ieee_band = IEEE80211_BAND_2GHZ; - rate = wl->conf.tx.basic_rate; - } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) { - ieee_band = IEEE80211_BAND_5GHZ; - rate = wl->conf.tx.basic_rate_5; - } else - return -EINVAL; - - if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) - return -EINVAL; - - channels = wl->hw->wiphy->bands[ieee_band]->channels; - n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels; - - if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) - return -EINVAL; - - params = kzalloc(sizeof(*params), GFP_KERNEL); - if (!params) - return -ENOMEM; - - params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); - params->params.rx_filter_options = - cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - - if (!active_scan) - scan_options |= WL1271_SCAN_OPT_PASSIVE; - if (high_prio) - scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH; - params->params.scan_options = cpu_to_le16(scan_options); - - params->params.num_probe_requests = probe_requests; - params->params.tx_rate = cpu_to_le32(rate); - params->params.tid_trigger = 0; - params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; - - if (band == WL1271_SCAN_BAND_DUAL) - params->params.band = WL1271_SCAN_BAND_2_4_GHZ; - else - params->params.band = band; - - for (i = 0, j = 0; i < n_ch && i < WL1271_SCAN_MAX_CHANNELS; i++) { - if (!(channels[i].flags & IEEE80211_CHAN_DISABLED)) { - params->channels[j].min_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); - params->channels[j].max_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); - memset(¶ms->channels[j].bssid_lsb, 0xff, 4); - memset(¶ms->channels[j].bssid_msb, 0xff, 2); - params->channels[j].early_termination = 0; - params->channels[j].tx_power_att = - WL1271_SCAN_CURRENT_TX_PWR; - params->channels[j].channel = channels[i].hw_value; - j++; - } - } - - params->params.num_channels = j; - - if (ssid_len && ssid) { - params->params.ssid_len = ssid_len; - memcpy(params->params.ssid, ssid, ssid_len); - } - - ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len, - ie, ie_len, ieee_band); - if (ret < 0) { - wl1271_error("PROBE request template failed"); - goto out; - } - - trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); - if (!trigger) { - ret = -ENOMEM; - goto out; - } - - /* disable the timeout */ - trigger->timeout = 0; - - ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, - sizeof(*trigger), 0); - if (ret < 0) { - wl1271_error("trigger scan to failed for hw scan"); - goto out; - } - - wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); - - set_bit(WL1271_FLAG_SCANNING, &wl->flags); - if (wl1271_11a_enabled()) { - wl->scan.state = band; - if (band == WL1271_SCAN_BAND_DUAL) { - wl->scan.active = active_scan; - wl->scan.high_prio = high_prio; - wl->scan.probe_requests = probe_requests; - if (ssid_len && ssid) { - wl->scan.ssid_len = ssid_len; - memcpy(wl->scan.ssid, ssid, ssid_len); - } else - wl->scan.ssid_len = 0; - } - } - - ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0); - if (ret < 0) { - wl1271_error("SCAN failed"); - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - goto out; - } - -out: - kfree(params); - kfree(trigger); - return ret; -} - int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates) { @@ -804,7 +567,7 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) goto out; ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, - skb->len, 0, wl->basic_rate); + skb->len, 0, wl->basic_rate_set); out: dev_kfree_skb(skb); diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index f2820b42a94..af577ee8eb0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -41,9 +41,6 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, size_t len); -int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 active_scan, - u8 high_prio, u8 band, u8 probe_requests); int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates); int wl1271_cmd_build_null_data(struct wl1271 *wl); @@ -136,14 +133,14 @@ struct wl1271_cmd_header { __le16 status; /* payload */ u8 data[0]; -} __attribute__ ((packed)); +} __packed; #define WL1271_CMD_MAX_PARAMS 572 struct wl1271_command { struct wl1271_cmd_header header; u8 parameters[WL1271_CMD_MAX_PARAMS]; -} __attribute__ ((packed)); +} __packed; enum { CMD_MAILBOX_IDLE = 0, @@ -196,7 +193,7 @@ struct cmd_read_write_memory { of this field is the Host in WRITE command or the Wilink in READ command. */ u8 value[MAX_READ_SIZE]; -} __attribute__ ((packed)); +} __packed; #define CMDMBOX_HEADER_LEN 4 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 @@ -243,14 +240,14 @@ struct wl1271_cmd_join { u8 ssid[IW_ESSID_MAX_SIZE]; u8 ctrl; /* JOIN_CMD_CTRL_* */ u8 reserved[3]; -} __attribute__ ((packed)); +} __packed; struct cmd_enabledisable_path { struct wl1271_cmd_header header; u8 channel; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; #define WL1271_RATE_AUTOMATIC 0 @@ -266,7 +263,7 @@ struct wl1271_cmd_template_set { u8 aflags; u8 reserved; u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE]; -} __attribute__ ((packed)); +} __packed; #define TIM_ELE_ID 5 #define PARTIAL_VBM_MAX 251 @@ -278,7 +275,7 @@ struct wl1271_tim { u8 dtim_period; u8 bitmap_ctrl; u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ -} __attribute__ ((packed)); +} __packed; enum wl1271_cmd_ps_mode { STATION_ACTIVE_MODE, @@ -298,7 +295,7 @@ struct wl1271_cmd_ps_params { */ u8 hang_over_period; __le32 null_data_rate; -} __attribute__ ((packed)); +} __packed; /* HW encryption keys */ #define NUM_ACCESS_CATEGORIES_COPY 4 @@ -348,77 +345,12 @@ struct wl1271_cmd_set_keys { u8 key[MAX_KEY_SIZE]; __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; -} __attribute__ ((packed)); - - -#define WL1271_SCAN_MAX_CHANNELS 24 -#define WL1271_SCAN_DEFAULT_TAG 1 -#define WL1271_SCAN_CURRENT_TX_PWR 0 -#define WL1271_SCAN_OPT_ACTIVE 0 -#define WL1271_SCAN_OPT_PASSIVE 1 -#define WL1271_SCAN_OPT_PRIORITY_HIGH 4 -#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */ -#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ -#define WL1271_SCAN_BAND_2_4_GHZ 0 -#define WL1271_SCAN_BAND_5_GHZ 1 -#define WL1271_SCAN_BAND_DUAL 2 - -struct basic_scan_params { - __le32 rx_config_options; - __le32 rx_filter_options; - /* Scan option flags (WL1271_SCAN_OPT_*) */ - __le16 scan_options; - /* Number of scan channels in the list (maximum 30) */ - u8 num_channels; - /* This field indicates the number of probe requests to send - per channel for an active scan */ - u8 num_probe_requests; - /* Rate bit field for sending the probes */ - __le32 tx_rate; - u8 tid_trigger; - u8 ssid_len; - /* in order to align */ - u8 padding1[2]; - u8 ssid[IW_ESSID_MAX_SIZE]; - /* Band to scan */ - u8 band; - u8 use_ssid_list; - u8 scan_tag; - u8 padding2; -} __attribute__ ((packed)); - -struct basic_scan_channel_params { - /* Duration in TU to wait for frames on a channel for active scan */ - __le32 min_duration; - __le32 max_duration; - __le32 bssid_lsb; - __le16 bssid_msb; - u8 early_termination; - u8 tx_power_att; - u8 channel; - /* FW internal use only! */ - u8 dfs_candidate; - u8 activity_detected; - u8 pad; -} __attribute__ ((packed)); - -struct wl1271_cmd_scan { - struct wl1271_cmd_header header; - - struct basic_scan_params params; - struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS]; -} __attribute__ ((packed)); - -struct wl1271_cmd_trigger_scan_to { - struct wl1271_cmd_header header; - - __le32 timeout; -} __attribute__ ((packed)); +} __packed; struct wl1271_cmd_test_header { u8 id; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; enum wl1271_channel_tune_bands { WL1271_CHANNEL_TUNE_BAND_2_4, @@ -439,25 +371,31 @@ struct wl1271_general_parms_cmd { struct wl1271_cmd_test_header test; - u8 params[WL1271_NVS_GENERAL_PARAMS_SIZE]; - s8 reserved[23]; -} __attribute__ ((packed)); + struct wl1271_ini_general_params general_params; -#define WL1271_STAT_RADIO_PARAMS_5_SIZE 29 -#define WL1271_DYN_RADIO_PARAMS_5_SIZE 104 + u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 sr_sen_n_p; + u8 sr_sen_n_p_gain; + u8 sr_sen_nrn; + u8 sr_sen_prn; + u8 padding[3]; +} __packed; struct wl1271_radio_parms_cmd { struct wl1271_cmd_header header; struct wl1271_cmd_test_header test; - u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE]; - u8 stat_radio_params_5[WL1271_STAT_RADIO_PARAMS_5_SIZE]; + /* Static radio parameters */ + struct wl1271_ini_band_params_2 static_params_2; + struct wl1271_ini_band_params_5 static_params_5; - u8 dyn_radio_params[WL1271_NVS_DYN_RADIO_PARAMS_SIZE]; - u8 reserved; - u8 dyn_radio_params_5[WL1271_DYN_RADIO_PARAMS_5_SIZE]; -} __attribute__ ((packed)); + /* Dynamic radio parameters */ + struct wl1271_ini_fem_params_2 dyn_params_2; + u8 padding2; + struct wl1271_ini_fem_params_5 dyn_params_5; + u8 padding3[2]; +} __packed; struct wl1271_cmd_cal_channel_tune { struct wl1271_cmd_header header; @@ -468,7 +406,7 @@ struct wl1271_cmd_cal_channel_tune { u8 channel; __le16 radio_status; -} __attribute__ ((packed)); +} __packed; struct wl1271_cmd_cal_update_ref_point { struct wl1271_cmd_header header; @@ -479,7 +417,7 @@ struct wl1271_cmd_cal_update_ref_point { __le32 ref_detector; u8 sub_band; u8 padding[3]; -} __attribute__ ((packed)); +} __packed; #define MAX_TLV_LENGTH 400 #define MAX_NVS_VERSION_LENGTH 12 @@ -501,7 +439,7 @@ struct wl1271_cmd_cal_p2g { u8 sub_band_mask; u8 padding2; -} __attribute__ ((packed)); +} __packed; /* @@ -529,6 +467,6 @@ struct wl1271_cmd_disconnect { u8 type; u8 padding; -} __attribute__ ((packed)); +} __packed; #endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index d046d044b5b..0435ffda8f7 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -874,6 +874,13 @@ struct conf_conn_settings { u8 ps_poll_threshold; /* + * PS Poll failure recovery ACTIVE period length + * + * Range: u32 (ms) + */ + u32 ps_poll_recovery_period; + + /* * Configuration of signal average weights. */ struct conf_sig_weights sig_weights; @@ -948,14 +955,6 @@ struct conf_radio_parms { u8 fem; }; -struct conf_init_settings { - /* - * Configure radio parameters. - */ - struct conf_radio_parms radioparam; - -}; - struct conf_itrim_settings { /* enable dco itrim */ u8 enable; @@ -1022,7 +1021,6 @@ struct conf_drv_settings { struct conf_rx_settings rx; struct conf_tx_settings tx; struct conf_conn_settings conn; - struct conf_init_settings init; struct conf_itrim_settings itrim; struct conf_pm_config_settings pm_config; struct conf_roam_trigger_settings roam_trigger; diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index cf37aa6eb13..25ce2cd5e3f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -26,36 +26,64 @@ #include "wl1271_io.h" #include "wl1271_event.h" #include "wl1271_ps.h" +#include "wl1271_scan.h" #include "wl12xx_80211.h" -static int wl1271_event_scan_complete(struct wl1271 *wl, - struct event_mailbox *mbox) +void wl1271_pspoll_work(struct work_struct *work) { - wl1271_debug(DEBUG_EVENT, "status: 0x%x", - mbox->scheduled_scan_status); - - if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { - if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { - /* 2.4 GHz band scanned, scan 5 GHz band, pretend - * to the wl1271_cmd_scan function that we are not - * scanning as it checks that. - */ - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - /* FIXME: ie missing! */ - wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, - NULL, 0, - wl->scan.active, - wl->scan.high_prio, - WL1271_SCAN_BAND_5_GHZ, - wl->scan.probe_requests); - } else { - mutex_unlock(&wl->mutex); - ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - } + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, pspoll_work); + + wl1271_debug(DEBUG_EVENT, "pspoll work"); + + mutex_lock(&wl->mutex); + + if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) + goto out; + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + /* + * if we end up here, then we were in powersave when the pspoll + * delivery failure occurred, and no-one changed state since, so + * we should go back to powersave. + */ + wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true); + +out: + mutex_unlock(&wl->mutex); +}; + +static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl) +{ + int delay = wl->conf.conn.ps_poll_recovery_period; + int ret; + + wl->ps_poll_failures++; + if (wl->ps_poll_failures == 1) + wl1271_info("AP with dysfunctional ps-poll, " + "trying to work around it."); + + /* force active mode receive data from the AP */ + if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true); + if (ret < 0) + return; + set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); + ieee80211_queue_delayed_work(wl->hw, &wl->pspoll_work, + msecs_to_jiffies(delay)); } - return 0; + + /* + * If already in active mode, lets we should be getting data from + * the AP right away. If we enter PSM too fast after this, and data + * remains on the AP, we will get another event like this, and we'll + * go into active once more. + */ } static int wl1271_event_ps_report(struct wl1271 *wl, @@ -163,9 +191,19 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector); if (vector & SCAN_COMPLETE_EVENT_ID) { - ret = wl1271_event_scan_complete(wl, mbox); - if (ret < 0) - return ret; + wl1271_debug(DEBUG_EVENT, "status: 0x%x", + mbox->scheduled_scan_status); + + wl1271_scan_stm(wl); + } + + /* disable dynamic PS when requested by the firmware */ + if (vector & SOFT_GEMINI_SENSE_EVENT_ID && + wl->bss_type == BSS_TYPE_STA_BSS) { + if (mbox->soft_gemini_sense_info) + ieee80211_disable_dyn_ps(wl->vif); + else + ieee80211_enable_dyn_ps(wl->vif); } /* @@ -191,6 +229,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) return ret; } + if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) + wl1271_event_pspoll_delivery_fail(wl); + if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); if (wl->vif) diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h index 58371008f27..e4751667cf5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.h +++ b/drivers/net/wireless/wl12xx/wl1271_event.h @@ -85,7 +85,7 @@ struct event_debug_report { __le32 report_1; __le32 report_2; __le32 report_3; -} __attribute__ ((packed)); +} __packed; #define NUM_OF_RSSI_SNR_TRIGGERS 8 @@ -116,10 +116,11 @@ struct event_mailbox { u8 ps_status; u8 reserved_5[29]; -} __attribute__ ((packed)); +} __packed; int wl1271_event_unmask(struct wl1271 *wl); void wl1271_event_mbox_config(struct wl1271 *wl); int wl1271_event_handle(struct wl1271 *wl, u8 mbox); +void wl1271_pspoll_work(struct work_struct *work); #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_ini.h b/drivers/net/wireless/wl12xx/wl1271_ini.h new file mode 100644 index 00000000000..2313047d401 --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl1271_ini.h @@ -0,0 +1,123 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2010 Nokia Corporation + * + * Contact: Luciano Coelho <luciano.coelho@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1271_INI_H__ +#define __WL1271_INI_H__ + +#define WL1271_INI_MAX_SMART_REFLEX_PARAM 16 + +struct wl1271_ini_general_params { + u8 ref_clock; + u8 settling_time; + u8 clk_valid_on_wakeup; + u8 dc2dc_mode; + u8 dual_mode_select; + u8 tx_bip_fem_auto_detect; + u8 tx_bip_fem_manufacturer; + u8 general_settings; + u8 sr_state; + u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM]; + u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM]; +} __packed; + +#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15 + +struct wl1271_ini_band_params_2 { + u8 rx_trace_insertion_loss; + u8 tx_trace_loss; + u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; +} __packed; + +#define WL1271_INI_RATE_GROUP_COUNT 6 +#define WL1271_INI_CHANNEL_COUNT_2 14 + +struct wl1271_ini_fem_params_2 { + __le16 tx_bip_ref_pd_voltage; + u8 tx_bip_ref_power; + u8 tx_bip_ref_offset; + u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2]; + u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2]; + u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; + u8 rx_fem_insertion_loss; + u8 degraded_low_to_normal_thr; + u8 normal_to_degraded_high_thr; +} __packed; + +#define WL1271_INI_CHANNEL_COUNT_5 35 +#define WL1271_INI_SUB_BAND_COUNT_5 7 + +struct wl1271_ini_band_params_5 { + u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_trace_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE]; +} __packed; + +struct wl1271_ini_fem_params_5 { + __le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5]; + u8 tx_per_rate_pwr_limits_normal[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_degraded[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_rate_pwr_limits_extreme[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5]; + u8 tx_pd_vs_rate_offsets[WL1271_INI_RATE_GROUP_COUNT]; + u8 tx_ibias[WL1271_INI_RATE_GROUP_COUNT]; + u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5]; + u8 degraded_low_to_normal_thr; + u8 normal_to_degraded_high_thr; +} __packed; + + +/* NVS data structure */ +#define WL1271_INI_NVS_SECTION_SIZE 468 +#define WL1271_INI_FEM_MODULE_COUNT 2 + +#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 + +struct wl1271_nvs_file { + /* NVS section */ + u8 nvs[WL1271_INI_NVS_SECTION_SIZE]; + + /* INI section */ + struct wl1271_ini_general_params general_params; + u8 padding1; + struct wl1271_ini_band_params_2 stat_radio_params_2; + u8 padding2; + struct { + struct wl1271_ini_fem_params_2 params; + u8 padding; + } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; + struct wl1271_ini_band_params_5 stat_radio_params_5; + u8 padding3; + struct { + struct wl1271_ini_fem_params_5 params; + u8 padding; + } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; +} __packed; + +#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index b7d9137851a..9d68f0012f0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -28,7 +28,6 @@ #include <linux/crc32.h> #include <linux/etherdevice.h> #include <linux/vmalloc.h> -#include <linux/inetdevice.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -45,6 +44,7 @@ #include "wl1271_cmd.h" #include "wl1271_boot.h" #include "wl1271_testmode.h" +#include "wl1271_scan.h" #define WL1271_BOOT_RETRIES 3 @@ -55,7 +55,7 @@ static struct conf_drv_settings default_conf = { [CONF_SG_HV3_MAX_OVERRIDE] = 0, [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, [CONF_SG_BT_LOAD_RATIO] = 50, - [CONF_SG_AUTO_PS_MODE] = 0, + [CONF_SG_AUTO_PS_MODE] = 1, [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, [CONF_SG_ANTENNA_CONFIGURATION] = 0, @@ -234,18 +234,14 @@ static struct conf_drv_settings default_conf = { .beacon_rx_timeout = 10000, .broadcast_timeout = 20000, .rx_broadcast_in_ps = 1, - .ps_poll_threshold = 20, + .ps_poll_threshold = 10, + .ps_poll_recovery_period = 700, .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 10, .psm_entry_retries = 3, .keep_alive_interval = 55000, .max_listen_interval = 20, }, - .init = { - .radioparam = { - .fem = 1, - } - }, .itrim = { .enable = false, .timeout = 50000, @@ -566,14 +562,21 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) return ret; } - if (fw->size != sizeof(struct wl1271_nvs_file)) { + /* + * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band + * configurations) can be removed when those NVS files stop floating + * around. + */ + if (fw->size != sizeof(struct wl1271_nvs_file) && + (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE || + wl1271_11a_enabled())) { wl1271_error("nvs size is not as expected: %zu != %zu", fw->size, sizeof(struct wl1271_nvs_file)); ret = -EILSEQ; goto out; } - wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); + wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); if (!wl->nvs) { wl1271_error("could not allocate memory for the nvs file"); @@ -581,8 +584,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) goto out; } - memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); - out: release_firmware(fw); @@ -811,93 +812,6 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, - void *arg) -{ - struct net_device *dev; - struct wireless_dev *wdev; - struct wiphy *wiphy; - struct ieee80211_hw *hw; - struct wl1271 *wl; - struct wl1271 *wl_temp; - struct in_device *idev; - struct in_ifaddr *ifa = arg; - int ret = 0; - - /* FIXME: this ugly function should probably be implemented in the - * mac80211, and here should only be a simple callback handling actual - * setting of the filters. Now we need to dig up references to - * various structures to gain access to what we need. - * Also, because of this, there is no "initial" setting of the filter - * in "op_start", because we don't want to dig up struct net_device - * there - the filter will be set upon first change of the interface - * IP address. */ - - dev = ifa->ifa_dev->dev; - - wdev = dev->ieee80211_ptr; - if (wdev == NULL) - return NOTIFY_DONE; - - wiphy = wdev->wiphy; - if (wiphy == NULL) - return NOTIFY_DONE; - - hw = wiphy_priv(wiphy); - if (hw == NULL) - return NOTIFY_DONE; - - /* Check that the interface is one supported by this driver. */ - wl_temp = hw->priv; - list_for_each_entry(wl, &wl_list, list) { - if (wl == wl_temp) - break; - } - if (wl != wl_temp) - return NOTIFY_DONE; - - /* Get the interface IP address for the device. "ifa" will become - NULL if: - - there is no IPV4 protocol address configured - - there are multiple (virtual) IPV4 addresses configured - When "ifa" is NULL, filtering will be disabled. - */ - ifa = NULL; - idev = dev->ip_ptr; - if (idev) - ifa = idev->ifa_list; - - if (ifa && ifa->ifa_next) - ifa = NULL; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - if (ifa) - ret = wl1271_acx_arp_ip_filter(wl, true, - (u8 *)&ifa->ifa_address, - ACX_IPV4_VERSION); - else - ret = wl1271_acx_arp_ip_filter(wl, false, NULL, - ACX_IPV4_VERSION); - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return NOTIFY_OK; -} - -static struct notifier_block wl1271_dev_notifier = { - .notifier_call = wl1271_dev_notify, -}; - - static int wl1271_op_start(struct ieee80211_hw *hw) { wl1271_debug(DEBUG_MAC80211, "mac80211 start"); @@ -925,6 +839,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wl1271 *wl = hw->priv; + struct wiphy *wiphy = hw->wiphy; int retries = WL1271_BOOT_RETRIES; int ret = 0; @@ -978,6 +893,12 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, wl->state = WL1271_STATE_ON; wl1271_info("firmware booted (%s)", wl->chip.fw_ver); + + /* update hw/fw version info in wiphy struct */ + wiphy->hw_version = wl->chip.id; + strncpy(wiphy->fw_version, wl->chip.fw_ver, + sizeof(wiphy->fw_version)); + goto out; irq_disable: @@ -1001,10 +922,8 @@ power_off: out: mutex_unlock(&wl->mutex); - if (!ret) { + if (!ret) list_add(&wl->list, &wl_list); - register_inetaddr_notifier(&wl1271_dev_notifier); - } return ret; } @@ -1015,8 +934,6 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, struct wl1271 *wl = hw->priv; int i; - unregister_inetaddr_notifier(&wl1271_dev_notifier); - mutex_lock(&wl->mutex); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); @@ -1026,10 +943,17 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, WARN_ON(wl->state != WL1271_STATE_ON); - if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) { + /* enable dyn ps just in case (if left on due to fw crash etc) */ + if (wl->bss_type == BSS_TYPE_STA_BSS) + ieee80211_enable_dyn_ps(wl->vif); + + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, true); mutex_lock(&wl->mutex); + wl->scan.state = WL1271_SCAN_STATE_IDLE; + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; } wl->state = WL1271_STATE_OFF; @@ -1040,11 +964,12 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); + cancel_delayed_work_sync(&wl->pspoll_work); mutex_lock(&wl->mutex); /* let's notify MAC80211 about the remaining pending TX frames */ - wl1271_tx_flush(wl); + wl1271_tx_reset(wl); wl1271_power_off(wl); memset(wl->bssid, 0, ETH_ALEN); @@ -1241,6 +1166,42 @@ static u32 wl1271_min_rate_get(struct wl1271 *wl) return rate; } +static int wl1271_handle_idle(struct wl1271 *wl, bool idle) +{ + int ret; + + if (idle) { + if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { + ret = wl1271_unjoin(wl); + if (ret < 0) + goto out; + } + wl->rate_set = wl1271_min_rate_get(wl); + wl->sta_rate_set = 0; + ret = wl1271_acx_rate_policies(wl); + if (ret < 0) + goto out; + ret = wl1271_acx_keep_alive_config( + wl, CMD_TEMPL_KLV_IDX_NULL_DATA, + ACX_KEEP_ALIVE_TPL_INVALID); + if (ret < 0) + goto out; + set_bit(WL1271_FLAG_IDLE, &wl->flags); + } else { + /* increment the session counter */ + wl->session_counter++; + if (wl->session_counter >= SESSION_COUNTER_MAX) + wl->session_counter = 0; + ret = wl1271_dummy_join(wl); + if (ret < 0) + goto out; + clear_bit(WL1271_FLAG_IDLE, &wl->flags); + } + +out: + return ret; +} + static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) { struct wl1271 *wl = hw->priv; @@ -1255,6 +1216,15 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) conf->power_level, conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); + /* + * mac80211 will go to idle nearly immediately after transmitting some + * frames, such as the deauth. To make sure those frames reach the air, + * wait here until the TX queue is fully flushed. + */ + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (conf->flags & IEEE80211_CONF_IDLE)) + wl1271_tx_flush(wl); + mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) @@ -1295,24 +1265,18 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_IDLE) { - if (conf->flags & IEEE80211_CONF_IDLE && - test_bit(WL1271_FLAG_JOINED, &wl->flags)) - wl1271_unjoin(wl); - else if (!(conf->flags & IEEE80211_CONF_IDLE)) - wl1271_dummy_join(wl); - - if (conf->flags & IEEE80211_CONF_IDLE) { - wl->rate_set = wl1271_min_rate_get(wl); - wl->sta_rate_set = 0; - wl1271_acx_rate_policies(wl); - wl1271_acx_keep_alive_config( - wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_INVALID); - set_bit(WL1271_FLAG_IDLE, &wl->flags); - } else - clear_bit(WL1271_FLAG_IDLE, &wl->flags); + ret = wl1271_handle_idle(wl, conf->flags & IEEE80211_CONF_IDLE); + if (ret < 0) + wl1271_warning("idle mode change failed %d", ret); } + /* + * if mac80211 changes the PSM mode, make sure the mode is not + * incorrectly changed after the pspoll failure active window. + */ + if (changed & IEEE80211_CONF_CHANGE_PS) + clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); + if (conf->flags & IEEE80211_CONF_PS && !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); @@ -1595,13 +1559,9 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, goto out; if (wl1271_11a_enabled()) - ret = wl1271_cmd_scan(hw->priv, ssid, len, - req->ie, req->ie_len, 1, 0, - WL1271_SCAN_BAND_DUAL, 3); + ret = wl1271_scan(hw->priv, ssid, len, req); else - ret = wl1271_cmd_scan(hw->priv, ssid, len, - req->ie, req->ie_len, 1, 0, - WL1271_SCAN_BAND_2_4_GHZ, 3); + ret = wl1271_scan(hw->priv, ssid, len, req); wl1271_ps_elp_sleep(wl); @@ -1774,6 +1734,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, wl->aid = bss_conf->aid; set_assoc = true; + wl->ps_poll_failures = 0; + /* * use basic rates from AP, and determine lowest rate * to use with control frames. @@ -1823,6 +1785,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); wl->aid = 0; + /* re-enable dynamic ps - just in case */ + ieee80211_enable_dyn_ps(wl->vif); + /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl); wl->basic_rate = wl1271_min_rate_get(wl); @@ -1871,6 +1836,19 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, } } + if (changed & BSS_CHANGED_ARP_FILTER) { + __be32 addr = bss_conf->arp_addr_list[0]; + WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); + + if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled) + ret = wl1271_acx_arp_ip_filter(wl, true, addr); + else + ret = wl1271_acx_arp_ip_filter(wl, false, addr); + + if (ret < 0) + goto out_sleep; + } + if (do_join) { ret = wl1271_join(wl, set_assoc); if (ret < 0) { @@ -1929,6 +1907,48 @@ out: return ret; } +static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) +{ + + struct wl1271 *wl = hw->priv; + u64 mactime = ULLONG_MAX; + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf"); + + mutex_lock(&wl->mutex); + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_acx_tsf_info(wl, &mactime); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return mactime; +} + +static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct wl1271 *wl = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = wl->noise; + + return 0; +} /* can't be const, mac80211 writes to this */ static struct ieee80211_rate wl1271_rates[] = { @@ -1991,7 +2011,7 @@ static struct ieee80211_channel wl1271_channels[] = { }; /* mapping to indexes for wl1271_rates */ -const static u8 wl1271_rate_to_idx_2ghz[] = { +static const u8 wl1271_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ @@ -2103,7 +2123,7 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = { }; /* mapping to indexes for wl1271_rates_5ghz */ -const static u8 wl1271_rate_to_idx_5ghz[] = { +static const u8 wl1271_rate_to_idx_5ghz[] = { /* MCS rates are used only with 11n */ CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ @@ -2139,7 +2159,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = { .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), }; -const static u8 *wl1271_band_rate_to_idx[] = { +static const u8 *wl1271_band_rate_to_idx[] = { [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz, [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz }; @@ -2158,6 +2178,8 @@ static const struct ieee80211_ops wl1271_ops = { .bss_info_changed = wl1271_op_bss_info_changed, .set_rts_threshold = wl1271_op_set_rts_threshold, .conf_tx = wl1271_op_conf_tx, + .get_tsf = wl1271_op_get_tsf, + .get_survey = wl1271_op_get_survey, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; @@ -2350,15 +2372,13 @@ struct ieee80211_hw *wl1271_alloc_hw(void) goto err_hw_alloc; } - plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL); + plat_dev = kmemdup(&wl1271_device, sizeof(wl1271_device), GFP_KERNEL); if (!plat_dev) { wl1271_error("could not allocate platform_device"); ret = -ENOMEM; goto err_plat_alloc; } - memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device)); - wl = hw->priv; memset(wl, 0, sizeof(*wl)); @@ -2370,6 +2390,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) skb_queue_head_init(&wl->tx_queue); INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); + INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); wl->channel = WL1271_DEFAULT_CHANNEL; wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index b98fb643fab..019aa79cd9d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -53,13 +53,14 @@ static void wl1271_rx_status(struct wl1271 *wl, status->band = wl->band; status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); + status->signal = desc->rssi; + /* - * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the - * timestamp from the beacon (acx_tsf_info). In BSS mode (infra) we - * only need the mactime for monitor mode. For now the mactime is - * not valid, so RX_FLAG_TSFT should not be set + * FIXME: In wl1251, the SNR should be divided by two. In wl1271 we + * need to divide by two for now, but TI has been discussing about + * changing it. This needs to be rechecked. */ - status->signal = desc->rssi; + wl->noise = desc->rssi - (desc->snr >> 1); status->freq = ieee80211_channel_to_frequency(desc->channel); diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h index b89be4758e7..13a232333b1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.h +++ b/drivers/net/wireless/wl12xx/wl1271_rx.h @@ -113,7 +113,7 @@ struct wl1271_rx_descriptor { u8 process_id; u8 pad_len; u8 reserved; -} __attribute__ ((packed)); +} __packed; void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c new file mode 100644 index 00000000000..fec43eed8c5 --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -0,0 +1,257 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho <luciano.coelho@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/ieee80211.h> + +#include "wl1271.h" +#include "wl1271_cmd.h" +#include "wl1271_scan.h" +#include "wl1271_acx.h" + +static int wl1271_get_scan_channels(struct wl1271 *wl, + struct cfg80211_scan_request *req, + struct basic_scan_channel_params *channels, + enum ieee80211_band band, bool passive) +{ + int i, j; + u32 flags; + + for (i = 0, j = 0; + i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; + i++) { + + flags = req->channels[i]->flags; + + if (!wl->scan.scanned_ch[i] && + !(flags & IEEE80211_CHAN_DISABLED) && + ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && + (req->channels[i]->band == band)) { + + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", + req->channels[i]->band, + req->channels[i]->center_freq); + wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", + req->channels[i]->hw_value, + req->channels[i]->flags); + wl1271_debug(DEBUG_SCAN, + "max_antenna_gain %d, max_power %d", + req->channels[i]->max_antenna_gain, + req->channels[i]->max_power); + wl1271_debug(DEBUG_SCAN, "beacon_found %d", + req->channels[i]->beacon_found); + + channels[j].min_duration = + cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); + channels[j].max_duration = + cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); + channels[j].early_termination = 0; + channels[j].tx_power_att = req->channels[i]->max_power; + channels[j].channel = req->channels[i]->hw_value; + + memset(&channels[j].bssid_lsb, 0xff, 4); + memset(&channels[j].bssid_msb, 0xff, 2); + + /* Mark the channels we already used */ + wl->scan.scanned_ch[i] = true; + + j++; + } + } + + return j; +} + +#define WL1271_NOTHING_TO_SCAN 1 + +static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, + bool passive, u32 basic_rate) +{ + struct wl1271_cmd_scan *cmd; + struct wl1271_cmd_trigger_scan_to *trigger; + int ret; + u16 scan_options = 0; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); + if (!cmd || !trigger) { + ret = -ENOMEM; + goto out; + } + + /* We always use high priority scans */ + scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; + if(passive) + scan_options |= WL1271_SCAN_OPT_PASSIVE; + cmd->params.scan_options = cpu_to_le16(scan_options); + + cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, + cmd->channels, + band, passive); + if (cmd->params.n_ch == 0) { + ret = WL1271_NOTHING_TO_SCAN; + goto out; + } + + cmd->params.tx_rate = cpu_to_le32(basic_rate); + cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); + cmd->params.rx_filter_options = + cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); + + cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS; + cmd->params.tx_rate = cpu_to_le32(basic_rate); + cmd->params.tid_trigger = 0; + cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; + + if (band == IEEE80211_BAND_2GHZ) + cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ; + else + cmd->params.band = WL1271_SCAN_BAND_5_GHZ; + + if (wl->scan.ssid_len && wl->scan.ssid) { + cmd->params.ssid_len = wl->scan.ssid_len; + memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); + } + + ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len, + wl->scan.req->ie, wl->scan.req->ie_len, + band); + if (ret < 0) { + wl1271_error("PROBE request template failed"); + goto out; + } + + /* disable the timeout */ + trigger->timeout = 0; + ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, + sizeof(*trigger), 0); + if (ret < 0) { + wl1271_error("trigger scan to failed for hw scan"); + goto out; + } + + wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd)); + + ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("SCAN failed"); + goto out; + } + +out: + kfree(cmd); + kfree(trigger); + return ret; +} + +void wl1271_scan_stm(struct wl1271 *wl) +{ + int ret; + + switch (wl->scan.state) { + case WL1271_SCAN_STATE_IDLE: + break; + + case WL1271_SCAN_STATE_2GHZ_ACTIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, + wl->conf.tx.basic_rate); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_2GHZ_PASSIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, + wl->conf.tx.basic_rate); + if (ret == WL1271_NOTHING_TO_SCAN) { + if (wl1271_11a_enabled()) + wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; + else + wl->scan.state = WL1271_SCAN_STATE_DONE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_5GHZ_ACTIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, + wl->conf.tx.basic_rate_5); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_5GHZ_PASSIVE: + ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, + wl->conf.tx.basic_rate_5); + if (ret == WL1271_NOTHING_TO_SCAN) { + wl->scan.state = WL1271_SCAN_STATE_DONE; + wl1271_scan_stm(wl); + } + + break; + + case WL1271_SCAN_STATE_DONE: + mutex_unlock(&wl->mutex); + ieee80211_scan_completed(wl->hw, false); + mutex_lock(&wl->mutex); + + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; + + wl->scan.state = WL1271_SCAN_STATE_IDLE; + break; + + default: + wl1271_error("invalid scan state"); + break; + } +} + +int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, + struct cfg80211_scan_request *req) +{ + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) + return -EBUSY; + + wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; + + if (ssid_len && ssid) { + wl->scan.ssid_len = ssid_len; + memcpy(wl->scan.ssid, ssid, ssid_len); + } else { + wl->scan.ssid_len = 0; + } + + wl->scan.req = req; + + wl->scan.scanned_ch = kzalloc(req->n_channels * + sizeof(*wl->scan.scanned_ch), + GFP_KERNEL); + wl1271_scan_stm(wl); + + return 0; +} diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h new file mode 100644 index 00000000000..f1815700f5f --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h @@ -0,0 +1,109 @@ +/* + * This file is part of wl1271 + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Contact: Luciano Coelho <luciano.coelho@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 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 St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __WL1271_SCAN_H__ +#define __WL1271_SCAN_H__ + +#include "wl1271.h" + +int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, + struct cfg80211_scan_request *req); +int wl1271_scan_build_probe_req(struct wl1271 *wl, + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len, u8 band); +void wl1271_scan_stm(struct wl1271 *wl); + +#define WL1271_SCAN_MAX_CHANNELS 24 +#define WL1271_SCAN_DEFAULT_TAG 1 +#define WL1271_SCAN_CURRENT_TX_PWR 0 +#define WL1271_SCAN_OPT_ACTIVE 0 +#define WL1271_SCAN_OPT_PASSIVE 1 +#define WL1271_SCAN_OPT_PRIORITY_HIGH 4 +#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */ +#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ +#define WL1271_SCAN_BAND_2_4_GHZ 0 +#define WL1271_SCAN_BAND_5_GHZ 1 +#define WL1271_SCAN_PROBE_REQS 3 + +enum { + WL1271_SCAN_STATE_IDLE, + WL1271_SCAN_STATE_2GHZ_ACTIVE, + WL1271_SCAN_STATE_2GHZ_PASSIVE, + WL1271_SCAN_STATE_5GHZ_ACTIVE, + WL1271_SCAN_STATE_5GHZ_PASSIVE, + WL1271_SCAN_STATE_DONE +}; + +struct basic_scan_params { + __le32 rx_config_options; + __le32 rx_filter_options; + /* Scan option flags (WL1271_SCAN_OPT_*) */ + __le16 scan_options; + /* Number of scan channels in the list (maximum 30) */ + u8 n_ch; + /* This field indicates the number of probe requests to send + per channel for an active scan */ + u8 n_probe_reqs; + /* Rate bit field for sending the probes */ + __le32 tx_rate; + u8 tid_trigger; + u8 ssid_len; + /* in order to align */ + u8 padding1[2]; + u8 ssid[IW_ESSID_MAX_SIZE]; + /* Band to scan */ + u8 band; + u8 use_ssid_list; + u8 scan_tag; + u8 padding2; +} __packed; + +struct basic_scan_channel_params { + /* Duration in TU to wait for frames on a channel for active scan */ + __le32 min_duration; + __le32 max_duration; + __le32 bssid_lsb; + __le16 bssid_msb; + u8 early_termination; + u8 tx_power_att; + u8 channel; + /* FW internal use only! */ + u8 dfs_candidate; + u8 activity_detected; + u8 pad; +} __packed; + +struct wl1271_cmd_scan { + struct wl1271_cmd_header header; + + struct basic_scan_params params; + struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS]; +} __packed; + +struct wl1271_cmd_trigger_scan_to { + struct wl1271_cmd_header header; + + __le32 timeout; +} __packed; + +#endif /* __WL1271_SCAN_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index d3d6f302f70..7059b5cccf0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -28,7 +28,7 @@ #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> #include <linux/mmc/card.h> -#include <plat/gpio.h> +#include <linux/gpio.h> #include "wl1271.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 5189b812f93..96d25fb5049 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -461,3 +461,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); MODULE_FIRMWARE(WL1271_FW_NAME); +MODULE_ALIAS("spi:wl1271"); diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index 554deb4d024..6e0952f79e9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c @@ -199,7 +199,14 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) buf = nla_data(tb[WL1271_TM_ATTR_DATA]); len = nla_len(tb[WL1271_TM_ATTR_DATA]); - if (len != sizeof(struct wl1271_nvs_file)) { + /* + * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band + * configurations) can be removed when those NVS files stop floating + * around. + */ + if (len != sizeof(struct wl1271_nvs_file) && + (len != WL1271_INI_LEGACY_NVS_FILE_SIZE || + wl1271_11a_enabled())) { wl1271_error("nvs size is not as expected: %zu != %zu", len, sizeof(struct wl1271_nvs_file)); return -EMSGSIZE; @@ -209,7 +216,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) kfree(wl->nvs); - wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); + wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); if (!wl->nvs) { wl1271_error("could not allocate memory for the nvs file"); ret = -ENOMEM; diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 62db79508dd..c592cc2e9fe 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -36,6 +36,7 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) for (i = 0; i < ACX_TX_DESCRIPTORS; i++) if (wl->tx_frames[i] == NULL) { wl->tx_frames[i] = skb; + wl->tx_frames_cnt++; return i; } @@ -73,8 +74,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) wl1271_debug(DEBUG_TX, "tx_allocate: size: %d, blocks: %d, id: %d", total_len, total_blocks, id); - } else + } else { wl->tx_frames[id] = NULL; + wl->tx_frames_cnt--; + } return ret; } @@ -358,6 +361,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* return the packet to the stack */ ieee80211_tx_status(wl->hw, skb); wl->tx_frames[result->id] = NULL; + wl->tx_frames_cnt--; } /* Called upon reception of a TX complete interrupt */ @@ -412,7 +416,7 @@ void wl1271_tx_complete(struct wl1271 *wl) } /* caller must hold wl->mutex */ -void wl1271_tx_flush(struct wl1271 *wl) +void wl1271_tx_reset(struct wl1271 *wl) { int i; struct sk_buff *skb; @@ -421,7 +425,7 @@ void wl1271_tx_flush(struct wl1271 *wl) /* control->flags = 0; FIXME */ while ((skb = skb_dequeue(&wl->tx_queue))) { - wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); ieee80211_tx_status(wl->hw, skb); } @@ -429,6 +433,32 @@ void wl1271_tx_flush(struct wl1271 *wl) if (wl->tx_frames[i] != NULL) { skb = wl->tx_frames[i]; wl->tx_frames[i] = NULL; + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); ieee80211_tx_status(wl->hw, skb); } + wl->tx_frames_cnt = 0; +} + +#define WL1271_TX_FLUSH_TIMEOUT 500000 + +/* caller must *NOT* hold wl->mutex */ +void wl1271_tx_flush(struct wl1271 *wl) +{ + unsigned long timeout; + timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); + + while (!time_after(jiffies, timeout)) { + mutex_lock(&wl->mutex); + wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", + wl->tx_frames_cnt); + if ((wl->tx_frames_cnt == 0) && + skb_queue_empty(&wl->tx_queue)) { + mutex_unlock(&wl->mutex); + return; + } + mutex_unlock(&wl->mutex); + msleep(1); + } + + wl1271_warning("Unable to flush all TX buffers, timed out."); } diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 3b8b7ac253f..48bf92621c0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h @@ -80,7 +80,7 @@ struct wl1271_tx_hw_descr { /* Identifier of the remote STA in IBSS, 1 in infra-BSS */ u8 aid; u8 reserved; -} __attribute__ ((packed)); +} __packed; enum wl1271_tx_hw_res_status { TX_SUCCESS = 0, @@ -115,13 +115,13 @@ struct wl1271_tx_hw_res_descr { u8 rate_class_index; /* for 4-byte alignment. */ u8 spare; -} __attribute__ ((packed)); +} __packed; struct wl1271_tx_hw_res_if { __le32 tx_result_fw_counter; __le32 tx_result_host_counter; struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; -} __attribute__ ((packed)); +} __packed; static inline int wl1271_tx_get_queue(int queue) { @@ -158,6 +158,7 @@ static inline int wl1271_tx_ac_to_tid(int ac) void wl1271_tx_work(struct work_struct *work); void wl1271_tx_complete(struct wl1271 *wl); +void wl1271_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 055d7bc6f59..18462802721 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -66,41 +66,41 @@ struct ieee80211_header { u8 bssid[ETH_ALEN]; __le16 seq_ctl; u8 payload[0]; -} __attribute__ ((packed)); +} __packed; struct wl12xx_ie_header { u8 id; u8 len; -} __attribute__ ((packed)); +} __packed; /* IEs */ struct wl12xx_ie_ssid { struct wl12xx_ie_header header; char ssid[IW_ESSID_MAX_SIZE]; -} __attribute__ ((packed)); +} __packed; struct wl12xx_ie_rates { struct wl12xx_ie_header header; u8 rates[MAX_SUPPORTED_RATES]; -} __attribute__ ((packed)); +} __packed; struct wl12xx_ie_ds_params { struct wl12xx_ie_header header; u8 channel; -} __attribute__ ((packed)); +} __packed; struct country_triplet { u8 channel; u8 num_channels; u8 max_tx_power; -} __attribute__ ((packed)); +} __packed; struct wl12xx_ie_country { struct wl12xx_ie_header header; u8 country_string[COUNTRY_STRING_LEN]; struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; -} __attribute__ ((packed)); +} __packed; /* Templates */ @@ -115,30 +115,30 @@ struct wl12xx_beacon_template { struct wl12xx_ie_rates ext_rates; struct wl12xx_ie_ds_params ds_params; struct wl12xx_ie_country country; -} __attribute__ ((packed)); +} __packed; struct wl12xx_null_data_template { struct ieee80211_header header; -} __attribute__ ((packed)); +} __packed; struct wl12xx_ps_poll_template { __le16 fc; __le16 aid; u8 bssid[ETH_ALEN]; u8 ta[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct wl12xx_qos_null_data_template { struct ieee80211_header header; __le16 qos_ctl; -} __attribute__ ((packed)); +} __packed; struct wl12xx_probe_req_template { struct ieee80211_header header; struct wl12xx_ie_ssid ssid; struct wl12xx_ie_rates rates; struct wl12xx_ie_rates ext_rates; -} __attribute__ ((packed)); +} __packed; struct wl12xx_probe_resp_template { @@ -151,6 +151,6 @@ struct wl12xx_probe_resp_template { struct wl12xx_ie_rates ext_rates; struct wl12xx_ie_ds_params ds_params; struct wl12xx_ie_country country; -} __attribute__ ((packed)); +} __packed; #endif diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h index 8816e371fd0..3fbfd19818f 100644 --- a/drivers/net/wireless/wl3501.h +++ b/drivers/net/wireless/wl3501.h @@ -231,12 +231,12 @@ struct iw_mgmt_info_element { but sizeof(enum) > sizeof(u8) :-( */ u8 len; u8 data[0]; -} __attribute__ ((packed)); +} __packed; struct iw_mgmt_essid_pset { struct iw_mgmt_info_element el; u8 essid[IW_ESSID_MAX_SIZE]; -} __attribute__ ((packed)); +} __packed; /* * According to 802.11 Wireless Netowors, the definitive guide - O'Reilly @@ -247,12 +247,12 @@ struct iw_mgmt_essid_pset { struct iw_mgmt_data_rset { struct iw_mgmt_info_element el; u8 data_rate_labels[IW_DATA_RATE_MAX_LABELS]; -} __attribute__ ((packed)); +} __packed; struct iw_mgmt_ds_pset { struct iw_mgmt_info_element el; u8 chan; -} __attribute__ ((packed)); +} __packed; struct iw_mgmt_cf_pset { struct iw_mgmt_info_element el; @@ -260,12 +260,12 @@ struct iw_mgmt_cf_pset { u8 cfp_period; u16 cfp_max_duration; u16 cfp_dur_remaining; -} __attribute__ ((packed)); +} __packed; struct iw_mgmt_ibss_pset { struct iw_mgmt_info_element el; u16 atim_window; -} __attribute__ ((packed)); +} __packed; struct wl3501_tx_hdr { u16 tx_cnt; @@ -544,12 +544,12 @@ struct wl3501_80211_tx_plcp_hdr { u8 service; u16 len; u16 crc16; -} __attribute__ ((packed)); +} __packed; struct wl3501_80211_tx_hdr { struct wl3501_80211_tx_plcp_hdr pclp_hdr; struct ieee80211_hdr mac_hdr; -} __attribute__ ((packed)); +} __packed; /* Reserve the beginning Tx space for descriptor use. diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index b0b666019a9..43307bd42a6 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -42,7 +42,8 @@ static struct zd_reg_alpha2_map reg_alpha2_map[] = { { ZD_REGDOMAIN_IC, "CA" }, { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */ { ZD_REGDOMAIN_JAPAN, "JP" }, - { ZD_REGDOMAIN_JAPAN_ADD, "JP" }, + { ZD_REGDOMAIN_JAPAN_2, "JP" }, + { ZD_REGDOMAIN_JAPAN_3, "JP" }, { ZD_REGDOMAIN_SPAIN, "ES" }, { ZD_REGDOMAIN_FRANCE, "FR" }, }; @@ -855,7 +856,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) if (skb == NULL) return -ENOMEM; if (need_padding) { - /* Make sure the the payload data is 4 byte aligned. */ + /* Make sure the payload data is 4 byte aligned. */ skb_reserve(skb, 2); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 630c298a730..a6d86b996c7 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -35,7 +35,7 @@ struct zd_ctrlset { __le16 current_length; u8 service; __le16 next_frame_length; -} __attribute__((packed)); +} __packed; #define ZD_CS_RESERVED_SIZE 25 @@ -106,7 +106,7 @@ struct zd_ctrlset { struct rx_length_info { __le16 length[3]; __le16 tag; -} __attribute__((packed)); +} __packed; #define RX_LENGTH_INFO_TAG 0x697e @@ -117,7 +117,7 @@ struct rx_status { u8 signal_quality_ofdm; u8 decryption_type; u8 frame_status; -} __attribute__((packed)); +} __packed; /* rx_status field decryption_type */ #define ZD_RX_NO_WEP 0 @@ -153,7 +153,7 @@ struct tx_status { u8 mac[ETH_ALEN]; u8 retry; u8 failure; -} __attribute__((packed)); +} __packed; enum mac_flags { MAC_FIXED_CHANNEL = 0x01, @@ -212,8 +212,9 @@ struct zd_mac { #define ZD_REGDOMAIN_ETSI 0x30 #define ZD_REGDOMAIN_SPAIN 0x31 #define ZD_REGDOMAIN_FRANCE 0x32 -#define ZD_REGDOMAIN_JAPAN_ADD 0x40 +#define ZD_REGDOMAIN_JAPAN_2 0x40 #define ZD_REGDOMAIN_JAPAN 0x41 +#define ZD_REGDOMAIN_JAPAN_3 0x49 enum { MIN_CHANNEL24 = 1, @@ -225,7 +226,7 @@ enum { struct ofdm_plcp_header { u8 prefix[3]; __le16 service; -} __attribute__((packed)); +} __packed; static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header) { @@ -252,7 +253,7 @@ struct cck_plcp_header { u8 service; __le16 length; __le16 crc16; -} __attribute__((packed)); +} __packed; static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header) { diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c257940b71b..818e1480ca9 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -844,7 +844,7 @@ out: * @usb: a &struct zd_usb pointer * @urb: URB to be freed * - * Frees the the transmission URB, which means to put it on the free URB + * Frees the transmission URB, which means to put it on the free URB * list. */ static void free_tx_urb(struct zd_usb *usb, struct urb *urb) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 049f8b91f02..1b1655cb7cb 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -79,17 +79,17 @@ enum control_requests { struct usb_req_read_regs { __le16 id; __le16 addr[0]; -} __attribute__((packed)); +} __packed; struct reg_data { __le16 addr; __le16 value; -} __attribute__((packed)); +} __packed; struct usb_req_write_regs { __le16 id; struct reg_data reg_writes[0]; -} __attribute__((packed)); +} __packed; enum { RF_IF_LE = 0x02, @@ -106,7 +106,7 @@ struct usb_req_rfwrite { /* RF2595: 24 */ __le16 bit_values[0]; /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ -} __attribute__((packed)); +} __packed; /* USB interrupt */ @@ -123,12 +123,12 @@ enum usb_int_flags { struct usb_int_header { u8 type; /* must always be 1 */ u8 id; -} __attribute__((packed)); +} __packed; struct usb_int_regs { struct usb_int_header hdr; struct reg_data regs[0]; -} __attribute__((packed)); +} __packed; struct usb_int_retry_fail { struct usb_int_header hdr; @@ -136,7 +136,7 @@ struct usb_int_retry_fail { u8 _dummy; u8 addr[ETH_ALEN]; u8 ibss_wakeup_dest; -} __attribute__((packed)); +} __packed; struct read_regs_int { struct completion completion; |