From c509c8b85548ae1ccd1ce10ef960d8f69c60b200 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 3 Jan 2013 00:09:46 -0500 Subject: [PATCH] --- yaml --- r: 351846 b: refs/heads/master c: 75ea719cb4773b05cc48e741feb4e267522b9656 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/bcma/bcma_private.h | 2 - trunk/drivers/bcma/driver_mips.c | 119 +-- trunk/drivers/bcma/main.c | 4 +- trunk/drivers/net/wireless/ath/ath9k/ahb.c | 22 +- .../net/wireless/ath/ath9k/ar5008_initvals.h | 8 +- .../net/wireless/ath/ath9k/ar5008_phy.c | 50 +- .../net/wireless/ath/ath9k/ar9001_initvals.h | 4 +- .../net/wireless/ath/ath9k/ar9002_hw.c | 11 +- .../net/wireless/ath/ath9k/ar9002_phy.c | 2 + .../net/wireless/ath/ath9k/ar9003_calib.c | 37 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 5 + trunk/drivers/net/wireless/ath/ath9k/hw-ops.h | 16 + trunk/drivers/net/wireless/ath/ath9k/hw.c | 35 +- trunk/drivers/net/wireless/ath/ath9k/hw.h | 10 +- trunk/drivers/net/wireless/ath/ath9k/init.c | 101 ++- trunk/drivers/net/wireless/ath/ath9k/mci.c | 7 +- trunk/drivers/net/wireless/ath/ath9k/pci.c | 39 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 11 +- trunk/drivers/net/wireless/ath/ath9k/reg.h | 3 + trunk/drivers/net/wireless/ath/ath9k/xmit.c | 37 +- .../net/wireless/ath/carl9170/carl9170.h | 19 +- trunk/drivers/net/wireless/ath/carl9170/fw.c | 37 +- .../drivers/net/wireless/ath/carl9170/fwcmd.h | 8 - trunk/drivers/net/wireless/ath/carl9170/hw.h | 2 +- .../drivers/net/wireless/ath/carl9170/main.c | 103 +-- trunk/drivers/net/wireless/ath/carl9170/tx.c | 133 ++- .../net/wireless/ath/carl9170/version.h | 6 +- .../net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 + .../brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 + .../net/wireless/brcm80211/brcmfmac/dhd.h | 39 +- .../net/wireless/brcm80211/brcmfmac/dhd_bus.h | 19 +- .../net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 48 +- .../wireless/brcm80211/brcmfmac/dhd_common.c | 2 + .../net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 35 +- .../wireless/brcm80211/brcmfmac/dhd_linux.c | 90 +- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 24 +- .../wireless/brcm80211/brcmfmac/sdio_chip.c | 2 + .../net/wireless/brcm80211/brcmfmac/usb.c | 27 +- .../wireless/brcm80211/brcmfmac/wl_cfg80211.c | 94 +- .../net/wireless/brcm80211/brcmsmac/ampdu.c | 7 +- .../wireless/brcm80211/brcmsmac/mac80211_if.c | 10 +- .../net/wireless/brcm80211/brcmsmac/main.c | 9 +- .../net/wireless/brcm80211/brcmsmac/scb.h | 1 + .../drivers/net/wireless/iwlegacy/3945-mac.c | 6 +- .../drivers/net/wireless/iwlegacy/4965-mac.c | 5 +- trunk/drivers/net/wireless/iwlegacy/common.c | 36 - trunk/drivers/net/wireless/iwlegacy/common.h | 1 - .../net/wireless/iwlwifi/dvm/commands.h | 8 +- .../net/wireless/iwlwifi/dvm/debugfs.c | 4 +- trunk/drivers/net/wireless/iwlwifi/dvm/led.c | 2 +- .../net/wireless/iwlwifi/dvm/mac80211.c | 8 +- trunk/drivers/net/wireless/iwlwifi/dvm/main.c | 21 +- trunk/drivers/net/wireless/iwlwifi/dvm/tt.c | 4 +- trunk/drivers/net/wireless/iwlwifi/dvm/tx.c | 21 +- .../drivers/net/wireless/iwlwifi/dvm/ucode.c | 96 ++- trunk/drivers/net/wireless/iwlwifi/iwl-csr.h | 4 +- trunk/drivers/net/wireless/iwlwifi/iwl-io.c | 168 +++- trunk/drivers/net/wireless/iwlwifi/iwl-io.h | 21 +- trunk/drivers/net/wireless/iwlwifi/iwl-test.c | 53 +- .../drivers/net/wireless/iwlwifi/iwl-trans.h | 69 +- .../net/wireless/iwlwifi/pcie/internal.h | 6 +- trunk/drivers/net/wireless/iwlwifi/pcie/rx.c | 2 - .../drivers/net/wireless/iwlwifi/pcie/trans.c | 179 +--- trunk/drivers/net/wireless/iwlwifi/pcie/tx.c | 31 +- trunk/drivers/net/wireless/mwifiex/11n.c | 4 +- trunk/drivers/net/wireless/mwifiex/11n_aggr.c | 6 +- trunk/drivers/net/wireless/mwifiex/cfg80211.c | 2 - trunk/drivers/net/wireless/mwifiex/decl.h | 18 - trunk/drivers/net/wireless/mwifiex/fw.h | 11 +- trunk/drivers/net/wireless/mwifiex/init.c | 6 - trunk/drivers/net/wireless/mwifiex/ioctl.h | 3 +- trunk/drivers/net/wireless/mwifiex/join.c | 10 - trunk/drivers/net/wireless/mwifiex/main.h | 6 - trunk/drivers/net/wireless/mwifiex/pcie.c | 654 +++++--------- trunk/drivers/net/wireless/mwifiex/pcie.h | 33 +- trunk/drivers/net/wireless/mwifiex/sta_cmd.c | 10 +- trunk/drivers/net/wireless/mwifiex/txrx.c | 6 +- trunk/drivers/net/wireless/mwifiex/uap_cmd.c | 44 - trunk/drivers/net/wireless/mwifiex/usb.c | 30 +- trunk/drivers/net/wireless/mwifiex/util.h | 8 +- trunk/drivers/net/wireless/mwifiex/wmm.c | 8 +- trunk/drivers/net/wireless/mwl8k.c | 116 +-- trunk/drivers/net/wireless/p54/p54pci.c | 7 +- trunk/drivers/net/wireless/rt2x00/rt2800lib.c | 804 ++++++++---------- trunk/drivers/net/wireless/rt2x00/rt2800lib.h | 8 +- trunk/drivers/net/wireless/rt2x00/rt2800pci.c | 35 +- trunk/drivers/net/wireless/rt2x00/rt2800usb.c | 12 +- trunk/include/linux/bcma/bcma_driver_mips.h | 1 + trunk/net/mac80211/mesh_hwmp.c | 5 +- 90 files changed, 1774 insertions(+), 2062 deletions(-) diff --git a/[refs] b/[refs] index 0049c20825a6..633f622f4396 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e7f767a7d9f809c494bfffffeda2bbdbfec110b4 +refs/heads/master: 75ea719cb4773b05cc48e741feb4e267522b9656 diff --git a/trunk/drivers/bcma/bcma_private.h b/trunk/drivers/bcma/bcma_private.h index d35294e81d15..4a2d72ec6d43 100644 --- a/trunk/drivers/bcma/bcma_private.h +++ b/trunk/drivers/bcma/bcma_private.h @@ -31,8 +31,6 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, int bcma_bus_suspend(struct bcma_bus *bus); int bcma_bus_resume(struct bcma_bus *bus); #endif -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, - u8 unit); /* scan.c */ int bcma_bus_scan(struct bcma_bus *bus); diff --git a/trunk/drivers/bcma/driver_mips.c b/trunk/drivers/bcma/driver_mips.c index 8a51c7950536..792daad28cbc 100644 --- a/trunk/drivers/bcma/driver_mips.c +++ b/trunk/drivers/bcma/driver_mips.c @@ -74,16 +74,11 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev) return dev->core_index; flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); - if (flag) - return flag & 0x1F; - else - return 0x3f; + return flag & 0x1F; } /* Get the MIPS IRQ assignment for a specified device. * If unassigned, 0 is returned. - * If disabled, 5 is returned. - * If not supported, 6 is returned. */ unsigned int bcma_core_mips_irq(struct bcma_device *dev) { @@ -92,15 +87,13 @@ unsigned int bcma_core_mips_irq(struct bcma_device *dev) unsigned int irq; irqflag = bcma_core_mips_irqflag(dev); - if (irqflag == 0x3f) - return 6; - for (irq = 0; irq <= 4; irq++) + for (irq = 1; irq <= 4; irq++) if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) & (1 << irqflag)) return irq; - return 5; + return 0; } EXPORT_SYMBOL(bcma_core_mips_irq); @@ -121,7 +114,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) & ~(1 << irqflag)); - else if (oldirq != 5) + else bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0); /* assign the new one */ @@ -130,9 +123,9 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | (1 << irqflag)); } else { - u32 irqinitmask = bcma_read32(mdev, - BCMA_MIPS_MIPS74K_INTMASK(irq)); - if (irqinitmask) { + u32 oldirqflag = bcma_read32(mdev, + BCMA_MIPS_MIPS74K_INTMASK(irq)); + if (oldirqflag) { struct bcma_device *core; /* backplane irq line is in use, find out who uses @@ -140,7 +133,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) */ list_for_each_entry(core, &bus->cores, list) { if ((1 << bcma_core_mips_irqflag(core)) == - irqinitmask) { + oldirqflag) { bcma_core_mips_set_irq(core, 0); break; } @@ -150,31 +143,15 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) 1 << irqflag); } - bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n", - dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2); -} - -static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq, - u16 coreid, u8 unit) -{ - struct bcma_device *core; - - core = bcma_find_core_unit(bus, coreid, unit); - if (!core) { - bcma_warn(bus, - "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n", - coreid, unit); - return; - } - - bcma_core_mips_set_irq(core, irq); + bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n", + dev->id.id, oldirq + 2, irq + 2); } static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq) { int i; static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; - printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); for (i = 0; i <= 6; i++) printk(" %s%s", irq_name[i], i == irq ? "*" : " "); printk("\n"); @@ -259,53 +236,43 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) if (mcore->setup_done) return; - bcma_debug(bus, "Initializing MIPS core...\n"); + bcma_info(bus, "Initializing MIPS core...\n"); bcma_core_mips_early_init(mcore); - switch (bus->chipinfo.id) { - case BCMA_CHIP_ID_BCM4716: - case BCMA_CHIP_ID_BCM4748: - bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); - bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); - bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0); - bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0); - break; - case BCMA_CHIP_ID_BCM5356: - case BCMA_CHIP_ID_BCM47162: - case BCMA_CHIP_ID_BCM53572: - bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); - bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); - break; - case BCMA_CHIP_ID_BCM5357: - case BCMA_CHIP_ID_BCM4749: - bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0); - bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0); - bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0); - break; - case BCMA_CHIP_ID_BCM4706: - bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0); - bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT, - 0); - bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1); - bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0); - bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON, - 0); - break; - default: - list_for_each_entry(core, &bus->cores, list) { - core->irq = bcma_core_irq(core); + mcore->assigned_irqs = 1; + + /* Assign IRQs to all cores on the bus */ + list_for_each_entry(core, &bus->cores, list) { + int mips_irq; + if (core->irq) + continue; + + mips_irq = bcma_core_mips_irq(core); + if (mips_irq > 4) + core->irq = 0; + else + core->irq = mips_irq + 2; + if (core->irq > 5) + continue; + switch (core->id.id) { + case BCMA_CORE_PCI: + case BCMA_CORE_PCIE: + case BCMA_CORE_ETHERNET: + case BCMA_CORE_ETHERNET_GBIT: + case BCMA_CORE_MAC_GBIT: + case BCMA_CORE_80211: + case BCMA_CORE_USB20_HOST: + /* These devices get their own IRQ line if available, + * the rest goes on IRQ0 + */ + if (mcore->assigned_irqs <= 4) + bcma_core_mips_set_irq(core, + mcore->assigned_irqs++); + break; } - bcma_err(bus, - "Unknown device (0x%x) found, can not configure IRQs\n", - bus->chipinfo.id); } - bcma_debug(bus, "IRQ reconfiguration done\n"); + bcma_info(bus, "IRQ reconfiguration done\n"); bcma_core_mips_dump_irq(bus); mcore->setup_done = true; diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index d12b7da556e1..53ba20ca17e0 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -81,8 +81,8 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) } EXPORT_SYMBOL_GPL(bcma_find_core); -struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, - u8 unit) +static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, + u8 unit) { struct bcma_device *core; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ahb.c b/trunk/drivers/net/wireless/ath/ath9k/ahb.c index d1ff3c246a12..3a69804f4c16 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ahb.c @@ -86,25 +86,29 @@ static int ath_ahb_probe(struct platform_device *pdev) if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data specified\n"); - return -EINVAL; + ret = -EINVAL; + goto err_out; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no memory resource found\n"); - return -ENXIO; + ret = -ENXIO; + goto err_out; } - mem = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); + mem = ioremap_nocache(res->start, resource_size(res)); if (mem == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_out; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "no IRQ resource found\n"); - return -ENXIO; + ret = -ENXIO; + goto err_iounmap; } irq = res->start; @@ -112,7 +116,8 @@ static int ath_ahb_probe(struct platform_device *pdev) hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (hw == NULL) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_iounmap; } SET_IEEE80211_DEV(hw, &pdev->dev); @@ -151,6 +156,9 @@ static int ath_ahb_probe(struct platform_device *pdev) err_free_hw: ieee80211_free_hw(hw); platform_set_drvdata(pdev, NULL); + err_iounmap: + iounmap(mem); + err_out: return ret; } @@ -160,10 +168,12 @@ static int ath_ahb_remove(struct platform_device *pdev) if (hw) { struct ath_softc *sc = hw->priv; + void __iomem *mem = sc->mem; ath9k_deinit_device(sc); free_irq(sc->irq, sc); ieee80211_free_hw(sc->hw); + iounmap(mem); platform_set_drvdata(pdev, NULL); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 467ccfae2cee..f81e7fc60a36 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -466,7 +466,7 @@ static const u32 ar5416Bank0[][2] = { }; static const u32 ar5416BB_RfGain[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x00009a00, 0x00000000, 0x00000000}, {0x00009a04, 0x00000040, 0x00000040}, {0x00009a08, 0x00000080, 0x00000080}, @@ -546,12 +546,12 @@ static const u32 ar5416Bank2[][2] = { }; static const u32 ar5416Bank3[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x000098f0, 0x01400018, 0x01c00018}, }; static const u32 ar5416Bank6[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, @@ -588,7 +588,7 @@ static const u32 ar5416Bank6[][3] = { }; static const u32 ar5416Bank6TPC[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index fd69376ecc83..874186bfda41 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -470,15 +470,16 @@ static void ar5008_hw_spur_mitigate(struct ath_hw *ah, static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) { #define ATH_ALLOC_BANK(bank, size) do { \ - bank = devm_kzalloc(ah->dev, sizeof(u32) * size, GFP_KERNEL); \ - if (!bank) \ - goto error; \ + bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ + if (!bank) { \ + ath_err(common, "Cannot allocate RF banks\n"); \ + return -ENOMEM; \ + } \ } while (0); struct ath_common *common = ath9k_hw_common(ah); - if (AR_SREV_9280_20_OR_LATER(ah)) - return 0; + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); @@ -491,12 +492,35 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) return 0; #undef ATH_ALLOC_BANK -error: - ath_err(common, "Cannot allocate RF banks\n"); - return -ENOMEM; } +/** + * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers + * @ah: atheros hardware struture + * For the external AR2133/AR5133 radios banks. + */ +static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) +{ +#define ATH_FREE_BANK(bank) do { \ + kfree(bank); \ + bank = NULL; \ + } while (0); + + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); + + ATH_FREE_BANK(ah->analogBank0Data); + ATH_FREE_BANK(ah->analogBank1Data); + ATH_FREE_BANK(ah->analogBank2Data); + ATH_FREE_BANK(ah->analogBank3Data); + ATH_FREE_BANK(ah->analogBank6Data); + ATH_FREE_BANK(ah->analogBank6TPCData); + ATH_FREE_BANK(ah->analogBank7Data); + ATH_FREE_BANK(ah->bank6Temp); + +#undef ATH_FREE_BANK +} + /* * * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM * @ah: atheros hardware structure @@ -1356,7 +1380,7 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah) conf->radar_inband = 8; } -int ar5008_hw_attach_phy_ops(struct ath_hw *ah) +void ar5008_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); static const u32 ar5416_cca_regs[6] = { @@ -1367,15 +1391,12 @@ int ar5008_hw_attach_phy_ops(struct ath_hw *ah) AR_PHY_CH1_EXT_CCA, AR_PHY_CH2_EXT_CCA }; - int ret; - - ret = ar5008_hw_rf_alloc_ext_banks(ah); - if (ret) - return ret; priv_ops->rf_set_freq = ar5008_hw_set_channel; priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; + priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks; + priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks; priv_ops->set_rf_regs = ar5008_hw_set_rf_regs; priv_ops->set_channel_regs = ar5008_hw_set_channel_regs; priv_ops->init_bb = ar5008_hw_init_bb; @@ -1400,5 +1421,4 @@ int ar5008_hw_attach_phy_ops(struct ath_hw *ah) ar5008_hw_set_nf_limits(ah); ar5008_hw_set_radar_conf(ah); memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); - return 0; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index 59524e1d4678..ea4a230997ac 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9001_initvals.h @@ -460,7 +460,7 @@ static const u32 ar5416Common_9100[][2] = { }; static const u32 ar5416Bank6_9100[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, @@ -497,7 +497,7 @@ static const u32 ar5416Bank6_9100[][3] = { }; static const u32 ar5416Bank6TPC_9100[][3] = { - /* Addr 5G 2G */ + /* Addr 5G_HT20 5G_HT40 */ {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 54da026f058c..648da3e885e9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -102,7 +102,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; u32 *data; - data = devm_kzalloc(ah->dev, size, GFP_KERNEL); + data = kmalloc(size, GFP_KERNEL); if (!data) return; @@ -409,27 +409,22 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah) } /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ -int ar9002_hw_attach_ops(struct ath_hw *ah) +void ar9002_hw_attach_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); struct ath_hw_ops *ops = ath9k_hw_ops(ah); - int ret; priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; ops->config_pci_powersave = ar9002_hw_configpcipowersave; - ret = ar5008_hw_attach_phy_ops(ah); - if (ret) - return ret; - + ar5008_hw_attach_phy_ops(ah); if (AR_SREV_9280_20_OR_LATER(ah)) ar9002_hw_attach_phy_ops(ah); ar9002_hw_attach_calib_ops(ah); ar9002_hw_attach_mac_ops(ah); - return 0; } void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 8b119811b2d9..846dd7974eb8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -561,6 +561,8 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) struct ath_hw_ops *ops = ath9k_hw_ops(ah); priv_ops->set_rf_regs = NULL; + priv_ops->rf_alloc_ext_banks = NULL; + priv_ops->rf_free_ext_banks = NULL; priv_ops->rf_set_freq = ar9002_hw_set_channel; priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; priv_ops->olc_init = ar9002_olc_init; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index fa67e84d51ea..8b0d8dcd7625 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -32,6 +32,7 @@ struct coeff { enum ar9003_cal_types { IQ_MISMATCH_CAL = BIT(0), + TEMP_COMP_CAL = BIT(1), }; static void ar9003_hw_setup_calibration(struct ath_hw *ah, @@ -48,7 +49,7 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, */ REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, - currCal->calData->calCountMax); + currCal->calData->calCountMax); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); ath_dbg(common, CALIBRATE, @@ -57,8 +58,14 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, /* Kick-off cal */ REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); break; - default: - ath_err(common, "Invalid calibration type\n"); + case TEMP_COMP_CAL: + REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, + AR_PHY_65NM_CH0_THERM_LOCAL, 1); + REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, + AR_PHY_65NM_CH0_THERM_START, 1); + + ath_dbg(common, CALIBRATE, + "starting Temperature Compensation Calibration\n"); break; } } @@ -316,14 +323,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = { static void ar9003_hw_init_cal_settings(struct ath_hw *ah) { ah->iq_caldata.calData = &iq_cal_single_sample; - - if (AR_SREV_9300_20_OR_LATER(ah)) { - ah->enabled_cals |= TX_IQ_CAL; - if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah)) - ah->enabled_cals |= TX_IQ_ON_AGC_CAL; - } - - ah->supp_cals = IQ_MISMATCH_CAL; } /* @@ -1132,10 +1131,20 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + ah->supp_cals = IQ_MISMATCH_CAL; + + if (ah->supp_cals & IQ_MISMATCH_CAL) { + INIT_CAL(&ah->iq_caldata); + INSERT_CAL(ah, &ah->iq_caldata); + ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); + } - INIT_CAL(&ah->iq_caldata); - INSERT_CAL(ah, &ah->iq_caldata); - ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); + if (ah->supp_cals & TEMP_COMP_CAL) { + INIT_CAL(&ah->tempCompCalData); + INSERT_CAL(ah, &ah->tempCompCalData); + ath_dbg(common, CALIBRATE, + "enabling Temperature Compensation Calibration\n"); + } /* Initialize current pointer to first element in list */ ah->cal_list_curr = ah->cal_list; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 72501073b499..86e26a19efda 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -109,11 +109,14 @@ struct ath_descdma { void *dd_desc; dma_addr_t dd_desc_paddr; u32 dd_desc_len; + struct ath_buf *dd_bufptr; }; int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, const char *name, int nbuf, int ndesc, bool is_tx); +void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, + struct list_head *head); /***********/ /* RX / TX */ @@ -317,6 +320,7 @@ struct ath_rx { spinlock_t rxbuflock; struct list_head rxbuf; struct ath_descdma rxdma; + struct ath_buf *rx_bufptr; struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; struct sk_buff *frag; @@ -341,6 +345,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_init(struct ath_softc *sc, int nbufs); +void ath_tx_cleanup(struct ath_softc *sc); int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_tx_queue_info *q); void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw-ops.h b/trunk/drivers/net/wireless/ath/ath9k/hw-ops.h index 14b701140b49..0f2b97f6b739 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -101,6 +101,22 @@ static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah, ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan); } +static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah) +{ + if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks) + return 0; + + return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah); +} + +static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah) +{ + if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks) + return; + + ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah); +} + static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan, u16 modesIndex) diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index caf0626eeaa5..7cb787065913 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -554,6 +554,14 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah)); + ecode = ath9k_hw_rf_alloc_ext_banks(ah); + if (ecode) { + ath_err(ath9k_hw_common(ah), + "Failed allocating banks for external radio\n"); + ath9k_hw_rf_free_ext_banks(ah); + return ecode; + } + if (ah->config.enable_ani) { ath9k_hw_ani_setup(ah); ath9k_hw_ani_init(ah); @@ -562,13 +570,12 @@ static int ath9k_hw_post_init(struct ath_hw *ah) return 0; } -static int ath9k_hw_attach_ops(struct ath_hw *ah) +static void ath9k_hw_attach_ops(struct ath_hw *ah) { - if (!AR_SREV_9300_20_OR_LATER(ah)) - return ar9002_hw_attach_ops(ah); - - ar9003_hw_attach_ops(ah); - return 0; + if (AR_SREV_9300_20_OR_LATER(ah)) + ar9003_hw_attach_ops(ah); + else + ar9002_hw_attach_ops(ah); } /* Called for all hardware families */ @@ -604,9 +611,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_init_defaults(ah); ath9k_hw_init_config(ah); - r = ath9k_hw_attach_ops(ah); - if (r) - return r; + ath9k_hw_attach_ops(ah); if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { ath_err(common, "Couldn't wakeup chip\n"); @@ -1148,9 +1153,12 @@ void ath9k_hw_deinit(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); if (common->state < ATH_HW_INITIALIZED) - return; + goto free_hw; ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); + +free_hw: + ath9k_hw_rf_free_ext_banks(ah); } EXPORT_SYMBOL(ath9k_hw_deinit); @@ -2568,6 +2576,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) rx_chainmask >>= 1; } + if (AR_SREV_9300_20_OR_LATER(ah)) { + ah->enabled_cals |= TX_IQ_CAL; + if (AR_SREV_9485_OR_LATER(ah)) + ah->enabled_cals |= TX_IQ_ON_AGC_CAL; + } + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) pCap->hw_caps |= ATH9K_HW_CAP_MCI; @@ -2576,6 +2590,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_RTT; } + if (AR_SREV_9280_20_OR_LATER(ah)) { pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | ATH9K_HW_WOW_PATTERN_MATCH_EXACT; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 38c5a8702fb2..7f1a8e91c908 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -604,6 +604,8 @@ struct ath_hw_radar_conf { * * @rf_set_freq: change frequency * @spur_mitigate_freq: spur mitigation + * @rf_alloc_ext_banks: + * @rf_free_ext_banks: * @set_rf_regs: * @compute_pll_control: compute the PLL control value to use for * AR_RTC_PLL_CONTROL for a given channel @@ -628,6 +630,8 @@ struct ath_hw_private_ops { struct ath9k_channel *chan); void (*spur_mitigate_freq)(struct ath_hw *ah, struct ath9k_channel *chan); + int (*rf_alloc_ext_banks)(struct ath_hw *ah); + void (*rf_free_ext_banks)(struct ath_hw *ah); bool (*set_rf_regs)(struct ath_hw *ah, struct ath9k_channel *chan, u16 modesIndex); @@ -706,7 +710,6 @@ enum ath_cal_list { struct ath_hw { struct ath_ops reg_ops; - struct device *dev; struct ieee80211_hw *hw; struct ath_common common; struct ath9k_hw_version hw_version; @@ -768,6 +771,7 @@ struct ath_hw { struct ath9k_cal_list iq_caldata; struct ath9k_cal_list adcgain_caldata; struct ath9k_cal_list adcdc_caldata; + struct ath9k_cal_list tempCompCalData; struct ath9k_cal_list *cal_list; struct ath9k_cal_list *cal_list_last; struct ath9k_cal_list *cal_list_curr; @@ -1064,14 +1068,14 @@ bool ar9003_paprd_is_done(struct ath_hw *ah); bool ar9003_is_paprd_enabled(struct ath_hw *ah); /* Hardware family op attach helpers */ -int ar5008_hw_attach_phy_ops(struct ath_hw *ah); +void ar5008_hw_attach_phy_ops(struct ath_hw *ah); void ar9002_hw_attach_phy_ops(struct ath_hw *ah); void ar9003_hw_attach_phy_ops(struct ath_hw *ah); void ar9002_hw_attach_calib_ops(struct ath_hw *ah); void ar9003_hw_attach_calib_ops(struct ath_hw *ah); -int ar9002_hw_attach_ops(struct ath_hw *ah); +void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index 5c01f43c32b0..f69ef5d48c7b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -337,7 +337,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct ath_common *common = ath9k_hw_common(sc->sc_ah); u8 *ds; struct ath_buf *bf; - int i, bsize, desc_len; + int i, bsize, error, desc_len; ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", name, nbuf, ndesc); @@ -353,7 +353,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, if ((desc_len % 4) != 0) { ath_err(common, "ath_desc not DWORD aligned\n"); BUG_ON((desc_len % 4) != 0); - return -ENOMEM; + error = -ENOMEM; + goto fail; } dd->dd_desc_len = desc_len * nbuf * ndesc; @@ -377,11 +378,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, } /* allocate descriptors */ - dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len, - &dd->dd_desc_paddr, GFP_KERNEL); - if (!dd->dd_desc) - return -ENOMEM; - + dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, + &dd->dd_desc_paddr, GFP_KERNEL); + if (dd->dd_desc == NULL) { + error = -ENOMEM; + goto fail; + } ds = (u8 *) dd->dd_desc; ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", name, ds, (u32) dd->dd_desc_len, @@ -389,9 +391,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, /* allocate buffers */ bsize = sizeof(struct ath_buf) * nbuf; - bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); - if (!bf) - return -ENOMEM; + bf = kzalloc(bsize, GFP_KERNEL); + if (bf == NULL) { + error = -ENOMEM; + goto fail2; + } + dd->dd_bufptr = bf; for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { bf->bf_desc = ds; @@ -417,6 +422,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, list_add_tail(&bf->list, head); } return 0; +fail2: + dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, + dd->dd_desc_paddr); +fail: + memset(dd, 0, sizeof(*dd)); + return error; } static int ath9k_init_queues(struct ath_softc *sc) @@ -446,13 +457,11 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) ATH9K_NUM_CHANNELS); if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { - channels = devm_kzalloc(sc->dev, + channels = kmemdup(ath9k_2ghz_chantable, sizeof(ath9k_2ghz_chantable), GFP_KERNEL); if (!channels) return -ENOMEM; - memcpy(channels, ath9k_2ghz_chantable, - sizeof(ath9k_2ghz_chantable)); sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; sc->sbands[IEEE80211_BAND_2GHZ].n_channels = @@ -463,13 +472,14 @@ static int ath9k_init_channels_rates(struct ath_softc *sc) } if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { - channels = devm_kzalloc(sc->dev, + channels = kmemdup(ath9k_5ghz_chantable, sizeof(ath9k_5ghz_chantable), GFP_KERNEL); - if (!channels) + if (!channels) { + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); return -ENOMEM; + } - memcpy(channels, ath9k_5ghz_chantable, - sizeof(ath9k_5ghz_chantable)); sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; sc->sbands[IEEE80211_BAND_5GHZ].n_channels = @@ -555,11 +565,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, int ret = 0, i; int csz = 0; - ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL); + ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); if (!ah) return -ENOMEM; - ah->dev = sc->dev; ah->hw = sc->hw; ah->hw_version.devid = devid; ah->reg_ops.read = ath9k_ioread32; @@ -627,7 +636,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, if (pdata && pdata->eeprom_name) { ret = ath9k_eeprom_request(sc, pdata->eeprom_name); if (ret) - return ret; + goto err_eeprom; } /* Initializes the hardware for all supported chipsets */ @@ -667,6 +676,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ath9k_hw_deinit(ah); err_hw: ath9k_eeprom_release(sc); +err_eeprom: + kfree(ah); + sc->sc_ah = NULL; + return ret; } @@ -831,8 +844,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, /* Bring up device */ error = ath9k_init_softc(devid, sc, bus_ops); - if (error) - return error; + if (error != 0) + goto error_init; ah = sc->sc_ah; common = ath9k_hw_common(ah); @@ -842,19 +855,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, error = ath_regd_init(&common->regulatory, sc->hw->wiphy, ath9k_reg_notifier); if (error) - goto deinit; + goto error_regd; reg = &common->regulatory; /* Setup TX DMA */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) - goto deinit; + goto error_tx; /* Setup RX DMA */ error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) - goto deinit; + goto error_rx; ath9k_init_txpower_limits(sc); @@ -868,19 +881,19 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) - goto rx_cleanup; + goto error_register; error = ath9k_init_debug(ah); if (error) { ath_err(common, "Unable to create debugfs files\n"); - goto unregister; + goto error_world; } /* Handle world regulatory */ if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) - goto unregister; + goto error_world; } ath_init_leds(sc); @@ -888,12 +901,17 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, return 0; -unregister: +error_world: ieee80211_unregister_hw(hw); -rx_cleanup: +error_register: ath_rx_cleanup(sc); -deinit: +error_rx: + ath_tx_cleanup(sc); +error_tx: + /* Nothing */ +error_regd: ath9k_deinit_softc(sc); +error_init: return error; } @@ -905,6 +923,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc) { int i = 0; + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); + + if (sc->sbands[IEEE80211_BAND_5GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); + ath9k_deinit_btcoex(sc); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) @@ -916,6 +940,8 @@ static void ath9k_deinit_softc(struct ath_softc *sc) sc->dfs_detector->exit(sc->dfs_detector); ath9k_eeprom_release(sc); + kfree(sc->sc_ah); + sc->sc_ah = NULL; } void ath9k_deinit_device(struct ath_softc *sc) @@ -931,9 +957,22 @@ void ath9k_deinit_device(struct ath_softc *sc) ieee80211_unregister_hw(hw); ath_rx_cleanup(sc); + ath_tx_cleanup(sc); ath9k_deinit_softc(sc); } +void ath_descdma_cleanup(struct ath_softc *sc, + struct ath_descdma *dd, + struct list_head *head) +{ + dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, + dd->dd_desc_paddr); + + INIT_LIST_HEAD(head); + kfree(dd->dd_bufptr); + memset(dd, 0, sizeof(*dd)); +} + /************************/ /* Module Hooks */ /************************/ diff --git a/trunk/drivers/net/wireless/ath/ath9k/mci.c b/trunk/drivers/net/wireless/ath/ath9k/mci.c index d2074334ec9b..5c02702f21e7 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/mci.c @@ -438,7 +438,7 @@ int ath_mci_setup(struct ath_softc *sc) struct ath_mci_buf *buf = &mci->sched_buf; int ret; - buf->bf_addr = dmam_alloc_coherent(sc->dev, + buf->bf_addr = dma_alloc_coherent(sc->dev, ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, &buf->bf_paddr, GFP_KERNEL); @@ -477,6 +477,11 @@ void ath_mci_cleanup(struct ath_softc *sc) struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_buf *buf = &mci->sched_buf; + if (buf->bf_addr) + dma_free_coherent(sc->dev, + ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, + buf->bf_addr, buf->bf_paddr); + ar9003_mci_cleanup(ah); ath_dbg(common, MCI, "MCI De-Initialized\n"); diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index 0e0d39583837..7ae73fbd9136 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -147,6 +147,7 @@ static const struct ath_bus_ops ath_pci_bus_ops = { static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + void __iomem *mem; struct ath_softc *sc; struct ieee80211_hw *hw; u8 csz; @@ -154,19 +155,19 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) int ret = 0; char hw_name[64]; - if (pcim_enable_device(pdev)) + if (pci_enable_device(pdev)) return -EIO; ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { pr_err("32-bit DMA not available\n"); - return ret; + goto err_dma; } ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { pr_err("32-bit DMA consistent DMA enable failed\n"); - return ret; + goto err_dma; } /* @@ -202,16 +203,25 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - ret = pcim_iomap_regions(pdev, BIT(0), "ath9k"); + ret = pci_request_region(pdev, 0, "ath9k"); if (ret) { dev_err(&pdev->dev, "PCI memory region reserve error\n"); - return -ENODEV; + ret = -ENODEV; + goto err_region; + } + + mem = pci_iomap(pdev, 0, 0); + if (!mem) { + pr_err("PCI memory map error\n") ; + ret = -EIO; + goto err_iomap; } hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (!hw) { dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err_alloc_hw; } SET_IEEE80211_DEV(hw, &pdev->dev); @@ -220,7 +230,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) sc = hw->priv; sc->hw = hw; sc->dev = &pdev->dev; - sc->mem = pcim_iomap_table(pdev)[0]; + sc->mem = mem; /* Will be cleared in ath9k_start() */ set_bit(SC_OP_INVALID, &sc->sc_flags); @@ -241,7 +251,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)sc->mem, pdev->irq); + hw_name, (unsigned long)mem, pdev->irq); return 0; @@ -249,6 +259,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) free_irq(sc->irq, sc); err_irq: ieee80211_free_hw(hw); +err_alloc_hw: + pci_iounmap(pdev, mem); +err_iomap: + pci_release_region(pdev, 0); +err_region: + /* Nothing */ +err_dma: + pci_disable_device(pdev); return ret; } @@ -256,12 +274,17 @@ static void ath_pci_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; + void __iomem *mem = sc->mem; if (!is_ath9k_unloaded) sc->sc_ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(sc); free_irq(sc->irq, sc); ieee80211_free_hw(sc->hw); + + pci_iounmap(pdev, mem); + pci_disable_device(pdev); + pci_release_region(pdev, 0); } #ifdef CONFIG_PM_SLEEP diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index 3d236aebf588..d4df98a938bf 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -180,6 +180,11 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) bf->bf_mpdu = NULL; } } + + INIT_LIST_HEAD(&sc->rx.rxbuf); + + kfree(sc->rx.rx_bufptr); + sc->rx.rx_bufptr = NULL; } static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) @@ -206,11 +211,12 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) ah->caps.rx_hp_qdepth); size = sizeof(struct ath_buf) * nbufs; - bf = devm_kzalloc(sc->dev, size, GFP_KERNEL); + bf = kzalloc(size, GFP_KERNEL); if (!bf) return -ENOMEM; INIT_LIST_HEAD(&sc->rx.rxbuf); + sc->rx.rx_bufptr = bf; for (i = 0; i < nbufs; i++, bf++) { skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); @@ -357,6 +363,9 @@ void ath_rx_cleanup(struct ath_softc *sc) bf->bf_mpdu = NULL; } } + + if (sc->rx.rxdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); } } diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h index 0ac205e4cd04..ad3c82c09177 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/reg.h +++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h @@ -884,6 +884,9 @@ #define AR_SREV_9485(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) +#define AR_SREV_9485_10(_ah) \ + (AR_SREV_9485(_ah) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) #define AR_SREV_9485_11(_ah) \ (AR_SREV_9485(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index ca4a0341294f..90e48a0fafe5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -2361,8 +2361,8 @@ static int ath_txstatus_setup(struct ath_softc *sc, int size) u8 txs_len = sc->sc_ah->caps.txs_len; dd->dd_desc_len = size * txs_len; - dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len, - &dd->dd_desc_paddr, GFP_KERNEL); + dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, + &dd->dd_desc_paddr, GFP_KERNEL); if (!dd->dd_desc) return -ENOMEM; @@ -2382,6 +2382,14 @@ static int ath_tx_edma_init(struct ath_softc *sc) return err; } +static void ath_tx_edma_cleanup(struct ath_softc *sc) +{ + struct ath_descdma *dd = &sc->txsdma; + + dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, + dd->dd_desc_paddr); +} + int ath_tx_init(struct ath_softc *sc, int nbufs) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -2394,7 +2402,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) if (error != 0) { ath_err(common, "Failed to allocate tx descriptors: %d\n", error); - return error; + goto err; } error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, @@ -2402,17 +2410,36 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) if (error != 0) { ath_err(common, "Failed to allocate beacon descriptors: %d\n", error); - return error; + goto err; } INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { error = ath_tx_edma_init(sc); + if (error) + goto err; + } + +err: + if (error != 0) + ath_tx_cleanup(sc); return error; } +void ath_tx_cleanup(struct ath_softc *sc) +{ + if (sc->beacon.bdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); + + if (sc->tx.txdma.dd_desc_len != 0) + ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + ath_tx_edma_cleanup(sc); +} + void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) { struct ath_atx_tid *tid; diff --git a/trunk/drivers/net/wireless/ath/carl9170/carl9170.h b/trunk/drivers/net/wireless/ath/carl9170/carl9170.h index 25599741cd8a..2df17f1e49ef 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/trunk/drivers/net/wireless/ath/carl9170/carl9170.h @@ -85,14 +85,20 @@ enum carl9170_device_state { CARL9170_STARTED, }; +#define CARL9170_NUM_TID 16 #define WME_BA_BMP_SIZE 64 #define CARL9170_TX_USER_RATE_TRIES 3 +#define WME_AC_BE 2 +#define WME_AC_BK 3 +#define WME_AC_VI 1 +#define WME_AC_VO 0 + #define TID_TO_WME_AC(_tid) \ - ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \ - (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \ - (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \ - IEEE80211_AC_VO) + ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ + (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ + (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ + WME_AC_VO) #define SEQ_DIFF(_start, _seq) \ (((_start) - (_seq)) & 0x0fff) @@ -284,7 +290,6 @@ struct ar9170 { unsigned int rx_size; unsigned int tx_seq_table; bool ba_filter; - bool disable_offload_fw; } fw; /* interface configuration combinations */ @@ -488,8 +493,8 @@ struct carl9170_sta_info { bool sleeping; atomic_t pending_frames; unsigned int ampdu_max_len; - struct carl9170_sta_tid __rcu *agg[IEEE80211_NUM_TIDS]; - struct carl9170_ba_stats stats[IEEE80211_NUM_TIDS]; + struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID]; + struct carl9170_ba_stats stats[CARL9170_NUM_TID]; }; struct carl9170_tx_info { diff --git a/trunk/drivers/net/wireless/ath/carl9170/fw.c b/trunk/drivers/net/wireless/ath/carl9170/fw.c index 6e76179f1a79..aaebecd19e59 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/fw.c +++ b/trunk/drivers/net/wireless/ath/carl9170/fw.c @@ -215,24 +215,6 @@ static int carl9170_fw_tx_sequence(struct ar9170 *ar) return 0; } -static void carl9170_fw_set_if_combinations(struct ar9170 *ar, - u16 if_comb_types) -{ - if (ar->fw.vif_num < 2) - return; - - ar->if_comb_limits[0].max = ar->fw.vif_num; - ar->if_comb_limits[0].types = if_comb_types; - - ar->if_combs[0].num_different_channels = 1; - ar->if_combs[0].max_interfaces = ar->fw.vif_num; - ar->if_combs[0].limits = ar->if_comb_limits; - ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); - - ar->hw->wiphy->iface_combinations = ar->if_combs; - ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); -} - static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) { const struct carl9170fw_otus_desc *otus_desc; @@ -282,7 +264,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (!SUPP(CARL9170FW_COMMAND_CAM)) { dev_info(&ar->udev->dev, "crypto offloading is disabled " "by firmware.\n"); - ar->fw.disable_offload_fw = true; + ar->disable_offload = true; } if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM)) @@ -359,15 +341,20 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) } } - carl9170_fw_set_if_combinations(ar, if_comb_types); + ar->if_comb_limits[0].max = ar->fw.vif_num; + ar->if_comb_limits[0].types = if_comb_types; - ar->hw->wiphy->interface_modes |= if_comb_types; + ar->if_combs[0].num_different_channels = 1; + ar->if_combs[0].max_interfaces = ar->fw.vif_num; + ar->if_combs[0].limits = ar->if_comb_limits; + ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); + + ar->hw->wiphy->iface_combinations = ar->if_combs; + ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); - ar->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + ar->hw->wiphy->interface_modes |= if_comb_types; - /* As IBSS Encryption is software-based, IBSS RSN is supported. */ - ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_SUPPORTS_TDLS; + ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; #undef SUPPORTED return carl9170_fw_tx_sequence(ar); diff --git a/trunk/drivers/net/wireless/ath/carl9170/fwcmd.h b/trunk/drivers/net/wireless/ath/carl9170/fwcmd.h index 9111d4ffc1b3..9443c802b25b 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/trunk/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -156,14 +156,6 @@ struct carl9170_psm { } __packed; #define CARL9170_PSM_SIZE 4 -/* - * Note: If a bit in rx_filter is set, then it - * means that the particular frames which matches - * the condition are FILTERED/REMOVED/DISCARDED! - * (This is can be a bit confusing, especially - * because someone people think it's the exact - * opposite way, so watch out!) - */ struct carl9170_rx_filter_cmd { __le32 rx_filter; } __packed; diff --git a/trunk/drivers/net/wireless/ath/carl9170/hw.h b/trunk/drivers/net/wireless/ath/carl9170/hw.h index 0db874abde50..fa834c1460f0 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/hw.h +++ b/trunk/drivers/net/wireless/ath/carl9170/hw.h @@ -384,7 +384,7 @@ #define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) #define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) -#define AR9170_MAC_BCN_LENGTH_MAX (512 - 32) +#define AR9170_MAC_BCN_LENGTH_MAX 256 #define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) diff --git a/trunk/drivers/net/wireless/ath/carl9170/main.c b/trunk/drivers/net/wireless/ath/carl9170/main.c index f22da264fd93..9d2051aeb782 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/main.c +++ b/trunk/drivers/net/wireless/ath/carl9170/main.c @@ -358,13 +358,8 @@ static int carl9170_op_start(struct ieee80211_hw *hw) ar->ps.last_action = jiffies; ar->ps.last_slept = jiffies; ar->erp_mode = CARL9170_ERP_AUTO; - - /* Set "disable hw crypto offload" whenever the module parameter - * nohwcrypt is true or if the firmware does not support it. - */ - ar->disable_offload = modparam_nohwcrypt | - ar->fw.disable_offload_fw; - ar->rx_software_decryption = ar->disable_offload; + ar->rx_software_decryption = false; + ar->disable_offload = false; for (i = 0; i < ar->hw->queues; i++) { ar->queue_stop_timeout[i] = jiffies; @@ -570,28 +565,12 @@ static int carl9170_init_interface(struct ar9170 *ar, memcpy(common->macaddr, vif->addr, ETH_ALEN); - /* We have to fall back to software crypto, whenever - * the user choose to participates in an IBSS. HW - * offload for IBSS RSN is not supported by this driver. - * - * NOTE: If the previous main interface has already - * disabled hw crypto offload, we have to keep this - * previous disable_offload setting as it was. - * Altough ideally, we should notify mac80211 and tell - * it to forget about any HW crypto offload for now. - */ - ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && - (vif->type != NL80211_IFTYPE_AP)); - - /* While the driver supports HW offload in a single - * P2P client configuration, it doesn't support HW - * offload in the favourit, concurrent P2P GO+CLIENT - * configuration. Hence, HW offload will always be - * disabled for P2P. - */ - ar->disable_offload |= vif->p2p; - - ar->rx_software_decryption = ar->disable_offload; + if (modparam_nohwcrypt || + ((vif->type != NL80211_IFTYPE_STATION) && + (vif->type != NL80211_IFTYPE_AP))) { + ar->rx_software_decryption = true; + ar->disable_offload = true; + } err = carl9170_set_operating_mode(ar); return err; @@ -601,7 +580,7 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; - struct ieee80211_vif *main_vif, *old_main = NULL; + struct ieee80211_vif *main_vif; struct ar9170 *ar = hw->priv; int vif_id = -1, err = 0; @@ -623,15 +602,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, goto init; } - /* Because the AR9170 HW's MAC doesn't provide full support for - * multiple, independent interfaces [of different operation modes]. - * We have to select ONE main interface [main mode of HW], but we - * can have multiple slaves [AKA: entry in the ACK-table]. - * - * The first (from HEAD/TOP) interface in the ar->vif_list is - * always the main intf. All following intfs in this list - * are considered to be slave intfs. - */ main_vif = carl9170_get_main_vif(ar); if (main_vif) { @@ -640,18 +610,6 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_STATION) break; - /* P2P GO [master] use-case - * Because the P2P GO station is selected dynamically - * by all participating peers of a WIFI Direct network, - * the driver has be able to change the main interface - * operating mode on the fly. - */ - if (main_vif->p2p && vif->p2p && - vif->type == NL80211_IFTYPE_AP) { - old_main = main_vif; - break; - } - err = -EBUSY; rcu_read_unlock(); @@ -690,41 +648,14 @@ static int carl9170_op_add_interface(struct ieee80211_hw *hw, vif_priv->id = vif_id; vif_priv->enable_beacon = false; ar->vifs++; - if (old_main) { - /* We end up in here, if the main interface is being replaced. - * Put the new main interface at the HEAD of the list and the - * previous inteface will automatically become second in line. - */ - list_add_rcu(&vif_priv->list, &ar->vif_list); - } else { - /* Add new inteface. If the list is empty, it will become the - * main inteface, otherwise it will be slave. - */ - list_add_tail_rcu(&vif_priv->list, &ar->vif_list); - } + list_add_tail_rcu(&vif_priv->list, &ar->vif_list); rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); init: - main_vif = carl9170_get_main_vif(ar); - - if (main_vif == vif) { + if (carl9170_get_main_vif(ar) == vif) { rcu_assign_pointer(ar->beacon_iter, vif_priv); rcu_read_unlock(); - if (old_main) { - struct carl9170_vif_info *old_main_priv = - (void *) old_main->drv_priv; - /* downgrade old main intf to slave intf. - * NOTE: We are no longer under rcu_read_lock. - * But we are still holding ar->mutex, so the - * vif data [id, addr] is safe. - */ - err = carl9170_mod_virtual_mac(ar, old_main_priv->id, - old_main->addr); - if (err) - goto unlock; - } - err = carl9170_init_interface(ar, vif); if (err) goto unlock; @@ -1181,7 +1112,9 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ar->disable_offload || !vif) return -EOPNOTSUPP; - /* Fall back to software encryption whenever the driver is connected + /* + * We have to fall back to software encryption, whenever + * the user choose to participates in an IBSS or is connected * to more than one network. * * This is very unfortunate, because some machines cannot handle @@ -1330,7 +1263,7 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, return 0; } - for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) + for (i = 0; i < CARL9170_NUM_TID; i++) RCU_INIT_POINTER(sta_info->agg[i], NULL); sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); @@ -1354,7 +1287,7 @@ static int carl9170_op_sta_remove(struct ieee80211_hw *hw, sta_info->ht_sta = false; rcu_read_lock(); - for (i = 0; i < ARRAY_SIZE(sta_info->agg); i++) { + for (i = 0; i < CARL9170_NUM_TID; i++) { struct carl9170_sta_tid *tid_info; tid_info = rcu_dereference(sta_info->agg[i]); @@ -1874,6 +1807,10 @@ void *carl9170_alloc(size_t priv_size) for (i = 0; i < ARRAY_SIZE(ar->noise); i++) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* As IBSS Encryption is software-based, IBSS RSN is supported. */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; return ar; err_nomem: diff --git a/trunk/drivers/net/wireless/ath/carl9170/tx.c b/trunk/drivers/net/wireless/ath/carl9170/tx.c index 9c0b150d5b8e..ef4ec0da6e49 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/tx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/tx.c @@ -1520,92 +1520,35 @@ void carl9170_tx_scheduler(struct ar9170 *ar) carl9170_tx(ar); } -/* caller has to take rcu_read_lock */ -static struct carl9170_vif_info *carl9170_pick_beaconing_vif(struct ar9170 *ar) +int carl9170_update_beacon(struct ar9170 *ar, const bool submit) { + struct sk_buff *skb = NULL; struct carl9170_vif_info *cvif; - int i = 1; - - /* The AR9170 hardware has no fancy beacon queue or some - * other scheduling mechanism. So, the driver has to make - * due by setting the two beacon timers (pretbtt and tbtt) - * once and then swapping the beacon address in the HW's - * register file each time the pretbtt fires. - */ - - cvif = rcu_dereference(ar->beacon_iter); - if (ar->vifs > 0 && cvif) { - do { - list_for_each_entry_continue_rcu(cvif, &ar->vif_list, - list) { - if (cvif->active && cvif->enable_beacon) - goto out; - } - } while (ar->beacon_enabled && i--); - } - -out: - rcu_assign_pointer(ar->beacon_iter, cvif); - return cvif; -} - -static bool carl9170_tx_beacon_physet(struct ar9170 *ar, struct sk_buff *skb, - u32 *ht1, u32 *plcp) -{ struct ieee80211_tx_info *txinfo; struct ieee80211_tx_rate *rate; - unsigned int power, chains; - bool ht_rate; - - txinfo = IEEE80211_SKB_CB(skb); - rate = &txinfo->control.rates[0]; - ht_rate = !!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS); - carl9170_tx_rate_tpc_chains(ar, txinfo, rate, plcp, &power, &chains); - - *ht1 = AR9170_MAC_BCN_HT1_TX_ANT0; - if (chains == AR9170_TX_PHY_TXCHAIN_2) - *ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1; - SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, *ht1, 7); - SET_VAL(AR9170_MAC_BCN_HT1_TPC, *ht1, power); - SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, *ht1, chains); - - if (ht_rate) { - *ht1 |= AR9170_MAC_BCN_HT1_HT_EN; - if (rate->flags & IEEE80211_TX_RC_SHORT_GI) - *plcp |= AR9170_MAC_BCN_HT2_SGI; + __le32 *data, *old = NULL; + unsigned int plcp, power, chains; + u32 word, ht1, off, addr, len; + int i = 0, err = 0; - if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { - *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED; - *plcp |= AR9170_MAC_BCN_HT2_BW40; - } else if (rate->flags & IEEE80211_TX_RC_DUP_DATA) { - *ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP; - *plcp |= AR9170_MAC_BCN_HT2_BW40; - } + rcu_read_lock(); + cvif = rcu_dereference(ar->beacon_iter); +retry: + if (ar->vifs == 0 || !cvif) + goto out_unlock; - SET_VAL(AR9170_MAC_BCN_HT2_LEN, *plcp, skb->len + FCS_LEN); - } else { - if (*plcp <= AR9170_TX_PHY_RATE_CCK_11M) - *plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; - else - *plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010; + list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) { + if (cvif->active && cvif->enable_beacon) + goto found; } - return ht_rate; -} + if (!ar->beacon_enabled || i++) + goto out_unlock; -int carl9170_update_beacon(struct ar9170 *ar, const bool submit) -{ - struct sk_buff *skb = NULL; - struct carl9170_vif_info *cvif; - __le32 *data, *old = NULL; - u32 word, ht1, plcp, off, addr, len; - int i = 0, err = 0; - bool ht_rate; + goto retry; - rcu_read_lock(); - cvif = carl9170_pick_beaconing_vif(ar); - if (!cvif) - goto out_unlock; +found: + rcu_assign_pointer(ar->beacon_iter, cvif); skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), NULL, NULL); @@ -1615,6 +1558,7 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) goto err_free; } + txinfo = IEEE80211_SKB_CB(skb); spin_lock_bh(&ar->beacon_lock); data = (__le32 *)skb->data; if (cvif->beacon) @@ -1644,14 +1588,43 @@ int carl9170_update_beacon(struct ar9170 *ar, const bool submit) goto err_unlock; } - ht_rate = carl9170_tx_beacon_physet(ar, skb, &ht1, &plcp); + ht1 = AR9170_MAC_BCN_HT1_TX_ANT0; + rate = &txinfo->control.rates[0]; + carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains); + if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { + if (plcp <= AR9170_TX_PHY_RATE_CCK_11M) + plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400; + else + plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010; + } else { + ht1 |= AR9170_MAC_BCN_HT1_HT_EN; + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + plcp |= AR9170_MAC_BCN_HT2_SGI; + + if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { + ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED; + plcp |= AR9170_MAC_BCN_HT2_BW40; + } + if (rate->flags & IEEE80211_TX_RC_DUP_DATA) { + ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP; + plcp |= AR9170_MAC_BCN_HT2_BW40; + } + + SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN); + } + + SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7); + SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power); + SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains); + if (chains == AR9170_TX_PHY_TXCHAIN_2) + ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1; carl9170_async_regwrite_begin(ar); carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1); - if (ht_rate) - carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp); - else + if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp); + else + carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp); for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { /* diff --git a/trunk/drivers/net/wireless/ath/carl9170/version.h b/trunk/drivers/net/wireless/ath/carl9170/version.h index 2282847d4bb8..2ec3e9191e4d 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/version.h +++ b/trunk/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,7 @@ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H #define CARL9170FW_VERSION_YEAR 12 -#define CARL9170FW_VERSION_MONTH 12 -#define CARL9170FW_VERSION_DAY 15 -#define CARL9170FW_VERSION_GIT "1.9.7" +#define CARL9170FW_VERSION_MONTH 7 +#define CARL9170FW_VERSION_DAY 7 +#define CARL9170FW_VERSION_GIT "1.9.6" #endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 11fd1c735589..be35a2f99b1c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -15,6 +15,8 @@ */ /* ****************** SDIO CARD Interface Functions **************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index d92d373733d7..d33e5598611b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index a2f32fb990fa..fd672bf53867 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -39,7 +39,6 @@ #define BRCMF_C_GET_BSSID 23 #define BRCMF_C_GET_SSID 25 #define BRCMF_C_SET_SSID 26 -#define BRCMF_C_TERMINATED 28 #define BRCMF_C_GET_CHANNEL 29 #define BRCMF_C_SET_CHANNEL 30 #define BRCMF_C_GET_SRL 31 @@ -481,14 +480,36 @@ struct brcmf_pub { unsigned long drv_version; /* Version of dongle-resident driver */ u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ + /* Additional stats for the bus level */ + /* Multicast data packets sent to dongle */ unsigned long tx_multicast; + /* Packets flushed due to unscheduled sendup thread */ + unsigned long rx_flushed; + /* Number of times dpc scheduled by watchdog timer */ + unsigned long wd_dpc_sched; + + /* Number of flow control pkts recvd */ + unsigned long fc_packets; + + /* Last error return */ + int bcmerror; + + /* Last error from dongle */ + int dongle_error; + + /* Suspend disable flag flag */ + int suspend_disable_flag; /* "1" to disable all extra powersaving + during suspend */ + int in_suspend; /* flag set to 1 when early suspend called */ + int dtim_skip; /* dtim skip , default 0 means wake each dtim */ struct brcmf_if *iflist[BRCMF_MAX_IFS]; struct mutex proto_block; unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; + u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; wait_queue_head_t pend_8021x_wait; @@ -498,6 +519,11 @@ struct brcmf_pub { #endif }; +struct bcmevent_name { + uint event; + const char *name; +}; + struct brcmf_if_event { u8 ifidx; u8 action; @@ -531,6 +557,13 @@ struct brcmf_if { u8 mac_addr[ETH_ALEN]; }; +static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) +{ + struct brcmf_if *ifp = netdev_priv(ndev); + return ifp->bssidx; +} + +extern const struct bcmevent_name bcmevent_names[]; extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); @@ -543,10 +576,6 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); -/* Remove any protocol-specific data header. */ -extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, - struct sk_buff *rxp); - extern int brcmf_net_attach(struct brcmf_if *ifp); extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, char *name, u8 *mac_addr); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 64c38f4226a3..dd38b78a9726 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -130,18 +130,31 @@ int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len) * interface functions from common layer */ +/* Remove any protocol-specific data header. */ +extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx, + struct sk_buff *rxp); + extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist); +extern void brcmf_rx_frame(struct device *dev, u8 ifidx, + struct sk_buff_head *rxlist); +static inline void brcmf_rx_packet(struct device *dev, int ifidx, + struct sk_buff *pkt) +{ + struct sk_buff_head q; + + skb_queue_head_init(&q); + skb_queue_tail(&q, pkt); + brcmf_rx_frame(dev, ifidx, &q); +} /* Indication from bus module regarding presence/insertion of dongle. */ extern int brcmf_attach(uint bus_hdrlen, struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ extern void brcmf_detach(struct device *dev); -/* Indication from bus module that dongle should be reset */ -extern void brcmf_dev_reset(struct device *dev); + /* Indication from bus module to change flow-control state */ extern void brcmf_txflowblock(struct device *dev, bool state); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index bb454cdab29d..83923553f1ac 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -19,6 +19,8 @@ * For certain dcmd codes, the dongle interprets string data from the host. ******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -92,6 +94,8 @@ struct brcmf_proto_bdc_header { struct brcmf_proto { u16 reqid; + u8 pending; + u32 lastcmd; u8 bus_header[BUS_HEADER_LEN]; struct brcmf_proto_cdc_dcmd msg; unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; @@ -103,7 +107,7 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) int len = le32_to_cpu(prot->msg.len) + sizeof(struct brcmf_proto_cdc_dcmd); - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(TRACE, "Enter\n"); /* NOTE : cdc->msg.len holds the desired length of the buffer to be * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area @@ -121,7 +125,7 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) int ret; struct brcmf_proto *prot = drvr->prot; - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(TRACE, "Enter\n"); len += sizeof(struct brcmf_proto_cdc_dcmd); do { ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, @@ -143,7 +147,20 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, int ret = 0, retries = 0; u32 id, flags; - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); + + /* Respond "bcmerror" and "bcmerrorstr" with local cache */ + if (cmd == BRCMF_C_GET_VAR && buf) { + if (!strcmp((char *)buf, "bcmerrorstr")) { + strncpy((char *)buf, "bcm_error", + BCME_STRLEN); + goto done; + } else if (!strcmp((char *)buf, "bcmerror")) { + *(int *)buf = drvr->dongle_error; + goto done; + } + } memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); @@ -193,8 +210,11 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, } /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) + if (flags & CDC_DCMD_ERROR) { ret = le32_to_cpu(msg->status); + /* Cache error from dongle */ + drvr->dongle_error = ret; + } done: return ret; @@ -208,7 +228,8 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, int ret = 0; u32 flags, id; - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); @@ -241,8 +262,11 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, } /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) + if (flags & CDC_DCMD_ERROR) { ret = le32_to_cpu(msg->status); + /* Cache error from dongle */ + drvr->dongle_error = ret; + } done: return ret; @@ -263,7 +287,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, { struct brcmf_proto_bdc_header *h; - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(TRACE, "Enter\n"); /* Push BDC header used to convey priority for buses that don't */ @@ -281,12 +305,14 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, BDC_SET_IF_IDX(h, ifidx); } -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, +int brcmf_proto_hdrpull(struct device *dev, int *ifidx, struct sk_buff *pktbuf) { struct brcmf_proto_bdc_header *h; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(TRACE, "Enter\n"); /* Pop BDC header used to convey priority for buses that don't */ @@ -312,7 +338,7 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, } if (h->flags & BDC_FLAG_SUM_GOOD) { - brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", + brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n", brcmf_ifname(drvr, *ifidx), h->flags); pkt_set_sum_good(pktbuf, true); } @@ -322,8 +348,6 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, skb_pull(pktbuf, BDC_HEADER_LEN); skb_pull(pktbuf, h->data_offset << 2); - if (pktbuf->len == 0) - return -ENODATA; return 0; } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 4544342a0428..f8b52e5b941a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index bc013cbe06f6..f2ab01cd7966 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -18,26 +18,21 @@ #define _BRCMF_DBG_H_ /* message levels */ -#define BRCMF_TRACE_VAL 0x00000002 -#define BRCMF_INFO_VAL 0x00000004 -#define BRCMF_DATA_VAL 0x00000008 -#define BRCMF_CTL_VAL 0x00000010 -#define BRCMF_TIMER_VAL 0x00000020 -#define BRCMF_HDRS_VAL 0x00000040 -#define BRCMF_BYTES_VAL 0x00000080 -#define BRCMF_INTR_VAL 0x00000100 -#define BRCMF_GLOM_VAL 0x00000200 -#define BRCMF_EVENT_VAL 0x00000400 -#define BRCMF_BTA_VAL 0x00000800 -#define BRCMF_FIL_VAL 0x00001000 -#define BRCMF_USB_VAL 0x00002000 -#define BRCMF_SCAN_VAL 0x00004000 -#define BRCMF_CONN_VAL 0x00008000 -#define BRCMF_CDC_VAL 0x00010000 - -/* set default print format */ -#undef pr_fmt -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define BRCMF_TRACE_VAL 0x0002 +#define BRCMF_INFO_VAL 0x0004 +#define BRCMF_DATA_VAL 0x0008 +#define BRCMF_CTL_VAL 0x0010 +#define BRCMF_TIMER_VAL 0x0020 +#define BRCMF_HDRS_VAL 0x0040 +#define BRCMF_BYTES_VAL 0x0080 +#define BRCMF_INTR_VAL 0x0100 +#define BRCMF_GLOM_VAL 0x0200 +#define BRCMF_EVENT_VAL 0x0400 +#define BRCMF_BTA_VAL 0x0800 +#define BRCMF_FIL_VAL 0x1000 +#define BRCMF_USB_VAL 0x2000 +#define BRCMF_SCAN_VAL 0x4000 +#define BRCMF_CONN_VAL 0x8000 /* Macro for error messages. net_ratelimit() is used when driver * debugging is not selected. When debugging the driver error diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index e3326a58bdb1..74a616b4de8e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -160,31 +162,28 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev) schedule_work(&ifp->multicast_work); } -static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, - struct net_device *ndev) +static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) { int ret; struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; - struct ethhdr *eh; brcmf_dbg(TRACE, "Enter\n"); - /* Can the device send data? */ - if (drvr->bus_if->state != BRCMF_BUS_DATA) { - brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); + /* Reject if down */ + if (!drvr->bus_if->drvr_up || + (drvr->bus_if->state != BRCMF_BUS_DATA)) { + brcmf_err("xmit rejected drvup=%d state=%d\n", + drvr->bus_if->drvr_up, + drvr->bus_if->state); netif_stop_queue(ndev); - dev_kfree_skb(skb); - ret = -ENODEV; - goto done; + return -ENODEV; } if (!drvr->iflist[ifp->idx]) { brcmf_err("bad ifidx %d\n", ifp->idx); netif_stop_queue(ndev); - dev_kfree_skb(skb); - ret = -ENODEV; - goto done; + return -ENODEV; } /* Make sure there's enough room for any header */ @@ -205,19 +204,16 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, } } - /* validate length for ether packet */ - if (skb->len < sizeof(*eh)) { - ret = -EINVAL; - dev_kfree_skb(skb); - goto done; - } + /* Update multicast statistic */ + if (skb->len >= ETH_ALEN) { + u8 *pktdata = (u8 *)(skb->data); + struct ethhdr *eh = (struct ethhdr *)pktdata; - /* handle ethernet header */ - eh = (struct ethhdr *)(skb->data); - if (is_multicast_ether_addr(eh->h_dest)) - drvr->tx_multicast++; - if (ntohs(eh->h_proto) == ETH_P_PAE) - atomic_inc(&drvr->pend_8021x_cnt); + if (is_multicast_ether_addr(eh->h_dest)) + drvr->tx_multicast++; + if (ntohs(eh->h_proto) == ETH_P_PAE) + atomic_inc(&drvr->pend_8021x_cnt); + } /* If the protocol uses a data header, apply it */ brcmf_proto_hdrpush(drvr, ifp->idx, skb); @@ -232,7 +228,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, drvr->bus_if->dstats.tx_packets++; /* Return ok: we always eat the packet */ - return NETDEV_TX_OK; + return 0; } void brcmf_txflowblock(struct device *dev, bool state) @@ -254,7 +250,8 @@ void brcmf_txflowblock(struct device *dev, bool state) } } -void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) +void brcmf_rx_frame(struct device *dev, u8 ifidx, + struct sk_buff_head *skb_list) { unsigned char *eth; uint len; @@ -262,24 +259,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) struct brcmf_if *ifp; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; - u8 ifidx; - int ret; brcmf_dbg(TRACE, "Enter\n"); skb_queue_walk_safe(skb_list, skb, pnext) { skb_unlink(skb, skb_list); - /* process and remove protocol-specific header - */ - ret = brcmf_proto_hdrpull(drvr, &ifidx, skb); - if (ret < 0) { - if (ret != -ENODATA) - bus_if->dstats.rx_errors++; - brcmu_pkt_buf_free_skb(skb); - continue; - } - /* Get the protocol, maintain skb around eth_type_trans() * The main reason for this hack is for the limitation of * Linux 2.4 where 'eth_type_trans' uses the @@ -343,13 +328,13 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) { - u8 ifidx; + uint ifidx; struct ethhdr *eh; u16 type; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; - brcmf_proto_hdrpull(drvr, &ifidx, txp); + brcmf_proto_hdrpull(dev, &ifidx, txp); eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); @@ -465,7 +450,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) sprintf(info.version, "%lu", drvr->drv_version); if (copy_to_user(uaddr, &info, sizeof(info))) return -EFAULT; - brcmf_dbg(TRACE, "given %*s, returning %s\n", + brcmf_dbg(CTL, "given %*s, returning %s\n", (int)sizeof(drvname), drvname, info.driver); break; @@ -585,9 +570,14 @@ static int brcmf_netdev_open(struct net_device *ndev) /* Get current TOE mode from dongle */ if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - ndev->features |= NETIF_F_IP_CSUM; + drvr->iflist[ifp->idx]->ndev->features |= + NETIF_F_IP_CSUM; else - ndev->features &= ~NETIF_F_IP_CSUM; + drvr->iflist[ifp->idx]->ndev->features &= + ~NETIF_F_IP_CSUM; + + /* make sure RF is ready for work */ + brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); /* Allow transmit calls */ netif_start_queue(ndev); @@ -855,17 +845,6 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) } } -void brcmf_dev_reset(struct device *dev) -{ - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_pub *drvr = bus_if->drvr; - - if (drvr == NULL) - return; - - brcmf_fil_cmd_int_set(drvr->iflist[0], BRCMF_C_TERMINATED, 1); -} - void brcmf_detach(struct device *dev) { int i; @@ -887,8 +866,9 @@ void brcmf_detach(struct device *dev) brcmf_bus_detach(drvr); - if (drvr->prot) + if (drvr->prot) { brcmf_proto_detach(drvr); + } brcmf_debugfs_detach(drvr); bus_if->drvr = NULL; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 7fef9b5ba003..cf857f1edf8c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1167,6 +1169,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) int errcode; u8 doff, sfdoff; + int ifidx = 0; bool usechain = bus->use_rxchain; struct brcmf_sdio_read rd_new; @@ -1385,6 +1388,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) skb_unlink(pfirst, &bus->glom); brcmu_pkt_buf_free_skb(pfirst); continue; + } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, + &ifidx, pfirst) != 0) { + brcmf_err("rx protocol error\n"); + bus->sdiodev->bus_if->dstats.rx_errors++; + skb_unlink(pfirst, &bus->glom); + brcmu_pkt_buf_free_skb(pfirst); + continue; } brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), @@ -1397,7 +1407,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } /* sent any remaining packets up */ if (bus->glom.qlen) - brcmf_rx_frames(bus->sdiodev->dev, &bus->glom); + brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); bus->sdcnt.rxglomframes++; bus->sdcnt.rxglompkts += bus->glom.qlen; @@ -1548,10 +1558,10 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) { struct sk_buff *pkt; /* Packet for event or data frames */ - struct sk_buff_head pktlist; /* needed for bus interface */ u16 pad; /* Number of pad bytes to read */ uint rxleft = 0; /* Remaining number of frames allowed */ int sdret; /* Return code from calls */ + int ifidx = 0; uint rxcount = 0; /* Total frames read */ struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; u8 head_read = 0; @@ -1750,11 +1760,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) if (pkt->len == 0) { brcmu_pkt_buf_free_skb(pkt); continue; + } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx, + pkt) != 0) { + brcmf_err("rx protocol error\n"); + brcmu_pkt_buf_free_skb(pkt); + bus->sdiodev->bus_if->dstats.rx_errors++; + continue; } - skb_queue_head_init(&pktlist); - skb_queue_tail(&pktlist, pkt); - brcmf_rx_frames(bus->sdiodev->dev, &pktlist); + brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); } rxcount = maxframes - rxleft; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 14be2d5530ce..b1bb46c49799 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -15,6 +15,8 @@ */ /* ***** SDIO interface chip backplane handle functions ***** */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c index e15630cc3889..914c56fe6c5f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -443,15 +443,14 @@ static void brcmf_usb_rx_complete(struct urb *urb) struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; struct brcmf_usbdev_info *devinfo = req->devinfo; struct sk_buff *skb; - struct sk_buff_head skbq; + int ifidx = 0; brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); brcmf_usb_del_fromq(devinfo, req); skb = req->skb; req->skb = NULL; - /* zero lenght packets indicate usb "failure". Do not refill */ - if (urb->status == 0 && urb->actual_length) { + if (urb->status == 0) { devinfo->bus_pub.bus->dstats.rx_packets++; } else { devinfo->bus_pub.bus->dstats.rx_errors++; @@ -461,10 +460,13 @@ static void brcmf_usb_rx_complete(struct urb *urb) } if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { - skb_queue_head_init(&skbq); - skb_queue_tail(&skbq, skb); skb_put(skb, urb->actual_length); - brcmf_rx_frames(devinfo->dev, &skbq); + if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { + brcmf_err("rx protocol error\n"); + brcmu_pkt_buf_free_skb(skb); + devinfo->bus_pub.bus->dstats.rx_errors++; + } else + brcmf_rx_packet(devinfo->dev, ifidx, skb); brcmf_usb_rx_refill(devinfo, req); } else { brcmu_pkt_buf_free_skb(skb); @@ -1518,23 +1520,10 @@ static void brcmf_release_fw(struct list_head *q) } } -static int brcmf_usb_reset_device(struct device *dev, void *notused) -{ - /* device past is the usb interface so we - * need to use parent here. - */ - brcmf_dev_reset(dev->parent); - return 0; -} void brcmf_usb_exit(void) { - struct device_driver *drv = &brcmf_usbdrvr.drvwrap.driver; - int ret; - brcmf_dbg(USB, "Enter\n"); - ret = driver_for_each_device(drv, NULL, NULL, - brcmf_usb_reset_device); usb_deregister(&brcmf_usbdrvr); brcmf_release_fw(&fw_image_list); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 730da84edb01..1261a9b84e04 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,6 +16,8 @@ /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -2009,6 +2011,67 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, return err; } +static s32 +brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, + const u8 *addr, + const struct cfg80211_bitrate_mask *mask) +{ + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcm_rateset_le rateset_le; + s32 rate; + s32 val; + s32 err_bg; + s32 err_a; + u32 legacy; + s32 err = 0; + + brcmf_dbg(TRACE, "Enter\n"); + if (!check_vif_up(ifp->vif)) + return -EIO; + + /* addr param is always NULL. ignore it */ + /* Get current rateset */ + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET, + &rateset_le, sizeof(rateset_le)); + if (err) { + brcmf_err("could not get current rateset (%d)\n", err); + goto done; + } + + legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF); + if (!legacy) + legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy & + 0xFFFF); + + val = wl_g_rates[legacy - 1].bitrate * 100000; + + if (val < le32_to_cpu(rateset_le.count)) + /* Select rate by rateset index */ + rate = rateset_le.rates[val] & 0x7f; + else + /* Specified rate in bps */ + rate = val / 500000; + + brcmf_dbg(CONN, "rate %d mbps\n", rate / 2); + + /* + * + * Set rate override, + * Since the is a/b/g-blind, both a/bg_rate are enforced. + */ + err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate); + err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate); + if (err_bg && err_a) { + brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg, + err_a); + err = err_bg | err_a; + } + +done: + brcmf_dbg(TRACE, "Exit\n"); + return err; +} + static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, struct brcmf_bss_info_le *bi) { @@ -3640,6 +3703,7 @@ static struct cfg80211_ops wl_cfg80211_ops = { .set_default_key = brcmf_cfg80211_config_default_key, .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key, .set_power_mgmt = brcmf_cfg80211_set_power_mgmt, + .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask, .connect = brcmf_cfg80211_connect, .disconnect = brcmf_cfg80211_disconnect, .suspend = brcmf_cfg80211_suspend, @@ -4265,8 +4329,9 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) } static s32 -brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) +brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) { + struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; __le32 roamtrigger[2]; __le32 roam_delta[2]; @@ -4317,9 +4382,10 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout) } static s32 -brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time, +brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, s32 scan_unassoc_time, s32 scan_passive_time) { + struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, @@ -4389,7 +4455,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) { struct net_device *ndev; struct wireless_dev *wdev; - struct brcmf_if *ifp; s32 power_mode; s32 err = 0; @@ -4398,35 +4463,36 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) ndev = cfg_to_ndev(cfg); wdev = ndev->ieee80211_ptr; - ifp = netdev_priv(ndev); - /* make sure RF is ready for work */ - brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); - - brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME, - WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); + brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, + WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode); + err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, + power_mode); if (err) goto default_conf_out; brcmf_dbg(INFO, "power save set to %s\n", (power_mode ? "enabled" : "disabled")); - err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); + err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1), + WL_BEACON_TIMEOUT); if (err) goto default_conf_out; err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, NULL, NULL); - if (err) + if (err && err != -EINPROGRESS) goto default_conf_out; err = brcmf_dongle_probecap(cfg); if (err) goto default_conf_out; - cfg->dongle_up = true; + /* -EINPROGRESS: Call commit handler */ + default_conf_out: + cfg->dongle_up = true; + return err; } @@ -4434,6 +4500,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) { set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); + if (ifp->idx) + return 0; return brcmf_config_dongle(ifp->drvr->config); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 1585cc5bf866..1de94f30564f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -961,6 +961,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { + ini->tx_in_transit--; ini->txretry[index] = 0; /* @@ -989,6 +990,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (retry && (ini->txretry[index] < (int)retry_limit)) { int ret; ini->txretry[index]++; + ini->tx_in_transit--; ret = brcms_c_txfifo(wlc, queue, p); /* * We shouldn't be out of space in the DMA @@ -998,6 +1000,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, WARN_ONCE(ret, "queue %d out of txds\n", queue); } else { /* Retry timeout */ + ini->tx_in_transit--; ieee80211_tx_info_clear_status(tx_info); tx_info->status.ampdu_ack_len = 0; tx_info->status.ampdu_len = 1; @@ -1006,8 +1009,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); brcms_dbg_ht(wlc->hw->d11core, - "BA Timeout, seq %d\n", - seq); + "BA Timeout, seq %d, in_transit %d\n", + seq, ini->tx_in_transit); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 7fc49ca3f597..f0fc8cd4d5df 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -362,11 +362,8 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return -EOPNOTSUPP; } - spin_lock_bh(&wl->lock); - memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr)); wl->mute_tx = false; brcms_c_mute(wl->wlc, false); - spin_unlock_bh(&wl->lock); return 0; } @@ -1412,10 +1409,9 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) #endif t->ms = ms; t->periodic = (bool) periodic; - if (!t->set) { - t->set = true; - atomic_inc(&t->wl->callbacks); - } + t->set = true; + + atomic_inc(&t->wl->callbacks); ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms)); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index c26992a60e6c..17594de4199e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -2473,7 +2473,6 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) { static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - u8 *ethaddr = wlc_hw->wlc->pub->cur_etheraddr; if (mute_tx) { /* suspend tx fifos */ @@ -2483,7 +2482,8 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); /* zero the address match register so we do not send ACKs */ - brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr); + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + null_ether_addr); } else { /* resume tx fifos */ brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); @@ -2492,7 +2492,8 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); /* Restore address */ - brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, ethaddr); + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + wlc_hw->etheraddr); } wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); @@ -7632,7 +7633,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) uint n = 0; uint bound_limit = bound ? RXBND : -1; - bool morepending = false; + bool morepending; skb_queue_head_init(&recv_frames); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/scb.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/scb.h index 3a3d73699f83..51c79c7239b7 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/scb.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/scb.h @@ -36,6 +36,7 @@ /* structure to store per-tid state for the ampdu initiator */ struct scb_ampdu_tid_ini { + u8 tx_in_transit; /* number of pending mpdus in transit in driver */ u8 tid; /* initiator tid for easy lookup */ /* tx retry count; indexed by seq modulo */ u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c index 3d76a3f595b7..d604b4036a76 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3474,7 +3474,6 @@ struct ieee80211_ops il3945_mac_ops = { .sta_add = il3945_mac_sta_add, .sta_remove = il_mac_sta_remove, .tx_last_beacon = il_mac_tx_last_beacon, - .flush = il_mac_flush, }; static int @@ -3549,8 +3548,7 @@ il3945_setup_mac(struct il_priv *il) hw->vif_data_size = sizeof(struct il_vif_priv); /* Tell mac80211 our characteristics */ - hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); @@ -3559,8 +3557,6 @@ il3945_setup_mac(struct il_priv *il) WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; /* we create the 802.11 header and a zero-length SSID element */ hw->wiphy->max_scan_ie_len = IL3945_MAX_PROBE_REQUEST - 24 - 2; diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index 10fc2493f415..6a86ed45835d 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5712,8 +5712,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS; + if (il->cfg->sku & IL_SKU_N) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | @@ -6308,7 +6308,6 @@ const struct ieee80211_ops il4965_mac_ops = { .sta_remove = il_mac_sta_remove, .channel_switch = il4965_mac_channel_switch, .tx_last_beacon = il_mac_tx_last_beacon, - .flush = il_mac_flush, }; static int diff --git a/trunk/drivers/net/wireless/iwlegacy/common.c b/trunk/drivers/net/wireless/iwlegacy/common.c index 56b80219d695..7e16d10a7f14 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.c +++ b/trunk/drivers/net/wireless/iwlegacy/common.c @@ -4707,42 +4707,6 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL(il_mac_change_interface); -void -il_mac_flush(struct ieee80211_hw *hw, bool drop) -{ - struct il_priv *il = hw->priv; - unsigned long timeout = jiffies + msecs_to_jiffies(500); - int i; - - mutex_lock(&il->mutex); - D_MAC80211("enter\n"); - - if (il->txq == NULL) - goto out; - - for (i = 0; i < il->hw_params.max_txq_num; i++) { - struct il_queue *q; - - if (i == il->cmd_queue) - continue; - - q = &il->txq[i].q; - if (q->read_ptr == q->write_ptr) - continue; - - if (time_after(jiffies, timeout)) { - IL_ERR("Failed to flush queue %d\n", q->id); - break; - } - - msleep(20); - } -out: - D_MAC80211("leave\n"); - mutex_unlock(&il->mutex); -} -EXPORT_SYMBOL(il_mac_flush); - /* * On every watchdog tick we check (latest) time stamp. If it does not * change during timeout period and queue is not empty we reset firmware. diff --git a/trunk/drivers/net/wireless/iwlegacy/common.h b/trunk/drivers/net/wireless/iwlegacy/common.h index 37fe553b25e0..a9a569f432fb 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.h +++ b/trunk/drivers/net/wireless/iwlegacy/common.h @@ -1723,7 +1723,6 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); -void il_mac_flush(struct ieee80211_hw *hw, bool drop); int il_alloc_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h index 0ca99c13f7f2..71ab76b2b39d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -3695,7 +3695,7 @@ struct iwl_bt_uart_msg { u8 frame5; u8 frame6; u8 frame7; -} __packed; +} __attribute__((packed)); struct iwl_bt_coex_profile_notif { struct iwl_bt_uart_msg last_bt_uart_msg; @@ -3703,7 +3703,7 @@ struct iwl_bt_coex_profile_notif { u8 bt_traffic_load; /* 0 .. 3? */ u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ u8 reserved; -} __packed; +} __attribute__((packed)); #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 #define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 @@ -3752,7 +3752,7 @@ enum bt_coex_prio_table_priorities { struct iwl_bt_coex_prio_table_cmd { u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; -} __packed; +} __attribute__((packed)); #define IWL_BT_COEX_ENV_CLOSE 0 #define IWL_BT_COEX_ENV_OPEN 1 @@ -3764,7 +3764,7 @@ struct iwl_bt_coex_prot_env_cmd { u8 action; /* 0 = closed, 1 = open */ u8 type; /* 0 .. 15 */ u8 reserved[2]; -} __packed; +} __attribute__((packed)); /* * REPLY_D3_CONFIG diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 72c74af38138..5b9533eef54d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -157,7 +157,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, sram = priv->dbgfs_sram_offset & ~0x3; /* read the first u32 from sram */ - val = iwl_trans_read_mem32(priv->trans, sram); + val = iwl_read_targ_mem(priv->trans, sram); for (; len; len--) { /* put the address at the start of every line */ @@ -176,7 +176,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, if (++offset == 4) { sram += 4; offset = 0; - val = iwl_trans_read_mem32(priv->trans, sram); + val = iwl_read_targ_mem(priv->trans, sram); } /* put in extra spaces and split lines for human readability */ diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/led.c b/trunk/drivers/net/wireless/iwlwifi/dvm/led.c index 844a17f99a18..bf479f709091 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/led.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/led.c @@ -69,7 +69,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* Set led register off */ void iwlagn_led_enable(struct iwl_priv *priv) { - iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON); + iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TRUN_ON); } /* diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 6660effc563f..02fdcea76b21 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -459,11 +459,11 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) base = priv->device_pointers.error_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { spin_lock_irqsave(&priv->trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(priv->trans, true)) { + ret = iwl_grab_nic_access_silent(priv->trans); + if (likely(ret == 0)) { iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base); status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); - iwl_trans_release_nic_access(priv->trans); - ret = 0; + iwl_release_nic_access(priv->trans); } spin_unlock_irqrestore(&priv->trans->reg_lock, flags); @@ -479,7 +479,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) } if (priv->wowlan_sram) - iwl_trans_read_mem( + _iwl_read_targ_mem_dwords( priv->trans, 0x800000, priv->wowlan_sram, img->sec[IWL_UCODE_SECTION_DATA].len / 4); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index a64f361e341c..faa05932efae 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, /* Make sure device is powered up for SRAM reads */ spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); - if (!iwl_trans_grab_nic_access(priv->trans, false)) { + if (unlikely(!iwl_grab_nic_access(priv->trans))) { spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); return; } @@ -388,7 +388,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, } } /* Allow device to power down */ - iwl_trans_release_nic_access(priv->trans); + iwl_release_nic_access(priv->trans); spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags); } @@ -408,8 +408,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) base = priv->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - iwl_trans_read_mem_bytes(priv->trans, base, - &read, sizeof(read)); + iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read)); capacity = read.capacity; mode = read.mode; num_wraps = read.wrap_counter; @@ -1628,7 +1627,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) } /*TODO: Update dbgfs with ISR error stats obtained below */ - iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); + iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table)); if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(trans, "Start IWL Error Log Dump:\n"); @@ -1718,7 +1717,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, /* Make sure device is powered up for SRAM reads */ spin_lock_irqsave(&trans->reg_lock, reg_flags); - if (!iwl_trans_grab_nic_access(trans, false)) + if (unlikely(!iwl_grab_nic_access(trans))) goto out_unlock; /* Set starting address; reads will auto-increment */ @@ -1757,7 +1756,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, } /* Allow device to power down */ - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); out_unlock: spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; @@ -1836,10 +1835,10 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, } /* event log header */ - capacity = iwl_trans_read_mem32(trans, base); - mode = iwl_trans_read_mem32(trans, base + (1 * sizeof(u32))); - num_wraps = iwl_trans_read_mem32(trans, base + (2 * sizeof(u32))); - next_entry = iwl_trans_read_mem32(trans, base + (3 * sizeof(u32))); + capacity = iwl_read_targ_mem(trans, base); + mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(priv, "Log capacity %d is bogus, limit to %d " diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tt.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tt.c index b28cfc8553d7..eb864433e59d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tt.c @@ -186,8 +186,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) } iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); spin_lock_irqsave(&priv->trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(priv->trans, false)) - iwl_trans_release_nic_access(priv->trans); + if (likely(iwl_grab_nic_access(priv->trans))) + iwl_release_nic_access(priv->trans); spin_unlock_irqrestore(&priv->trans->reg_lock, flags); /* Reschedule the ct_kill timer to occur in diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index df76881385ae..da21328ca8ed 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -541,9 +541,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; - txq_id = tid_data->agg.txq_id; + txq_id = priv->tid_data[sta_id][tid].agg.txq_id; - switch (tid_data->agg.state) { + switch (priv->tid_data[sta_id][tid].agg.state) { case IWL_EMPTYING_HW_QUEUE_ADDBA: /* * This can happen if the peer stops aggregation @@ -563,9 +563,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, case IWL_AGG_ON: break; default: - IWL_WARN(priv, - "Stopping AGG while state not ON or starting for %d on %d (%d)\n", - sta_id, tid, tid_data->agg.state); + IWL_WARN(priv, "Stopping AGG while state not ON " + "or starting for %d on %d (%d)\n", sta_id, tid, + priv->tid_data[sta_id][tid].agg.state); spin_unlock_bh(&priv->sta_lock); return 0; } @@ -578,11 +578,12 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, "stopping AGG on STA/TID %d/%d but hwq %d not used\n", sta_id, tid, txq_id); } else if (tid_data->agg.ssn != tid_data->next_reclaimed) { - IWL_DEBUG_TX_QUEUES(priv, - "Can't proceed: ssn %d, next_recl = %d\n", + IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " + "next_recl = %d\n", tid_data->agg.ssn, tid_data->next_reclaimed); - tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; + priv->tid_data[sta_id][tid].agg.state = + IWL_EMPTYING_HW_QUEUE_DELBA; spin_unlock_bh(&priv->sta_lock); return 0; } @@ -590,8 +591,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", tid_data->agg.ssn); turn_off: - agg_state = tid_data->agg.state; - tid_data->agg.state = IWL_AGG_OFF; + agg_state = priv->tid_data[sta_id][tid].agg.state; + priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; spin_unlock_bh(&priv->sta_lock); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c index ebec13a3329f..c6467e5554f5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -286,6 +286,89 @@ static int iwl_alive_notify(struct iwl_priv *priv) return iwl_send_calib_results(priv); } + +/** + * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, + * using sample data 100 bytes apart. If these sample points are good, + * it's a pretty good bet that everything between them is good, too. + */ +static int iwl_verify_sec_sparse(struct iwl_priv *priv, + const struct fw_desc *fw_desc) +{ + __le32 *image = (__le32 *)fw_desc->data; + u32 len = fw_desc->len; + u32 val; + u32 i; + + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); + + for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, + i + fw_desc->offset); + val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) + return -EIO; + } + + return 0; +} + +static void iwl_print_mismatch_sec(struct iwl_priv *priv, + const struct fw_desc *fw_desc) +{ + __le32 *image = (__le32 *)fw_desc->data; + u32 len = fw_desc->len; + u32 val; + u32 offs; + int errors = 0; + + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); + + iwl_write_direct32(priv->trans, HBUS_TARG_MEM_RADDR, + fw_desc->offset); + + for (offs = 0; + offs < len && errors < 20; + offs += sizeof(u32), image++) { + /* read data comes through single port, auto-incr addr */ + val = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "uCode INST section at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + offs, val, le32_to_cpu(*image)); + errors++; + } + } +} + +/** + * iwl_verify_ucode - determine which instruction image is in SRAM, + * and verify its contents + */ +static int iwl_verify_ucode(struct iwl_priv *priv, + enum iwl_ucode_type ucode_type) +{ + const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); + + if (!img) { + IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); + return -EINVAL; + } + + if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { + IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); + return 0; + } + + IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); + + iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); + return -EIO; +} + struct iwl_alive_data { bool valid; u8 subtype; @@ -343,7 +426,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, alive_cmd, ARRAY_SIZE(alive_cmd), iwl_alive_fn, &alive_data); - ret = iwl_trans_start_fw(priv->trans, fw, false); + ret = iwl_trans_start_fw(priv->trans, fw); if (ret) { priv->cur_ucode = old_type; iwl_remove_notification(&priv->notif_wait, &alive_wait); @@ -367,7 +450,18 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } + /* + * This step takes a long time (60-80ms!!) and + * WoWLAN image should be loaded quickly, so + * skip it for WoWLAN. + */ if (ucode_type != IWL_UCODE_WOWLAN) { + ret = iwl_verify_ucode(priv, ucode_type); + if (ret) { + priv->cur_ucode = old_type; + return ret; + } + /* delay a bit to give rfkill time to run */ msleep(5); } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-csr.h b/trunk/drivers/net/wireless/iwlwifi/iwl-csr.h index b419a1efac0a..34a5287dfc2f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -381,8 +381,8 @@ /* LED */ #define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) -#define CSR_LED_REG_TURN_ON (0x60) -#define CSR_LED_REG_TURN_OFF (0x20) +#define CSR_LED_REG_TRUN_ON (0x78) +#define CSR_LED_REG_TRUN_OFF (0x38) /* ANA_PLL */ #define CSR50_ANA_PLL_CFG_VAL (0x00880300) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-io.c b/trunk/drivers/net/wireless/iwlwifi/iwl-io.c index bff3ac96c00b..cdaff9572059 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-io.c @@ -35,12 +35,12 @@ #define IWL_POLL_INTERVAL 10 /* microseconds */ -void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) +static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); } -void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) +static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); } @@ -99,16 +99,86 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, } EXPORT_SYMBOL_GPL(iwl_poll_bit); +int iwl_grab_nic_access_silent(struct iwl_trans *trans) +{ + int ret; + + lockdep_assert_held(&trans->reg_lock); + + /* this bit wakes up the NIC */ + __iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + + /* + * These bits say the device is running, and should keep running for + * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), + * but they do not indicate that embedded SRAM is restored yet; + * 3945 and 4965 have volatile SRAM, and must save/restore contents + * to/from host DRAM when sleeping/waking for power-saving. + * Each direction takes approximately 1/4 millisecond; with this + * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a + * series of register accesses are expected (e.g. reading Event Log), + * to keep device from sleeping. + * + * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that + * SRAM is okay/restored. We don't check that here because this call + * is just for hardware register access; but GP1 MAC_SLEEP check is a + * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). + * + * 5000 series and later (including 1000 series) have non-volatile SRAM, + * and do not save/restore SRAM when power cycling. + */ + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); + if (ret < 0) { + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + return -EIO; + } + + return 0; +} +EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent); + +bool iwl_grab_nic_access(struct iwl_trans *trans) +{ + int ret = iwl_grab_nic_access_silent(trans); + if (unlikely(ret)) { + u32 val = iwl_read32(trans, CSR_GP_CNTRL); + WARN_ONCE(1, "Timeout waiting for hardware access " + "(CSR_GP_CNTRL 0x%08x)\n", val); + return false; + } + + return true; +} +EXPORT_SYMBOL_GPL(iwl_grab_nic_access); + +void iwl_release_nic_access(struct iwl_trans *trans) +{ + lockdep_assert_held(&trans->reg_lock); + __iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + /* + * Above we read the CSR_GP_CNTRL register, which will flush + * any previous writes, but we need the write that clears the + * MAC_ACCESS_REQ bit to be performed before any other writes + * scheduled on different CPUs (after we drop reg_lock). + */ + mmiowb(); +} +EXPORT_SYMBOL_GPL(iwl_release_nic_access); + u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { - u32 value = 0x5a5a5a5a; + u32 value; unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { - value = iwl_read32(trans, reg); - iwl_trans_release_nic_access(trans); - } + iwl_grab_nic_access(trans); + value = iwl_read32(trans, reg); + iwl_release_nic_access(trans); spin_unlock_irqrestore(&trans->reg_lock, flags); return value; @@ -120,9 +190,9 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { + if (likely(iwl_grab_nic_access(trans))) { iwl_write32(trans, reg, value); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -160,13 +230,12 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) { unsigned long flags; - u32 val = 0x5a5a5a5a; + u32 val; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { - val = __iwl_read_prph(trans, ofs); - iwl_trans_release_nic_access(trans); - } + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, ofs); + iwl_release_nic_access(trans); spin_unlock_irqrestore(&trans->reg_lock, flags); return val; } @@ -177,9 +246,9 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { + if (likely(iwl_grab_nic_access(trans))) { __iwl_write_prph(trans, ofs, val); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -190,10 +259,10 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { + if (likely(iwl_grab_nic_access(trans))) { __iwl_write_prph(trans, ofs, __iwl_read_prph(trans, ofs) | mask); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -205,10 +274,10 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, unsigned long flags; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { + if (likely(iwl_grab_nic_access(trans))) { __iwl_write_prph(trans, ofs, (__iwl_read_prph(trans, ofs) & mask) | bits); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } @@ -220,11 +289,66 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) u32 val; spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { + if (likely(iwl_grab_nic_access(trans))) { val = __iwl_read_prph(trans, ofs); __iwl_write_prph(trans, ofs, (val & ~mask)); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); } spin_unlock_irqrestore(&trans->reg_lock, flags); } EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); + +void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords) +{ + unsigned long flags; + int offs; + u32 *vals = buf; + + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); + for (offs = 0; offs < dwords; offs++) + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans); + } + spin_unlock_irqrestore(&trans->reg_lock, flags); +} +EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords); + +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) +{ + u32 value; + + _iwl_read_targ_mem_dwords(trans, addr, &value, 1); + + return value; +} +EXPORT_SYMBOL_GPL(iwl_read_targ_mem); + +int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + const void *buf, int dwords) +{ + unsigned long flags; + int offs, result = 0; + const u32 *vals = buf; + + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); + for (offs = 0; offs < dwords; offs++) + iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); + iwl_release_nic_access(trans); + } else + result = -EBUSY; + spin_unlock_irqrestore(&trans->reg_lock, flags); + + return result; +} +EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords); + +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) +{ + return _iwl_write_targ_mem_dwords(trans, addr, &val, 1); +} +EXPORT_SYMBOL_GPL(iwl_write_targ_mem); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-io.h b/trunk/drivers/net/wireless/iwlwifi/iwl-io.h index dc478068596b..48dc753e3742 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-io.h @@ -53,8 +53,6 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); -void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); -void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); @@ -63,6 +61,10 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout); +int iwl_grab_nic_access_silent(struct iwl_trans *trans); +bool iwl_grab_nic_access(struct iwl_trans *trans); +void iwl_release_nic_access(struct iwl_trans *trans); + u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); @@ -74,4 +76,19 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, u32 bits, u32 mask); void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); +void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + void *buf, int dwords); + +#define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \ + do { \ + BUILD_BUG_ON((bufsize) % sizeof(u32)); \ + _iwl_read_targ_mem_dwords(trans, addr, buf, \ + (bufsize) / sizeof(u32));\ + } while (0) + +int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, + const void *buf, int dwords); + +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); #endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-test.c b/trunk/drivers/net/wireless/iwlwifi/iwl-test.c index 1a226114fe73..81e8c7126d72 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-test.c @@ -467,20 +467,18 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) if (IWL_ABS_PRPH_START <= addr && addr < IWL_ABS_PRPH_START + PRPH_END) { spin_lock_irqsave(&trans->reg_lock, flags); - if (!iwl_trans_grab_nic_access(trans, false)) { - spin_unlock_irqrestore(&trans->reg_lock, flags); - return -EIO; - } + iwl_grab_nic_access(trans); iwl_write32(trans, HBUS_TARG_PRPH_RADDR, addr | (3 << 24)); for (i = 0; i < size; i += 4) *(u32 *)(tst->mem.addr + i) = iwl_read32(trans, HBUS_TARG_PRPH_RDAT); - iwl_trans_release_nic_access(trans); + iwl_release_nic_access(trans); spin_unlock_irqrestore(&trans->reg_lock, flags); } else { /* target memory (SRAM) */ - iwl_trans_read_mem(trans, addr, tst->mem.addr, - tst->mem.size / 4); + _iwl_read_targ_mem_dwords(trans, addr, + tst->mem.addr, + tst->mem.size / 4); } tst->mem.nchunks = @@ -503,31 +501,28 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, if (IWL_ABS_PRPH_START <= addr && addr < IWL_ABS_PRPH_START + PRPH_END) { - /* Periphery writes can be 1-3 bytes long, or DWORDs */ - if (size < 4) { - memcpy(&val, buf, size); - spin_lock_irqsave(&trans->reg_lock, flags); - if (!iwl_trans_grab_nic_access(trans, false)) { + /* Periphery writes can be 1-3 bytes long, or DWORDs */ + if (size < 4) { + memcpy(&val, buf, size); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, + (addr & 0x0000FFFF) | + ((size - 1) << 24)); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); + iwl_release_nic_access(trans); + /* needed after consecutive writes w/o read */ + mmiowb(); spin_unlock_irqrestore(&trans->reg_lock, flags); - return -EIO; + } else { + if (size % 4) + return -EINVAL; + for (i = 0; i < size; i += 4) + iwl_write_prph(trans, addr+i, + *(u32 *)(buf+i)); } - iwl_write32(trans, HBUS_TARG_PRPH_WADDR, - (addr & 0x0000FFFF) | - ((size - 1) << 24)); - iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); - iwl_trans_release_nic_access(trans); - /* needed after consecutive writes w/o read */ - mmiowb(); - spin_unlock_irqrestore(&trans->reg_lock, flags); - } else { - if (size % 4) - return -EINVAL; - for (i = 0; i < size; i += 4) - iwl_write_prph(trans, addr+i, - *(u32 *)(buf+i)); - } } else if (iwl_test_valid_hw_addr(tst, addr)) { - iwl_trans_write_mem(trans, addr, buf, size / 4); + _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4); } else { return -EINVAL; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h index b0d5c715ca1e..b76532e238c1 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -321,8 +321,6 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * @n_no_reclaim_cmds: # of commands in list * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, * if unset 4k will be the RX buffer size - * @bc_table_dword: set to true if the BC table expects the byte count to be - * in DWORD (as opposed to bytes) * @queue_watchdog_timeout: time (in ms) after which queues * are considered stuck and will trigger device restart * @command_names: array of command names, must be 256 entries @@ -337,7 +335,6 @@ struct iwl_trans_config { int n_no_reclaim_cmds; bool rx_buf_size_8k; - bool bc_table_dword; unsigned int queue_watchdog_timeout; const char **command_names; }; @@ -390,21 +387,16 @@ struct iwl_trans; * @read32: read a u32 register at offset ofs from the BAR * @read_prph: read a DWORD from a periphery register * @write_prph: write a DWORD to a periphery register - * @read_mem: read device's SRAM in DWORD - * @write_mem: write device's SRAM in DWORD * @configure: configure parameters required by the transport layer from * the op_mode. May be called several times before start_fw, can't be * called after that. * @set_pmi: set the power pmi state - * @grab_nic_access: wake the NIC to be able to access non-HBUS regs - * @release_nic_access: let the NIC go to sleep */ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); - int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, - bool run_in_rfkill); + int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); void (*stop_device)(struct iwl_trans *trans); @@ -432,15 +424,9 @@ struct iwl_trans_ops { u32 (*read32)(struct iwl_trans *trans, u32 ofs); u32 (*read_prph)(struct iwl_trans *trans, u32 ofs); void (*write_prph)(struct iwl_trans *trans, u32 ofs, u32 val); - int (*read_mem)(struct iwl_trans *trans, u32 addr, - void *buf, int dwords); - int (*write_mem)(struct iwl_trans *trans, u32 addr, - void *buf, int dwords); void (*configure)(struct iwl_trans *trans, const struct iwl_trans_config *trans_cfg); void (*set_pmi)(struct iwl_trans *trans, bool state); - bool (*grab_nic_access)(struct iwl_trans *trans, bool silent); - void (*release_nic_access)(struct iwl_trans *trans); }; /** @@ -542,14 +528,13 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) } static inline int iwl_trans_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, - bool run_in_rfkill) + const struct fw_img *fw) { might_sleep(); WARN_ON_ONCE(!trans->rx_mpdu_cmd); - return trans->ops->start_fw(trans, fw, run_in_rfkill); + return trans->ops->start_fw(trans, fw); } static inline void iwl_trans_stop_device(struct iwl_trans *trans) @@ -651,7 +636,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) } static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, - struct dentry *dir) + struct dentry *dir) { return trans->ops->dbgfs_register(trans, dir); } @@ -694,57 +679,11 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, return trans->ops->write_prph(trans, ofs, val); } -static inline int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr, - void *buf, int dwords) -{ - return trans->ops->read_mem(trans, addr, buf, dwords); -} - -#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \ - do { \ - if (__builtin_constant_p(bufsize)) \ - BUILD_BUG_ON((bufsize) % sizeof(u32)); \ - iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\ - } while (0) - -static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr) -{ - u32 value; - - if (WARN_ON(iwl_trans_read_mem(trans, addr, &value, 1))) - return 0xa5a5a5a5; - - return value; -} - -static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, - void *buf, int dwords) -{ - return trans->ops->write_mem(trans, addr, buf, dwords); -} - -static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr, - u32 val) -{ - return iwl_trans_write_mem(trans, addr, &val, 1); -} - static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) { trans->ops->set_pmi(trans, state); } -#define iwl_trans_grab_nic_access(trans, silent) \ - __cond_lock(nic_access, \ - likely((trans)->ops->grab_nic_access(trans, silent))) - -static inline void __releases(nic_access) -iwl_trans_release_nic_access(struct iwl_trans *trans) -{ - trans->ops->release_nic_access(trans); - __release(nic_access); -} - /***************************************************** * driver (transport) register/unregister functions ******************************************************/ diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h index 8f017c34ab2b..d91d2e8c62f5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -222,6 +222,8 @@ struct iwl_txq { * @rx_replenish: work that will be called when buffers need to be allocated * @drv - pointer to iwl_drv * @trans: pointer to the generic transport area + * @irq - the irq number for the device + * @irq_requested: true when the irq has been requested * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler * @kw: keep warm address @@ -232,7 +234,6 @@ struct iwl_txq { * @status - transport specific status flags * @cmd_queue - command queue number * @rx_buf_size_8k: 8 kB RX buffer size - * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) * @rx_page_order: page order for receive buffer size * @wd_timeout: queue watchdog timeout (jiffies) */ @@ -248,9 +249,11 @@ struct iwl_trans_pcie { int ict_index; u32 inta; bool use_ict; + bool irq_requested; struct tasklet_struct irq_tasklet; struct isr_statistics isr_stats; + unsigned int irq; spinlock_t irq_lock; u32 inta_mask; u32 scd_base_addr; @@ -276,7 +279,6 @@ struct iwl_trans_pcie { u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; bool rx_buf_size_8k; - bool bc_table_dword; u32 rx_page_order; const char **command_names; diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index 02c9016d9684..dad4c4aad91f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -545,8 +545,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) return; } - cancel_work_sync(&trans_pcie->rx_replenish); - spin_lock_irqsave(&rxq->lock, flags); iwl_pcie_rxq_free_rbs(trans); spin_unlock_irqrestore(&rxq->lock, flags); diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index db3b0552b2eb..35708b959ad6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -435,7 +435,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, } static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, - const struct fw_img *fw, bool run_in_rfkill) + const struct fw_img *fw) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; @@ -454,7 +454,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_is_rfkill_set(trans); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); - if (hw_rfkill && !run_in_rfkill) + if (hw_rfkill) return -ERFKILL; iwl_write32(trans, CSR_INT, 0xFFFFFFFF); @@ -534,6 +534,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) iwl_enable_rfkill_int(trans); + /* wait to make sure we flush pending tasklet*/ + synchronize_irq(trans_pcie->irq); + tasklet_kill(&trans_pcie->irq_tasklet); + + cancel_work_sync(&trans_pcie->rx_replenish); + /* stop and reset the on-board processor */ iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); @@ -558,13 +564,33 @@ static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { - bool hw_rfkill; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int err; + bool hw_rfkill; + + trans_pcie->inta_mask = CSR_INI_SET_MASK; + + if (!trans_pcie->irq_requested) { + tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) + iwl_pcie_tasklet, (unsigned long)trans); + + iwl_pcie_alloc_ict(trans); + + err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict, + IRQF_SHARED, DRV_NAME, trans); + if (err) { + IWL_ERR(trans, "Error allocating IRQ %d\n", + trans_pcie->irq); + goto error; + } + + trans_pcie->irq_requested = true; + } err = iwl_pcie_prepare_card_hw(trans); if (err) { IWL_ERR(trans, "Error while preparing HW: %d\n", err); - return err; + goto err_free_irq; } iwl_pcie_apm_init(trans); @@ -575,7 +601,15 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) hw_rfkill = iwl_is_rfkill_set(trans); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); - return 0; + return err; + +err_free_irq: + trans_pcie->irq_requested = false; + free_irq(trans_pcie->irq, trans); +error: + iwl_pcie_free_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; } static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, @@ -669,21 +703,19 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); trans_pcie->command_names = trans_cfg->command_names; - trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; } void iwl_trans_pcie_free(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - synchronize_irq(trans_pcie->pci_dev->irq); - tasklet_kill(&trans_pcie->irq_tasklet); - iwl_pcie_tx_free(trans); iwl_pcie_rx_free(trans); - free_irq(trans_pcie->pci_dev->irq, trans); - iwl_pcie_free_ict(trans); + if (trans_pcie->irq_requested == true) { + free_irq(trans_pcie->irq, trans); + iwl_pcie_free_ict(trans); + } pci_disable_msi(trans_pcie->pci_dev); iounmap(trans_pcie->hw_base); @@ -726,107 +758,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) } #endif /* CONFIG_PM_SLEEP */ -static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent) -{ - int ret; - - lockdep_assert_held(&trans->reg_lock); - - /* this bit wakes up the NIC */ - __iwl_set_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - - /* - * These bits say the device is running, and should keep running for - * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), - * but they do not indicate that embedded SRAM is restored yet; - * 3945 and 4965 have volatile SRAM, and must save/restore contents - * to/from host DRAM when sleeping/waking for power-saving. - * Each direction takes approximately 1/4 millisecond; with this - * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a - * series of register accesses are expected (e.g. reading Event Log), - * to keep device from sleeping. - * - * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that - * SRAM is okay/restored. We don't check that here because this call - * is just for hardware register access; but GP1 MAC_SLEEP check is a - * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). - * - * 5000 series and later (including 1000 series) have non-volatile SRAM, - * and do not save/restore SRAM when power cycling. - */ - ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, - (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | - CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); - if (unlikely(ret < 0)) { - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); - if (!silent) { - u32 val = iwl_read32(trans, CSR_GP_CNTRL); - WARN_ONCE(1, - "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", - val); - return false; - } - } - - return true; -} - -static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) -{ - lockdep_assert_held(&trans->reg_lock); - __iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - /* - * Above we read the CSR_GP_CNTRL register, which will flush - * any previous writes, but we need the write that clears the - * MAC_ACCESS_REQ bit to be performed before any other writes - * scheduled on different CPUs (after we drop reg_lock). - */ - mmiowb(); -} - -static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, - void *buf, int dwords) -{ - unsigned long flags; - int offs, ret = 0; - u32 *vals = buf; - - spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { - iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - for (offs = 0; offs < dwords; offs++) - vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - iwl_trans_release_nic_access(trans); - } else { - ret = -EBUSY; - } - spin_unlock_irqrestore(&trans->reg_lock, flags); - return ret; -} - -static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, - void *buf, int dwords) -{ - unsigned long flags; - int offs, ret = 0; - u32 *vals = buf; - - spin_lock_irqsave(&trans->reg_lock, flags); - if (iwl_trans_grab_nic_access(trans, false)) { - iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); - for (offs = 0; offs < dwords; offs++) - iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); - iwl_trans_release_nic_access(trans); - } else { - ret = -EBUSY; - } - spin_unlock_irqrestore(&trans->reg_lock, flags); - return ret; -} - #define IWL_FLUSH_WAIT_MS 2000 static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) @@ -1304,12 +1235,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { .read32 = iwl_trans_pcie_read32, .read_prph = iwl_trans_pcie_read_prph, .write_prph = iwl_trans_pcie_write_prph, - .read_mem = iwl_trans_pcie_read_mem, - .write_mem = iwl_trans_pcie_write_mem, .configure = iwl_trans_pcie_configure, .set_pmi = iwl_trans_pcie_set_pmi, - .grab_nic_access = iwl_trans_pcie_grab_nic_access, - .release_nic_access = iwl_trans_pcie_release_nic_access }; struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, @@ -1391,6 +1318,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } trans->dev = &pdev->dev; + trans_pcie->irq = pdev->irq; trans_pcie->pci_dev = pdev; trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; @@ -1416,27 +1344,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, if (!trans->dev_cmd_pool) goto out_pci_disable_msi; - trans_pcie->inta_mask = CSR_INI_SET_MASK; - - tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) - iwl_pcie_tasklet, (unsigned long)trans); - - if (iwl_pcie_alloc_ict(trans)) - goto out_free_cmd_pool; - - err = request_irq(pdev->irq, iwl_pcie_isr_ict, - IRQF_SHARED, DRV_NAME, trans); - if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq); - goto out_free_ict; - } - return trans; -out_free_ict: - iwl_pcie_free_ict(trans); -out_free_cmd_pool: - kmem_cache_destroy(trans->dev_cmd_pool); out_pci_disable_msi: pci_disable_msi(pdev); out_pci_release_regions: diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index d25fc8aaccc6..6c5b867c353a 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", txq->q.read_ptr, txq->q.write_ptr); - iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); + iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); iwl_print_hex_error(trans, buf, sizeof(buf)); @@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); u32 tbl_dw = - iwl_trans_read_mem32(trans, - trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE(i)); + iwl_read_targ_mem(trans, + trans_pcie->scd_base_addr + + SCD_TRANS_TBL_OFFSET_QUEUE(i)); if (i & 0x1) tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; @@ -237,10 +237,7 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, break; } - if (trans_pcie->bc_table_dword) - len = DIV_ROUND_UP(len, 4); - - bc_ent = cpu_to_le16(len | (sta_id << 12)); + bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; @@ -659,16 +656,16 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) /* reset conext data memory */ for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) - iwl_trans_write_mem32(trans, a, 0); + iwl_write_targ_mem(trans, a, 0); /* reset tx status memory */ for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) - iwl_trans_write_mem32(trans, a, 0); + iwl_write_targ_mem(trans, a, 0); for (; a < trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE( trans->cfg->base_params->num_of_queues); a += 4) - iwl_trans_write_mem32(trans, a, 0); + iwl_write_targ_mem(trans, a, 0); iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); @@ -1005,14 +1002,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr); + tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw); + iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); return 0; } @@ -1071,9 +1068,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); /* Set up Tx window size and frame limit for this queue */ - iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); - iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | @@ -1104,8 +1101,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) iwl_pcie_txq_set_inactive(trans, txq_id); - iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, - ARRAY_SIZE(zero_val)); + _iwl_write_targ_mem_dwords(trans, stts_addr, + zero_val, ARRAY_SIZE(zero_val)); iwl_pcie_txq_unmap(trans, txq_id); diff --git a/trunk/drivers/net/wireless/mwifiex/11n.c b/trunk/drivers/net/wireless/mwifiex/11n.c index 9cd6216c61e6..245a371f1a43 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n.c +++ b/trunk/drivers/net/wireless/mwifiex/11n.c @@ -53,9 +53,7 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, sizeof(sband->ht_cap.mcs)); if (priv->bss_mode == NL80211_IFTYPE_STATION || - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && - (priv->adapter->sec_chan_offset != - IEEE80211_HT_PARAM_CHA_SEC_NONE))) + sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); diff --git a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c index af8fe6352eed..68d52cfc1ebd 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c @@ -278,16 +278,14 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); break; case -1: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); return 0; case -EINPROGRESS: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; break; case 0: mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index c4edb28cce08..a875499f8945 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1327,7 +1327,6 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, } mwifiex_set_ht_params(priv, bss_cfg, params); - mwifiex_set_wmm_params(priv, bss_cfg, params); if (params->inactivity_timeout > 0) { /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */ @@ -2262,7 +2261,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | - WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; diff --git a/trunk/drivers/net/wireless/mwifiex/decl.h b/trunk/drivers/net/wireless/mwifiex/decl.h index e8a569aaa2e8..e9357d87d327 100644 --- a/trunk/drivers/net/wireless/mwifiex/decl.h +++ b/trunk/drivers/net/wireless/mwifiex/decl.h @@ -26,7 +26,6 @@ #include #include #include -#include #define MWIFIEX_MAX_BSS_NUM (3) @@ -59,8 +58,6 @@ #define MWIFIEX_RTS_MAX_VALUE (2347) #define MWIFIEX_FRAG_MIN_VALUE (256) #define MWIFIEX_FRAG_MAX_VALUE (2346) -#define MWIFIEX_WMM_VERSION 0x01 -#define MWIFIEX_WMM_SUBTYPE 0x01 #define MWIFIEX_RETRY_LIMIT 14 #define MWIFIEX_SDIO_BLOCK_SIZE 256 @@ -129,19 +126,4 @@ enum mwifiex_wmm_ac_e { WMM_AC_VI, WMM_AC_VO } __packed; - -struct ieee_types_wmm_ac_parameters { - u8 aci_aifsn_bitmap; - u8 ecw_bitmap; - __le16 tx_op_limit; -} __packed; - -struct mwifiex_types_wmm_info { - u8 oui[4]; - u8 subtype; - u8 version; - u8 qos_info; - u8 reserved; - struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS]; -} __packed; #endif /* !_MWIFIEX_DECL_H_ */ diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index 41c85dd78084..4dc8e2e9a889 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -1131,6 +1131,12 @@ struct ieee_types_vendor_header { u8 version; } __packed; +struct ieee_types_wmm_ac_parameters { + u8 aci_aifsn_bitmap; + u8 ecw_bitmap; + __le16 tx_op_limit; +} __packed; + struct ieee_types_wmm_parameter { /* * WMM Parameter IE - Vendor Specific Header: @@ -1180,11 +1186,6 @@ struct mwifiex_ie_types_htcap { struct ieee80211_ht_cap ht_cap; } __packed; -struct mwifiex_ie_types_wmmcap { - struct mwifiex_ie_types_header header; - struct mwifiex_types_wmm_info wmm_info; -} __packed; - struct mwifiex_ie_types_htinfo { struct mwifiex_ie_types_header header; struct ieee80211_ht_operation ht_oper; diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index e00b8060aff7..39f03ce5a5b1 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -591,12 +591,6 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter) return -1; } } - - if (adapter->if_ops.init_fw_port) { - if (adapter->if_ops.init_fw_port(adapter)) - return -1; - } - for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); diff --git a/trunk/drivers/net/wireless/mwifiex/ioctl.h b/trunk/drivers/net/wireless/mwifiex/ioctl.h index 6095b3e53f4e..4e31c6013ebe 100644 --- a/trunk/drivers/net/wireless/mwifiex/ioctl.h +++ b/trunk/drivers/net/wireless/mwifiex/ioctl.h @@ -20,6 +20,7 @@ #ifndef _MWIFIEX_IOCTL_H_ #define _MWIFIEX_IOCTL_H_ +#include #include enum { @@ -106,8 +107,6 @@ struct mwifiex_uap_bss_param { u8 rates[MWIFIEX_SUPPORTED_RATES]; u32 sta_ao_timer; u32 ps_sta_ao_timer; - u8 qos_info; - struct mwifiex_types_wmm_info wmm_info; }; enum { diff --git a/trunk/drivers/net/wireless/mwifiex/join.c b/trunk/drivers/net/wireless/mwifiex/join.c index 3c7cabeddf76..88664ae667ba 100644 --- a/trunk/drivers/net/wireless/mwifiex/join.c +++ b/trunk/drivers/net/wireless/mwifiex/join.c @@ -969,16 +969,6 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, priv->adapter->config_bands); mwifiex_fill_cap_info(priv, radio_type, ht_cap); - if (adapter->sec_chan_offset == - IEEE80211_HT_PARAM_CHA_SEC_NONE) { - u16 tmp_ht_cap; - - tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info); - tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40; - ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap); - } - pos += sizeof(struct mwifiex_ie_types_htcap); cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index 51044e3ea89b..1b3cfc821940 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -599,10 +599,8 @@ struct mwifiex_if_ops { int (*cmdrsp_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); - int (*init_fw_port) (struct mwifiex_adapter *); int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); void (*card_reset) (struct mwifiex_adapter *); - int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); }; struct mwifiex_adapter { @@ -892,10 +890,6 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params); void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_ap_settings *params); -void -mwifiex_set_wmm_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_cfg, - struct cfg80211_ap_settings *params); /* * This function checks if the queuing is RA based or not. diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.c b/trunk/drivers/net/wireless/mwifiex/pcie.c index 3da89b456c13..13fbc4eb1595 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.c +++ b/trunk/drivers/net/wireless/mwifiex/pcie.c @@ -39,20 +39,17 @@ static struct semaphore add_remove_card_sem; static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter); static int mwifiex_pcie_resume(struct pci_dev *pdev); -static int -mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, - int size, int flags) +/* + * This function is called after skb allocation to update + * "skb->cb" with physical address of data pointer. + */ +static phys_addr_t *mwifiex_update_sk_buff_pa(struct sk_buff *skb) { - struct pcie_service_card *card = adapter->card; - dma_addr_t buf_pa; + phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); - buf_pa = pci_map_single(card->dev, skb->data, size, flags); - if (pci_dma_mapping_error(card->dev, buf_pa)) { - dev_err(adapter->dev, "failed to map pci memory!\n"); - return -1; - } - memcpy(skb->cb, &buf_pa, sizeof(dma_addr_t)); - return 0; + *buf_pa = (phys_addr_t)virt_to_phys(skb->data); + + return buf_pa; } /* @@ -63,8 +60,8 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) u32 *cookie_addr; struct pcie_service_card *card = adapter->card; - if (card->sleep_cookie_vbase) { - cookie_addr = (u32 *)card->sleep_cookie_vbase; + if (card->sleep_cookie) { + cookie_addr = (u32 *)card->sleep_cookie->data; dev_dbg(adapter->dev, "info: ACCESS_HW: sleep cookie=0x%x\n", *cookie_addr); if (*cookie_addr == FW_AWAKE_COOKIE) @@ -369,7 +366,9 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + struct sk_buff *skb; int i; + phys_addr_t *buf_pa; /* * driver maintaines the write pointer and firmware maintaines the read @@ -385,18 +384,16 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", card->txbd_ring_size); - card->txbd_ring_vbase = pci_alloc_consistent(card->dev, - card->txbd_ring_size, - &card->txbd_ring_pbase); + card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); if (!card->txbd_ring_vbase) { - dev_err(adapter->dev, - "allocate consistent memory (%d bytes) failed!\n", - card->txbd_ring_size); + dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); return -ENOMEM; } + card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); + dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", - card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase, + card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { @@ -405,9 +402,24 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) (sizeof(struct mwifiex_pcie_buf_desc) * i)); - card->tx_buf_list[i] = NULL; - card->txbd_ring[i]->paddr = 0; - card->txbd_ring[i]->len = 0; + /* Allocate buffer here so that firmware can DMA data from it */ + skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); + if (!skb) { + dev_err(adapter->dev, "Unable to allocate skb for TX ring.\n"); + kfree(card->txbd_ring_vbase); + return -ENOMEM; + } + buf_pa = mwifiex_update_sk_buff_pa(skb); + + skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); + dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, + (u32)(((u64)*buf_pa >> 32)), skb->len); + + card->tx_buf_list[i] = skb; + card->txbd_ring[i]->paddr = *buf_pa; + card->txbd_ring[i]->len = (u16)skb->len; card->txbd_ring[i]->flags = 0; } @@ -417,16 +429,11 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - struct sk_buff *skb; int i; for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - if (card->tx_buf_list[i]) { - skb = card->tx_buf_list[i]; - pci_unmap_single(card->dev, card->txbd_ring[i]->paddr, - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb_any(skb); - } + if (card->tx_buf_list[i]) + dev_kfree_skb_any(card->tx_buf_list[i]); card->tx_buf_list[i] = NULL; card->txbd_ring[i]->paddr = 0; card->txbd_ring[i]->len = 0; @@ -434,15 +441,11 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) card->txbd_ring[i] = NULL; } - if (card->txbd_ring_vbase) - pci_free_consistent(card->dev, card->txbd_ring_size, - card->txbd_ring_vbase, - card->txbd_ring_pbase); + kfree(card->txbd_ring_vbase); card->txbd_ring_size = 0; card->txbd_wrptr = 0; card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; card->txbd_ring_vbase = NULL; - card->txbd_ring_pbase = 0; return 0; } @@ -455,7 +458,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; struct sk_buff *skb; int i; - dma_addr_t buf_pa; + phys_addr_t *buf_pa; /* * driver maintaines the read pointer and firmware maintaines the write @@ -469,15 +472,13 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", card->rxbd_ring_size); - card->rxbd_ring_vbase = pci_alloc_consistent(card->dev, - card->rxbd_ring_size, - &card->rxbd_ring_pbase); + card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); if (!card->rxbd_ring_vbase) { - dev_err(adapter->dev, - "allocate consistent memory (%d bytes) failed!\n", - card->rxbd_ring_size); + dev_err(adapter->dev, "Unable to allocate buffer for " + "rxbd_ring.\n"); return -ENOMEM; } + card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", @@ -499,20 +500,16 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) kfree(card->rxbd_ring_vbase); return -ENOMEM; } - if (mwifiex_map_pci_memory(adapter, skb, - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); + buf_pa = mwifiex_update_sk_buff_pa(skb); + skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", - skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), skb->len); card->rx_buf_list[i] = skb; - card->rxbd_ring[i]->paddr = buf_pa; + card->rxbd_ring[i]->paddr = *buf_pa; card->rxbd_ring[i]->len = (u16)skb->len; card->rxbd_ring[i]->flags = 0; } @@ -526,17 +523,11 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - struct sk_buff *skb; int i; for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - if (card->rx_buf_list[i]) { - skb = card->rx_buf_list[i]; - pci_unmap_single(card->dev, card->rxbd_ring[i]->paddr , - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(skb); - } + if (card->rx_buf_list[i]) + dev_kfree_skb_any(card->rx_buf_list[i]); card->rx_buf_list[i] = NULL; card->rxbd_ring[i]->paddr = 0; card->rxbd_ring[i]->len = 0; @@ -544,15 +535,11 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_ring[i] = NULL; } - if (card->rxbd_ring_vbase) - pci_free_consistent(card->dev, card->rxbd_ring_size, - card->rxbd_ring_vbase, - card->rxbd_ring_pbase); + kfree(card->rxbd_ring_vbase); card->rxbd_ring_size = 0; card->rxbd_wrptr = 0; card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; card->rxbd_ring_vbase = NULL; - card->rxbd_ring_pbase = 0; return 0; } @@ -565,7 +552,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; struct sk_buff *skb; int i; - dma_addr_t buf_pa; + phys_addr_t *buf_pa; /* * driver maintaines the read pointer and firmware maintaines the write @@ -579,15 +566,13 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) MWIFIEX_MAX_EVT_BD; dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", card->evtbd_ring_size); - card->evtbd_ring_vbase = pci_alloc_consistent(card->dev, - card->evtbd_ring_size, - &card->evtbd_ring_pbase); + card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); if (!card->evtbd_ring_vbase) { dev_err(adapter->dev, - "allocate consistent memory (%d bytes) failed!\n", - card->evtbd_ring_size); + "Unable to allocate buffer. Terminating download\n"); return -ENOMEM; } + card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", @@ -609,20 +594,16 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) kfree(card->evtbd_ring_vbase); return -ENOMEM; } + buf_pa = mwifiex_update_sk_buff_pa(skb); skb_put(skb, MAX_EVENT_SIZE); - if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", - skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), skb->len); card->evt_buf_list[i] = skb; - card->evtbd_ring[i]->paddr = buf_pa; + card->evtbd_ring[i]->paddr = *buf_pa; card->evtbd_ring[i]->len = (u16)skb->len; card->evtbd_ring[i]->flags = 0; } @@ -636,16 +617,11 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - struct sk_buff *skb; int i; for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { - if (card->evt_buf_list[i]) { - skb = card->evt_buf_list[i]; - pci_unmap_single(card->dev, card->evtbd_ring[i]->paddr, - MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(skb); - } + if (card->evt_buf_list[i]) + dev_kfree_skb_any(card->evt_buf_list[i]); card->evt_buf_list[i] = NULL; card->evtbd_ring[i]->paddr = 0; card->evtbd_ring[i]->len = 0; @@ -653,15 +629,11 @@ static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_ring[i] = NULL; } - if (card->evtbd_ring_vbase) - pci_free_consistent(card->dev, card->evtbd_ring_size, - card->evtbd_ring_vbase, - card->evtbd_ring_pbase); + kfree(card->evtbd_ring_vbase); card->evtbd_wrptr = 0; card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; card->evtbd_ring_size = 0; card->evtbd_ring_vbase = NULL; - card->evtbd_ring_pbase = 0; return 0; } @@ -681,13 +653,22 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) "Unable to allocate skb for command response data.\n"); return -ENOMEM; } + mwifiex_update_sk_buff_pa(skb); skb_put(skb, MWIFIEX_UPLD_SIZE); - if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - card->cmdrsp_buf = skb; + skb = NULL; + /* Allocate memory for sending command to firmware */ + skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); + if (!skb) { + dev_err(adapter->dev, + "Unable to allocate skb for command data.\n"); + return -ENOMEM; + } + mwifiex_update_sk_buff_pa(skb); + skb_put(skb, MWIFIEX_SIZE_OF_CMD_BUFFER); + card->cmd_buf = skb; + return 0; } @@ -697,26 +678,18 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card; - dma_addr_t buf_pa; if (!adapter) return 0; card = adapter->card; - if (card && card->cmdrsp_buf) { - MWIFIEX_SKB_PACB(card->cmdrsp_buf, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); + if (card && card->cmdrsp_buf) dev_kfree_skb_any(card->cmdrsp_buf); - } - if (card && card->cmd_buf) { - MWIFIEX_SKB_PACB(card->cmd_buf, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_SIZE_OF_CMD_BUFFER, - PCI_DMA_TODEVICE); + if (card && card->cmd_buf) dev_kfree_skb_any(card->cmd_buf); - } + return 0; } @@ -725,19 +698,27 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) */ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) { + struct sk_buff *skb; struct pcie_service_card *card = adapter->card; - card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32), - &card->sleep_cookie_pbase); - if (!card->sleep_cookie_vbase) { - dev_err(adapter->dev, "pci_alloc_consistent failed!\n"); + /* Allocate memory for sleep cookie */ + skb = dev_alloc_skb(sizeof(u32)); + if (!skb) { + dev_err(adapter->dev, + "Unable to allocate skb for sleep cookie!\n"); return -ENOMEM; } + mwifiex_update_sk_buff_pa(skb); + skb_put(skb, sizeof(u32)); + /* Init val of Sleep Cookie */ - *(u32 *)card->sleep_cookie_vbase = FW_AWAKE_COOKIE; + *(u32 *)skb->data = FW_AWAKE_COOKIE; dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", - *((u32 *)card->sleep_cookie_vbase)); + *((u32 *)skb->data)); + + /* Save the sleep cookie */ + card->sleep_cookie = skb; return 0; } @@ -754,57 +735,24 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter) card = adapter->card; - if (card && card->sleep_cookie_vbase) { - pci_free_consistent(card->dev, sizeof(u32), - card->sleep_cookie_vbase, - card->sleep_cookie_pbase); - card->sleep_cookie_vbase = NULL; + if (card && card->sleep_cookie) { + dev_kfree_skb_any(card->sleep_cookie); + card->sleep_cookie = NULL; } return 0; } -/* This function flushes the TX buffer descriptor ring - * This function defined as handler is also called while cleaning TXRX - * during disconnect/ bss stop. - */ -static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) -{ - struct pcie_service_card *card = adapter->card; - u32 rdptr; - - /* Read the TX ring read pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { - dev_err(adapter->dev, - "Flush TXBD: failed to read REG_TXBD_RDPTR\n"); - return -1; - } - - if (!mwifiex_pcie_txbd_empty(card, rdptr)) { - card->txbd_flush = 1; - /* write pointer already set at last send - * send dnld-rdy intr again, wait for completion. - */ - if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, - CPU_INTR_DNLD_RDY)) { - dev_err(adapter->dev, - "failed to assert dnld-rdy interrupt.\n"); - return -1; - } - } - return 0; -} - /* - * This function unmaps and frees downloaded data buffer + * This function sends data buffer to device */ -static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) +static int +mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD; - struct sk_buff *skb; - dma_addr_t buf_pa; - u32 wrdoneidx, rdptr, unmap_count = 0; struct pcie_service_card *card = adapter->card; + u32 wrindx, rdptr; + phys_addr_t *buf_pa; + __le16 *tmp; if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); @@ -812,112 +760,34 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) /* Read the TX ring read pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { dev_err(adapter->dev, - "SEND COMP: failed to read REG_TXBD_RDPTR\n"); - return -1; - } - - dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n", - card->txbd_rdptr, rdptr); - - /* free from previous txbd_rdptr to current txbd_rdptr */ - while (((card->txbd_rdptr & MWIFIEX_TXBD_MASK) != - (rdptr & MWIFIEX_TXBD_MASK)) || - ((card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { - wrdoneidx = card->txbd_rdptr & MWIFIEX_TXBD_MASK; - - skb = card->tx_buf_list[wrdoneidx]; - if (skb) { - dev_dbg(adapter->dev, - "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", - skb, wrdoneidx); - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); - - unmap_count++; - - if (card->txbd_flush) - mwifiex_write_data_complete(adapter, skb, 0, - -1); - else - mwifiex_write_data_complete(adapter, skb, 0, 0); - } - - card->tx_buf_list[wrdoneidx] = NULL; - card->txbd_ring[wrdoneidx]->paddr = 0; - card->rxbd_ring[wrdoneidx]->len = 0; - card->rxbd_ring[wrdoneidx]->flags = 0; - card->txbd_rdptr++; - - if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs) - card->txbd_rdptr = ((card->txbd_rdptr & - MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ - MWIFIEX_BD_FLAG_ROLLOVER_IND); - } - - if (unmap_count) - adapter->data_sent = false; - - if (card->txbd_flush) { - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == - (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) && - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) - card->txbd_flush = 0; - else - mwifiex_clean_pcie_ring_buf(adapter); - } - - return 0; -} - -/* This function sends data buffer to device. First 4 bytes of payload - * are filled with payload length and payload type. Then this payload - * is mapped to PCI device memory. Tx ring pointers are advanced accordingly. - * Download ready interrupt to FW is deffered if Tx ring is not full and - * additional payload can be accomodated. - */ -static int -mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, - struct mwifiex_tx_param *tx_param) -{ - struct pcie_service_card *card = adapter->card; - u32 wrindx; - int ret; - dma_addr_t buf_pa; - __le16 *tmp; - - if (!(skb->data && skb->len)) { - dev_err(adapter->dev, "%s(): invalid parameter <%p, %#x>\n", - __func__, skb->data, skb->len); + "SEND DATA: failed to read REG_TXBD_RDPTR\n"); return -1; } - if (!mwifiex_pcie_ok_to_access_hw(adapter)) - mwifiex_pm_wakeup_card(adapter); + wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; - dev_dbg(adapter->dev, "info: SEND DATA: \n", - card->txbd_rdptr, card->txbd_wrptr); - if (mwifiex_pcie_txbd_not_full(card)) { + dev_dbg(adapter->dev, "info: SEND DATA: \n", rdptr, + card->txbd_wrptr); + if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != + (rdptr & MWIFIEX_TXBD_MASK)) || + ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != + (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { + struct sk_buff *skb_data; u8 *payload; adapter->data_sent = true; - payload = skb->data; + skb_data = card->tx_buf_list[wrindx]; + memcpy(skb_data->data, skb->data, skb->len); + payload = skb_data->data; tmp = (__le16 *)&payload[0]; *tmp = cpu_to_le16((u16)skb->len); tmp = (__le16 *)&payload[2]; *tmp = cpu_to_le16(MWIFIEX_TYPE_DATA); - - if (mwifiex_map_pci_memory(adapter, skb, skb->len , - PCI_DMA_TODEVICE)) - return -1; - - wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; - MWIFIEX_SKB_PACB(skb, &buf_pa); - card->tx_buf_list[wrindx] = skb; - card->txbd_ring[wrindx]->paddr = buf_pa; - card->txbd_ring[wrindx]->len = (u16)skb->len; + skb_put(skb_data, MWIFIEX_RX_DATA_BUF_SIZE - skb_data->len); + skb_trim(skb_data, skb->len); + buf_pa = MWIFIEX_SKB_PACB(skb_data); + card->txbd_ring[wrindx]->paddr = *buf_pa; + card->txbd_ring[wrindx]->len = (u16)skb_data->len; card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC | MWIFIEX_BD_FLAG_LAST_DESC; @@ -932,28 +802,19 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, card->txbd_wrptr)) { dev_err(adapter->dev, "SEND DATA: failed to write REG_TXBD_WRPTR\n"); - ret = -1; - goto done_unmap; + return 0; } - if ((mwifiex_pcie_txbd_not_full(card)) && - tx_param->next_pkt_len) { - /* have more packets and TxBD still can hold more */ - dev_dbg(adapter->dev, - "SEND DATA: delay dnld-rdy interrupt.\n"); - adapter->data_sent = false; - } else { - /* Send the TX ready interrupt */ - if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, - CPU_INTR_DNLD_RDY)) { - dev_err(adapter->dev, - "SEND DATA: failed to assert dnld-rdy interrupt.\n"); - ret = -1; - goto done_unmap; - } + + /* Send the TX ready interrupt */ + if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, + CPU_INTR_DNLD_RDY)) { + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); + return -1; } dev_dbg(adapter->dev, "info: SEND DATA: Updated and sent packet to firmware successfully\n", - card->txbd_rdptr, card->txbd_wrptr); + rdptr, card->txbd_wrptr); } else { dev_dbg(adapter->dev, "info: TX Ring full, can't send packets to fw\n"); @@ -966,15 +827,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, return -EBUSY; } - return -EINPROGRESS; -done_unmap: - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); - card->tx_buf_list[wrindx] = NULL; - card->txbd_ring[wrindx]->paddr = 0; - card->txbd_ring[wrindx]->len = 0; - card->txbd_ring[wrindx]->flags = 0; - return ret; + return 0; } /* @@ -985,13 +838,9 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; u32 wrptr, rd_index; - dma_addr_t buf_pa; int ret = 0; struct sk_buff *skb_tmp = NULL; - if (!mwifiex_pcie_ok_to_access_hw(adapter)) - mwifiex_pm_wakeup_card(adapter); - /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { dev_err(adapter->dev, @@ -999,7 +848,6 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) ret = -1; goto done; } - card->rxbd_wrptr = wrptr; while (((wrptr & MWIFIEX_RXBD_MASK) != (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) || @@ -1007,50 +855,27 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { struct sk_buff *skb_data; u16 rx_len; - __le16 pkt_len; rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK; skb_data = card->rx_buf_list[rd_index]; - MWIFIEX_SKB_PACB(skb_data, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE); - card->rx_buf_list[rd_index] = NULL; - /* Get data length from interface header - - * first 2 bytes for len, next 2 bytes is for type - */ - pkt_len = *((__le16 *)skb_data->data); - rx_len = le16_to_cpu(pkt_len); - skb_put(skb_data, rx_len); + first byte is len, second byte is type */ + rx_len = *((u16 *)skb_data->data); dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); - skb_pull(skb_data, INTF_HEADER_LEN); - mwifiex_handle_rx_packet(adapter, skb_data); - - skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); + skb_tmp = dev_alloc_skb(rx_len); if (!skb_tmp) { - dev_err(adapter->dev, - "Unable to allocate skb.\n"); - return -ENOMEM; + dev_dbg(adapter->dev, + "info: Failed to alloc skb for RX\n"); + ret = -EBUSY; + goto done; } - if (mwifiex_map_pci_memory(adapter, skb_tmp, - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); - - dev_dbg(adapter->dev, - "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", - skb_tmp, rd_index); - card->rx_buf_list[rd_index] = skb_tmp; - card->rxbd_ring[rd_index]->paddr = buf_pa; - card->rxbd_ring[rd_index]->len = skb_tmp->len; - card->rxbd_ring[rd_index]->flags = 0; + skb_put(skb_tmp, rx_len); + memcpy(skb_tmp->data, skb_data->data + INTF_HEADER_LEN, rx_len); if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) == MWIFIEX_MAX_TXRX_BD) { card->rxbd_rdptr = ((card->rxbd_rdptr & @@ -1078,10 +903,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) } dev_dbg(adapter->dev, "info: RECV DATA: Rcvd packet from fw successfully\n"); - card->rxbd_wrptr = wrptr; + mwifiex_handle_rx_packet(adapter, skb_tmp); } done: + if (ret && skb_tmp) + dev_kfree_skb_any(skb_tmp); return ret; } @@ -1091,41 +918,32 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) static int mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - dma_addr_t buf_pa; - struct pcie_service_card *card = adapter->card; + phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); - if (!(skb->data && skb->len)) { + if (!(skb->data && skb->len && *buf_pa)) { dev_err(adapter->dev, - "Invalid parameter in %s <%p. len %d>\n", - __func__, skb->data, skb->len); + "Invalid parameter in %s <%p, %#x:%x, %x>\n", + __func__, skb->data, skb->len, + (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); return -1; } - if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); - /* Write the lower 32bits of the physical address to scratch * register 0 */ - if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)buf_pa)) { + if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); return -1; } /* Write the upper 32bits of the physical address to scratch * register 1 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, - (u32)((u64)buf_pa >> 32))) { + (u32)((u64)*buf_pa >> 32))) { dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); return -1; } @@ -1134,8 +952,6 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) dev_err(adapter->dev, "%s: failed to write command len to scratch reg 2\n", __func__); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_TODEVICE); return -1; } @@ -1144,39 +960,22 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) CPU_INTR_DOOR_BELL)) { dev_err(adapter->dev, "%s: failed to assert door-bell intr\n", __func__); - pci_unmap_single(card->dev, buf_pa, - MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE); return -1; } return 0; } -/* This function init rx port in firmware which in turn enables to receive data - * from device before transmitting any packet. - */ -static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) -{ - struct pcie_service_card *card = adapter->card; - - /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ - if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr | 0)) { - dev_err(adapter->dev, - "RECV DATA: failed to write REG_RXBD_RDPTR\n"); - return -1; - } - return 0; -} - -/* This function downloads commands to the device +/* + * This function downloads commands to the device */ static int mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; int ret = 0; - dma_addr_t cmd_buf_pa, cmdrsp_buf_pa; - u8 *payload = (u8 *)skb->data; + phys_addr_t *cmd_buf_pa; + phys_addr_t *cmdrsp_buf_pa; if (!(skb->data && skb->len)) { dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", @@ -1191,18 +990,17 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -EBUSY; } - if (!mwifiex_pcie_ok_to_access_hw(adapter)) - mwifiex_pm_wakeup_card(adapter); + /* Make sure a command buffer is available */ + if (!card->cmd_buf) { + dev_err(adapter->dev, "Command buffer not available\n"); + return -EBUSY; + } adapter->cmd_sent = true; - - *(__le16 *)&payload[0] = cpu_to_le16((u16)skb->len); - *(__le16 *)&payload[2] = cpu_to_le16(MWIFIEX_TYPE_CMD); - - if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE)) - return -1; - - card->cmd_buf = skb; + /* Copy the given skb in to DMA accessable shared buffer */ + skb_put(card->cmd_buf, MWIFIEX_SIZE_OF_CMD_BUFFER - card->cmd_buf->len); + skb_trim(card->cmd_buf, skb->len); + memcpy(card->cmd_buf->data, skb->data, skb->len); /* To send a command, the driver will: 1. Write the 64bit physical address of the data buffer to @@ -1215,11 +1013,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) */ if (card->cmdrsp_buf) { - MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); + cmdrsp_buf_pa = MWIFIEX_SKB_PACB(card->cmdrsp_buf); /* Write the lower 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, - (u32)cmdrsp_buf_pa)) { + (u32)*cmdrsp_buf_pa)) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); ret = -1; @@ -1228,7 +1026,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, - (u32)((u64)cmdrsp_buf_pa >> 32))) { + (u32)((u64)*cmdrsp_buf_pa >> 32))) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); ret = -1; @@ -1236,9 +1034,9 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) } } - MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); + cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)cmd_buf_pa)) { + if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); ret = -1; @@ -1246,7 +1044,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) } /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, - (u32)((u64)cmd_buf_pa >> 32))) { + (u32)((u64)*cmd_buf_pa >> 32))) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); ret = -1; @@ -1285,22 +1083,11 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; struct sk_buff *skb = card->cmdrsp_buf; int count = 0; - u16 rx_len; - __le16 pkt_len; - dma_addr_t buf_pa; dev_dbg(adapter->dev, "info: Rx CMD Response\n"); - MWIFIEX_SKB_PACB(skb, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); - - pkt_len = *((__le16 *)skb->data); - rx_len = le16_to_cpu(pkt_len); - skb_trim(skb, rx_len); - skb_pull(skb, INTF_HEADER_LEN); - if (!adapter->curr_cmd) { + skb_pull(skb, INTF_HEADER_LEN); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp(adapter, skb->data, skb->len); @@ -1313,12 +1100,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) } memcpy(adapter->upld_buf, skb->data, min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); - if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); + skb_push(skb, INTF_HEADER_LEN); } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { + skb_pull(skb, INTF_HEADER_LEN); adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; /* Take the pointer and set it to CMD node and will @@ -1352,23 +1136,10 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; - dma_addr_t buf_pa; - struct sk_buff *skb_tmp; if (skb) { card->cmdrsp_buf = skb; skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); - if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - } - - skb_tmp = card->cmd_buf; - if (skb_tmp) { - MWIFIEX_SKB_PACB(skb_tmp, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); - card->cmd_buf = NULL; } return 0; @@ -1382,10 +1153,6 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr, event; - dma_addr_t buf_pa; - - if (!mwifiex_pcie_ok_to_access_hw(adapter)) - mwifiex_pm_wakeup_card(adapter); if (adapter->event_received) { dev_dbg(adapter->dev, "info: Event being processed, " @@ -1417,10 +1184,6 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "info: Read Index: %d\n", rdptr); skb_cmd = card->evt_buf_list[rdptr]; - MWIFIEX_SKB_PACB(skb_cmd, &buf_pa); - pci_unmap_single(card->dev, buf_pa, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE); - /* Take the pointer and set it to event pointer in adapter and will return back after event handling callback */ card->evt_buf_list[rdptr] = NULL; @@ -1465,7 +1228,7 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, int ret = 0; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr; - dma_addr_t buf_pa; + phys_addr_t *buf_pa; if (!skb) return 0; @@ -1485,14 +1248,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, if (!card->evt_buf_list[rdptr]) { skb_push(skb, INTF_HEADER_LEN); - if (mwifiex_map_pci_memory(adapter, skb, - MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - MWIFIEX_SKB_PACB(skb, &buf_pa); card->evt_buf_list[rdptr] = skb; - MWIFIEX_SKB_PACB(skb, &buf_pa); - card->evtbd_ring[rdptr]->paddr = buf_pa; + buf_pa = MWIFIEX_SKB_PACB(skb); + card->evtbd_ring[rdptr]->paddr = *buf_pa; card->evtbd_ring[rdptr]->len = (u16)skb->len; card->evtbd_ring[rdptr]->flags = 0; skb = NULL; @@ -1541,8 +1299,11 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, struct sk_buff *skb; u32 txlen, tx_blocks = 0, tries, len; u32 block_retry_cnt = 0; - dma_addr_t buf_pa; - struct pcie_service_card *card = adapter->card; + + if (!adapter) { + pr_err("adapter structure is not valid\n"); + return -1; + } if (!firmware || !firmware_len) { dev_err(adapter->dev, @@ -1564,6 +1325,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = -ENOMEM; goto done; } + mwifiex_update_sk_buff_pa(skb); /* Perform firmware data transfer */ do { @@ -1638,9 +1400,6 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = -1; goto done; } - - MWIFIEX_SKB_PACB(skb, &buf_pa); - /* Wait for the command done interrupt */ do { if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, @@ -1648,17 +1407,11 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_err(adapter->dev, "%s: Failed to read " "interrupt status during fw dnld.\n", __func__); - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); ret = -1; goto done; } } while ((ireg_intr & CPU_INTR_DOOR_BELL) == CPU_INTR_DOOR_BELL); - - pci_unmap_single(card->dev, buf_pa, skb->len, - PCI_DMA_TODEVICE); - offset += txlen; } while (true); @@ -1841,40 +1594,39 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) { int ret; - u32 pcie_ireg; + u32 pcie_ireg = 0; unsigned long flags; spin_lock_irqsave(&adapter->int_lock, flags); /* Clear out unused interrupts */ - pcie_ireg = adapter->int_status; - adapter->int_status = 0; + adapter->int_status &= HOST_INTR_MASK; spin_unlock_irqrestore(&adapter->int_lock, flags); - while (pcie_ireg & HOST_INTR_MASK) { - if (pcie_ireg & HOST_INTR_DNLD_DONE) { - pcie_ireg &= ~HOST_INTR_DNLD_DONE; - dev_dbg(adapter->dev, "info: TX DNLD Done\n"); - ret = mwifiex_pcie_send_data_complete(adapter); - if (ret) - return ret; + while (adapter->int_status & HOST_INTR_MASK) { + if (adapter->int_status & HOST_INTR_DNLD_DONE) { + adapter->int_status &= ~HOST_INTR_DNLD_DONE; + if (adapter->data_sent) { + dev_dbg(adapter->dev, "info: DATA sent intr\n"); + adapter->data_sent = false; + } } - if (pcie_ireg & HOST_INTR_UPLD_RDY) { - pcie_ireg &= ~HOST_INTR_UPLD_RDY; + if (adapter->int_status & HOST_INTR_UPLD_RDY) { + adapter->int_status &= ~HOST_INTR_UPLD_RDY; dev_dbg(adapter->dev, "info: Rx DATA\n"); ret = mwifiex_pcie_process_recv_data(adapter); if (ret) return ret; } - if (pcie_ireg & HOST_INTR_EVENT_RDY) { - pcie_ireg &= ~HOST_INTR_EVENT_RDY; + if (adapter->int_status & HOST_INTR_EVENT_RDY) { + adapter->int_status &= ~HOST_INTR_EVENT_RDY; dev_dbg(adapter->dev, "info: Rx EVENT\n"); ret = mwifiex_pcie_process_event_ready(adapter); if (ret) return ret; } - if (pcie_ireg & HOST_INTR_CMD_DONE) { - pcie_ireg &= ~HOST_INTR_CMD_DONE; + if (adapter->int_status & HOST_INTR_CMD_DONE) { + adapter->int_status &= ~HOST_INTR_CMD_DONE; if (adapter->cmd_sent) { dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); @@ -1902,6 +1654,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) "Write register failed\n"); return -1; } + adapter->int_status |= pcie_ireg; + adapter->int_status &= HOST_INTR_MASK; } } @@ -1933,7 +1687,7 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type, } if (type == MWIFIEX_TYPE_DATA) - return mwifiex_pcie_send_data(adapter, skb, tx_param); + return mwifiex_pcie_send_data(adapter, skb); else if (type == MWIFIEX_TYPE_CMD) return mwifiex_pcie_send_cmd(adapter, skb); @@ -2060,8 +1814,15 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; struct pci_dev *pdev = card->dev; + mwifiex_pcie_delete_sleep_cookie_buf(adapter); + mwifiex_pcie_delete_cmdrsp_buf(adapter); + mwifiex_pcie_delete_evtbd_ring(adapter); + mwifiex_pcie_delete_rxbd_ring(adapter); + mwifiex_pcie_delete_txbd_ring(adapter); + card->cmdrsp_buf = NULL; + + dev_dbg(adapter->dev, "Clearing driver ready signature\n"); if (user_rmmod) { - dev_dbg(adapter->dev, "Clearing driver ready signature\n"); if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); @@ -2118,13 +1879,6 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) if (card) { dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__); free_irq(card->dev->irq, card->dev); - - mwifiex_pcie_delete_sleep_cookie_buf(adapter); - mwifiex_pcie_delete_cmdrsp_buf(adapter); - mwifiex_pcie_delete_evtbd_ring(adapter); - mwifiex_pcie_delete_rxbd_ring(adapter); - mwifiex_pcie_delete_txbd_ring(adapter); - card->cmdrsp_buf = NULL; } } @@ -2146,8 +1900,6 @@ static struct mwifiex_if_ops pcie_ops = { .event_complete = mwifiex_pcie_event_complete, .update_mp_end_port = NULL, .cleanup_mpa_buf = NULL, - .init_fw_port = mwifiex_pcie_init_fw_port, - .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, }; /* diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.h b/trunk/drivers/net/wireless/mwifiex/pcie.h index 37eeb2ca6b29..2f218f9a3fd3 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.h +++ b/trunk/drivers/net/wireless/mwifiex/pcie.h @@ -114,12 +114,11 @@ struct pcie_service_card { struct pci_dev *dev; struct mwifiex_adapter *adapter; - u8 txbd_flush; u32 txbd_wrptr; u32 txbd_rdptr; u32 txbd_ring_size; u8 *txbd_ring_vbase; - dma_addr_t txbd_ring_pbase; + phys_addr_t txbd_ring_pbase; struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD]; struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD]; @@ -127,7 +126,7 @@ struct pcie_service_card { u32 rxbd_rdptr; u32 rxbd_ring_size; u8 *rxbd_ring_vbase; - dma_addr_t rxbd_ring_pbase; + phys_addr_t rxbd_ring_pbase; struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD]; struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD]; @@ -135,39 +134,15 @@ struct pcie_service_card { u32 evtbd_rdptr; u32 evtbd_ring_size; u8 *evtbd_ring_vbase; - dma_addr_t evtbd_ring_pbase; + phys_addr_t evtbd_ring_pbase; struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD]; struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD]; struct sk_buff *cmd_buf; struct sk_buff *cmdrsp_buf; - u8 *sleep_cookie_vbase; - dma_addr_t sleep_cookie_pbase; + struct sk_buff *sleep_cookie; void __iomem *pci_mmap; void __iomem *pci_mmap1; }; -static inline int -mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) -{ - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == - (rdptr & MWIFIEX_TXBD_MASK)) && - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) - return 1; - - return 0; -} - -static inline int -mwifiex_pcie_txbd_not_full(struct pcie_service_card *card) -{ - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != - (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) || - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) - return 1; - - return 0; -} #endif /* _MWIFIEX_PCIE_H */ diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c index c4607859d59d..5d87195390f8 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c @@ -931,6 +931,7 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, struct host_cmd_ds_pcie_details *host_spec = &cmd->params.pcie_host_spec; struct pcie_service_card *card = priv->adapter->card; + phys_addr_t *buf_pa; cmd->command = cpu_to_le16(HostCmd_CMD_PCIE_DESC_DETAILS); cmd->size = cpu_to_le16(sizeof(struct @@ -952,11 +953,10 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; - if (card->sleep_cookie_vbase) { - host_spec->sleep_cookie_addr_lo = - (u32)(card->sleep_cookie_pbase); - host_spec->sleep_cookie_addr_hi = - (u32)(((u64)(card->sleep_cookie_pbase)) >> 32); + if (card->sleep_cookie) { + buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); + host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; + host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", host_spec->sleep_cookie_addr_lo); } diff --git a/trunk/drivers/net/wireless/mwifiex/txrx.c b/trunk/drivers/net/wireless/mwifiex/txrx.c index 296faec14365..8c80024c30ff 100644 --- a/trunk/drivers/net/wireless/mwifiex/txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/txrx.c @@ -117,16 +117,14 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, dev_dbg(adapter->dev, "data: -EBUSY is returned\n"); break; case -1: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, 0, ret); break; case -EINPROGRESS: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; break; case 0: mwifiex_write_data_complete(adapter, skb, 0, ret); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c index 6e76a15a8950..8dd72240f162 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c @@ -219,7 +219,6 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) config->rts_threshold = 0x7FFF; config->frag_threshold = 0x7FFF; config->retry_limit = 0x7F; - config->qos_info = 0xFF; } /* This function parses BSS related parameters from structure @@ -298,38 +297,6 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) return; } -/* This function parses WMM related parameters from cfg80211_ap_settings - * structure and updates bss_config structure. - */ -void -mwifiex_set_wmm_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_cfg, - struct cfg80211_ap_settings *params) -{ - const u8 *vendor_ie; - struct ieee_types_header *wmm_ie; - u8 wmm_oui[] = {0x00, 0x50, 0xf2, 0x02}; - - vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, - WLAN_OUI_TYPE_MICROSOFT_WMM, - params->beacon.tail, - params->beacon.tail_len); - if (vendor_ie) { - wmm_ie = (struct ieee_types_header *)vendor_ie; - memcpy(&bss_cfg->wmm_info, wmm_ie + 1, - sizeof(bss_cfg->wmm_info)); - priv->wmm_enabled = 1; - } else { - memset(&bss_cfg->wmm_info, 0, sizeof(bss_cfg->wmm_info)); - memcpy(&bss_cfg->wmm_info.oui, wmm_oui, sizeof(wmm_oui)); - bss_cfg->wmm_info.subtype = MWIFIEX_WMM_SUBTYPE; - bss_cfg->wmm_info.version = MWIFIEX_WMM_VERSION; - priv->wmm_enabled = 0; - } - - bss_cfg->qos_info = 0x00; - return; -} /* This function parses BSS related parameters from structure * and prepares TLVs specific to WEP encryption. * These TLVs are appended to command buffer. @@ -387,7 +354,6 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_rates *tlv_rates; struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; struct mwifiex_ie_types_htcap *htcap; - struct mwifiex_ie_types_wmmcap *wmm_cap; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; int i; u16 cmd_size = *param_size; @@ -541,16 +507,6 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(struct mwifiex_ie_types_htcap); } - if (bss_cfg->wmm_info.qos_info != 0xFF) { - wmm_cap = (struct mwifiex_ie_types_wmmcap *)tlv; - wmm_cap->header.type = cpu_to_le16(WLAN_EID_VENDOR_SPECIFIC); - wmm_cap->header.len = cpu_to_le16(sizeof(wmm_cap->wmm_info)); - memcpy(&wmm_cap->wmm_info, &bss_cfg->wmm_info, - sizeof(wmm_cap->wmm_info)); - cmd_size += sizeof(struct mwifiex_ie_types_wmmcap); - tlv += sizeof(struct mwifiex_ie_types_wmmcap); - } - if (bss_cfg->sta_ao_timer) { ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv; ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER); diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index 5d4a10a8a005..63ac9f2d11ae 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -786,6 +786,21 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) return 0; } +/* This function reads one block of firmware data. */ +static int mwifiex_get_fw_data(struct mwifiex_adapter *adapter, + u32 offset, u32 len, u8 *buf) +{ + if (!buf || !len) + return -1; + + if (offset + len > adapter->firmware->size) + return -1; + + memcpy(buf, adapter->firmware->data + offset, len); + + return 0; +} + static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, struct mwifiex_fw_image *fw) { @@ -821,14 +836,23 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dlen = 0; } else { /* copy the header of the fw_data to get the length */ - memcpy(&fwdata->fw_hdr, &firmware[tlen], - sizeof(struct fw_header)); + if (firmware) + memcpy(&fwdata->fw_hdr, &firmware[tlen], + sizeof(struct fw_header)); + else + mwifiex_get_fw_data(adapter, tlen, + sizeof(struct fw_header), + (u8 *)&fwdata->fw_hdr); dlen = le32_to_cpu(fwdata->fw_hdr.data_len); dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd); tlen += sizeof(struct fw_header); - memcpy(fwdata->data, &firmware[tlen], dlen); + if (firmware) + memcpy(fwdata->data, &firmware[tlen], dlen); + else + mwifiex_get_fw_data(adapter, tlen, dlen, + (u8 *)fwdata->data); fwdata->seq_num = cpu_to_le32(fw_seqnum); tlen += dlen; diff --git a/trunk/drivers/net/wireless/mwifiex/util.h b/trunk/drivers/net/wireless/mwifiex/util.h index cb2d0582bd36..f6d36b9654a0 100644 --- a/trunk/drivers/net/wireless/mwifiex/util.h +++ b/trunk/drivers/net/wireless/mwifiex/util.h @@ -22,16 +22,16 @@ static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) { - return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t)); + return (struct mwifiex_rxinfo *)(skb->cb + sizeof(phys_addr_t)); } static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) { - return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t)); + return (struct mwifiex_txinfo *)(skb->cb + sizeof(phys_addr_t)); } -static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, dma_addr_t *buf_pa) +static inline phys_addr_t *MWIFIEX_SKB_PACB(struct sk_buff *skb) { - memcpy(buf_pa, skb->cb, sizeof(dma_addr_t)); + return (phys_addr_t *)skb->cb; } #endif /* !_MWIFIEX_UTIL_H_ */ diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 135d96df2063..818f871ae987 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -568,8 +568,6 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) mwifiex_wmm_delete_all_ralist(priv); memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); - if (priv->adapter->if_ops.clean_pcie_ring) - priv->adapter->if_ops.clean_pcie_ring(priv->adapter); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -1208,15 +1206,13 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, ra_list_flags); break; case -1: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, 0, ret); break; case -EINPROGRESS: - if (adapter->iface_type != MWIFIEX_PCIE) - adapter->data_sent = false; + adapter->data_sent = false; default: break; } diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index c4d287b48e64..19b46fdf9f0f 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -101,18 +101,6 @@ MODULE_PARM_DESC(ap_mode_default, #define MWL8K_MAX_TX_QUEUES (MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES) #define mwl8k_tx_queues(priv) (MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues) -/* txpriorities are mapped with hw queues. - * Each hw queue has a txpriority. - */ -#define TOTAL_HW_TX_QUEUES 8 - -/* Each HW queue can have one AMPDU stream. - * But, because one of the hw queue is reserved, - * maximum AMPDU queues that can be created are - * one short of total tx queues. - */ -#define MWL8K_NUM_AMPDU_STREAMS (TOTAL_HW_TX_QUEUES - 1) - struct rxd_ops { int rxd_size; void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr); @@ -172,6 +160,7 @@ struct mwl8k_ampdu_stream { u8 tid; u8 state; u8 idx; + u8 txq_idx; /* index of this stream in priv->txq */ }; struct mwl8k_priv { @@ -213,8 +202,6 @@ struct mwl8k_priv { int fw_mutex_depth; struct completion *hostcmd_wait; - atomic_t watchdog_event_pending; - /* lock held over TX and TX reap */ spinlock_t tx_lock; @@ -1529,9 +1516,6 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) return -EBUSY; } - if (atomic_read(&priv->watchdog_event_pending)) - return 0; - /* * The TX queues are stopped at this point, so this test * doesn't need to take ->tx_lock. @@ -1553,14 +1537,6 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) spin_unlock_bh(&priv->tx_lock); timeout = wait_for_completion_timeout(&tx_wait, msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS)); - - if (atomic_read(&priv->watchdog_event_pending)) { - spin_lock_bh(&priv->tx_lock); - priv->tx_wait = NULL; - spin_unlock_bh(&priv->tx_lock); - return 0; - } - spin_lock_bh(&priv->tx_lock); if (timeout) { @@ -1758,13 +1734,14 @@ mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid) struct mwl8k_priv *priv = hw->priv; int i; - for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) { + for (i = 0; i < priv->num_ampdu_queues; i++) { stream = &priv->ampdu[i]; if (stream->state == AMPDU_NO_STREAM) { stream->sta = sta; stream->state = AMPDU_STREAM_NEW; stream->tid = tid; stream->idx = i; + stream->txq_idx = MWL8K_TX_WMM_QUEUES + i; wiphy_debug(hw->wiphy, "Added a new stream for %pM %d", sta->addr, tid); return stream; @@ -1805,7 +1782,7 @@ mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid) struct mwl8k_priv *priv = hw->priv; int i; - for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) { + for (i = 0 ; i < priv->num_ampdu_queues; i++) { struct mwl8k_ampdu_stream *stream; stream = &priv->ampdu[i]; if (stream->state == AMPDU_NO_STREAM) @@ -1852,13 +1829,6 @@ static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) tx_stats->pkts++; } -/* The hardware ampdu queues start from 5. - * txpriorities for ampdu queues are - * 5 6 7 0 1 2 3 4 ie., queue 5 is highest - * and queue 3 is lowest (queue 4 is reserved) - */ -#define BA_QUEUE 5 - static void mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, @@ -1958,13 +1928,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, stream = mwl8k_lookup_stream(hw, sta->addr, tid); if (stream != NULL) { if (stream->state == AMPDU_STREAM_ACTIVE) { - WARN_ON(!(qos & MWL8K_QOS_ACK_POLICY_BLOCKACK)); - txpriority = (BA_QUEUE + stream->idx) % - TOTAL_HW_TX_QUEUES; - if (stream->idx <= 1) - index = stream->idx + - MWL8K_TX_WMM_QUEUES; - + txpriority = stream->txq_idx; + index = stream->txq_idx; } else if (stream->state == AMPDU_STREAM_NEW) { /* We get here if the driver sends us packets * after we've initiated a stream, but before @@ -2006,9 +1971,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, } } spin_unlock(&priv->stream_lock); - } else { - qos &= ~MWL8K_QOS_ACK_POLICY_MASK; - qos |= MWL8K_QOS_ACK_POLICY_NORMAL; } dma = pci_map_single(priv->pdev, skb->data, @@ -3616,11 +3578,7 @@ static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap) return rc; } -#define MWL8K_WMM_QUEUE_NUMBER 3 - -static void mwl8k_destroy_ba(struct ieee80211_hw *hw, - u8 idx); - +#define INVALID_BA 0xAA static void mwl8k_watchdog_ba_events(struct work_struct *work) { int rc; @@ -3628,41 +3586,24 @@ static void mwl8k_watchdog_ba_events(struct work_struct *work) struct mwl8k_ampdu_stream *streams; struct mwl8k_priv *priv = container_of(work, struct mwl8k_priv, watchdog_ba_handle); - struct ieee80211_hw *hw = priv->hw; - int i; - u32 status = 0; - - mwl8k_fw_lock(hw); rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap); if (rc) - goto done; + return; - spin_lock(&priv->stream_lock); + if (bitmap == INVALID_BA) + return; /* the bitmap is the hw queue number. Map it to the ampdu queue. */ - for (i = 0; i < TOTAL_HW_TX_QUEUES; i++) { - if (bitmap & (1 << i)) { - stream_index = (i + MWL8K_WMM_QUEUE_NUMBER) % - TOTAL_HW_TX_QUEUES; - streams = &priv->ampdu[stream_index]; - if (streams->state == AMPDU_STREAM_ACTIVE) { - ieee80211_stop_tx_ba_session(streams->sta, - streams->tid); - spin_unlock(&priv->stream_lock); - mwl8k_destroy_ba(hw, stream_index); - spin_lock(&priv->stream_lock); - } - } - } + stream_index = bitmap - MWL8K_TX_WMM_QUEUES; + + BUG_ON(stream_index >= priv->num_ampdu_queues); + + streams = &priv->ampdu[stream_index]; + + if (streams->state == AMPDU_STREAM_ACTIVE) + ieee80211_stop_tx_ba_session(streams->sta, streams->tid); - spin_unlock(&priv->stream_lock); -done: - atomic_dec(&priv->watchdog_event_pending); - status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); - iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG), - priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); - mwl8k_fw_unlock(hw); return; } @@ -3822,7 +3763,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, } static void mwl8k_destroy_ba(struct ieee80211_hw *hw, - u8 idx) + struct mwl8k_ampdu_stream *stream) { struct mwl8k_cmd_bastream *cmd; @@ -3834,10 +3775,10 @@ static void mwl8k_destroy_ba(struct ieee80211_hw *hw, cmd->header.length = cpu_to_le16(sizeof(*cmd)); cmd->action = cpu_to_le32(MWL8K_BA_DESTROY); - cmd->destroy_params.ba_context = cpu_to_le32(idx); + cmd->destroy_params.ba_context = cpu_to_le32(stream->idx); mwl8k_post_cmd(hw, &cmd->header); - wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx); + wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx); kfree(cmd); } @@ -4360,10 +4301,6 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id) } if (status & MWL8K_A2H_INT_BA_WATCHDOG) { - iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG, - priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); - - atomic_inc(&priv->watchdog_event_pending); status &= ~MWL8K_A2H_INT_BA_WATCHDOG; ieee80211_queue_work(hw, &priv->watchdog_ba_handle); } @@ -5155,7 +5092,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int i, rc = 0; struct mwl8k_priv *priv = hw->priv; struct mwl8k_ampdu_stream *stream; - u8 *addr = sta->addr, idx; + u8 *addr = sta->addr; struct mwl8k_sta *sta_info = MWL8K_STA(sta); if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) @@ -5238,9 +5175,8 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: if (stream) { if (stream->state == AMPDU_STREAM_ACTIVE) { - idx = stream->idx; spin_unlock(&priv->stream_lock); - mwl8k_destroy_ba(hw, idx); + mwl8k_destroy_ba(hw, stream); spin_lock(&priv->stream_lock); } mwl8k_remove_stream(hw, stream); @@ -5256,9 +5192,8 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!rc) stream->state = AMPDU_STREAM_ACTIVE; else { - idx = stream->idx; spin_unlock(&priv->stream_lock); - mwl8k_destroy_ba(hw, idx); + mwl8k_destroy_ba(hw, stream); spin_lock(&priv->stream_lock); wiphy_debug(hw->wiphy, "Failed adding stream for sta %pM tid %d\n", @@ -5321,7 +5256,7 @@ enum { MWL8366, }; -#define MWL8K_8366_AP_FW_API 3 +#define MWL8K_8366_AP_FW_API 2 #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) @@ -5538,7 +5473,6 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw) priv->sniffer_enabled = false; priv->wmm_enabled = false; priv->pending_tx_pkts = 0; - atomic_set(&priv->watchdog_event_pending, 0); rc = mwl8k_rxq_init(hw, 0); if (rc) diff --git a/trunk/drivers/net/wireless/p54/p54pci.c b/trunk/drivers/net/wireless/p54/p54pci.c index 57e3af8ebb4b..933e5d941937 100644 --- a/trunk/drivers/net/wireless/p54/p54pci.c +++ b/trunk/drivers/net/wireless/p54/p54pci.c @@ -559,7 +559,6 @@ static int p54p_probe(struct pci_dev *pdev, mem_len = pci_resource_len(pdev, 0); if (mem_len < sizeof(struct p54p_csr)) { dev_err(&pdev->dev, "Too short PCI resources\n"); - err = -ENODEV; goto err_disable_dev; } @@ -569,10 +568,8 @@ static int p54p_probe(struct pci_dev *pdev, goto err_disable_dev; } - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - if (err) { + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || + pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { dev_err(&pdev->dev, "No suitable DMA available\n"); goto err_free_reg; } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index f139a913c25a..12f93e42e160 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3866,400 +3866,6 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, return rfcsr24; } -static void rt2800_init_rfcsr_305x_soc(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 0, 0x50); - rt2800_rfcsr_write(rt2x00dev, 1, 0x01); - rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); - rt2800_rfcsr_write(rt2x00dev, 3, 0x75); - rt2800_rfcsr_write(rt2x00dev, 4, 0x40); - rt2800_rfcsr_write(rt2x00dev, 5, 0x03); - rt2800_rfcsr_write(rt2x00dev, 6, 0x02); - rt2800_rfcsr_write(rt2x00dev, 7, 0x50); - rt2800_rfcsr_write(rt2x00dev, 8, 0x39); - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 10, 0x60); - rt2800_rfcsr_write(rt2x00dev, 11, 0x21); - rt2800_rfcsr_write(rt2x00dev, 12, 0x75); - rt2800_rfcsr_write(rt2x00dev, 13, 0x75); - rt2800_rfcsr_write(rt2x00dev, 14, 0x90); - rt2800_rfcsr_write(rt2x00dev, 15, 0x58); - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); - rt2800_rfcsr_write(rt2x00dev, 17, 0x92); - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); - rt2800_rfcsr_write(rt2x00dev, 19, 0x02); - rt2800_rfcsr_write(rt2x00dev, 20, 0xba); - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 22, 0x00); - rt2800_rfcsr_write(rt2x00dev, 23, 0x31); - rt2800_rfcsr_write(rt2x00dev, 24, 0x08); - rt2800_rfcsr_write(rt2x00dev, 25, 0x01); - rt2800_rfcsr_write(rt2x00dev, 26, 0x25); - rt2800_rfcsr_write(rt2x00dev, 27, 0x23); - rt2800_rfcsr_write(rt2x00dev, 28, 0x13); - rt2800_rfcsr_write(rt2x00dev, 29, 0x83); - rt2800_rfcsr_write(rt2x00dev, 30, 0x00); - rt2800_rfcsr_write(rt2x00dev, 31, 0x00); -} - -static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 4, 0x40); - rt2800_rfcsr_write(rt2x00dev, 5, 0x03); - rt2800_rfcsr_write(rt2x00dev, 6, 0x02); - rt2800_rfcsr_write(rt2x00dev, 7, 0x60); - rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 10, 0x41); - rt2800_rfcsr_write(rt2x00dev, 11, 0x21); - rt2800_rfcsr_write(rt2x00dev, 12, 0x7b); - rt2800_rfcsr_write(rt2x00dev, 14, 0x90); - rt2800_rfcsr_write(rt2x00dev, 15, 0x58); - rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); - rt2800_rfcsr_write(rt2x00dev, 17, 0x92); - rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); - rt2800_rfcsr_write(rt2x00dev, 19, 0x02); - rt2800_rfcsr_write(rt2x00dev, 20, 0xba); - rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 24, 0x16); - rt2800_rfcsr_write(rt2x00dev, 25, 0x01); - rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); -} - -static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x08); - rt2800_rfcsr_write(rt2x00dev, 4, 0x00); - rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); - rt2800_rfcsr_write(rt2x00dev, 9, 0x02); - rt2800_rfcsr_write(rt2x00dev, 10, 0x53); - rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 12, 0x46); - rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); - rt2800_rfcsr_write(rt2x00dev, 18, 0x02); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 25, 0x83); - rt2800_rfcsr_write(rt2x00dev, 26, 0x82); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x05); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 38, 0x85); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); - rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - rt2800_rfcsr_write(rt2x00dev, 47, 0x00); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x98); - rt2800_rfcsr_write(rt2x00dev, 52, 0x38); - rt2800_rfcsr_write(rt2x00dev, 53, 0x00); - rt2800_rfcsr_write(rt2x00dev, 54, 0x78); - rt2800_rfcsr_write(rt2x00dev, 55, 0x43); - rt2800_rfcsr_write(rt2x00dev, 56, 0x02); - rt2800_rfcsr_write(rt2x00dev, 57, 0x80); - rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 59, 0x09); - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); -} - -static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); - rt2800_rfcsr_write(rt2x00dev, 1, 0x23); - rt2800_rfcsr_write(rt2x00dev, 2, 0x50); - rt2800_rfcsr_write(rt2x00dev, 3, 0x18); - rt2800_rfcsr_write(rt2x00dev, 4, 0x00); - rt2800_rfcsr_write(rt2x00dev, 5, 0x00); - rt2800_rfcsr_write(rt2x00dev, 6, 0x33); - rt2800_rfcsr_write(rt2x00dev, 7, 0x00); - rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); - rt2800_rfcsr_write(rt2x00dev, 9, 0x02); - rt2800_rfcsr_write(rt2x00dev, 10, 0xd2); - rt2800_rfcsr_write(rt2x00dev, 11, 0x42); - rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); - rt2800_rfcsr_write(rt2x00dev, 13, 0x00); - rt2800_rfcsr_write(rt2x00dev, 14, 0x5a); - rt2800_rfcsr_write(rt2x00dev, 15, 0x00); - rt2800_rfcsr_write(rt2x00dev, 16, 0x01); - rt2800_rfcsr_write(rt2x00dev, 18, 0x45); - rt2800_rfcsr_write(rt2x00dev, 19, 0x02); - rt2800_rfcsr_write(rt2x00dev, 20, 0x00); - rt2800_rfcsr_write(rt2x00dev, 21, 0x00); - rt2800_rfcsr_write(rt2x00dev, 22, 0x00); - rt2800_rfcsr_write(rt2x00dev, 23, 0x00); - rt2800_rfcsr_write(rt2x00dev, 24, 0x00); - rt2800_rfcsr_write(rt2x00dev, 25, 0x80); - rt2800_rfcsr_write(rt2x00dev, 26, 0x00); - rt2800_rfcsr_write(rt2x00dev, 27, 0x03); - rt2800_rfcsr_write(rt2x00dev, 28, 0x03); - rt2800_rfcsr_write(rt2x00dev, 29, 0x00); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x01); - rt2800_rfcsr_write(rt2x00dev, 35, 0x03); - rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); - rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); - rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); - rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); - rt2800_rfcsr_write(rt2x00dev, 40, 0x33); - rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); - rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); - rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); - rt2800_rfcsr_write(rt2x00dev, 46, 0xdd); - rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); - rt2800_rfcsr_write(rt2x00dev, 48, 0x14); - rt2800_rfcsr_write(rt2x00dev, 49, 0x00); - rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); - rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 52, 0x00); - rt2800_rfcsr_write(rt2x00dev, 53, 0x52); - rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 56, 0x00); - rt2800_rfcsr_write(rt2x00dev, 57, 0x52); - rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 59, 0x00); - rt2800_rfcsr_write(rt2x00dev, 60, 0x00); - rt2800_rfcsr_write(rt2x00dev, 61, 0x00); - rt2800_rfcsr_write(rt2x00dev, 62, 0x00); - rt2800_rfcsr_write(rt2x00dev, 63, 0x00); -} - -static void rt2800_init_rfcsr_3390(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); - rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); - rt2800_rfcsr_write(rt2x00dev, 3, 0x62); - rt2800_rfcsr_write(rt2x00dev, 4, 0x40); - rt2800_rfcsr_write(rt2x00dev, 5, 0x8b); - rt2800_rfcsr_write(rt2x00dev, 6, 0x42); - rt2800_rfcsr_write(rt2x00dev, 7, 0x34); - rt2800_rfcsr_write(rt2x00dev, 8, 0x00); - rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); - rt2800_rfcsr_write(rt2x00dev, 10, 0x61); - rt2800_rfcsr_write(rt2x00dev, 11, 0x21); - rt2800_rfcsr_write(rt2x00dev, 12, 0x3b); - rt2800_rfcsr_write(rt2x00dev, 13, 0xe0); - rt2800_rfcsr_write(rt2x00dev, 14, 0x90); - rt2800_rfcsr_write(rt2x00dev, 15, 0x53); - rt2800_rfcsr_write(rt2x00dev, 16, 0xe0); - rt2800_rfcsr_write(rt2x00dev, 17, 0x94); - rt2800_rfcsr_write(rt2x00dev, 18, 0x5c); - rt2800_rfcsr_write(rt2x00dev, 19, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 20, 0xb2); - rt2800_rfcsr_write(rt2x00dev, 21, 0xf6); - rt2800_rfcsr_write(rt2x00dev, 22, 0x00); - rt2800_rfcsr_write(rt2x00dev, 23, 0x14); - rt2800_rfcsr_write(rt2x00dev, 24, 0x08); - rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); - rt2800_rfcsr_write(rt2x00dev, 26, 0x85); - rt2800_rfcsr_write(rt2x00dev, 27, 0x00); - rt2800_rfcsr_write(rt2x00dev, 28, 0x41); - rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); - rt2800_rfcsr_write(rt2x00dev, 30, 0x20); - rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); -} - -static void rt2800_init_rfcsr_3572(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 0, 0x70); - rt2800_rfcsr_write(rt2x00dev, 1, 0x81); - rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); - rt2800_rfcsr_write(rt2x00dev, 3, 0x02); - rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); - rt2800_rfcsr_write(rt2x00dev, 5, 0x05); - rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); - rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); - rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); - rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); - rt2800_rfcsr_write(rt2x00dev, 12, 0x70); - rt2800_rfcsr_write(rt2x00dev, 13, 0x65); - rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 15, 0x53); - rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); - rt2800_rfcsr_write(rt2x00dev, 17, 0x23); - rt2800_rfcsr_write(rt2x00dev, 18, 0xac); - rt2800_rfcsr_write(rt2x00dev, 19, 0x93); - rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); - rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); - rt2800_rfcsr_write(rt2x00dev, 22, 0x00); - rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); - rt2800_rfcsr_write(rt2x00dev, 24, 0x16); - rt2800_rfcsr_write(rt2x00dev, 25, 0x15); - rt2800_rfcsr_write(rt2x00dev, 26, 0x85); - rt2800_rfcsr_write(rt2x00dev, 27, 0x00); - rt2800_rfcsr_write(rt2x00dev, 28, 0x00); - rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); - rt2800_rfcsr_write(rt2x00dev, 30, 0x09); - rt2800_rfcsr_write(rt2x00dev, 31, 0x10); -} - -static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x88); - rt2800_rfcsr_write(rt2x00dev, 5, 0x10); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); - else - rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 7, 0x00); - rt2800_rfcsr_write(rt2x00dev, 10, 0x53); - rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); - rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); - rt2800_rfcsr_write(rt2x00dev, 14, 0x00); - rt2800_rfcsr_write(rt2x00dev, 15, 0x00); - rt2800_rfcsr_write(rt2x00dev, 16, 0x00); - rt2800_rfcsr_write(rt2x00dev, 18, 0x03); - rt2800_rfcsr_write(rt2x00dev, 19, 0x00); - - rt2800_rfcsr_write(rt2x00dev, 20, 0x00); - rt2800_rfcsr_write(rt2x00dev, 21, 0x00); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 23, 0x00); - rt2800_rfcsr_write(rt2x00dev, 24, 0x00); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 25, 0x80); - else - rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); - rt2800_rfcsr_write(rt2x00dev, 26, 0x00); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 28, 0x00); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - - rt2800_rfcsr_write(rt2x00dev, 30, 0x00); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x07); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 37, 0x08); - rt2800_rfcsr_write(rt2x00dev, 38, 0x85); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); - else - rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); - rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - else - rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); - rt2800_rfcsr_write(rt2x00dev, 47, 0x00); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x94); - - rt2800_rfcsr_write(rt2x00dev, 52, 0x38); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 53, 0x00); - else - rt2800_rfcsr_write(rt2x00dev, 53, 0x84); - rt2800_rfcsr_write(rt2x00dev, 54, 0x78); - rt2800_rfcsr_write(rt2x00dev, 55, 0x44); - rt2800_rfcsr_write(rt2x00dev, 56, 0x22); - rt2800_rfcsr_write(rt2x00dev, 57, 0x80); - rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 59, 0x63); - - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); - else - rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); - rt2800_rfcsr_write(rt2x00dev, 62, 0x00); - rt2800_rfcsr_write(rt2x00dev, 63, 0x00); -} - -static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) -{ - rt2800_rfcsr_write(rt2x00dev, 1, 0x17); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x88); - rt2800_rfcsr_write(rt2x00dev, 5, 0x10); - rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); - rt2800_rfcsr_write(rt2x00dev, 7, 0x00); - rt2800_rfcsr_write(rt2x00dev, 10, 0x53); - rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 12, 0x46); - rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); - rt2800_rfcsr_write(rt2x00dev, 14, 0x00); - rt2800_rfcsr_write(rt2x00dev, 15, 0x00); - rt2800_rfcsr_write(rt2x00dev, 16, 0x00); - rt2800_rfcsr_write(rt2x00dev, 18, 0x03); - rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); - rt2800_rfcsr_write(rt2x00dev, 20, 0x00); - rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); - rt2800_rfcsr_write(rt2x00dev, 24, 0x44); - rt2800_rfcsr_write(rt2x00dev, 25, 0x80); - rt2800_rfcsr_write(rt2x00dev, 26, 0x82); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 28, 0x00); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x20); - rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); - rt2800_rfcsr_write(rt2x00dev, 34, 0x07); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 37, 0x08); - rt2800_rfcsr_write(rt2x00dev, 38, 0x89); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); - rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x94); - rt2800_rfcsr_write(rt2x00dev, 50, 0x94); - rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); - rt2800_rfcsr_write(rt2x00dev, 52, 0x48); - rt2800_rfcsr_write(rt2x00dev, 53, 0x44); - rt2800_rfcsr_write(rt2x00dev, 54, 0x38); - rt2800_rfcsr_write(rt2x00dev, 55, 0x43); - rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); - rt2800_rfcsr_write(rt2x00dev, 57, 0x00); - rt2800_rfcsr_write(rt2x00dev, 58, 0x39); - rt2800_rfcsr_write(rt2x00dev, 59, 0x07); - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - rt2800_rfcsr_write(rt2x00dev, 61, 0x91); - rt2800_rfcsr_write(rt2x00dev, 62, 0x39); - rt2800_rfcsr_write(rt2x00dev, 63, 0x07); -} - static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; @@ -4283,7 +3889,6 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { @@ -4302,35 +3907,379 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); } - if (rt2800_is_305x_soc(rt2x00dev)) { - rt2800_init_rfcsr_305x_soc(rt2x00dev); + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3090)) { + rt2800_rfcsr_write(rt2x00dev, 4, 0x40); + rt2800_rfcsr_write(rt2x00dev, 5, 0x03); + rt2800_rfcsr_write(rt2x00dev, 6, 0x02); + rt2800_rfcsr_write(rt2x00dev, 7, 0x60); + rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 10, 0x41); + rt2800_rfcsr_write(rt2x00dev, 11, 0x21); + rt2800_rfcsr_write(rt2x00dev, 12, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 14, 0x90); + rt2800_rfcsr_write(rt2x00dev, 15, 0x58); + rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); + rt2800_rfcsr_write(rt2x00dev, 17, 0x92); + rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); + rt2800_rfcsr_write(rt2x00dev, 19, 0x02); + rt2800_rfcsr_write(rt2x00dev, 20, 0xba); + rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 24, 0x16); + rt2800_rfcsr_write(rt2x00dev, 25, 0x01); + rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); + } else if (rt2x00_rt(rt2x00dev, RT3290)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 4, 0x00); + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); + rt2800_rfcsr_write(rt2x00dev, 9, 0x02); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 18, 0x02); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 25, 0x83); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x05); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x98); + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0x02); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x09); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); + } else if (rt2x00_rt(rt2x00dev, RT3390)) { + rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); + rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 3, 0x62); + rt2800_rfcsr_write(rt2x00dev, 4, 0x40); + rt2800_rfcsr_write(rt2x00dev, 5, 0x8b); + rt2800_rfcsr_write(rt2x00dev, 6, 0x42); + rt2800_rfcsr_write(rt2x00dev, 7, 0x34); + rt2800_rfcsr_write(rt2x00dev, 8, 0x00); + rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 10, 0x61); + rt2800_rfcsr_write(rt2x00dev, 11, 0x21); + rt2800_rfcsr_write(rt2x00dev, 12, 0x3b); + rt2800_rfcsr_write(rt2x00dev, 13, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 14, 0x90); + rt2800_rfcsr_write(rt2x00dev, 15, 0x53); + rt2800_rfcsr_write(rt2x00dev, 16, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 17, 0x94); + rt2800_rfcsr_write(rt2x00dev, 18, 0x5c); + rt2800_rfcsr_write(rt2x00dev, 19, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 20, 0xb2); + rt2800_rfcsr_write(rt2x00dev, 21, 0xf6); + rt2800_rfcsr_write(rt2x00dev, 22, 0x00); + rt2800_rfcsr_write(rt2x00dev, 23, 0x14); + rt2800_rfcsr_write(rt2x00dev, 24, 0x08); + rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); + rt2800_rfcsr_write(rt2x00dev, 26, 0x85); + rt2800_rfcsr_write(rt2x00dev, 27, 0x00); + rt2800_rfcsr_write(rt2x00dev, 28, 0x41); + rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); + rt2800_rfcsr_write(rt2x00dev, 30, 0x20); + rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); + } else if (rt2x00_rt(rt2x00dev, RT3572)) { + rt2800_rfcsr_write(rt2x00dev, 0, 0x70); + rt2800_rfcsr_write(rt2x00dev, 1, 0x81); + rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 3, 0x02); + rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); + rt2800_rfcsr_write(rt2x00dev, 5, 0x05); + rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); + rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); + rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); + rt2800_rfcsr_write(rt2x00dev, 12, 0x70); + rt2800_rfcsr_write(rt2x00dev, 13, 0x65); + rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 15, 0x53); + rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); + rt2800_rfcsr_write(rt2x00dev, 17, 0x23); + rt2800_rfcsr_write(rt2x00dev, 18, 0xac); + rt2800_rfcsr_write(rt2x00dev, 19, 0x93); + rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); + rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); + rt2800_rfcsr_write(rt2x00dev, 22, 0x00); + rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); + rt2800_rfcsr_write(rt2x00dev, 24, 0x16); + rt2800_rfcsr_write(rt2x00dev, 25, 0x15); + rt2800_rfcsr_write(rt2x00dev, 26, 0x85); + rt2800_rfcsr_write(rt2x00dev, 27, 0x00); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 30, 0x09); + rt2800_rfcsr_write(rt2x00dev, 31, 0x10); + } else if (rt2800_is_305x_soc(rt2x00dev)) { + rt2800_rfcsr_write(rt2x00dev, 0, 0x50); + rt2800_rfcsr_write(rt2x00dev, 1, 0x01); + rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); + rt2800_rfcsr_write(rt2x00dev, 3, 0x75); + rt2800_rfcsr_write(rt2x00dev, 4, 0x40); + rt2800_rfcsr_write(rt2x00dev, 5, 0x03); + rt2800_rfcsr_write(rt2x00dev, 6, 0x02); + rt2800_rfcsr_write(rt2x00dev, 7, 0x50); + rt2800_rfcsr_write(rt2x00dev, 8, 0x39); + rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 10, 0x60); + rt2800_rfcsr_write(rt2x00dev, 11, 0x21); + rt2800_rfcsr_write(rt2x00dev, 12, 0x75); + rt2800_rfcsr_write(rt2x00dev, 13, 0x75); + rt2800_rfcsr_write(rt2x00dev, 14, 0x90); + rt2800_rfcsr_write(rt2x00dev, 15, 0x58); + rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); + rt2800_rfcsr_write(rt2x00dev, 17, 0x92); + rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); + rt2800_rfcsr_write(rt2x00dev, 19, 0x02); + rt2800_rfcsr_write(rt2x00dev, 20, 0xba); + rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 22, 0x00); + rt2800_rfcsr_write(rt2x00dev, 23, 0x31); + rt2800_rfcsr_write(rt2x00dev, 24, 0x08); + rt2800_rfcsr_write(rt2x00dev, 25, 0x01); + rt2800_rfcsr_write(rt2x00dev, 26, 0x25); + rt2800_rfcsr_write(rt2x00dev, 27, 0x23); + rt2800_rfcsr_write(rt2x00dev, 28, 0x13); + rt2800_rfcsr_write(rt2x00dev, 29, 0x83); + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); + rt2800_rfcsr_write(rt2x00dev, 31, 0x00); return 0; - } - - switch (rt2x00dev->chip.rt) { - case RT3070: - case RT3071: - case RT3090: - rt2800_init_rfcsr_30xx(rt2x00dev); - break; - case RT3290: - rt2800_init_rfcsr_3290(rt2x00dev); - break; - case RT3352: - rt2800_init_rfcsr_3352(rt2x00dev); - break; - case RT3390: - rt2800_init_rfcsr_3390(rt2x00dev); - break; - case RT3572: - rt2800_init_rfcsr_3572(rt2x00dev); - break; - case RT5390: - rt2800_init_rfcsr_5390(rt2x00dev); - break; - case RT5392: - rt2800_init_rfcsr_5392(rt2x00dev); - break; + } else if (rt2x00_rt(rt2x00dev, RT3352)) { + rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); + rt2800_rfcsr_write(rt2x00dev, 1, 0x23); + rt2800_rfcsr_write(rt2x00dev, 2, 0x50); + rt2800_rfcsr_write(rt2x00dev, 3, 0x18); + rt2800_rfcsr_write(rt2x00dev, 4, 0x00); + rt2800_rfcsr_write(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write(rt2x00dev, 6, 0x33); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 9, 0x02); + rt2800_rfcsr_write(rt2x00dev, 10, 0xd2); + rt2800_rfcsr_write(rt2x00dev, 11, 0x42); + rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); + rt2800_rfcsr_write(rt2x00dev, 13, 0x00); + rt2800_rfcsr_write(rt2x00dev, 14, 0x5a); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x01); + rt2800_rfcsr_write(rt2x00dev, 18, 0x45); + rt2800_rfcsr_write(rt2x00dev, 19, 0x02); + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); + rt2800_rfcsr_write(rt2x00dev, 22, 0x00); + rt2800_rfcsr_write(rt2x00dev, 23, 0x00); + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); + rt2800_rfcsr_write(rt2x00dev, 27, 0x03); + rt2800_rfcsr_write(rt2x00dev, 28, 0x03); + rt2800_rfcsr_write(rt2x00dev, 29, 0x00); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x01); + rt2800_rfcsr_write(rt2x00dev, 35, 0x03); + rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); + rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); + rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); + rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); + rt2800_rfcsr_write(rt2x00dev, 40, 0x33); + rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); + rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); + rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 46, 0xdd); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); + rt2800_rfcsr_write(rt2x00dev, 48, 0x14); + rt2800_rfcsr_write(rt2x00dev, 49, 0x00); + rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); + rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 52, 0x00); + rt2800_rfcsr_write(rt2x00dev, 53, 0x52); + rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 56, 0x00); + rt2800_rfcsr_write(rt2x00dev, 57, 0x52); + rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 59, 0x00); + rt2800_rfcsr_write(rt2x00dev, 60, 0x00); + rt2800_rfcsr_write(rt2x00dev, 61, 0x00); + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + else + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x00); + + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x00); + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + else + rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + else + rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + else + rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + else + rt2800_rfcsr_write(rt2x00dev, 53, 0x84); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x44); + rt2800_rfcsr_write(rt2x00dev, 56, 0x22); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x63); + + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); + else + rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } else if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x17); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 24, 0x44); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x20); + rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x89); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + rt2800_rfcsr_write(rt2x00dev, 50, 0x94); + rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); + rt2800_rfcsr_write(rt2x00dev, 52, 0x48); + rt2800_rfcsr_write(rt2x00dev, 53, 0x44); + rt2800_rfcsr_write(rt2x00dev, 54, 0x38); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); + rt2800_rfcsr_write(rt2x00dev, 57, 0x00); + rt2800_rfcsr_write(rt2x00dev, 58, 0x39); + rt2800_rfcsr_write(rt2x00dev, 59, 0x07); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0x91); + rt2800_rfcsr_write(rt2x00dev, 62, 0x39); + rt2800_rfcsr_write(rt2x00dev, 63, 0x07); } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -4671,14 +4620,12 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) mutex_unlock(&rt2x00dev->csr_mutex); } -int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) +void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { unsigned int i; for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8) rt2800_efuse_read(rt2x00dev, i); - - return 0; } EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); @@ -4688,14 +4635,11 @@ static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) u16 word; u8 *mac; u8 default_lna_gain; - int retval; /* * Read the EEPROM. */ - retval = rt2800_read_eeprom(rt2x00dev); - if (retval) - return retval; + rt2800_read_eeprom(rt2x00dev); /* * Start validation of the data that has been read. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.h b/trunk/drivers/net/wireless/rt2x00/rt2800lib.h index 6ec739466db4..a128ceadcb3e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.h @@ -43,7 +43,7 @@ struct rt2800_ops { const unsigned int offset, const struct rt2x00_field32 field, u32 *reg); - int (*read_eeprom)(struct rt2x00_dev *rt2x00dev); + void (*read_eeprom)(struct rt2x00_dev *rt2x00dev); bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev); int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, @@ -117,11 +117,11 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev, return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); } -static inline int rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev) +static inline void rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev) { const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; - return rt2800ops->read_eeprom(rt2x00dev); + rt2800ops->read_eeprom(rt2x00dev); } static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) @@ -207,7 +207,7 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); -int rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); +void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index 0e8d1705e368..9224d874bf24 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -90,22 +90,17 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) } #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) -static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); - if (!base_addr) - return -ENOMEM; - memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); iounmap(base_addr); - return 0; } #else -static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { - return -ENOMEM; } #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ @@ -140,7 +135,7 @@ static void rt2800pci_eepromregister_write(struct eeprom_93cx6 *eeprom) rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); } -static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) +static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) { struct eeprom_93cx6 eeprom; u32 reg; @@ -169,8 +164,6 @@ static int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, EEPROM_SIZE / sizeof(u16)); - - return 0; } static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) @@ -178,14 +171,13 @@ static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) return rt2800_efuse_detect(rt2x00dev); } -static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) +static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { - return rt2800_read_eeprom_efuse(rt2x00dev); + rt2800_read_eeprom_efuse(rt2x00dev); } #else -static inline int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) +static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) { - return -EOPNOTSUPP; } static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) @@ -193,9 +185,8 @@ static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) return 0; } -static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) +static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { - return -EOPNOTSUPP; } #endif /* CONFIG_PCI */ @@ -979,18 +970,14 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) /* * Device probe functions. */ -static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) +static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) { - int retval; - if (rt2x00_is_soc(rt2x00dev)) - retval = rt2800pci_read_eeprom_soc(rt2x00dev); + rt2800pci_read_eeprom_soc(rt2x00dev); else if (rt2800pci_efuse_detect(rt2x00dev)) - retval = rt2800pci_read_eeprom_efuse(rt2x00dev); + rt2800pci_read_eeprom_efuse(rt2x00dev); else - retval = rt2800pci_read_eeprom_pci(rt2x00dev); - - return retval; + rt2800pci_read_eeprom_pci(rt2x00dev); } static const struct ieee80211_ops rt2800pci_mac80211_ops = { diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 4721cada1591..5c149b58ab46 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -735,17 +735,13 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, /* * Device probe functions. */ -static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) +static void rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev) { - int retval; - if (rt2800_efuse_detect(rt2x00dev)) - retval = rt2800_read_eeprom_efuse(rt2x00dev); + rt2800_read_eeprom_efuse(rt2x00dev); else - retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, - EEPROM_SIZE); - - return retval; + rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, + EEPROM_SIZE); } static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) diff --git a/trunk/include/linux/bcma/bcma_driver_mips.h b/trunk/include/linux/bcma/bcma_driver_mips.h index 6495579e3f35..0baf8a56b794 100644 --- a/trunk/include/linux/bcma/bcma_driver_mips.h +++ b/trunk/include/linux/bcma/bcma_driver_mips.h @@ -36,6 +36,7 @@ struct bcma_drv_mips { struct bcma_device *core; u8 setup_done:1; u8 early_setup_done:1; + unsigned int assigned_irqs; }; #ifdef CONFIG_BCMA_DRIVER_MIPS diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 47aeee2d8db1..9044296c8876 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -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.