Merge tag 'nfc-next-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo...
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 14 Jan 2013 20:08:52 +0000 (15:08 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 14 Jan 2013 20:08:52 +0000 (15:08 -0500)
Samuel Ortiz <sameo@linux.intel.com> says:

"This is the first NFC patchset targeted at the 3.9 merge window.

It brings the following goodies:

- LLCP socket timestamping (To be used e.g with the recently released nfctool
  application for a more efficient skb timestamping when sniffing).
- A pretty big pn533 rework from Waldemar, preparing the driver to support
  more flavours of pn533 based devices.
- HCI changes from Eric in preparation for the microread driver support.
- Some LLCP memory leak fixes, cleanups and slight improvements.
- pn544 and nfcwilink move to the devm_kzalloc API.
- An initial Secure Element (SE) API.
- An nfc.h license change from the original author, allowing non GPL
  application code to safely include it."

Signed-off-by: John W. Linville <linville@tuxdriver.com>
35 files changed:
arch/mips/bcm47xx/serial.c
drivers/bcma/driver_chipcommon.c
drivers/bcma/driver_mips.c
drivers/bcma/driver_pci_host.c
drivers/net/wireless/ath/ath9k/ar9002_phy.c
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9340_initvals.h
drivers/net/wireless/ath/ath9k/ar9485_initvals.h
drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/ssb/Kconfig
drivers/ssb/Makefile
drivers/ssb/driver_chipcommon_sflash.c [new file with mode: 0644]
drivers/ssb/driver_mipscore.c
drivers/ssb/ssb_private.h
include/linux/bcma/bcma_driver_mips.h
include/linux/bcma/bcma_driver_pci.h
net/mac80211/mesh_hwmp.c
net/wireless/reg.c

index 57981e4fe2bc94c143070ee99ecf66d09ceae223..b8ef965705cf6ca4b7ceb890528d63e5236fb34e 100644 (file)
@@ -62,7 +62,7 @@ static int __init uart8250_init_bcma(void)
 
                p->mapbase = (unsigned int) bcma_port->regs;
                p->membase = (void *) bcma_port->regs;
-               p->irq = bcma_port->irq + 2;
+               p->irq = bcma_port->irq;
                p->uartclk = bcma_port->baud_base;
                p->regshift = bcma_port->reg_shift;
                p->iotype = UPIO_MEM;
index e461ad25fda4825dbc36a632d5781015843eb268..28fa50ad87bee80630758b2c5ace883d02ce2c0d 100644 (file)
@@ -329,7 +329,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
                return;
        }
 
-       irq = bcma_core_mips_irq(cc->core);
+       irq = bcma_core_irq(cc->core);
 
        /* Determine the registers of the UARTs */
        cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
index 8a51c79505364cfc9e8a41830a33bb7e24183c31..a808404db4b1e8fbe30949c55579c2358076e2eb 100644 (file)
@@ -85,7 +85,7 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
  * If disabled, 5 is returned.
  * If not supported, 6 is returned.
  */
-unsigned int bcma_core_mips_irq(struct bcma_device *dev)
+static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
 {
        struct bcma_device *mdev = dev->bus->drv_mips.core;
        u32 irqflag;
@@ -102,7 +102,13 @@ unsigned int bcma_core_mips_irq(struct bcma_device *dev)
 
        return 5;
 }
-EXPORT_SYMBOL(bcma_core_mips_irq);
+
+unsigned int bcma_core_irq(struct bcma_device *dev)
+{
+       unsigned int mips_irq = bcma_core_mips_irq(dev);
+       return mips_irq <= 4 ? mips_irq + 2 : 0;
+}
+EXPORT_SYMBOL(bcma_core_irq);
 
 static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
 {
index e6b5c89469dcea0fd7dec00809934b54eccafcbe..37d1777dcd47996709a2aae41b36bee7509c07df 100644 (file)
@@ -427,7 +427,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
        /* Reset RC */
        usleep_range(3000, 5000);
        pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
-       usleep_range(1000, 2000);
+       msleep(50);
        pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
                        BCMA_CORE_PCI_CTL_RST_OE);
 
@@ -489,6 +489,17 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
 
        bcma_core_pci_enable_crs(pc);
 
+       if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 ||
+           bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) {
+               u16 val16;
+               bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
+                                       &val16, sizeof(val16));
+               val16 |= (2 << 5);      /* Max payload size of 512 */
+               val16 |= (2 << 12);     /* MRRS 512 */
+               bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
+                                        &val16, sizeof(val16));
+       }
+
        /* Enable PCI bridge BAR0 memory & master access */
        tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
        bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
@@ -577,7 +588,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
        pr_info("PCI: Fixing up device %s\n", pci_name(dev));
 
        /* Fix up interrupt lines */
-       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
+       dev->irq = bcma_core_irq(pc_host->pdev->core);
        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 
        return 0;
@@ -596,6 +607,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
 
        pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
                               pci_ops);
-       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
+       return bcma_core_irq(pc_host->pdev->core);
 }
 EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
index 8b119811b2d9ed113b26a70259f306848b79d367..2cb665e2ea229021c7d11a98caf740b3b05d4f63 100644 (file)
@@ -555,6 +555,67 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
        REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
 }
 
+void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
+                                   struct ath_spec_scan *param)
+{
+       u8 count;
+
+       if (!param->enabled) {
+               REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_ENABLE);
+               return;
+       }
+       REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
+
+       if (param->short_repeat)
+               REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+       else
+               REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+
+       /* on AR92xx, the highest bit of count will make the the chip send
+        * spectral samples endlessly. Check if this really was intended,
+        * and fix otherwise.
+        */
+       count = param->count;
+       if (param->endless)
+               count = 0x80;
+       else if (count & 0x80)
+               count = 0x7f;
+
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_COUNT, count);
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period);
+
+       return;
+}
+
+static void ar9002_hw_spectral_scan_trigger(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
+       /* Activate spectral scan */
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                   AR_PHY_SPECTRAL_SCAN_ACTIVE);
+}
+
+static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       /* Poll for spectral scan complete */
+       if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
+                          AR_PHY_SPECTRAL_SCAN_ACTIVE,
+                          0, AH_WAIT_TIMEOUT)) {
+               ath_err(common, "spectral scan wait failed\n");
+               return;
+       }
+}
+
 void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -569,6 +630,9 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 
        ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
        ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+       ops->spectral_scan_config = ar9002_hw_spectral_scan_config;
+       ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger;
+       ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait;
 
        ar9002_hw_set_nf_limits(ah);
 }
index 262e1e036fd730fe63f273001aff016ac600e0cf..db5ffada221718f76f6a1dfeabfbb5c6ed2929ef 100644 (file)
@@ -744,6 +744,186 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
        {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
 };
 
+static const u32 ar9300Modes_mixed_ob_db_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {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, 0x11000400, 0x11000400},
+       {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+       {0x0000a544, 0x52022470, 0x52022470, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x55022490, 0x55022490, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59022492, 0x59022492, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5d022692, 0x5d022692, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61022892, 0x61022892, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x65024890, 0x65024890, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x69024892, 0x69024892, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6e024c92, 0x6e024c92, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x74026e92, 0x74026e92, 0x56001eec, 0x56001eec},
+       {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, 0x11800400, 0x11800400},
+       {0x0000a598, 0x21802220, 0x21802220, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x52822470, 0x52822470, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x55822490, 0x55822490, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59822492, 0x59822492, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5d822692, 0x5d822692, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61822892, 0x61822892, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x65824890, 0x65824890, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x69824892, 0x69824892, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x74826e92, 0x74826e92, 0x56801eec, 0x56801eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+       {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+       {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
+       {0x00016048, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
+       {0x00016448, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x056db2e4, 0x056db2e4},
+       {0x00016848, 0x66480001, 0x66480001, 0x8e480001, 0x8e480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
+static const u32 ar9300Modes_type5_tx_gain_table_2p2[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {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, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
+       {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
+       {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
+       {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
 static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
        /* Addr      allmodes  */
        {0x0000a000, 0x00010000},
index fa67e84d51ea3786e9168c448b250b1c72d2a850..9221f32a322e0c25ddfdff1205fb3181fd0379e0 100644 (file)
@@ -960,22 +960,68 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
                      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
 }
 
+static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       int i;
+
+       if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah))
+               return;
+
+       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+               if (!(ah->rxchainmask & (1 << i)))
+                       continue;
+               ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
+       }
+}
+
+static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
+{
+       u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
+                                         AR_PHY_CL_TAB_1,
+                                         AR_PHY_CL_TAB_2 };
+       struct ath9k_hw_cal_data *caldata = ah->caldata;
+       bool txclcal_done = false;
+       int i, j;
+
+       if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
+               return;
+
+       txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
+                         AR_PHY_AGC_CONTROL_CLC_SUCCESS);
+
+       if (caldata->done_txclcal_once) {
+               for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+                       if (!(ah->txchainmask & (1 << i)))
+                               continue;
+                       for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
+                               REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
+                                         caldata->tx_clcal[i][j]);
+               }
+       } else if (is_reusable && txclcal_done) {
+               for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+                       if (!(ah->txchainmask & (1 << i)))
+                               continue;
+                       for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
+                               caldata->tx_clcal[i][j] =
+                                       REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
+               }
+               caldata->done_txclcal_once = true;
+       }
+}
+
 static bool ar9003_hw_init_cal(struct ath_hw *ah,
                               struct ath9k_channel *chan)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath9k_hw_cal_data *caldata = ah->caldata;
-       bool txiqcal_done = false, txclcal_done = false;
+       bool txiqcal_done = false;
        bool is_reusable = true, status = true;
-       bool run_rtt_cal = false, run_agc_cal;
+       bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
        bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
        u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
                                          AR_PHY_AGC_CONTROL_FLTR_CAL   |
                                          AR_PHY_AGC_CONTROL_PKDET_CAL;
-       int i, j;
-       u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
-                                         AR_PHY_CL_TAB_1,
-                                         AR_PHY_CL_TAB_2 };
 
        if (rtt) {
                if (!ar9003_hw_rtt_restore(ah, chan))
@@ -1013,7 +1059,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                }
        }
 
-       if (!(ah->enabled_cals & TX_IQ_CAL))
+       if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
+           !(ah->enabled_cals & TX_IQ_CAL))
                goto skip_tx_iqcal;
 
        /* Do Tx IQ Calibration */
@@ -1033,21 +1080,22 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                        REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
                                    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
                txiqcal_done = run_agc_cal = true;
-               goto skip_tx_iqcal;
-       } else if (caldata && !caldata->done_txiqcal_once)
+       } else if (caldata && !caldata->done_txiqcal_once) {
                run_agc_cal = true;
+               sep_iq_cal = true;
+       }
 
+skip_tx_iqcal:
        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
                ar9003_mci_init_cal_req(ah, &is_reusable);
 
-       if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
+       if (sep_iq_cal) {
                txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
                udelay(5);
                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
        }
 
-skip_tx_iqcal:
        if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
                /* Calibrate the AGC */
                REG_WRITE(ah, AR_PHY_AGC_CONTROL,
@@ -1058,14 +1106,8 @@ skip_tx_iqcal:
                status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
                                       AR_PHY_AGC_CONTROL_CAL,
                                       0, AH_WAIT_TIMEOUT);
-               if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
-                       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
-                               if (!(ah->rxchainmask & (1 << i)))
-                                       continue;
-                               ar9003_hw_manual_peak_cal(ah, i,
-                                                         IS_CHAN_2GHZ(chan));
-                       }
-               }
+
+               ar9003_hw_do_manual_peak_cal(ah, chan);
        }
 
        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
@@ -1090,31 +1132,7 @@ skip_tx_iqcal:
        else if (caldata && caldata->done_txiqcal_once)
                ar9003_hw_tx_iq_cal_reload(ah);
 
-#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
-       if (caldata && (ah->enabled_cals & TX_CL_CAL)) {
-               txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
-                                          AR_PHY_AGC_CONTROL_CLC_SUCCESS);
-               if (caldata->done_txclcal_once) {
-                       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
-                               if (!(ah->txchainmask & (1 << i)))
-                                       continue;
-                               for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
-                                       REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
-                                                 caldata->tx_clcal[i][j]);
-                       }
-               } else if (is_reusable && txclcal_done) {
-                       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
-                               if (!(ah->txchainmask & (1 << i)))
-                                       continue;
-                               for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
-                                       caldata->tx_clcal[i][j] =
-                                               REG_READ(ah,
-                                                 CL_TAB_ENTRY(cl_idx[i]));
-                       }
-                       caldata->done_txclcal_once = true;
-               }
-       }
-#undef CL_TAB_ENTRY
+       ar9003_hw_cl_cal_post_proc(ah, is_reusable);
 
        if (run_rtt_cal && caldata) {
                if (is_reusable) {
index 562186ca9b5248a26c7cb957357d80f0d5f162fb..881e989ea4701b0dc98c3229e196b5b2b2a5b70f 100644 (file)
@@ -4586,14 +4586,14 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
        return 0;
 }
 
-static int ar9003_hw_power_control_override(struct ath_hw *ah,
-                                           int frequency,
-                                           int *correction,
-                                           int *voltage, int *temperature)
+static void ar9003_hw_power_control_override(struct ath_hw *ah,
+                                            int frequency,
+                                            int *correction,
+                                            int *voltage, int *temperature)
 {
-       int tempSlope = 0;
+       int temp_slope = 0, temp_slope1 = 0, temp_slope2 = 0;
        struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-       int f[8], t[8], i;
+       int f[8], t[8], t1[3], t2[3], i;
 
        REG_RMW(ah, AR_PHY_TPC_11_B0,
                (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
@@ -4624,38 +4624,108 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
         * enable temperature compensation
         * Need to use register names
         */
-       if (frequency < 4000)
-               tempSlope = eep->modalHeader2G.tempSlope;
-       else if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
-               for (i = 0; i < 8; i++) {
-                       t[i] = eep->base_ext1.tempslopextension[i];
-                       f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
+       if (frequency < 4000) {
+               temp_slope = eep->modalHeader2G.tempSlope;
+       } else {
+               if (AR_SREV_9550(ah)) {
+                       t[0] = eep->base_ext1.tempslopextension[2];
+                       t1[0] = eep->base_ext1.tempslopextension[3];
+                       t2[0] = eep->base_ext1.tempslopextension[4];
+                       f[0] = 5180;
+
+                       t[1] = eep->modalHeader5G.tempSlope;
+                       t1[1] = eep->base_ext1.tempslopextension[0];
+                       t2[1] = eep->base_ext1.tempslopextension[1];
+                       f[1] = 5500;
+
+                       t[2] = eep->base_ext1.tempslopextension[5];
+                       t1[2] = eep->base_ext1.tempslopextension[6];
+                       t2[2] = eep->base_ext1.tempslopextension[7];
+                       f[2] = 5785;
+
+                       temp_slope = ar9003_hw_power_interpolate(frequency,
+                                                                f, t, 3);
+                       temp_slope1 = ar9003_hw_power_interpolate(frequency,
+                                                                  f, t1, 3);
+                       temp_slope2 = ar9003_hw_power_interpolate(frequency,
+                                                                  f, t2, 3);
+
+                       goto tempslope;
                }
-               tempSlope = ar9003_hw_power_interpolate((s32) frequency,
-                                                       f, t, 8);
-       } else if (eep->base_ext2.tempSlopeLow != 0) {
-               t[0] = eep->base_ext2.tempSlopeLow;
-               f[0] = 5180;
-               t[1] = eep->modalHeader5G.tempSlope;
-               f[1] = 5500;
-               t[2] = eep->base_ext2.tempSlopeHigh;
-               f[2] = 5785;
-               tempSlope = ar9003_hw_power_interpolate((s32) frequency,
-                                                       f, t, 3);
-       } else
-               tempSlope = eep->modalHeader5G.tempSlope;
 
-       REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
+               if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
+                       for (i = 0; i < 8; i++) {
+                               t[i] = eep->base_ext1.tempslopextension[i];
+                               f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
+                       }
+                       temp_slope = ar9003_hw_power_interpolate((s32) frequency,
+                                                                f, t, 8);
+               } else if (eep->base_ext2.tempSlopeLow != 0) {
+                       t[0] = eep->base_ext2.tempSlopeLow;
+                       f[0] = 5180;
+                       t[1] = eep->modalHeader5G.tempSlope;
+                       f[1] = 5500;
+                       t[2] = eep->base_ext2.tempSlopeHigh;
+                       f[2] = 5785;
+                       temp_slope = ar9003_hw_power_interpolate((s32) frequency,
+                                                                f, t, 3);
+               } else {
+                       temp_slope = eep->modalHeader5G.tempSlope;
+               }
+       }
+
+tempslope:
+       if (AR_SREV_9550(ah)) {
+               /*
+                * AR955x has tempSlope register for each chain.
+                * Check whether temp_compensation feature is enabled or not.
+                */
+               if (eep->baseEepHeader.featureEnable & 0x1) {
+                       if (frequency < 4000) {
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             eep->base_ext2.tempSlopeLow);
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             temp_slope);
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             eep->base_ext2.tempSlopeHigh);
+                       } else {
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             temp_slope);
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             temp_slope1);
+                               REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+                                             AR_PHY_TPC_19_ALPHA_THERM,
+                                             temp_slope2);
+                       }
+               } else {
+                       /*
+                        * If temp compensation is not enabled,
+                        * set all registers to 0.
+                        */
+                       REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+                                     AR_PHY_TPC_19_ALPHA_THERM, 0);
+                       REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+                                     AR_PHY_TPC_19_ALPHA_THERM, 0);
+                       REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+                                     AR_PHY_TPC_19_ALPHA_THERM, 0);
+               }
+       } else {
+               REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+                             AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
+       }
 
        if (AR_SREV_9462_20(ah))
                REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
-                             AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
+                             AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
 
 
        REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
                      temperature[0]);
-
-       return 0;
 }
 
 /* Apply the recorded correction values. */
index 74fd3977feeb845adf93f6ed0fd650d506ca2ee1..de8a56c92e1a3bd44e8a74383207a30685070541 100644 (file)
@@ -507,28 +507,59 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
        else if (AR_SREV_9580(ah))
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9580_1p0_mixed_ob_db_tx_gain_table);
+       else
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
+}
+
+static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
+{
+       if (AR_SREV_9485_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9485Modes_green_ob_db_tx_gain_1_1);
+       else if (AR_SREV_9340(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9340Modes_ub124_tx_gain_table_1p0);
+       else if (AR_SREV_9580(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9580_1p0_type5_tx_gain_table);
+       else if (AR_SREV_9300_22(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9300Modes_type5_tx_gain_table_2p2);
 }
 
+static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
+{
+       if (AR_SREV_9340(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0);
+       else if (AR_SREV_9485_11(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9485Modes_green_spur_ob_db_tx_gain_1_1);
+       else if (AR_SREV_9580(ah))
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9580_1p0_type6_tx_gain_table);
+}
+
+typedef void (*ath_txgain_tab)(struct ath_hw *ah);
+
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
 {
-       switch (ar9003_hw_get_tx_gain_idx(ah)) {
-       case 0:
-       default:
-               ar9003_tx_gain_table_mode0(ah);
-               break;
-       case 1:
-               ar9003_tx_gain_table_mode1(ah);
-               break;
-       case 2:
-               ar9003_tx_gain_table_mode2(ah);
-               break;
-       case 3:
-               ar9003_tx_gain_table_mode3(ah);
-               break;
-       case 4:
-               ar9003_tx_gain_table_mode4(ah);
-               break;
-       }
+       static const ath_txgain_tab modes[] = {
+               ar9003_tx_gain_table_mode0,
+               ar9003_tx_gain_table_mode1,
+               ar9003_tx_gain_table_mode2,
+               ar9003_tx_gain_table_mode3,
+               ar9003_tx_gain_table_mode4,
+               ar9003_tx_gain_table_mode5,
+               ar9003_tx_gain_table_mode6,
+       };
+       int idx = ar9003_hw_get_tx_gain_idx(ah);
+
+       if (idx >= ARRAY_SIZE(modes))
+               idx = 0;
+
+       modes[idx](ah);
 }
 
 static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
index ce19c09fa8e84aec2877e2f14861b0284f4d958e..bf119a5f865a119e0a50a3468e5a17d7d6276065 100644 (file)
@@ -68,7 +68,7 @@ static const int m2ThreshExt_off = 127;
 static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
        u16 bMode, fracMode = 0, aModeRefSel = 0;
-       u32 freq, channelSel = 0, reg32 = 0;
+       u32 freq, chan_frac, div, channelSel = 0, reg32 = 0;
        struct chan_centers centers;
        int loadSynthChannel;
 
@@ -77,9 +77,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 
        if (freq < 4800) {     /* 2 GHz, fractional mode */
                if (AR_SREV_9330(ah)) {
-                       u32 chan_frac;
-                       u32 div;
-
                        if (ah->is_clk_25mhz)
                                div = 75;
                        else
@@ -89,34 +86,40 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
                        chan_frac = (((freq * 4) % div) * 0x20000) / div;
                        channelSel = (channelSel << 17) | chan_frac;
                } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
-                       u32 chan_frac;
-
                        /*
-                        * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
+                        * freq_ref = 40 / (refdiva >> amoderefsel);
+                        * where refdiva=1 and amoderefsel=0
                         * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
                         * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
                         */
                        channelSel = (freq * 4) / 120;
                        chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
                        channelSel = (channelSel << 17) | chan_frac;
-               } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
+               } else if (AR_SREV_9340(ah)) {
                        if (ah->is_clk_25mhz) {
-                               u32 chan_frac;
-
                                channelSel = (freq * 2) / 75;
                                chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
                                channelSel = (channelSel << 17) | chan_frac;
-                       } else
+                       } else {
                                channelSel = CHANSEL_2G(freq) >> 1;
-               } else
+                       }
+               } else if (AR_SREV_9550(ah)) {
+                       if (ah->is_clk_25mhz)
+                               div = 75;
+                       else
+                               div = 120;
+
+                       channelSel = (freq * 4) / div;
+                       chan_frac = (((freq * 4) % div) * 0x20000) / div;
+                       channelSel = (channelSel << 17) | chan_frac;
+               } else {
                        channelSel = CHANSEL_2G(freq);
+               }
                /* Set to 2G mode */
                bMode = 1;
        } else {
                if ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) &&
                    ah->is_clk_25mhz) {
-                       u32 chan_frac;
-
                        channelSel = freq / 75;
                        chan_frac = ((freq % 75) * 0x20000) / 75;
                        channelSel = (channelSel << 17) | chan_frac;
@@ -1450,6 +1453,67 @@ set_rfmode:
        return 0;
 }
 
+static void ar9003_hw_spectral_scan_config(struct ath_hw *ah,
+                                          struct ath_spec_scan *param)
+{
+       u8 count;
+
+       if (!param->enabled) {
+               REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_ENABLE);
+               return;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
+
+       /* on AR93xx and newer, count = 0 will make the the chip send
+        * spectral samples endlessly. Check if this really was intended,
+        * and fix otherwise.
+        */
+       count = param->count;
+       if (param->endless)
+               count = 0;
+       else if (param->count == 0)
+               count = 1;
+
+       if (param->short_repeat)
+               REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+       else
+               REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                           AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_COUNT, count);
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
+       REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+                     AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period);
+
+       return;
+}
+
+static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah)
+{
+       /* Activate spectral scan */
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                   AR_PHY_SPECTRAL_SCAN_ACTIVE);
+}
+
+static void ar9003_hw_spectral_scan_wait(struct ath_hw *ah)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+
+       /* Poll for spectral scan complete */
+       if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
+                          AR_PHY_SPECTRAL_SCAN_ACTIVE,
+                          0, AH_WAIT_TIMEOUT)) {
+               ath_err(common, "spectral scan wait failed\n");
+               return;
+       }
+}
+
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 {
        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1483,6 +1547,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
        ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
        ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
        ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv;
+       ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
+       ops->spectral_scan_trigger = ar9003_hw_spectral_scan_trigger;
+       ops->spectral_scan_wait = ar9003_hw_spectral_scan_wait;
 
        ar9003_hw_set_nf_limits(ah);
        ar9003_hw_set_radar_conf(ah);
index 10795629848871cbd2e34df016102fd9cfe920f2..e71774196c01bbf7fa6f3a33b1789556fc63ae9a 100644 (file)
 #define AR_PHY_TPC_5_B2          (AR_SM2_BASE + 0x208)
 #define AR_PHY_TPC_6_B2          (AR_SM2_BASE + 0x20c)
 #define AR_PHY_TPC_11_B2         (AR_SM2_BASE + 0x220)
-#define AR_PHY_PDADC_TAB_2       (AR_SM2_BASE + 0x240)
+#define AR_PHY_TPC_19_B2         (AR_SM2_BASE + 0x240)
 #define AR_PHY_TX_IQCAL_STATUS_B2   (AR_SM2_BASE + 0x48c)
 #define AR_PHY_TX_IQCAL_CORR_COEFF_B2(_i)    (AR_SM2_BASE + 0x450 + ((_i) << 2))
 
index f69d292bdc027403aa7400bce554899a41462a0b..25db9215985aa1519e0901cb698b312811d6dc91 100644 (file)
@@ -1172,6 +1172,106 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
        {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
 };
 
+static const u32 ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
+       {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
+       {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
+       {0x0000a394, 0x00000444, 0x00000444, 0x00000404, 0x00000404},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x02000001, 0x02000001},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x05000003, 0x05000003},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0a000005, 0x0a000005},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0e000201, 0x0e000201},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x11000203, 0x11000203},
+       {0x0000a518, 0x21002220, 0x21002220, 0x14000401, 0x14000401},
+       {0x0000a51c, 0x27002223, 0x27002223, 0x18000403, 0x18000403},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000602, 0x1b000602},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000802, 0x1f000802},
+       {0x0000a528, 0x34022225, 0x34022225, 0x21000620, 0x21000620},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x25000820, 0x25000820},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x29000822, 0x29000822},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x2d000824, 0x2d000824},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x30000828, 0x30000828},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x3400082a, 0x3400082a},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38000849, 0x38000849},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3b000a2c, 0x3b000a2c},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x3e000e2b, 0x3e000e2b},
+       {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42000e2d, 0x42000e2d},
+       {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4500124a, 0x4500124a},
+       {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4900124c, 0x4900124c},
+       {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c00126c, 0x4c00126c},
+       {0x0000a55c, 0x7002708c, 0x7002708c, 0x4f00128c, 0x4f00128c},
+       {0x0000a560, 0x7302b08a, 0x7302b08a, 0x52001290, 0x52001290},
+       {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001292, 0x56001292},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x02800001, 0x02800001},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x05800003, 0x05800003},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0a800005, 0x0a800005},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0e800201, 0x0e800201},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x11800203, 0x11800203},
+       {0x0000a598, 0x21820220, 0x21820220, 0x14800401, 0x14800401},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x18800403, 0x18800403},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800602, 0x1b800602},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800802, 0x1f800802},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x21800620, 0x21800620},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x25800820, 0x25800820},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x29800822, 0x29800822},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2d800824, 0x2d800824},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x30800828, 0x30800828},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x3480082a, 0x3480082a},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38800849, 0x38800849},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b800a2c, 0x3b800a2c},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e800e2b, 0x3e800e2b},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42800e2d, 0x42800e2d},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4580124a, 0x4580124a},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4980124c, 0x4980124c},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c80126c, 0x4c80126c},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x4f80128c, 0x4f80128c},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x52801290, 0x52801290},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801292, 0x56801292},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a614, 0x01404000, 0x01404000, 0x01404501, 0x01404501},
+       {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x02008802, 0x02008802, 0x01404501, 0x01404501},
+       {0x0000a620, 0x0300cc03, 0x0300cc03, 0x03c0cf02, 0x03c0cf02},
+       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03c0cf03, 0x03c0cf03},
+       {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04011004, 0x04011004},
+       {0x0000a62c, 0x03810c03, 0x03810c03, 0x05419405, 0x05419405},
+       {0x0000a630, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
+       {0x0000a634, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
+       {0x0000a638, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
+       {0x0000a63c, 0x03810e04, 0x03810e04, 0x05419506, 0x05419506},
+       {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03eaac5a, 0x03eaac5a},
+       {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03f330ac, 0x03f330ac},
+       {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc3f00, 0x03fc3f00},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ffc000, 0x03ffc000},
+       {0x00016044, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
+       {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
+       {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
+       {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000},
+       {0x00016444, 0x022492db, 0x022492db, 0x022492db, 0x022492db},
+       {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266},
+};
+
 static const u32 ar9340_1p0_mac_core[][2] = {
        /* Addr      allmodes  */
        {0x00000008, 0x00000000},
index a3710f3bb90c5b0fe8a02cc26455ec31b3697162..712f415b8c0861165ab2a2ee74cbea853788295b 100644 (file)
@@ -260,6 +260,79 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
+static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
+       {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
+       {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
+       {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
+       {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
 static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
@@ -450,6 +523,79 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
 
 #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
 
+static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006},
+       {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x07000203, 0x07000203},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x14000406, 0x14000406},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1800040a, 0x1800040a},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000460, 0x1c000460},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x22000463, 0x22000463},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x26000465, 0x26000465},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2e0006e0, 0x2e0006e0},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x310006e0, 0x310006e0},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x330006e0, 0x330006e0},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x3e0008e3, 0x3e0008e3},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x410008e5, 0x410008e5},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x430008e6, 0x430008e6},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4a0008ec, 0x4a0008ec},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4e0008f1, 0x4e0008f1},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x520008f3, 0x520008f3},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x54000eed, 0x54000eed},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x58000ef1, 0x58000ef1},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5c000ef3, 0x5c000ef3},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x60000ef5, 0x60000ef5},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x62000ef6, 0x62000ef6},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6},
+       {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a},
+       {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a},
+       {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a},
+       {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a},
+       {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
+
 static const u32 ar9485_1_1[][2] = {
        /* Addr      allmodes  */
        {0x0000a580, 0x00000000},
index df97f21c52dc1d9a895e4b3a4ce466861f03b792..ccc5b6c99add76617b4b990e106bd57be0d1f09f 100644 (file)
 static const u32 ar955x_1p0_radio_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xd28b3330, 0xd28b3330},
-       {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x06345f2a, 0x06345f2a},
-       {0x000160ac, 0xa4647c00, 0xa4647c00, 0xa4646800, 0xa4646800},
-       {0x000160b0, 0x01885f52, 0x01885f52, 0x04accf3a, 0x04accf3a},
-       {0x00016104, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
+       {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a, 0x0a566f3a},
+       {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24647c00, 0x24647c00},
+       {0x000160b0, 0x01885f52, 0x01885f52, 0x01885f52, 0x01885f52},
+       {0x00016104, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
        {0x0001610c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016140, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
-       {0x00016504, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
+       {0x00016504, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
        {0x0001650c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016540, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
-       {0x00016904, 0xb7a00001, 0xb7a00001, 0xb7a00001, 0xb7a00001},
+       {0x00016904, 0xb7a00000, 0xb7a00000, 0xb7a00001, 0xb7a00001},
        {0x0001690c, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000},
        {0x00016940, 0x10804008, 0x10804008, 0x10804008, 0x10804008},
 };
@@ -69,15 +69,15 @@ static const u32 ar955x_1p0_baseband_postamble[][5] = {
        {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0},
        {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
        {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
-       {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+       {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
        {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
        {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
        {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
        {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
        {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
-       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+       {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
        {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
-       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+       {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
        {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
        {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
        {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
@@ -125,7 +125,7 @@ static const u32 ar955x_1p0_radio_core[][2] = {
        {0x00016094, 0x00000000},
        {0x000160a0, 0x0a108ffe},
        {0x000160a4, 0x812fc370},
-       {0x000160a8, 0x423c8000},
+       {0x000160a8, 0x423c8100},
        {0x000160b4, 0x92480080},
        {0x000160c0, 0x006db6d0},
        {0x000160c4, 0x6db6db60},
@@ -134,7 +134,7 @@ static const u32 ar955x_1p0_radio_core[][2] = {
        {0x00016100, 0x11999601},
        {0x00016108, 0x00080010},
        {0x00016144, 0x02084080},
-       {0x00016148, 0x000080c0},
+       {0x00016148, 0x00008040},
        {0x00016280, 0x01800804},
        {0x00016284, 0x00038dc5},
        {0x00016288, 0x00000000},
@@ -178,7 +178,7 @@ static const u32 ar955x_1p0_radio_core[][2] = {
        {0x00016500, 0x11999601},
        {0x00016508, 0x00080010},
        {0x00016544, 0x02084080},
-       {0x00016548, 0x000080c0},
+       {0x00016548, 0x00008040},
        {0x00016780, 0x00000000},
        {0x00016784, 0x00000000},
        {0x00016788, 0x00400705},
@@ -218,7 +218,7 @@ static const u32 ar955x_1p0_radio_core[][2] = {
        {0x00016900, 0x11999601},
        {0x00016908, 0x00080010},
        {0x00016944, 0x02084080},
-       {0x00016948, 0x000080c0},
+       {0x00016948, 0x00008040},
        {0x00016b80, 0x00000000},
        {0x00016b84, 0x00000000},
        {0x00016b88, 0x00400705},
@@ -245,9 +245,9 @@ static const u32 ar955x_1p0_radio_core[][2] = {
 
 static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = {
        /* Addr      5G_HT20_L   5G_HT40_L   5G_HT20_M   5G_HT40_M   5G_HT20_H   5G_HT40_H   2G_HT40     2G_HT20  */
-       {0x0000a2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
-       {0x0000a2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
-       {0x0000a2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
+       {0x0000a2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
+       {0x0000a2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
+       {0x0000a2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
        {0x0000a2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
        {0x0000a410, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050de, 0x000050da, 0x000050da},
        {0x0000a500, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000000, 0x00000000},
@@ -256,63 +256,63 @@ static const u32 ar955x_1p0_modes_xpa_tx_gain_table[][9] = {
        {0x0000a50c, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c00000b, 0x0c000006, 0x0c000006},
        {0x0000a510, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x1000000d, 0x0f00000a, 0x0f00000a},
        {0x0000a514, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x14000011, 0x1300000c, 0x1300000c},
-       {0x0000a518, 0x19004008, 0x19004008, 0x19004008, 0x19004008, 0x18004008, 0x18004008, 0x1700000e, 0x1700000e},
-       {0x0000a51c, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1d00400a, 0x1c00400a, 0x1c00400a, 0x1b000064, 0x1b000064},
-       {0x0000a520, 0x230020a2, 0x230020a2, 0x210020a2, 0x210020a2, 0x200020a2, 0x200020a2, 0x1f000242, 0x1f000242},
-       {0x0000a524, 0x2500006e, 0x2500006e, 0x2500006e, 0x2500006e, 0x2400006e, 0x2400006e, 0x23000229, 0x23000229},
-       {0x0000a528, 0x29022221, 0x29022221, 0x28022221, 0x28022221, 0x27022221, 0x27022221, 0x270002a2, 0x270002a2},
-       {0x0000a52c, 0x2d00062a, 0x2d00062a, 0x2c00062a, 0x2c00062a, 0x2a00062a, 0x2a00062a, 0x2c001203, 0x2c001203},
-       {0x0000a530, 0x340220a5, 0x340220a5, 0x320220a5, 0x320220a5, 0x2f0220a5, 0x2f0220a5, 0x30001803, 0x30001803},
-       {0x0000a534, 0x380022c5, 0x380022c5, 0x350022c5, 0x350022c5, 0x320022c5, 0x320022c5, 0x33000881, 0x33000881},
-       {0x0000a538, 0x3b002486, 0x3b002486, 0x39002486, 0x39002486, 0x36002486, 0x36002486, 0x38001809, 0x38001809},
-       {0x0000a53c, 0x3f00248a, 0x3f00248a, 0x3d00248a, 0x3d00248a, 0x3a00248a, 0x3a00248a, 0x3a000814, 0x3a000814},
-       {0x0000a540, 0x4202242c, 0x4202242c, 0x4102242c, 0x4102242c, 0x3f02242c, 0x3f02242c, 0x3f001a0c, 0x3f001a0c},
-       {0x0000a544, 0x490044c6, 0x490044c6, 0x460044c6, 0x460044c6, 0x420044c6, 0x420044c6, 0x43001a0e, 0x43001a0e},
-       {0x0000a548, 0x4d024485, 0x4d024485, 0x4a024485, 0x4a024485, 0x46024485, 0x46024485, 0x46001812, 0x46001812},
-       {0x0000a54c, 0x51044483, 0x51044483, 0x4e044483, 0x4e044483, 0x4a044483, 0x4a044483, 0x49001884, 0x49001884},
-       {0x0000a550, 0x5404a40c, 0x5404a40c, 0x5204a40c, 0x5204a40c, 0x4d04a40c, 0x4d04a40c, 0x4d001e84, 0x4d001e84},
-       {0x0000a554, 0x57024632, 0x57024632, 0x55024632, 0x55024632, 0x52024632, 0x52024632, 0x50001e69, 0x50001e69},
-       {0x0000a558, 0x5c00a634, 0x5c00a634, 0x5900a634, 0x5900a634, 0x5600a634, 0x5600a634, 0x550006f4, 0x550006f4},
-       {0x0000a55c, 0x5f026832, 0x5f026832, 0x5d026832, 0x5d026832, 0x5a026832, 0x5a026832, 0x59000ad3, 0x59000ad3},
-       {0x0000a560, 0x6602b012, 0x6602b012, 0x6202b012, 0x6202b012, 0x5d02b012, 0x5d02b012, 0x5e000ad5, 0x5e000ad5},
-       {0x0000a564, 0x6e02d0e1, 0x6e02d0e1, 0x6802d0e1, 0x6802d0e1, 0x6002d0e1, 0x6002d0e1, 0x61001ced, 0x61001ced},
-       {0x0000a568, 0x7202b4c4, 0x7202b4c4, 0x6c02b4c4, 0x6c02b4c4, 0x6502b4c4, 0x6502b4c4, 0x660018d4, 0x660018d4},
-       {0x0000a56c, 0x75007894, 0x75007894, 0x70007894, 0x70007894, 0x6b007894, 0x6b007894, 0x660018d4, 0x660018d4},
-       {0x0000a570, 0x7b025c74, 0x7b025c74, 0x75025c74, 0x75025c74, 0x70025c74, 0x70025c74, 0x660018d4, 0x660018d4},
-       {0x0000a574, 0x8300bcb5, 0x8300bcb5, 0x7a00bcb5, 0x7a00bcb5, 0x7600bcb5, 0x7600bcb5, 0x660018d4, 0x660018d4},
-       {0x0000a578, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4},
-       {0x0000a57c, 0x8a04dc74, 0x8a04dc74, 0x7f04dc74, 0x7f04dc74, 0x7c04dc74, 0x7c04dc74, 0x660018d4, 0x660018d4},
+       {0x0000a518, 0x1700002b, 0x1700002b, 0x1700002b, 0x1700002b, 0x1600002b, 0x1600002b, 0x1700000e, 0x1700000e},
+       {0x0000a51c, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1b00002d, 0x1a00002d, 0x1a00002d, 0x1b000064, 0x1b000064},
+       {0x0000a520, 0x20000031, 0x20000031, 0x1f000031, 0x1f000031, 0x1e000031, 0x1e000031, 0x1f000242, 0x1f000242},
+       {0x0000a524, 0x24000051, 0x24000051, 0x23000051, 0x23000051, 0x23000051, 0x23000051, 0x23000229, 0x23000229},
+       {0x0000a528, 0x27000071, 0x27000071, 0x27000071, 0x27000071, 0x26000071, 0x26000071, 0x270002a2, 0x270002a2},
+       {0x0000a52c, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2b000092, 0x2c001203, 0x2c001203},
+       {0x0000a530, 0x3000028c, 0x3000028c, 0x2f00028c, 0x2f00028c, 0x2e00028c, 0x2e00028c, 0x30001803, 0x30001803},
+       {0x0000a534, 0x34000290, 0x34000290, 0x33000290, 0x33000290, 0x32000290, 0x32000290, 0x33000881, 0x33000881},
+       {0x0000a538, 0x37000292, 0x37000292, 0x36000292, 0x36000292, 0x35000292, 0x35000292, 0x38001809, 0x38001809},
+       {0x0000a53c, 0x3b02028d, 0x3b02028d, 0x3a02028d, 0x3a02028d, 0x3902028d, 0x3902028d, 0x3a000814, 0x3a000814},
+       {0x0000a540, 0x3f020291, 0x3f020291, 0x3e020291, 0x3e020291, 0x3d020291, 0x3d020291, 0x3f001a0c, 0x3f001a0c},
+       {0x0000a544, 0x44020490, 0x44020490, 0x43020490, 0x43020490, 0x42020490, 0x42020490, 0x43001a0e, 0x43001a0e},
+       {0x0000a548, 0x48020492, 0x48020492, 0x47020492, 0x47020492, 0x46020492, 0x46020492, 0x46001812, 0x46001812},
+       {0x0000a54c, 0x4c020692, 0x4c020692, 0x4b020692, 0x4b020692, 0x4a020692, 0x4a020692, 0x49001884, 0x49001884},
+       {0x0000a550, 0x50020892, 0x50020892, 0x4f020892, 0x4f020892, 0x4e020892, 0x4e020892, 0x4d001e84, 0x4d001e84},
+       {0x0000a554, 0x53040891, 0x53040891, 0x53040891, 0x53040891, 0x52040891, 0x52040891, 0x50001e69, 0x50001e69},
+       {0x0000a558, 0x58040893, 0x58040893, 0x57040893, 0x57040893, 0x56040893, 0x56040893, 0x550006f4, 0x550006f4},
+       {0x0000a55c, 0x5c0408b4, 0x5c0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x5a0408b4, 0x59000ad3, 0x59000ad3},
+       {0x0000a560, 0x610408b6, 0x610408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e0408b6, 0x5e000ad5, 0x5e000ad5},
+       {0x0000a564, 0x670408f6, 0x670408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x620408f6, 0x61001ced, 0x61001ced},
+       {0x0000a568, 0x6a040cf6, 0x6a040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x66040cf6, 0x660018d4, 0x660018d4},
+       {0x0000a56c, 0x6d040d76, 0x6d040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x6a040d76, 0x660018d4, 0x660018d4},
+       {0x0000a570, 0x70060db6, 0x70060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x6e060db6, 0x660018d4, 0x660018d4},
+       {0x0000a574, 0x730a0df6, 0x730a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x720a0df6, 0x660018d4, 0x660018d4},
+       {0x0000a578, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4},
+       {0x0000a57c, 0x770a13f6, 0x770a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x760a13f6, 0x660018d4, 0x660018d4},
        {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03804000, 0x03804000},
-       {0x0000a610, 0x04c08c01, 0x04c08c01, 0x04808b01, 0x04808b01, 0x04808a01, 0x04808a01, 0x0300ca02, 0x0300ca02},
-       {0x0000a614, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00000e04, 0x00000e04},
-       {0x0000a618, 0x04010c01, 0x04010c01, 0x03c10b01, 0x03c10b01, 0x03810a01, 0x03810a01, 0x03014000, 0x03014000},
-       {0x0000a61c, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x00000000, 0x00000000},
-       {0x0000a620, 0x04010303, 0x04010303, 0x03c10303, 0x03c10303, 0x03810303, 0x03810303, 0x00000000, 0x00000000},
-       {0x0000a624, 0x03814e05, 0x03814e05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03414d05, 0x03014000, 0x03014000},
-       {0x0000a628, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x00c0c000, 0x03804c05, 0x03804c05},
-       {0x0000a62c, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x00c0c303, 0x0701de06, 0x0701de06},
-       {0x0000a630, 0x03418000, 0x03418000, 0x03018000, 0x03018000, 0x02c18000, 0x02c18000, 0x07819c07, 0x07819c07},
-       {0x0000a634, 0x03815004, 0x03815004, 0x03414f04, 0x03414f04, 0x03414e04, 0x03414e04, 0x0701dc07, 0x0701dc07},
-       {0x0000a638, 0x03005302, 0x03005302, 0x02c05202, 0x02c05202, 0x02805202, 0x02805202, 0x0701dc07, 0x0701dc07},
-       {0x0000a63c, 0x04c09302, 0x04c09302, 0x04809202, 0x04809202, 0x04809202, 0x04809202, 0x0701dc07, 0x0701dc07},
-       {0x0000b2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
-       {0x0000b2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
-       {0x0000b2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
+       {0x0000a60c, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x02c04b01, 0x03804000, 0x03804000},
+       {0x0000a610, 0x04008b01, 0x04008b01, 0x04008b01, 0x04008b01, 0x03c08b01, 0x03c08b01, 0x0300ca02, 0x0300ca02},
+       {0x0000a614, 0x05811403, 0x05811403, 0x05411303, 0x05411303, 0x05411303, 0x05411303, 0x00000e04, 0x00000e04},
+       {0x0000a618, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000},
+       {0x0000a61c, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000},
+       {0x0000a620, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x00000000, 0x00000000},
+       {0x0000a624, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03014000, 0x03014000},
+       {0x0000a628, 0x05811604, 0x05811604, 0x05411504, 0x05411504, 0x05411504, 0x05411504, 0x03804c05, 0x03804c05},
+       {0x0000a62c, 0x06815604, 0x06815604, 0x06415504, 0x06415504, 0x06015504, 0x06015504, 0x0701de06, 0x0701de06},
+       {0x0000a630, 0x07819a05, 0x07819a05, 0x07419905, 0x07419905, 0x07019805, 0x07019805, 0x07819c07, 0x07819c07},
+       {0x0000a634, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
+       {0x0000a638, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
+       {0x0000a63c, 0x07819e06, 0x07819e06, 0x07419d06, 0x07419d06, 0x07019c06, 0x07019c06, 0x0701dc07, 0x0701dc07},
+       {0x0000b2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
+       {0x0000b2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
+       {0x0000b2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
        {0x0000b2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
-       {0x0000c2dc, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xffffaaaa, 0xfffd5aaa, 0xfffd5aaa},
-       {0x0000c2e0, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xffffcccc, 0xfffe9ccc, 0xfffe9ccc},
-       {0x0000c2e4, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xfffff0f0, 0xffffe0f0, 0xffffe0f0},
+       {0x0000c2dc, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xffff6aaa, 0xfffd5aaa, 0xfffd5aaa},
+       {0x0000c2e0, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffdcccc, 0xfffe9ccc, 0xfffe9ccc},
+       {0x0000c2e4, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffe3b0f0, 0xffffe0f0, 0xffffe0f0},
        {0x0000c2e8, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xffffff00, 0xfffcff00, 0xfffcff00},
        {0x00016044, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
-       {0x00016048, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
+       {0x00016048, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
        {0x00016280, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01801e84, 0x01808e84, 0x01808e84},
        {0x00016444, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
-       {0x00016448, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
+       {0x00016448, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
        {0x00016844, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x056db2d4, 0x010002d4, 0x010002d4},
-       {0x00016848, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x62482401, 0x66482401, 0x66482401},
+       {0x00016848, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401, 0x66482401},
 };
 
 static const u32 ar955x_1p0_mac_core[][2] = {
@@ -846,7 +846,7 @@ static const u32 ar955x_1p0_baseband_core[][2] = {
        {0x0000a44c, 0x00000001},
        {0x0000a450, 0x00010000},
        {0x0000a458, 0x00000000},
-       {0x0000a644, 0x3fad9d74},
+       {0x0000a644, 0xbfad9d74},
        {0x0000a648, 0x0048060a},
        {0x0000a64c, 0x00003c37},
        {0x0000a670, 0x03020100},
@@ -1277,7 +1277,7 @@ static const u32 ar955x_1p0_modes_fast_clock[][3] = {
        {0x0000801c, 0x148ec02b, 0x148ec057},
        {0x00008318, 0x000044c0, 0x00008980},
        {0x00009e00, 0x0372131c, 0x0372131c},
-       {0x0000a230, 0x0000000b, 0x00000016},
+       {0x0000a230, 0x0000400b, 0x00004016},
        {0x0000a254, 0x00000898, 0x00001130},
 };
 
index 6e1915aee712c5978d2d581311366e82b0d24d70..28fd99203f6447e4d3545b0fd12b920733ffc10c 100644 (file)
@@ -685,6 +685,82 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
 
 #define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
 
+#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
+
+static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {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, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
+       {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
+       {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
+       {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
+       {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
+       {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
+       {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
+       {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
+       {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
+       {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
+       {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
+       {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
+       {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
+       {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
+       {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
+       {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
+       {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
+       {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
+       {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
+       {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
+       {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
+       {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
+       {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
+       {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
+       {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
+       {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
+       {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
+       {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
+       {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
+       {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
+       {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+       {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+       {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+       {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+       {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+       {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
+       {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
+};
+
 static const u32 ar9580_1p0_soc_preamble[][2] = {
        /* Addr      allmodes  */
        {0x000040a4, 0x00a0c1c9},
index 72501073b499d5c7d5b312dd74d5fd1424da24b6..094a9322f092faa74d64d42a5c1f3b5d5aabef78 100644 (file)
@@ -670,6 +670,23 @@ struct ath9k_vif_iter_data {
        int nadhocs;   /* number of adhoc vifs */
 };
 
+/* enum spectral_mode:
+ *
+ * @SPECTRAL_DISABLED: spectral mode is disabled
+ * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
+ *     something else.
+ * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
+ *     is performed manually.
+ * @SPECTRAL_CHANSCAN: Like manual, but also triggered when changing channels
+ *     during a channel scan.
+ */
+enum spectral_mode {
+       SPECTRAL_DISABLED = 0,
+       SPECTRAL_BACKGROUND,
+       SPECTRAL_MANUAL,
+       SPECTRAL_CHANSCAN,
+};
+
 struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
@@ -738,6 +755,10 @@ struct ath_softc {
        u8 ant_tx, ant_rx;
        struct dfs_pattern_detector *dfs_detector;
        u32 wow_enabled;
+       /* relay(fs) channel for spectral scan */
+       struct rchan *rfs_chan_spec_scan;
+       enum spectral_mode spectral_mode;
+       int scanning;
 
 #ifdef CONFIG_PM_SLEEP
        atomic_t wow_got_bmiss_intr;
@@ -746,6 +767,133 @@ struct ath_softc {
 #endif
 };
 
+#define SPECTRAL_SCAN_BITMASK          0x10
+/* Radar info packet format, used for DFS and spectral formats. */
+struct ath_radar_info {
+       u8 pulse_length_pri;
+       u8 pulse_length_ext;
+       u8 pulse_bw_info;
+} __packed;
+
+/* The HT20 spectral data has 4 bytes of additional information at it's end.
+ *
+ * [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
+ * [7:0]: all bins  max_magnitude[9:2]
+ * [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
+ * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
+ */
+struct ath_ht20_mag_info {
+       u8 all_bins[3];
+       u8 max_exp;
+} __packed;
+
+#define SPECTRAL_HT20_NUM_BINS         56
+
+/* WARNING: don't actually use this struct! MAC may vary the amount of
+ * data by -1/+2. This struct is for reference only.
+ */
+struct ath_ht20_fft_packet {
+       u8 data[SPECTRAL_HT20_NUM_BINS];
+       struct ath_ht20_mag_info mag_info;
+       struct ath_radar_info radar_info;
+} __packed;
+
+#define SPECTRAL_HT20_TOTAL_DATA_LEN   (sizeof(struct ath_ht20_fft_packet))
+
+/* Dynamic 20/40 mode:
+ *
+ * [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
+ * [7:0]: lower bins  max_magnitude[9:2]
+ * [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
+ * [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
+ * [7:0]: upper bins  max_magnitude[9:2]
+ * [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
+ * [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)
+ */
+struct ath_ht20_40_mag_info {
+       u8 lower_bins[3];
+       u8 upper_bins[3];
+       u8 max_exp;
+} __packed;
+
+#define SPECTRAL_HT20_40_NUM_BINS              128
+
+/* WARNING: don't actually use this struct! MAC may vary the amount of
+ * data. This struct is for reference only.
+ */
+struct ath_ht20_40_fft_packet {
+       u8 data[SPECTRAL_HT20_40_NUM_BINS];
+       struct ath_ht20_40_mag_info mag_info;
+       struct ath_radar_info radar_info;
+} __packed;
+
+
+#define SPECTRAL_HT20_40_TOTAL_DATA_LEN        (sizeof(struct ath_ht20_40_fft_packet))
+
+/* grabs the max magnitude from the all/upper/lower bins */
+static inline u16 spectral_max_magnitude(u8 *bins)
+{
+       return (bins[0] & 0xc0) >> 6 |
+              (bins[1] & 0xff) << 2 |
+              (bins[2] & 0x03) << 10;
+}
+
+/* return the max magnitude from the all/upper/lower bins */
+static inline u8 spectral_max_index(u8 *bins)
+{
+       s8 m = (bins[2] & 0xfc) >> 2;
+
+       /* TODO: this still doesn't always report the right values ... */
+       if (m > 32)
+               m |= 0xe0;
+       else
+               m &= ~0xe0;
+
+       return m + 29;
+}
+
+/* return the bitmap weight from the all/upper/lower bins */
+static inline u8 spectral_bitmap_weight(u8 *bins)
+{
+       return bins[0] & 0x3f;
+}
+
+/* FFT sample format given to userspace via debugfs.
+ *
+ * Please keep the type/length at the front position and change
+ * other fields after adding another sample type
+ *
+ * TODO: this might need rework when switching to nl80211-based
+ * interface.
+ */
+enum ath_fft_sample_type {
+       ATH_FFT_SAMPLE_HT20 = 0,
+};
+
+struct fft_sample_tlv {
+       u8 type;        /* see ath_fft_sample */
+       u16 length;
+       /* type dependent data follows */
+} __packed;
+
+struct fft_sample_ht20 {
+       struct fft_sample_tlv tlv;
+
+       u8 __alignment;
+
+       u16 freq;
+       s8 rssi;
+       s8 noise;
+
+       u16 max_magnitude;
+       u8 max_index;
+       u8 bitmap_weight;
+
+       u64 tsf;
+
+       u16 data[SPECTRAL_HT20_NUM_BINS];
+} __packed;
+
 void ath9k_tasklet(unsigned long data);
 int ath_cabq_update(struct ath_softc *);
 
@@ -768,6 +916,10 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
 void ath9k_reload_chainmask_settings(struct ath_softc *sc);
 
 bool ath9k_uses_beacons(int type);
+void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw);
+int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
+                              enum spectral_mode spectral_mode);
+
 
 #ifdef CONFIG_ATH9K_PCI
 int ath_pci_init(void);
index 13ff9edc24015e5e2126fc4f6c7fde8dcb003c90..75b504ba3b3f9817d5d023250c65935e49630ab0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
+#include <linux/relay.h>
 #include <asm/unaligned.h>
 
 #include "ath9k.h"
@@ -966,6 +967,112 @@ static const struct file_operations fops_recv = {
        .llseek = default_llseek,
 };
 
+static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf,
+                                      size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char *mode = "";
+       unsigned int len;
+
+       switch (sc->spectral_mode) {
+       case SPECTRAL_DISABLED:
+               mode = "disable";
+               break;
+       case SPECTRAL_BACKGROUND:
+               mode = "background";
+               break;
+       case SPECTRAL_CHANSCAN:
+               mode = "chanscan";
+               break;
+       case SPECTRAL_MANUAL:
+               mode = "manual";
+               break;
+       }
+       len = strlen(mode);
+       return simple_read_from_buffer(user_buf, count, ppos, mode, len);
+}
+
+static ssize_t write_file_spec_scan_ctl(struct file *file,
+                                       const char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+       char buf[32];
+       ssize_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+
+       buf[len] = '\0';
+
+       if (strncmp("trigger", buf, 7) == 0) {
+               ath9k_spectral_scan_trigger(sc->hw);
+       } else if (strncmp("background", buf, 9) == 0) {
+               ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND);
+               ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n");
+       } else if (strncmp("chanscan", buf, 8) == 0) {
+               ath9k_spectral_scan_config(sc->hw, SPECTRAL_CHANSCAN);
+               ath_dbg(common, CONFIG, "spectral scan: channel scan mode enabled\n");
+       } else if (strncmp("manual", buf, 6) == 0) {
+               ath9k_spectral_scan_config(sc->hw, SPECTRAL_MANUAL);
+               ath_dbg(common, CONFIG, "spectral scan: manual mode enabled\n");
+       } else if (strncmp("disable", buf, 7) == 0) {
+               ath9k_spectral_scan_config(sc->hw, SPECTRAL_DISABLED);
+               ath_dbg(common, CONFIG, "spectral scan: disabled\n");
+       } else {
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+static const struct file_operations fops_spec_scan_ctl = {
+       .read = read_file_spec_scan_ctl,
+       .write = write_file_spec_scan_ctl,
+       .open = simple_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
+static struct dentry *create_buf_file_handler(const char *filename,
+                                             struct dentry *parent,
+                                             umode_t mode,
+                                             struct rchan_buf *buf,
+                                             int *is_global)
+{
+       struct dentry *buf_file;
+
+       buf_file = debugfs_create_file(filename, mode, parent, buf,
+                                      &relay_file_operations);
+       *is_global = 1;
+       return buf_file;
+}
+
+static int remove_buf_file_handler(struct dentry *dentry)
+{
+       debugfs_remove(dentry);
+
+       return 0;
+}
+
+void ath_debug_send_fft_sample(struct ath_softc *sc,
+                              struct fft_sample_tlv *fft_sample_tlv)
+{
+       if (!sc->rfs_chan_spec_scan)
+               return;
+
+       relay_write(sc->rfs_chan_spec_scan, fft_sample_tlv,
+                   fft_sample_tlv->length + sizeof(*fft_sample_tlv));
+}
+
+static struct rchan_callbacks rfs_spec_scan_cb = {
+       .create_buf_file = create_buf_file_handler,
+       .remove_buf_file = remove_buf_file_handler,
+};
+
+
 static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
                                 size_t count, loff_t *ppos)
 {
@@ -1780,6 +1887,14 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_base_eeprom);
        debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_modal_eeprom);
+       sc->rfs_chan_spec_scan = relay_open("spectral_scan",
+                                           sc->debug.debugfs_phy,
+                                           262144, 4, &rfs_spec_scan_cb,
+                                           NULL);
+       debugfs_create_file("spectral_scan_ctl", S_IRUSR | S_IWUSR,
+                           sc->debug.debugfs_phy, sc,
+                           &fops_spec_scan_ctl);
+
 #ifdef CONFIG_ATH9K_MAC_DEBUG
        debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_samps);
index 375c3b46411eee6cd140dbc22e6e435fe0e32ad9..b19bed7f74c2c069623dd67abf9d936399753499 100644 (file)
@@ -23,6 +23,7 @@
 
 struct ath_txq;
 struct ath_buf;
+struct fft_sample_tlv;
 
 #ifdef CONFIG_ATH9K_DEBUGFS
 #define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
@@ -323,6 +324,10 @@ void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif,
                              struct ieee80211_sta *sta,
                              struct dentry *dir);
+
+void ath_debug_send_fft_sample(struct ath_softc *sc,
+                              struct fft_sample_tlv *fft_sample);
+
 #else
 
 #define RX_STAT_INC(c) /* NOP */
index 38c5a8702fb2006ba69835c348a4d0643f7c77c8..d32ebf7a2414234d96d7169f12ab71d37fc80225 100644 (file)
@@ -397,6 +397,7 @@ enum ath9k_int {
 #define MAX_RTT_TABLE_ENTRY     6
 #define MAX_IQCAL_MEASUREMENT  8
 #define MAX_CL_TAB_ENTRY       16
+#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
 
 struct ath9k_hw_cal_data {
        u16 channel;
@@ -656,6 +657,37 @@ struct ath_hw_private_ops {
        void (*ani_cache_ini_regs)(struct ath_hw *ah);
 };
 
+/**
+ * struct ath_spec_scan - parameters for Atheros spectral scan
+ *
+ * @enabled: enable/disable spectral scan
+ * @short_repeat: controls whether the chip is in spectral scan mode
+ *               for 4 usec (enabled) or 204 usec (disabled)
+ * @count: number of scan results requested. There are special meanings
+ *        in some chip revisions:
+ *        AR92xx: highest bit set (>=128) for endless mode
+ *                (spectral scan won't stopped until explicitly disabled)
+ *        AR9300 and newer: 0 for endless mode
+ * @endless: true if endless mode is intended. Otherwise, count value is
+ *           corrected to the next possible value.
+ * @period: time duration between successive spectral scan entry points
+ *         (period*256*Tclk). Tclk = ath_common->clockrate
+ * @fft_period: PHY passes FFT frames to MAC every (fft_period+1)*4uS
+ *
+ * Note: Tclk = 40MHz or 44MHz depending upon operating mode.
+ *      Typically it's 44MHz in 2/5GHz on later chips, but there's
+ *      a "fast clock" check for this in 5GHz.
+ *
+ */
+struct ath_spec_scan {
+       bool enabled;
+       bool short_repeat;
+       bool endless;
+       u8 count;
+       u8 period;
+       u8 fft_period;
+};
+
 /**
  * struct ath_hw_ops - callbacks used by hardware code and driver code
  *
@@ -664,6 +696,10 @@ struct ath_hw_private_ops {
  *
  * @config_pci_powersave:
  * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
+ *
+ * @spectral_scan_config: set parameters for spectral scan and enable/disable it
+ * @spectral_scan_trigger: trigger a spectral scan run
+ * @spectral_scan_wait: wait for a spectral scan run to finish
  */
 struct ath_hw_ops {
        void (*config_pci_powersave)(struct ath_hw *ah,
@@ -684,6 +720,10 @@ struct ath_hw_ops {
        void (*antdiv_comb_conf_set)(struct ath_hw *ah,
                        struct ath_hw_antcomb_conf *antconf);
        void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable);
+       void (*spectral_scan_config)(struct ath_hw *ah,
+                                    struct ath_spec_scan *param);
+       void (*spectral_scan_trigger)(struct ath_hw *ah);
+       void (*spectral_scan_wait)(struct ath_hw *ah);
 };
 
 struct ath_nf_limits {
index 5c01f43c32b05a722f1e2e01dd603c627b1f7e68..90cfcb3983d1b683fa6cbc7e1c6e0c12c39d8863 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/ath9k_platform.h>
 #include <linux/module.h>
+#include <linux/relay.h>
 
 #include "ath9k.h"
 
@@ -916,6 +917,11 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
                sc->dfs_detector->exit(sc->dfs_detector);
 
        ath9k_eeprom_release(sc);
+
+       if (sc->rfs_chan_spec_scan) {
+               relay_close(sc->rfs_chan_spec_scan);
+               sc->rfs_chan_spec_scan = NULL;
+       }
 }
 
 void ath9k_deinit_device(struct ath_softc *sc)
index 4a745e68dd941d9351e4fe911b47d76ec288551d..1ff817061ebc44e07d1af87edb4d9ce471980bb2 100644 (file)
@@ -226,7 +226,8 @@ enum ath9k_phyerr {
        ATH9K_PHYERR_HT_LENGTH_ILLEGAL    = 35,
        ATH9K_PHYERR_HT_RATE_ILLEGAL      = 36,
 
-       ATH9K_PHYERR_MAX                  = 37,
+       ATH9K_PHYERR_SPECTRAL             = 38,
+       ATH9K_PHYERR_MAX                  = 39,
 };
 
 struct ath_desc {
index e1fa70596e613520c5d83edb72eda81b331c36c0..32417fd4bf5a7bba051abf3f40ac246fc6048000 100644 (file)
@@ -1075,6 +1075,86 @@ static void ath9k_disable_ps(struct ath_softc *sc)
        ath_dbg(common, PS, "PowerSave disabled\n");
 }
 
+void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw)
+{
+       struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 rxfilter;
+
+       if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
+               ath_err(common, "spectrum analyzer not implemented on this hardware\n");
+               return;
+       }
+
+       ath9k_ps_wakeup(sc);
+       rxfilter = ath9k_hw_getrxfilter(ah);
+       ath9k_hw_setrxfilter(ah, rxfilter |
+                                ATH9K_RX_FILTER_PHYRADAR |
+                                ATH9K_RX_FILTER_PHYERR);
+
+       /* TODO: usually this should not be neccesary, but for some reason
+        * (or in some mode?) the trigger must be called after the
+        * configuration, otherwise the register will have its values reset
+        * (on my ar9220 to value 0x01002310)
+        */
+       ath9k_spectral_scan_config(hw, sc->spectral_mode);
+       ath9k_hw_ops(ah)->spectral_scan_trigger(ah);
+       ath9k_ps_restore(sc);
+}
+
+int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
+                              enum spectral_mode spectral_mode)
+{
+       struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath_spec_scan param;
+
+       if (!ath9k_hw_ops(ah)->spectral_scan_trigger) {
+               ath_err(common, "spectrum analyzer not implemented on this hardware\n");
+               return -1;
+       }
+
+       /* NOTE: this will generate a few samples ...
+        *
+        * TODO: review default parameters, and/or define an interface to set
+        * them.
+        */
+       param.enabled = 1;
+       param.short_repeat = true;
+       param.count = 8;
+       param.endless = false;
+       param.period = 0xFF;
+       param.fft_period = 0xF;
+
+       switch (spectral_mode) {
+       case SPECTRAL_DISABLED:
+               param.enabled = 0;
+               break;
+       case SPECTRAL_BACKGROUND:
+               /* send endless samples.
+                * TODO: is this really useful for "background"?
+                */
+               param.endless = 1;
+               break;
+       case SPECTRAL_CHANSCAN:
+               break;
+       case SPECTRAL_MANUAL:
+               break;
+       default:
+               return -1;
+       }
+
+       ath9k_ps_wakeup(sc);
+       ath9k_hw_ops(ah)->spectral_scan_config(ah, &param);
+       ath9k_ps_restore(sc);
+
+       sc->spectral_mode = spectral_mode;
+
+       return 0;
+}
+
 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct ath_softc *sc = hw->priv;
@@ -1188,6 +1268,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                 */
                if (old_pos >= 0)
                        ath_update_survey_nf(sc, old_pos);
+
+               /* perform spectral scan if requested. */
+               if (sc->scanning && sc->spectral_mode == SPECTRAL_CHANSCAN)
+                       ath9k_spectral_scan_trigger(hw);
+
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -2240,6 +2325,19 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
 }
 
 #endif
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+       struct ath_softc *sc = hw->priv;
+
+       sc->scanning = 1;
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+       struct ath_softc *sc = hw->priv;
+
+       sc->scanning = 0;
+}
 
 struct ieee80211_ops ath9k_ops = {
        .tx                 = ath9k_tx,
@@ -2286,4 +2384,6 @@ struct ieee80211_ops ath9k_ops = {
        .sta_add_debugfs    = ath9k_sta_add_debugfs,
        .sta_remove_debugfs = ath9k_sta_remove_debugfs,
 #endif
+       .sw_scan_start      = ath9k_sw_scan_start,
+       .sw_scan_complete   = ath9k_sw_scan_complete,
 };
index 3d236aebf58834421093510bbbb1081a63b8b589..45f2d475ac1a0089d1d0dd175d23cc04c7aef96f 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/dma-mapping.h>
+#include <linux/relay.h>
 #include "ath9k.h"
 #include "ar9003_mac.h"
 
@@ -1025,6 +1026,108 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
                rxs->flag &= ~RX_FLAG_DECRYPTED;
 }
 
+static s8 fix_rssi_inv_only(u8 rssi_val)
+{
+       if (rssi_val == 128)
+               rssi_val = 0;
+       return (s8) rssi_val;
+}
+
+
+static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
+                           struct ath_rx_status *rs, u64 tsf)
+{
+#ifdef CONFIG_ATH_DEBUG
+       struct ath_hw *ah = sc->sc_ah;
+       u8 bins[SPECTRAL_HT20_NUM_BINS];
+       u8 *vdata = (u8 *)hdr;
+       struct fft_sample_ht20 fft_sample;
+       struct ath_radar_info *radar_info;
+       struct ath_ht20_mag_info *mag_info;
+       int len = rs->rs_datalen;
+       int i, dc_pos;
+
+       /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer
+        * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT
+        * yet, but this is supposed to be possible as well.
+        */
+       if (rs->rs_phyerr != ATH9K_PHYERR_RADAR &&
+           rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT &&
+           rs->rs_phyerr != ATH9K_PHYERR_SPECTRAL)
+               return;
+
+       /* Variation in the data length is possible and will be fixed later.
+        * Note that we only support HT20 for now.
+        *
+        * TODO: add HT20_40 support as well.
+        */
+       if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) ||
+           (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1))
+               return;
+
+       /* check if spectral scan bit is set. This does not have to be checked
+        * if received through a SPECTRAL phy error, but shouldn't hurt.
+        */
+       radar_info = ((struct ath_radar_info *)&vdata[len]) - 1;
+       if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
+               return;
+
+       fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20;
+       fft_sample.tlv.length = sizeof(fft_sample) - sizeof(fft_sample.tlv);
+
+       fft_sample.freq = ah->curchan->chan->center_freq;
+       fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
+       fft_sample.noise = ah->noise;
+
+       switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
+       case 0:
+               /* length correct, nothing to do. */
+               memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS);
+               break;
+       case -1:
+               /* first byte missing, duplicate it. */
+               memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1);
+               bins[0] = vdata[0];
+               break;
+       case 2:
+               /* MAC added 2 extra bytes at bin 30 and 32, remove them. */
+               memcpy(bins, vdata, 30);
+               bins[30] = vdata[31];
+               memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31);
+               break;
+       case 1:
+               /* MAC added 2 extra bytes AND first byte is missing. */
+               bins[0] = vdata[0];
+               memcpy(&bins[0], vdata, 30);
+               bins[31] = vdata[31];
+               memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32);
+               break;
+       default:
+               return;
+       }
+
+       /* DC value (value in the middle) is the blind spot of the spectral
+        * sample and invalid, interpolate it.
+        */
+       dc_pos = SPECTRAL_HT20_NUM_BINS / 2;
+       bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2;
+
+       /* mag data is at the end of the frame, in front of radar_info */
+       mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1;
+
+       /* Apply exponent and grab further auxiliary information. */
+       for (i = 0; i < SPECTRAL_HT20_NUM_BINS; i++)
+               fft_sample.data[i] = bins[i] << mag_info->max_exp;
+
+       fft_sample.max_magnitude = spectral_max_magnitude(mag_info->all_bins);
+       fft_sample.max_index = spectral_max_index(mag_info->all_bins);
+       fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins);
+       fft_sample.tsf = tsf;
+
+       ath_debug_send_fft_sample(sc, &fft_sample.tlv);
+#endif
+}
+
 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 {
        struct ath_buf *bf;
@@ -1122,6 +1225,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                    unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
                        rxs->mactime += 0x100000000ULL;
 
+               if ((rs.rs_status & ATH9K_RXERR_PHY))
+                       ath_process_fft(sc, hdr, &rs, rxs->mactime);
+
                retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
                                                 rxs, &decrypt_error);
                if (retval)
index 0ac205e4cd044790f3a65a9a902644cbeab561a4..5929850649f0ee45a024a8328d6c76c17b5127bb 100644 (file)
 #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_REVISION_9300_22       3
 #define AR_SREV_VERSION_9330           0x200
 #define AR_SREV_REVISION_9330_10       0
 #define AR_SREV_REVISION_9330_11       1
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
 #define AR_SREV_9300_20_OR_LATER(_ah) \
        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
+#define AR_SREV_9300_22(_ah) \
+       (AR_SREV_9300(ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_22))
 
 #define AR_SREV_9330(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9330))
index d248a4cc665645c1aa8c59e0296d5499f596450a..b73e497fe77049b59d13f9c822492c2dceb2aba1 100644 (file)
@@ -337,11 +337,11 @@ struct mac80211_hwsim_data {
        int scan_chan_idx;
 
        struct ieee80211_channel *channel;
-       unsigned long beacon_int; /* in jiffies unit */
+       u64 beacon_int  /* beacon interval in us */;
        unsigned int rx_filter;
        bool started, idle, scanning;
        struct mutex mutex;
-       struct timer_list beacon_timer;
+       struct tasklet_hrtimer beacon_timer;
        enum ps_mode {
                PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
        } ps;
@@ -361,7 +361,10 @@ struct mac80211_hwsim_data {
        int power_level;
 
        /* difference between this hw's clock and the real clock, in usecs */
-       u64 tsf_offset;
+       s64 tsf_offset;
+       s64 bcn_delta;
+       /* absolute beacon transmission time. Used to cover up "tx" delay. */
+       u64 abs_bcn_ts;
 };
 
 
@@ -409,15 +412,19 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 }
 
+static inline u64 mac80211_hwsim_get_tsf_raw(void)
+{
+       return ktime_to_us(ktime_get_real());
+}
+
 static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
 {
-       struct timeval tv = ktime_to_timeval(ktime_get_real());
-       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+       u64 now = mac80211_hwsim_get_tsf_raw();
        return cpu_to_le64(now + data->tsf_offset);
 }
 
 static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
-               struct ieee80211_vif *vif)
+                                 struct ieee80211_vif *vif)
 {
        struct mac80211_hwsim_data *data = hw->priv;
        return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
@@ -427,9 +434,13 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
                struct ieee80211_vif *vif, u64 tsf)
 {
        struct mac80211_hwsim_data *data = hw->priv;
-       struct timeval tv = ktime_to_timeval(ktime_get_real());
-       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
-       data->tsf_offset = tsf - now;
+       u64 now = mac80211_hwsim_get_tsf(hw, vif);
+       u32 bcn_int = data->beacon_int;
+       s64 delta = tsf - now;
+
+       data->tsf_offset += delta;
+       /* adjust after beaconing with new timestamp at old TBTT */
+       data->bcn_delta = do_div(delta, bcn_int);
 }
 
 static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
@@ -700,7 +711,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_rx_status rx_status;
-       struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
+       u64 now;
 
        memset(&rx_status, 0, sizeof(rx_status));
        rx_status.flag |= RX_FLAG_MACTIME_START;
@@ -726,11 +737,23 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        secpath_reset(skb);
        nf_reset(skb);
 
+       /*
+        * Get absolute mactime here so all HWs RX at the "same time", and
+        * absolute TX time for beacon mactime so the timestamp matches.
+        * Giving beacons a different mactime than non-beacons looks messy, but
+        * it helps the Toffset be exact and a ~10us mactime discrepancy
+        * probably doesn't really matter.
+        */
+       if (ieee80211_is_beacon(hdr->frame_control) ||
+           ieee80211_is_probe_resp(hdr->frame_control))
+               now = data->abs_bcn_ts;
+       else
+               now = mac80211_hwsim_get_tsf_raw();
+
        /* Copy skb to all enabled radios that are on the current frequency */
        spin_lock(&hwsim_radio_lock);
        list_for_each_entry(data2, &hwsim_radios, list) {
                struct sk_buff *nskb;
-               struct ieee80211_mgmt *mgmt;
                struct tx_iter_data tx_iter_data = {
                        .receive = false,
                        .channel = chan,
@@ -782,17 +805,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
                if (mac80211_hwsim_addr_match(data2, hdr->addr1))
                        ack = true;
 
-               /* set bcn timestamp relative to receiver mactime */
-               rx_status.mactime =
-                               le64_to_cpu(__mac80211_hwsim_get_tsf(data2));
-               mgmt = (struct ieee80211_mgmt *) nskb->data;
-               if (ieee80211_is_beacon(mgmt->frame_control) ||
-                   ieee80211_is_probe_resp(mgmt->frame_control))
-                       mgmt->u.beacon.timestamp = cpu_to_le64(
-                               rx_status.mactime +
-                               (data->tsf_offset - data2->tsf_offset) +
-                               24 * 8 * 10 / txrate->bitrate);
-
+               rx_status.mactime = now + data2->tsf_offset;
 #if 0
                /*
                 * Don't enable this code by default as the OUI 00:00:00
@@ -916,7 +929,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
 {
        struct mac80211_hwsim_data *data = hw->priv;
        data->started = false;
-       del_timer(&data->beacon_timer);
+       tasklet_hrtimer_cancel(&data->beacon_timer);
        wiphy_debug(hw->wiphy, "%s\n", __func__);
 }
 
@@ -982,7 +995,11 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
                                     struct ieee80211_vif *vif)
 {
-       struct ieee80211_hw *hw = arg;
+       struct mac80211_hwsim_data *data = arg;
+       struct ieee80211_hw *hw = data->hw;
+       struct ieee80211_tx_info *info;
+       struct ieee80211_rate *txrate;
+       struct ieee80211_mgmt *mgmt;
        struct sk_buff *skb;
 
        hwsim_check_magic(vif);
@@ -995,26 +1012,48 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
        skb = ieee80211_beacon_get(hw, vif);
        if (skb == NULL)
                return;
+       info = IEEE80211_SKB_CB(skb);
+       txrate = ieee80211_get_tx_rate(hw, info);
+
+       mgmt = (struct ieee80211_mgmt *) skb->data;
+       /* fake header transmission time */
+       data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw();
+       mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts +
+                                              data->tsf_offset +
+                                              24 * 8 * 10 / txrate->bitrate);
 
        mac80211_hwsim_tx_frame(hw, skb,
                                rcu_dereference(vif->chanctx_conf)->def.chan);
 }
 
-
-static void mac80211_hwsim_beacon(unsigned long arg)
+static enum hrtimer_restart
+mac80211_hwsim_beacon(struct hrtimer *timer)
 {
-       struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
-       struct mac80211_hwsim_data *data = hw->priv;
+       struct mac80211_hwsim_data *data =
+               container_of(timer, struct mac80211_hwsim_data,
+                            beacon_timer.timer);
+       struct ieee80211_hw *hw = data->hw;
+       u64 bcn_int = data->beacon_int;
+       ktime_t next_bcn;
 
        if (!data->started)
-               return;
+               goto out;
 
        ieee80211_iterate_active_interfaces_atomic(
                hw, IEEE80211_IFACE_ITER_NORMAL,
-               mac80211_hwsim_beacon_tx, hw);
+               mac80211_hwsim_beacon_tx, data);
+
+       /* beacon at new TBTT + beacon interval */
+       if (data->bcn_delta) {
+               bcn_int -= data->bcn_delta;
+               data->bcn_delta = 0;
+       }
 
-       data->beacon_timer.expires = jiffies + data->beacon_int;
-       add_timer(&data->beacon_timer);
+       next_bcn = ktime_add(hrtimer_get_expires(timer),
+                            ns_to_ktime(bcn_int * 1000));
+       tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
+out:
+       return HRTIMER_NORESTART;
 }
 
 static const char *hwsim_chantypes[] = {
@@ -1052,9 +1091,16 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
 
        data->power_level = conf->power_level;
        if (!data->started || !data->beacon_int)
-               del_timer(&data->beacon_timer);
-       else
-               mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
+               tasklet_hrtimer_cancel(&data->beacon_timer);
+       else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
+               u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
+               u32 bcn_int = data->beacon_int;
+               u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);
+
+               tasklet_hrtimer_start(&data->beacon_timer,
+                                     ns_to_ktime(until_tbtt * 1000),
+                                     HRTIMER_MODE_REL);
+       }
 
        return 0;
 }
@@ -1104,12 +1150,26 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changed & BSS_CHANGED_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;
-               if (data->started)
-                       mod_timer(&data->beacon_timer,
-                                 jiffies + data->beacon_int);
+               data->beacon_int = info->beacon_int * 1024;
+       }
+
+       if (changed & BSS_CHANGED_BEACON_ENABLED) {
+               wiphy_debug(hw->wiphy, "  BCN EN: %d\n", info->enable_beacon);
+               if (data->started &&
+                   !hrtimer_is_queued(&data->beacon_timer.timer) &&
+                   info->enable_beacon) {
+                       u64 tsf, until_tbtt;
+                       u32 bcn_int;
+                       if (WARN_ON(!data->beacon_int))
+                               data->beacon_int = 1000 * 1024;
+                       tsf = mac80211_hwsim_get_tsf(hw, vif);
+                       bcn_int = data->beacon_int;
+                       until_tbtt = bcn_int - do_div(tsf, bcn_int);
+                       tasklet_hrtimer_start(&data->beacon_timer,
+                                             ns_to_ktime(until_tbtt * 1000),
+                                             HRTIMER_MODE_REL);
+               } else if (!info->enable_beacon)
+                       tasklet_hrtimer_cancel(&data->beacon_timer);
        }
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT) {
@@ -2392,8 +2452,9 @@ static int __init init_mac80211_hwsim(void)
                                                        data->debugfs, data,
                                                        &hwsim_fops_group);
 
-               setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
-                           (unsigned long) hw);
+               tasklet_hrtimer_init(&data->beacon_timer,
+                                    mac80211_hwsim_beacon,
+                                    CLOCK_REALTIME, HRTIMER_MODE_ABS);
 
                list_add_tail(&data->list, &hwsim_radios);
        }
index c4d287b48e6452f473a888be2b1a019736ba15f4..a9c0788992526c0303af58c437674e0e7068e5d3 100644 (file)
@@ -1588,6 +1588,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 
                rc = -ETIMEDOUT;
        }
+       priv->tx_wait = NULL;
        spin_unlock_bh(&priv->tx_lock);
 
        return rc;
@@ -3934,7 +3935,30 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif, u8 *addr)
 {
        struct mwl8k_cmd_set_new_stn *cmd;
-       int rc;
+       struct mwl8k_priv *priv = hw->priv;
+       int rc, i;
+       u8 idx;
+
+       spin_lock(&priv->stream_lock);
+       /* Destroy any active ampdu streams for this sta */
+       for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
+               struct mwl8k_ampdu_stream *s;
+               s = &priv->ampdu[i];
+               if (s->state != AMPDU_NO_STREAM) {
+                       if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) {
+                               if (s->state == AMPDU_STREAM_ACTIVE) {
+                                       idx = s->idx;
+                                       spin_unlock(&priv->stream_lock);
+                                       mwl8k_destroy_ba(hw, idx);
+                                       spin_lock(&priv->stream_lock);
+                               } else if (s->state == AMPDU_STREAM_NEW) {
+                                       mwl8k_remove_stream(hw, s);
+                               }
+                       }
+               }
+       }
+
+       spin_unlock(&priv->stream_lock);
 
        cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
        if (cmd == NULL)
@@ -4507,6 +4531,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
                priv->irq = -1;
                tasklet_disable(&priv->poll_tx_task);
                tasklet_disable(&priv->poll_rx_task);
+       } else {
+               ieee80211_wake_queues(hw);
        }
 
        return rc;
index ff3c8a21f10d90397dc9fda07b99dcfb08ebc9b9..f7305e2fddcc690b09d2a793d553c0b8b937390e 100644 (file)
@@ -136,6 +136,11 @@ config SSB_DRIVER_MIPS
 
          If unsure, say N
 
+config SSB_SFLASH
+       bool "SSB serial flash support"
+       depends on SSB_DRIVER_MIPS && BROKEN
+       default y
+
 # Assumption: We are on embedded, if we compile the MIPS core.
 config SSB_EMBEDDED
        bool
index 9159ba77c388086a06196767da05d87150d3aacd..b1ddc116d387c47119408ed07d71d3274cce0691 100644 (file)
@@ -11,6 +11,7 @@ ssb-$(CONFIG_SSB_SDIOHOST)            += sdio.o
 # built-in drivers
 ssb-y                                  += driver_chipcommon.o
 ssb-y                                  += driver_chipcommon_pmu.o
+ssb-$(CONFIG_SSB_SFLASH)               += driver_chipcommon_sflash.o
 ssb-$(CONFIG_SSB_DRIVER_MIPS)          += driver_mipscore.o
 ssb-$(CONFIG_SSB_DRIVER_EXTIF)         += driver_extif.o
 ssb-$(CONFIG_SSB_DRIVER_PCICORE)       += driver_pcicore.o
diff --git a/drivers/ssb/driver_chipcommon_sflash.c b/drivers/ssb/driver_chipcommon_sflash.c
new file mode 100644 (file)
index 0000000..720665c
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Sonics Silicon Backplane
+ * ChipCommon serial flash interface
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/ssb/ssb.h>
+
+#include "ssb_private.h"
+
+struct ssb_sflash_tbl_e {
+       char *name;
+       u32 id;
+       u32 blocksize;
+       u16 numblocks;
+};
+
+static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
+       { "M25P20", 0x11, 0x10000, 4, },
+       { "M25P40", 0x12, 0x10000, 8, },
+
+       { "M25P16", 0x14, 0x10000, 32, },
+       { "M25P32", 0x15, 0x10000, 64, },
+       { "M25P64", 0x16, 0x10000, 128, },
+       { "M25FL128", 0x17, 0x10000, 256, },
+       { 0 },
+};
+
+static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
+       { "SST25WF512", 1, 0x1000, 16, },
+       { "SST25VF512", 0x48, 0x1000, 16, },
+       { "SST25WF010", 2, 0x1000, 32, },
+       { "SST25VF010", 0x49, 0x1000, 32, },
+       { "SST25WF020", 3, 0x1000, 64, },
+       { "SST25VF020", 0x43, 0x1000, 64, },
+       { "SST25WF040", 4, 0x1000, 128, },
+       { "SST25VF040", 0x44, 0x1000, 128, },
+       { "SST25VF040B", 0x8d, 0x1000, 128, },
+       { "SST25WF080", 5, 0x1000, 256, },
+       { "SST25VF080B", 0x8e, 0x1000, 256, },
+       { "SST25VF016", 0x41, 0x1000, 512, },
+       { "SST25VF032", 0x4a, 0x1000, 1024, },
+       { "SST25VF064", 0x4b, 0x1000, 2048, },
+       { 0 },
+};
+
+static struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
+       { "AT45DB011", 0xc, 256, 512, },
+       { "AT45DB021", 0x14, 256, 1024, },
+       { "AT45DB041", 0x1c, 256, 2048, },
+       { "AT45DB081", 0x24, 256, 4096, },
+       { "AT45DB161", 0x2c, 512, 4096, },
+       { "AT45DB321", 0x34, 512, 8192, },
+       { "AT45DB642", 0x3c, 1024, 8192, },
+       { 0 },
+};
+
+static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode)
+{
+       int i;
+       chipco_write32(cc, SSB_CHIPCO_FLASHCTL,
+                      SSB_CHIPCO_FLASHCTL_START | opcode);
+       for (i = 0; i < 1000; i++) {
+               if (!(chipco_read32(cc, SSB_CHIPCO_FLASHCTL) &
+                     SSB_CHIPCO_FLASHCTL_BUSY))
+                       return;
+               cpu_relax();
+       }
+       pr_err("SFLASH control command failed (timeout)!\n");
+}
+
+/* Initialize serial flash access */
+int ssb_sflash_init(struct ssb_chipcommon *cc)
+{
+       struct ssb_sflash_tbl_e *e;
+       u32 id, id2;
+
+       switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
+       case SSB_CHIPCO_FLASHT_STSER:
+               ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP);
+
+               chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0);
+               ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
+               id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
+
+               chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1);
+               ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
+               id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
+
+               switch (id) {
+               case 0xbf:
+                       for (e = ssb_sflash_sst_tbl; e->name; e++) {
+                               if (e->id == id2)
+                                       break;
+                       }
+                       break;
+               case 0x13:
+                       return -ENOTSUPP;
+               default:
+                       for (e = ssb_sflash_st_tbl; e->name; e++) {
+                               if (e->id == id)
+                                       break;
+                       }
+                       break;
+               }
+               if (!e->name) {
+                       pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n",
+                              id, id2);
+                       return -ENOTSUPP;
+               }
+
+               break;
+       case SSB_CHIPCO_FLASHT_ATSER:
+               ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS);
+               id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c;
+
+               for (e = ssb_sflash_at_tbl; e->name; e++) {
+                       if (e->id == id)
+                               break;
+               }
+               if (!e->name) {
+                       pr_err("Unsupported Atmel serial flash (id: 0x%X)\n",
+                              id);
+                       return -ENOTSUPP;
+               }
+
+               break;
+       default:
+               pr_err("Unsupported flash type\n");
+               return -ENOTSUPP;
+       }
+
+       pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n",
+               e->name, e->blocksize, e->numblocks);
+
+       pr_err("Serial flash support is not implemented yet!\n");
+
+       return -ENOTSUPP;
+}
index 5bd05b136d22ef80b2cd93f78b65d6ef60640473..2a7684c90243f78fce00c314bc56bff701b671ab 100644 (file)
@@ -203,7 +203,8 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
        switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
        case SSB_CHIPCO_FLASHT_STSER:
        case SSB_CHIPCO_FLASHT_ATSER:
-               pr_err("Serial flash not supported\n");
+               pr_debug("Found serial flash\n");
+               ssb_sflash_init(&bus->chipco);
                break;
        case SSB_CHIPCO_FLASHT_PARA:
                pr_debug("Found parallel flash\n");
index 6c10b66c796cf7ee23ae3e9334086034198e911c..77d942630750c5ca7bd7ae50d2aacd1f4bc377f0 100644 (file)
@@ -217,6 +217,17 @@ extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
                                             u32 ticks);
 extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
 
+/* driver_chipcommon_sflash.c */
+#ifdef CONFIG_SSB_SFLASH
+int ssb_sflash_init(struct ssb_chipcommon *cc);
+#else
+static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
+{
+       pr_err("Serial flash not supported\n");
+       return 0;
+}
+#endif /* CONFIG_SSB_SFLASH */
+
 #ifdef CONFIG_SSB_DRIVER_EXTIF
 extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
 extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
index 6495579e3f355c5e458260902be3e9e7fa8412e5..73c7f4b882cc6d6d922a8dd4003e66251c40e9b2 100644 (file)
@@ -48,6 +48,6 @@ static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { }
 
 extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
 
-extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
+extern unsigned int bcma_core_irq(struct bcma_device *core);
 
 #endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
index 41da581e1612a515157559aee5b5e90e23fccf50..31232247a1ee90db5fc1e0a13f7a9d39af8b4e53 100644 (file)
@@ -179,6 +179,8 @@ struct pci_dev;
 #define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
 #define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
 
+#define BCMA_CORE_PCI_CFG_DEVCTRL              0xd8
+
 /* PCIE Root Capability Register bits (Host mode only) */
 #define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
 
index 47aeee2d8db160f6fa9eb62c32131bbd686acc29..9044296c8876925f6e31d59386e7dea6c7100f63 100644 (file)
@@ -219,12 +219,14 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
 }
 
 /**
- * mesh_send_path error - Sends a PERR mesh management frame
+ * mesh_path_error_tx - Sends a PERR mesh management frame
  *
+ * @ttl: allowed remaining hops
  * @target: broken destination
  * @target_sn: SN of the broken destination
  * @target_rcode: reason code for this PERR
  * @ra: node this frame is addressed to
+ * @sdata: local mesh subif
  *
  * Note: This function may be called with driver locks taken that the driver
  * also acquires in the TX path.  To avoid a deadlock we don't transmit the
@@ -350,6 +352,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
  * @sdata: local mesh subif
  * @mgmt: mesh management frame
  * @hwmp_ie: hwmp information element (PREP or PREQ)
+ * @action: type of hwmp ie
  *
  * This function updates the path routing information to the originator and the
  * transmitter of a HWMP PREQ or PREP frame.
index 0b35de00193786e723d93cac6663ab1318dade96..8c114e8a9135517e994d3ec64d650c9f8a83fcbf 100644 (file)
@@ -140,8 +140,8 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)
 
 static struct regulatory_request *get_last_request(void)
 {
-       return rcu_dereference_protected(last_request,
-                                        lockdep_is_held(&reg_mutex));
+       return rcu_dereference_check(last_request,
+                                    lockdep_is_held(&reg_mutex));
 }
 
 /* Used to queue up regulatory hints */
@@ -1848,7 +1848,7 @@ static void restore_regulatory_settings(bool reset_user)
        mutex_lock(&cfg80211_mutex);
        mutex_lock(&reg_mutex);
 
-       reset_regdomains(true, cfg80211_world_regdom);
+       reset_regdomains(true, &world_regdom);
        restore_alpha2(alpha2, reset_user);
 
        /*
@@ -2250,14 +2250,21 @@ int set_regdom(const struct ieee80211_regdomain *rd)
 #ifdef CONFIG_HOTPLUG
 int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       struct regulatory_request *lr = get_last_request();
+       struct regulatory_request *lr;
+       u8 alpha2[2];
+       bool add = false;
 
+       rcu_read_lock();
+       lr = get_last_request();
        if (lr && !lr->processed) {
-               if (add_uevent_var(env, "COUNTRY=%c%c",
-                                  lr->alpha2[0], lr->alpha2[1]))
-                       return -ENOMEM;
+               memcpy(alpha2, lr->alpha2, 2);
+               add = true;
        }
+       rcu_read_unlock();
 
+       if (add)
+               return add_uevent_var(env, "COUNTRY=%c%c",
+                                     alpha2[0], alpha2[1]);
        return 0;
 }
 #else
This page took 0.068058 seconds and 5 git commands to generate.