diff --git a/[refs] b/[refs] index a15b6b3f8dd3..115a0355d4e5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ad66786718989c20c91e855baa40371e01daf0a1 +refs/heads/master: dbeca583f9b8e35aa08279b81d5340dac3a60aff diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index ed5b5f5ac175..e73060fe0788 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5067,7 +5067,6 @@ F: net/nfc/ F: include/linux/nfc.h F: include/net/nfc/ F: drivers/nfc/ -F: include/linux/platform_data/pn544.h NFS, SUNRPC, AND LOCKD CLIENTS M: Trond Myklebust @@ -7478,12 +7477,6 @@ S: Maintained F: Documentation/usb/acm.txt F: drivers/usb/class/cdc-acm.* -USB AR5523 WIRELESS DRIVER -M: Pontus Fuchs -L: linux-wireless@vger.kernel.org -S: Maintained -F: drivers/net/wireless/ath/ar5523/ - USB ATTACHED SCSI M: Matthew Wilcox M: Sarah Sharp diff --git a/trunk/arch/mips/bcm47xx/nvram.c b/trunk/arch/mips/bcm47xx/nvram.c index 48a4c70b3842..d43ceff5be47 100644 --- a/trunk/arch/mips/bcm47xx/nvram.c +++ b/trunk/arch/mips/bcm47xx/nvram.c @@ -43,8 +43,8 @@ static void early_nvram_init(void) #ifdef CONFIG_BCM47XX_SSB case BCM47XX_BUS_TYPE_SSB: mcore_ssb = &bcm47xx_bus.ssb.mipscore; - base = mcore_ssb->pflash.window; - lim = mcore_ssb->pflash.window_size; + base = mcore_ssb->flash_window; + lim = mcore_ssb->flash_window_size; break; #endif #ifdef CONFIG_BCM47XX_BCMA diff --git a/trunk/arch/mips/bcm47xx/wgt634u.c b/trunk/arch/mips/bcm47xx/wgt634u.c index e80d585731aa..e9f9ec8d443b 100644 --- a/trunk/arch/mips/bcm47xx/wgt634u.c +++ b/trunk/arch/mips/bcm47xx/wgt634u.c @@ -156,10 +156,10 @@ static int __init wgt634u_init(void) SSB_CHIPCO_IRQ_GPIO); } - wgt634u_flash_data.width = mcore->pflash.buswidth; - wgt634u_flash_resource.start = mcore->pflash.window; - wgt634u_flash_resource.end = mcore->pflash.window - + mcore->pflash.window_size + wgt634u_flash_data.width = mcore->flash_buswidth; + wgt634u_flash_resource.start = mcore->flash_window; + wgt634u_flash_resource.end = mcore->flash_window + + mcore->flash_window_size - 1; return platform_add_devices(wgt634u_devices, ARRAY_SIZE(wgt634u_devices)); diff --git a/trunk/drivers/bcma/driver_chipcommon.c b/trunk/drivers/bcma/driver_chipcommon.c index ffd74e51f02d..a4c3ebcc4c86 100644 --- a/trunk/drivers/bcma/driver_chipcommon.c +++ b/trunk/drivers/bcma/driver_chipcommon.c @@ -22,23 +22,6 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, return value; } -void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) -{ - if (cc->early_setup_done) - return; - - if (cc->core->id.rev >= 11) - cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); - cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); - if (cc->core->id.rev >= 35) - cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); - - if (cc->capabilities & BCMA_CC_CAP_PMU) - bcma_pmu_early_init(cc); - - cc->early_setup_done = true; -} - void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) { u32 leddc_on = 10; @@ -47,7 +30,11 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) if (cc->setup_done) return; - bcma_core_chipcommon_early_init(cc); + if (cc->core->id.rev >= 11) + cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); + cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); + if (cc->core->id.rev >= 35) + cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); if (cc->core->id.rev >= 20) { bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); diff --git a/trunk/drivers/bcma/driver_chipcommon_nflash.c b/trunk/drivers/bcma/driver_chipcommon_nflash.c index dbda91e4dff5..9042781edec3 100644 --- a/trunk/drivers/bcma/driver_chipcommon_nflash.c +++ b/trunk/drivers/bcma/driver_chipcommon_nflash.c @@ -32,9 +32,6 @@ int bcma_nflash_init(struct bcma_drv_cc *cc) } cc->nflash.present = true; - if (cc->core->id.rev == 38 && - (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) - cc->nflash.boot = true; /* Prepare platform device, but don't register it yet. It's too early, * malloc (required by device_private_init) is not available yet. */ diff --git a/trunk/drivers/bcma/driver_chipcommon_pmu.c b/trunk/drivers/bcma/driver_chipcommon_pmu.c index a63ddd9c70eb..201faf106b3f 100644 --- a/trunk/drivers/bcma/driver_chipcommon_pmu.c +++ b/trunk/drivers/bcma/driver_chipcommon_pmu.c @@ -144,7 +144,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc) } } -void bcma_pmu_early_init(struct bcma_drv_cc *cc) +void bcma_pmu_init(struct bcma_drv_cc *cc) { u32 pmucap; @@ -153,10 +153,7 @@ void bcma_pmu_early_init(struct bcma_drv_cc *cc) bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, pmucap); -} -void bcma_pmu_init(struct bcma_drv_cc *cc) -{ if (cc->pmu.rev == 1) bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, ~BCMA_CC_PMU_CTL_NOILPONW); diff --git a/trunk/drivers/bcma/driver_chipcommon_sflash.c b/trunk/drivers/bcma/driver_chipcommon_sflash.c index 63e688393825..2c4eec2ca5a0 100644 --- a/trunk/drivers/bcma/driver_chipcommon_sflash.c +++ b/trunk/drivers/bcma/driver_chipcommon_sflash.c @@ -12,7 +12,7 @@ static struct resource bcma_sflash_resource = { .name = "bcma_sflash", - .start = BCMA_SOC_FLASH2, + .start = BCMA_SFLASH, .end = 0, .flags = IORESOURCE_MEM | IORESOURCE_READONLY, }; @@ -31,42 +31,15 @@ struct bcma_sflash_tbl_e { }; static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { - { "M25P20", 0x11, 0x10000, 4, }, - { "M25P40", 0x12, 0x10000, 8, }, - - { "M25P16", 0x14, 0x10000, 32, }, - { "M25P32", 0x14, 0x10000, 64, }, - { "M25P64", 0x16, 0x10000, 128, }, - { "M25FL128", 0x17, 0x10000, 256, }, + { "", 0x14, 0x10000, 32, }, { 0 }, }; static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { - { "SST25WF512", 1, 0x1000, 16, }, - { "SST25VF512", 0x48, 0x1000, 16, }, - { "SST25WF010", 2, 0x1000, 32, }, - { "SST25VF010", 0x49, 0x1000, 32, }, - { "SST25WF020", 3, 0x1000, 64, }, - { "SST25VF020", 0x43, 0x1000, 64, }, - { "SST25WF040", 4, 0x1000, 128, }, - { "SST25VF040", 0x44, 0x1000, 128, }, - { "SST25VF040B", 0x8d, 0x1000, 128, }, - { "SST25WF080", 5, 0x1000, 256, }, - { "SST25VF080B", 0x8e, 0x1000, 256, }, - { "SST25VF016", 0x41, 0x1000, 512, }, - { "SST25VF032", 0x4a, 0x1000, 1024, }, - { "SST25VF064", 0x4b, 0x1000, 2048, }, { 0 }, }; static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { - { "AT45DB011", 0xc, 256, 512, }, - { "AT45DB021", 0x14, 256, 1024, }, - { "AT45DB041", 0x1c, 256, 2048, }, - { "AT45DB081", 0x24, 256, 4096, }, - { "AT45DB161", 0x2c, 512, 4096, }, - { "AT45DB321", 0x34, 512, 8192, }, - { "AT45DB642", 0x3c, 1024, 8192, }, { 0 }, }; @@ -111,8 +84,6 @@ int bcma_sflash_init(struct bcma_drv_cc *cc) break; } break; - case 0x13: - return -ENOTSUPP; default: for (e = bcma_sflash_st_tbl; e->name; e++) { if (e->id == id) @@ -145,7 +116,7 @@ int bcma_sflash_init(struct bcma_drv_cc *cc) return -ENOTSUPP; } - sflash->window = BCMA_SOC_FLASH2; + sflash->window = BCMA_SFLASH; sflash->blocksize = e->blocksize; sflash->numblocks = e->numblocks; sflash->size = sflash->blocksize * sflash->numblocks; diff --git a/trunk/drivers/bcma/driver_mips.c b/trunk/drivers/bcma/driver_mips.c index 170822ea51c7..cc65b45b4368 100644 --- a/trunk/drivers/bcma/driver_mips.c +++ b/trunk/drivers/bcma/driver_mips.c @@ -181,66 +181,47 @@ EXPORT_SYMBOL(bcma_cpu_clock); static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) { struct bcma_bus *bus = mcore->core->bus; - struct bcma_drv_cc *cc = &bus->drv_cc; - switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { case BCMA_CC_FLASHT_STSER: case BCMA_CC_FLASHT_ATSER: bcma_debug(bus, "Found serial flash\n"); - bcma_sflash_init(cc); + bcma_sflash_init(&bus->drv_cc); break; case BCMA_CC_FLASHT_PARA: bcma_debug(bus, "Found parallel flash\n"); - cc->pflash.present = true; - cc->pflash.window = BCMA_SOC_FLASH2; - cc->pflash.window_size = BCMA_SOC_FLASH2_SZ; + bus->drv_cc.pflash.window = 0x1c000000; + bus->drv_cc.pflash.window_size = 0x02000000; - if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS) == 0) - cc->pflash.buswidth = 1; + bus->drv_cc.pflash.buswidth = 1; else - cc->pflash.buswidth = 2; + bus->drv_cc.pflash.buswidth = 2; break; default: bcma_err(bus, "Flash type not supported\n"); } - if (cc->core->id.rev == 38 || + if (bus->drv_cc.core->id.rev == 38 || bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { - if (cc->capabilities & BCMA_CC_CAP_NFLASH) { + if (bus->drv_cc.capabilities & BCMA_CC_CAP_NFLASH) { bcma_debug(bus, "Found NAND flash\n"); - bcma_nflash_init(cc); + bcma_nflash_init(&bus->drv_cc); } } } -void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) -{ - struct bcma_bus *bus = mcore->core->bus; - - if (mcore->early_setup_done) - return; - - bcma_chipco_serial_init(&bus->drv_cc); - bcma_core_mips_flash_detect(mcore); - - mcore->early_setup_done = true; -} - void bcma_core_mips_init(struct bcma_drv_mips *mcore) { struct bcma_bus *bus; struct bcma_device *core; bus = mcore->core->bus; - if (mcore->setup_done) - return; - bcma_info(bus, "Initializing MIPS core...\n"); - bcma_core_mips_early_init(mcore); - - mcore->assigned_irqs = 1; + if (!mcore->setup_done) + mcore->assigned_irqs = 1; /* Assign IRQs to all cores on the bus */ list_for_each_entry(core, &bus->cores, list) { @@ -275,5 +256,10 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) bcma_info(bus, "IRQ reconfiguration done\n"); bcma_core_mips_dump_irq(bus); + if (mcore->setup_done) + return; + + bcma_chipco_serial_init(&bus->drv_cc); + bcma_core_mips_flash_detect(mcore); mcore->setup_done = true; } diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index e56449506695..9baf886e82df 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -35,6 +35,11 @@ bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) chipid_top != 0x5300) return false; + if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { + bcma_info(bus, "This PCI core is disabled and not working\n"); + return false; + } + bcma_core_enable(pc->core, 0); return !mips_busprobe32(tmp, pc->core->io_addr); @@ -391,11 +396,6 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) bcma_info(bus, "PCIEcore in host mode found\n"); - if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { - bcma_info(bus, "This PCIE core is disabled and not working\n"); - return; - } - pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); if (!pc_host) { bcma_err(bus, "can not allocate memory"); @@ -452,8 +452,6 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + BCMA_SOC_PCI_MEM_SZ - 1; - pc_host->io_resource.start = 0x100; - pc_host->io_resource.end = 0x47F; pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, tmp | BCMA_SOC_PCI_MEM); @@ -461,8 +459,6 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + BCMA_SOC_PCI_MEM_SZ - 1; - pc_host->io_resource.start = 0x480; - pc_host->io_resource.end = 0x7FF; pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, diff --git a/trunk/drivers/bcma/host_pci.c b/trunk/drivers/bcma/host_pci.c index 98fdc3e014e7..b6b4b5ebd4c2 100644 --- a/trunk/drivers/bcma/host_pci.c +++ b/trunk/drivers/bcma/host_pci.c @@ -238,7 +238,7 @@ static void __devexit bcma_host_pci_remove(struct pci_dev *dev) pci_set_drvdata(dev, NULL); } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int bcma_host_pci_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -261,11 +261,11 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, bcma_host_pci_resume); #define BCMA_PM_OPS (&bcma_pm_ops) -#else /* CONFIG_PM_SLEEP */ +#else /* CONFIG_PM */ #define BCMA_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index a9718893000b..432aeeedfd5e 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -81,18 +81,6 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) } EXPORT_SYMBOL_GPL(bcma_find_core); -static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, - u8 unit) -{ - struct bcma_device *core; - - list_for_each_entry(core, &bus->cores, list) { - if (core->id.id == coreid && core->core_unit == unit) - return core; - } - return NULL; -} - static void bcma_release_core_dev(struct device *dev) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); @@ -170,10 +158,9 @@ static int bcma_register_cores(struct bcma_bus *bus) static void bcma_unregister_cores(struct bcma_bus *bus) { - struct bcma_device *core, *tmp; + struct bcma_device *core; - list_for_each_entry_safe(core, tmp, &bus->cores, list) { - list_del(&core->list); + list_for_each_entry(core, &bus->cores, list) { if (core->dev_registered) device_unregister(&core->dev); } @@ -195,20 +182,6 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) return -1; } - /* Early init CC core */ - core = bcma_find_core(bus, bcma_cc_core_id(bus)); - if (core) { - bus->drv_cc.core = core; - bcma_core_chipcommon_early_init(&bus->drv_cc); - } - - /* Try to get SPROM */ - err = bcma_sprom_get(bus); - if (err == -ENOENT) { - bcma_err(bus, "No SPROM available\n"); - } else if (err) - bcma_err(bus, "Failed to get SPROM: %d\n", err); - /* Init CC core */ core = bcma_find_core(bus, bcma_cc_core_id(bus)); if (core) { @@ -224,17 +197,10 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) } /* Init PCIE core */ - core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0); - if (core) { - bus->drv_pci[0].core = core; - bcma_core_pci_init(&bus->drv_pci[0]); - } - - /* Init PCIE core */ - core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1); + core = bcma_find_core(bus, BCMA_CORE_PCIE); if (core) { - bus->drv_pci[1].core = core; - bcma_core_pci_init(&bus->drv_pci[1]); + bus->drv_pci.core = core; + bcma_core_pci_init(&bus->drv_pci); } /* Init GBIT MAC COMMON core */ @@ -244,6 +210,13 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn); } + /* Try to get SPROM */ + err = bcma_sprom_get(bus); + if (err == -ENOENT) { + bcma_err(bus, "No SPROM available\n"); + } else if (err) + bcma_err(bus, "Failed to get SPROM: %d\n", err); + /* Register found cores */ bcma_register_cores(bus); @@ -301,18 +274,18 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, return -1; } - /* Early init CC core */ + /* Init CC core */ core = bcma_find_core(bus, bcma_cc_core_id(bus)); if (core) { bus->drv_cc.core = core; - bcma_core_chipcommon_early_init(&bus->drv_cc); + bcma_core_chipcommon_init(&bus->drv_cc); } - /* Early init MIPS core */ + /* Init MIPS core */ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); if (core) { bus->drv_mips.core = core; - bcma_core_mips_early_init(&bus->drv_mips); + bcma_core_mips_init(&bus->drv_mips); } bcma_info(bus, "Early bus registered\n"); diff --git a/trunk/drivers/bcma/sprom.c b/trunk/drivers/bcma/sprom.c index 4adf9ef9a113..0d546b64be34 100644 --- a/trunk/drivers/bcma/sprom.c +++ b/trunk/drivers/bcma/sprom.c @@ -595,11 +595,8 @@ int bcma_sprom_get(struct bcma_bus *bus) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); err = bcma_sprom_valid(sprom); - if (err) { - bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n"); - err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); + if (err) goto out; - } bcma_sprom_extract_r8(bus, sprom); diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index b00000e8aef6..fc2de5528dcc 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -67,7 +67,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, - { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/trunk/drivers/bluetooth/btmrvl_sdio.c b/trunk/drivers/bluetooth/btmrvl_sdio.c index 9959d4cb23dc..3f4bfc814dc7 100644 --- a/trunk/drivers/bluetooth/btmrvl_sdio.c +++ b/trunk/drivers/bluetooth/btmrvl_sdio.c @@ -492,7 +492,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) { u16 buf_len = 0; - int ret, num_blocks, blksz; + int ret, buf_block_len, blksz; struct sk_buff *skb = NULL; u32 type; u8 *payload = NULL; @@ -514,17 +514,18 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) } blksz = SDIO_BLOCK_SIZE; - num_blocks = DIV_ROUND_UP(buf_len, blksz); + buf_block_len = (buf_len + blksz - 1) / blksz; if (buf_len <= SDIO_HEADER_LEN - || (num_blocks * blksz) > ALLOC_BUF_SIZE) { + || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { BT_ERR("invalid packet length: %d", buf_len); ret = -EINVAL; goto exit; } /* Allocate buffer */ - skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC); + skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, + GFP_ATOMIC); if (skb == NULL) { BT_ERR("No free skb"); goto exit; @@ -540,7 +541,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) payload = skb->data; ret = sdio_readsb(card->func, payload, card->ioport, - num_blocks * blksz); + buf_block_len * blksz); if (ret < 0) { BT_ERR("readsb failed: %d", ret); ret = -EIO; @@ -552,16 +553,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) */ buf_len = payload[0]; - buf_len |= payload[1] << 8; - buf_len |= payload[2] << 16; - - if (buf_len > blksz * num_blocks) { - BT_ERR("Skip incorrect packet: hdrlen %d buffer %d", - buf_len, blksz * num_blocks); - ret = -EIO; - goto exit; - } - + buf_len |= (u16) payload[1] << 8; type = payload[3]; switch (type) { @@ -597,7 +589,8 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) default: BT_ERR("Unknown packet type:%d", type); - BT_ERR("hex: %*ph", blksz * num_blocks, payload); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, + blksz * buf_block_len); kfree_skb(skb); skb = NULL; @@ -856,7 +849,8 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, if (ret < 0) { i++; BT_ERR("i=%d writesb failed: %d", i, ret); - BT_ERR("hex: %*ph", nb, payload); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + payload, nb); ret = -EIO; if (i > MAX_WRITE_IOMEM_RETRY) goto exit; diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index a1d4ede5b892..debda27df9b0 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -96,7 +96,6 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ - { USB_DEVICE(0x0b05, 0x17b5) }, { USB_DEVICE(0x04ca, 0x2003) }, { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x413c, 0x8197) }, @@ -125,7 +124,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 72b775fd49c8..961c8321451f 100644 --- a/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/trunk/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -452,7 +452,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf, if (rsn) *buf++ = WLAN_EID_RSN; else - *buf++ = WLAN_EID_VENDOR_SPECIFIC; + *buf++ = WLAN_EID_GENERIC; /* length filed; set later */ buf++; @@ -540,7 +540,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len, break; switch (item_id) { - case WLAN_EID_VENDOR_SPECIFIC: + case WLAN_EID_GENERIC: if ((OUI_LEN + 1 <= item_len) && !memcmp(pos, wpa_oui, OUI_LEN) && pos[OUI_LEN] == 0x01) { diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index 57f7db1ac31b..3cd05a7173f6 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -7433,7 +7433,7 @@ static inline char *airo_translate_scan(struct net_device *dev, num_null_ies++; break; - case WLAN_EID_VENDOR_SPECIFIC: + case WLAN_EID_GENERIC: if (ie[1] >= 4 && ie[2] == 0x00 && ie[3] == 0x50 && diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 77fa4286e5e9..99b9ddf21273 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -379,7 +379,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, manifest_sync_timeout); if (!size) { - dev_err(&udev->dev, "FW buffer length invalid!\n"); + dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n"); return -EINVAL; } @@ -391,8 +391,8 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, if (need_dfu_state) { ret = at76_dfu_get_state(udev, &dfu_state); if (ret < 0) { - dev_err(&udev->dev, - "cannot get DFU state: %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "cannot get DFU state: %d\n", ret); goto exit; } need_dfu_state = 0; @@ -407,9 +407,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, dfu_timeout = at76_get_timeout(&dfu_stat_buf); need_dfu_state = 0; } else - dev_err(&udev->dev, - "at76_dfu_get_status returned %d\n", - ret); + dev_printk(KERN_ERR, &udev->dev, + "at76_dfu_get_status returned %d\n", + ret); break; case STATE_DFU_DOWNLOAD_BUSY: @@ -438,9 +438,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, blockno++; if (ret != bsize) - dev_err(&udev->dev, - "at76_load_int_fw_block returned %d\n", - ret); + dev_printk(KERN_ERR, &udev->dev, + "at76_load_int_fw_block " + "returned %d\n", ret); need_dfu_state = 1; break; @@ -1255,7 +1255,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { - dev_err(&udev->dev, "unexpected opmode %d\n", op_mode); + dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", + op_mode); return -EINVAL; } @@ -1274,9 +1275,9 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) size, bsize, blockno); ret = at76_load_ext_fw_block(udev, blockno, block, bsize); if (ret != bsize) { - dev_err(&udev->dev, - "loading %dth firmware block failed: %d\n", - blockno, ret); + dev_printk(KERN_ERR, &udev->dev, + "loading %dth firmware block failed: %d\n", + blockno, ret); goto exit; } buf += bsize; @@ -1292,8 +1293,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) exit: kfree(block); if (ret < 0) - dev_err(&udev->dev, - "downloading external firmware failed: %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "downloading external firmware failed: %d\n", ret); return ret; } @@ -1307,8 +1308,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) need_remap ? 0 : 2 * HZ); if (ret < 0) { - dev_err(&udev->dev, - "downloading internal fw failed with %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "downloading internal fw failed with %d\n", ret); goto exit; } @@ -1318,8 +1319,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) if (need_remap) { ret = at76_remap(udev); if (ret < 0) { - dev_err(&udev->dev, - "sending REMAP failed with %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "sending REMAP failed with %d\n", ret); goto exit; } } @@ -1554,10 +1555,11 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); if (ret < 0) { - dev_err(&udev->dev, "firmware %s not found!\n", - fwe->fwname); - dev_err(&udev->dev, - "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n"); + dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", + fwe->fwname); + dev_printk(KERN_ERR, &udev->dev, + "you may need to download the firmware from " + "http://developer.berlios.de/projects/at76c503a/\n"); goto exit; } @@ -1565,17 +1567,17 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, fwh = (struct at76_fw_header *)(fwe->fw->data); if (fwe->fw->size <= sizeof(*fwh)) { - dev_err(&udev->dev, - "firmware is too short (0x%zx)\n", fwe->fw->size); + dev_printk(KERN_ERR, &udev->dev, + "firmware is too short (0x%zx)\n", fwe->fw->size); goto exit; } /* CRC currently not checked */ fwe->board_type = le32_to_cpu(fwh->board_type); if (fwe->board_type != board_type) { - dev_err(&udev->dev, - "board type mismatch, requested %u, got %u\n", - board_type, fwe->board_type); + dev_printk(KERN_ERR, &udev->dev, + "board type mismatch, requested %u, got %u\n", + board_type, fwe->board_type); goto exit; } @@ -2148,7 +2150,8 @@ static int at76_alloc_urbs(struct at76_priv *priv, } if (!ep_in || !ep_out) { - dev_err(&interface->dev, "bulk endpoints missing\n"); + dev_printk(KERN_ERR, &interface->dev, + "bulk endpoints missing\n"); return -ENXIO; } @@ -2158,14 +2161,15 @@ static int at76_alloc_urbs(struct at76_priv *priv, priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!priv->rx_urb || !priv->tx_urb) { - dev_err(&interface->dev, "cannot allocate URB\n"); + dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n"); return -ENOMEM; } buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!priv->bulk_out_buffer) { - dev_err(&interface->dev, "cannot allocate output buffer\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot allocate output buffer\n"); return -ENOMEM; } @@ -2226,7 +2230,8 @@ static int at76_init_new_device(struct at76_priv *priv, /* MAC address */ ret = at76_get_hw_config(priv); if (ret < 0) { - dev_err(&interface->dev, "cannot get MAC address\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot get MAC address\n"); goto exit; } @@ -2353,8 +2358,8 @@ static int at76_probe(struct usb_interface *interface, we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ if (op_mode == OPMODE_HW_CONFIG_MODE) { - dev_err(&interface->dev, - "cannot handle a device in HW_CONFIG_MODE\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot handle a device in HW_CONFIG_MODE\n"); ret = -EBUSY; goto error; } @@ -2366,9 +2371,9 @@ static int at76_probe(struct usb_interface *interface, "downloading internal firmware\n"); ret = at76_load_internal_fw(udev, fwe); if (ret < 0) { - dev_err(&interface->dev, - "error %d downloading internal firmware\n", - ret); + dev_printk(KERN_ERR, &interface->dev, + "error %d downloading internal firmware\n", + ret); goto error; } usb_put_dev(udev); @@ -2403,8 +2408,8 @@ static int at76_probe(struct usb_interface *interface, /* Re-check firmware version */ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); if (ret < 0) { - dev_err(&interface->dev, - "error %d getting firmware version\n", ret); + dev_printk(KERN_ERR, &interface->dev, + "error %d getting firmware version\n", ret); goto error; } } @@ -2444,7 +2449,7 @@ static void at76_disconnect(struct usb_interface *interface) wiphy_info(priv->hw->wiphy, "disconnecting\n"); at76_delete_device(priv); - dev_info(&interface->dev, "disconnected\n"); + dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); } /* Structure for registering this driver with the USB subsystem */ diff --git a/trunk/drivers/net/wireless/ath/Kconfig b/trunk/drivers/net/wireless/ath/Kconfig index c25dcf192fec..09602241901b 100644 --- a/trunk/drivers/net/wireless/ath/Kconfig +++ b/trunk/drivers/net/wireless/ath/Kconfig @@ -26,6 +26,5 @@ source "drivers/net/wireless/ath/ath5k/Kconfig" source "drivers/net/wireless/ath/ath9k/Kconfig" source "drivers/net/wireless/ath/carl9170/Kconfig" source "drivers/net/wireless/ath/ath6kl/Kconfig" -source "drivers/net/wireless/ath/ar5523/Kconfig" endif diff --git a/trunk/drivers/net/wireless/ath/Makefile b/trunk/drivers/net/wireless/ath/Makefile index 1e18621326dc..d716b748e574 100644 --- a/trunk/drivers/net/wireless/ath/Makefile +++ b/trunk/drivers/net/wireless/ath/Makefile @@ -2,7 +2,6 @@ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K_HW) += ath9k/ obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH6KL) += ath6kl/ -obj-$(CONFIG_AR5523) += ar5523/ obj-$(CONFIG_ATH_COMMON) += ath.o diff --git a/trunk/drivers/net/wireless/ath/ar5523/Kconfig b/trunk/drivers/net/wireless/ath/ar5523/Kconfig deleted file mode 100644 index 11d99ee8de51..000000000000 --- a/trunk/drivers/net/wireless/ath/ar5523/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config AR5523 - tristate "Atheros AR5523 wireless driver support" - depends on MAC80211 && USB - select FW_LOADER - ---help--- - This module add support for AR5523 based USB dongles such as D-Link - DWL-G132, Netgear WPN111 and many more. diff --git a/trunk/drivers/net/wireless/ath/ar5523/Makefile b/trunk/drivers/net/wireless/ath/ar5523/Makefile deleted file mode 100644 index ebf7f3bf0a33..000000000000 --- a/trunk/drivers/net/wireless/ath/ar5523/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_AR5523) := ar5523.o diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523.c b/trunk/drivers/net/wireless/ath/ar5523/ar5523.c deleted file mode 100644 index 7157f7d311c5..000000000000 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523.c +++ /dev/null @@ -1,1798 +0,0 @@ -/* - * Copyright (c) 2006 Damien Bergamini - * Copyright (c) 2006 Sam Leffler, Errno Consulting - * Copyright (c) 2007 Christoph Hellwig - * Copyright (c) 2008-2009 Weongyo Jeong - * Copyright (c) 2012 Pontus Fuchs - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This driver is based on the uath driver written by Damien Bergamini for - * OpenBSD, who did black-box analysis of the Windows binary driver to find - * out how the hardware works. It contains a lot magic numbers because of - * that and only has minimal functionality. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ar5523.h" -#include "ar5523_hw.h" - -/* - * Various supported device vendors/products. - * UB51: AR5005UG 802.11b/g, UB52: AR5005UX 802.11a/b/g - */ - -static int ar5523_submit_rx_cmd(struct ar5523 *ar); -static void ar5523_data_tx_pkt_put(struct ar5523 *ar); - -static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr, - struct ar5523_tx_cmd *cmd) -{ - int dlen, olen; - __be32 *rp; - - dlen = be32_to_cpu(hdr->len) - sizeof(*hdr); - - if (dlen < 0) { - WARN_ON(1); - goto out; - } - - ar5523_dbg(ar, "Code = %d len = %d\n", be32_to_cpu(hdr->code) & 0xff, - dlen); - - rp = (__be32 *)(hdr + 1); - if (dlen >= sizeof(u32)) { - olen = be32_to_cpu(rp[0]); - dlen -= sizeof(u32); - if (olen == 0) { - /* convention is 0 =>'s one word */ - olen = sizeof(u32); - } - } else - olen = 0; - - if (cmd->odata) { - if (cmd->olen < olen) { - ar5523_err(ar, "olen to small %d < %d\n", - cmd->olen, olen); - cmd->olen = 0; - cmd->res = -EOVERFLOW; - } else { - cmd->olen = olen; - memcpy(cmd->odata, &rp[1], olen); - cmd->res = 0; - } - } - -out: - complete(&cmd->done); -} - -static void ar5523_cmd_rx_cb(struct urb *urb) -{ - struct ar5523 *ar = urb->context; - struct ar5523_tx_cmd *cmd = &ar->tx_cmd; - struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; - int dlen; - u32 code, hdrlen; - - if (urb->status) { - if (urb->status != -ESHUTDOWN) - ar5523_err(ar, "RX USB error %d.\n", urb->status); - goto skip; - } - - if (urb->actual_length < sizeof(struct ar5523_cmd_hdr)) { - ar5523_err(ar, "RX USB to short.\n"); - goto skip; - } - - ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, - be32_to_cpu(hdr->code) & 0xff, hdr->priv); - - code = be32_to_cpu(hdr->code); - hdrlen = be32_to_cpu(hdr->len); - - switch (code & 0xff) { - default: - /* reply to a read command */ - if (hdr->priv != AR5523_CMD_ID) { - ar5523_err(ar, "Unexpected command id: %02x\n", - code & 0xff); - goto skip; - } - ar5523_read_reply(ar, hdr, cmd); - break; - - case WDCMSG_DEVICE_AVAIL: - ar5523_dbg(ar, "WDCMSG_DEVICE_AVAIL\n"); - cmd->res = 0; - cmd->olen = 0; - complete(&cmd->done); - break; - - case WDCMSG_SEND_COMPLETE: - ar5523_dbg(ar, "WDCMSG_SEND_COMPLETE: %d pending\n", - atomic_read(&ar->tx_nr_pending)); - if (!test_bit(AR5523_HW_UP, &ar->flags)) - ar5523_dbg(ar, "Unexpected WDCMSG_SEND_COMPLETE\n"); - else { - mod_timer(&ar->tx_wd_timer, - jiffies + AR5523_TX_WD_TIMEOUT); - ar5523_data_tx_pkt_put(ar); - - } - break; - - case WDCMSG_TARGET_START: - /* This command returns a bogus id so it needs special - handling */ - dlen = hdrlen - sizeof(*hdr); - if (dlen != (int)sizeof(u32)) { - ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); - return; - } - memcpy(cmd->odata, hdr + 1, sizeof(u32)); - cmd->olen = sizeof(u32); - cmd->res = 0; - complete(&cmd->done); - break; - - case WDCMSG_STATS_UPDATE: - ar5523_dbg(ar, "WDCMSG_STATS_UPDATE\n"); - break; - } - -skip: - ar5523_submit_rx_cmd(ar); -} - -static int ar5523_alloc_rx_cmd(struct ar5523 *ar) -{ - ar->rx_cmd_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ar->rx_cmd_urb) - return -ENOMEM; - - ar->rx_cmd_buf = usb_alloc_coherent(ar->dev, AR5523_MAX_RXCMDSZ, - GFP_KERNEL, - &ar->rx_cmd_urb->transfer_dma); - if (!ar->rx_cmd_buf) { - usb_free_urb(ar->rx_cmd_urb); - return -ENOMEM; - } - return 0; -} - -static void ar5523_cancel_rx_cmd(struct ar5523 *ar) -{ - usb_kill_urb(ar->rx_cmd_urb); -} - -static void ar5523_free_rx_cmd(struct ar5523 *ar) -{ - usb_free_coherent(ar->dev, AR5523_MAX_RXCMDSZ, - ar->rx_cmd_buf, ar->rx_cmd_urb->transfer_dma); - usb_free_urb(ar->rx_cmd_urb); -} - -static int ar5523_submit_rx_cmd(struct ar5523 *ar) -{ - int error; - - usb_fill_bulk_urb(ar->rx_cmd_urb, ar->dev, - ar5523_cmd_rx_pipe(ar->dev), ar->rx_cmd_buf, - AR5523_MAX_RXCMDSZ, ar5523_cmd_rx_cb, ar); - ar->rx_cmd_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = usb_submit_urb(ar->rx_cmd_urb, GFP_ATOMIC); - if (error) { - if (error != -ENODEV) - ar5523_err(ar, "error %d when submitting rx urb\n", - error); - return error; - } - return 0; -} - -/* - * Command submitted cb - */ -static void ar5523_cmd_tx_cb(struct urb *urb) -{ - struct ar5523_tx_cmd *cmd = urb->context; - struct ar5523 *ar = cmd->ar; - - if (urb->status) { - ar5523_err(ar, "Failed to TX command. Status = %d\n", - urb->status); - cmd->res = urb->status; - complete(&cmd->done); - return; - } - - if (!(cmd->flags & AR5523_CMD_FLAG_READ)) { - cmd->res = 0; - complete(&cmd->done); - } -} - -static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata, - int ilen, void *odata, int olen, int flags) -{ - struct ar5523_cmd_hdr *hdr; - struct ar5523_tx_cmd *cmd = &ar->tx_cmd; - int xferlen, error; - - /* always bulk-out a multiple of 4 bytes */ - xferlen = (sizeof(struct ar5523_cmd_hdr) + ilen + 3) & ~3; - - hdr = (struct ar5523_cmd_hdr *)cmd->buf_tx; - memset(hdr, 0, sizeof(struct ar5523_cmd_hdr)); - hdr->len = cpu_to_be32(xferlen); - hdr->code = cpu_to_be32(code); - hdr->priv = AR5523_CMD_ID; - - if (flags & AR5523_CMD_FLAG_MAGIC) - hdr->magic = cpu_to_be32(1 << 24); - memcpy(hdr + 1, idata, ilen); - - cmd->odata = odata; - cmd->olen = olen; - cmd->flags = flags; - - ar5523_dbg(ar, "do cmd %02x\n", code); - - usb_fill_bulk_urb(cmd->urb_tx, ar->dev, ar5523_cmd_tx_pipe(ar->dev), - cmd->buf_tx, xferlen, ar5523_cmd_tx_cb, cmd); - cmd->urb_tx->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - error = usb_submit_urb(cmd->urb_tx, GFP_KERNEL); - if (error) { - ar5523_err(ar, "could not send command 0x%x, error=%d\n", - code, error); - return error; - } - - if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) { - cmd->odata = NULL; - ar5523_err(ar, "timeout waiting for command %02x reply\n", - code); - cmd->res = -ETIMEDOUT; - } - return cmd->res; -} - -static int ar5523_cmd_write(struct ar5523 *ar, u32 code, const void *data, - int len, int flags) -{ - flags &= ~AR5523_CMD_FLAG_READ; - return ar5523_cmd(ar, code, data, len, NULL, 0, flags); -} - -static int ar5523_cmd_read(struct ar5523 *ar, u32 code, const void *idata, - int ilen, void *odata, int olen, int flags) -{ - flags |= AR5523_CMD_FLAG_READ; - return ar5523_cmd(ar, code, idata, ilen, odata, olen, flags); -} - -static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val) -{ - struct ar5523_write_mac write; - int error; - - write.reg = cpu_to_be32(reg); - write.len = cpu_to_be32(0); /* 0 = single write */ - *(__be32 *)write.data = cpu_to_be32(val); - - error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, - 3 * sizeof(u32), 0); - if (error != 0) - ar5523_err(ar, "could not write register 0x%02x\n", reg); - return error; -} - -static int ar5523_config_multi(struct ar5523 *ar, u32 reg, const void *data, - int len) -{ - struct ar5523_write_mac write; - int error; - - write.reg = cpu_to_be32(reg); - write.len = cpu_to_be32(len); - memcpy(write.data, data, len); - - /* properly handle the case where len is zero (reset) */ - error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, - (len == 0) ? sizeof(u32) : 2 * sizeof(u32) + len, 0); - if (error != 0) - ar5523_err(ar, "could not write %d bytes to register 0x%02x\n", - len, reg); - return error; -} - -static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata, - int olen) -{ - int error; - __be32 which_be; - - which_be = cpu_to_be32(which); - error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, - &which_be, sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC); - if (error != 0) - ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", which); - return error; -} - -static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) -{ - int error; - __be32 cap_be, val_be; - - cap_be = cpu_to_be32(cap); - error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, &cap_be, - sizeof(cap_be), &val_be, sizeof(__be32), - AR5523_CMD_FLAG_MAGIC); - if (error != 0) { - ar5523_err(ar, "could not read capability %u\n", cap); - return error; - } - *val = be32_to_cpu(val_be); - return error; -} - -static int ar5523_get_devcap(struct ar5523 *ar) -{ -#define GETCAP(x) do { \ - error = ar5523_get_capability(ar, x, &cap); \ - if (error != 0) \ - return error; \ - ar5523_info(ar, "Cap: " \ - "%s=0x%08x\n", #x, cap); \ -} while (0) - int error; - u32 cap; - - /* collect device capabilities */ - GETCAP(CAP_TARGET_VERSION); - GETCAP(CAP_TARGET_REVISION); - GETCAP(CAP_MAC_VERSION); - GETCAP(CAP_MAC_REVISION); - GETCAP(CAP_PHY_REVISION); - GETCAP(CAP_ANALOG_5GHz_REVISION); - GETCAP(CAP_ANALOG_2GHz_REVISION); - - GETCAP(CAP_REG_DOMAIN); - GETCAP(CAP_REG_CAP_BITS); - GETCAP(CAP_WIRELESS_MODES); - GETCAP(CAP_CHAN_SPREAD_SUPPORT); - GETCAP(CAP_COMPRESS_SUPPORT); - GETCAP(CAP_BURST_SUPPORT); - GETCAP(CAP_FAST_FRAMES_SUPPORT); - GETCAP(CAP_CHAP_TUNING_SUPPORT); - GETCAP(CAP_TURBOG_SUPPORT); - GETCAP(CAP_TURBO_PRIME_SUPPORT); - GETCAP(CAP_DEVICE_TYPE); - GETCAP(CAP_WME_SUPPORT); - GETCAP(CAP_TOTAL_QUEUES); - GETCAP(CAP_CONNECTION_ID_MAX); - - GETCAP(CAP_LOW_5GHZ_CHAN); - GETCAP(CAP_HIGH_5GHZ_CHAN); - GETCAP(CAP_LOW_2GHZ_CHAN); - GETCAP(CAP_HIGH_2GHZ_CHAN); - GETCAP(CAP_TWICE_ANTENNAGAIN_5G); - GETCAP(CAP_TWICE_ANTENNAGAIN_2G); - - GETCAP(CAP_CIPHER_AES_CCM); - GETCAP(CAP_CIPHER_TKIP); - GETCAP(CAP_MIC_TKIP); - return 0; -} - -static int ar5523_set_ledsteady(struct ar5523 *ar, int lednum, int ledmode) -{ - struct ar5523_cmd_ledsteady led; - - led.lednum = cpu_to_be32(lednum); - led.ledmode = cpu_to_be32(ledmode); - - ar5523_dbg(ar, "set %s led %s (steady)\n", - (lednum == UATH_LED_LINK) ? "link" : "activity", - ledmode ? "on" : "off"); - return ar5523_cmd_write(ar, WDCMSG_SET_LED_STEADY, &led, sizeof(led), - 0); -} - -static int ar5523_set_rxfilter(struct ar5523 *ar, u32 bits, u32 op) -{ - struct ar5523_cmd_rx_filter rxfilter; - - rxfilter.bits = cpu_to_be32(bits); - rxfilter.op = cpu_to_be32(op); - - ar5523_dbg(ar, "setting Rx filter=0x%x flags=0x%x\n", bits, op); - return ar5523_cmd_write(ar, WDCMSG_RX_FILTER, &rxfilter, - sizeof(rxfilter), 0); -} - -static int ar5523_reset_tx_queues(struct ar5523 *ar) -{ - __be32 qid = cpu_to_be32(0); - - ar5523_dbg(ar, "resetting Tx queue\n"); - return ar5523_cmd_write(ar, WDCMSG_RELEASE_TX_QUEUE, - &qid, sizeof(qid), 0); -} - -static int ar5523_set_chan(struct ar5523 *ar) -{ - struct ieee80211_conf *conf = &ar->hw->conf; - - struct ar5523_cmd_reset reset; - - memset(&reset, 0, sizeof(reset)); - reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); - reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); - reset.freq = cpu_to_be32(conf->channel->center_freq); - reset.maxrdpower = cpu_to_be32(50); /* XXX */ - reset.channelchange = cpu_to_be32(1); - reset.keeprccontent = cpu_to_be32(0); - - ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", - be32_to_cpu(reset.flags), - conf->channel->center_freq); - return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0); -} - -static int ar5523_queue_init(struct ar5523 *ar) -{ - struct ar5523_cmd_txq_setup qinfo; - - ar5523_dbg(ar, "setting up Tx queue\n"); - qinfo.qid = cpu_to_be32(0); - qinfo.len = cpu_to_be32(sizeof(qinfo.attr)); - qinfo.attr.priority = cpu_to_be32(0); /* XXX */ - qinfo.attr.aifs = cpu_to_be32(3); - qinfo.attr.logcwmin = cpu_to_be32(4); - qinfo.attr.logcwmax = cpu_to_be32(10); - qinfo.attr.bursttime = cpu_to_be32(0); - qinfo.attr.mode = cpu_to_be32(0); - qinfo.attr.qflags = cpu_to_be32(1); /* XXX? */ - return ar5523_cmd_write(ar, WDCMSG_SETUP_TX_QUEUE, &qinfo, - sizeof(qinfo), 0); -} - -static int ar5523_switch_chan(struct ar5523 *ar) -{ - int error; - - error = ar5523_set_chan(ar); - if (error) { - ar5523_err(ar, "could not set chan, error %d\n", error); - goto out_err; - } - - /* reset Tx rings */ - error = ar5523_reset_tx_queues(ar); - if (error) { - ar5523_err(ar, "could not reset Tx queues, error %d\n", - error); - goto out_err; - } - /* set Tx rings WME properties */ - error = ar5523_queue_init(ar); - if (error) - ar5523_err(ar, "could not init wme, error %d\n", error); - -out_err: - return error; -} - -static void ar5523_rx_data_put(struct ar5523 *ar, - struct ar5523_rx_data *data) -{ - unsigned long flags; - spin_lock_irqsave(&ar->rx_data_list_lock, flags); - list_move(&data->list, &ar->rx_data_free); - spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); -} - -static void ar5523_data_rx_cb(struct urb *urb) -{ - struct ar5523_rx_data *data = urb->context; - struct ar5523 *ar = data->ar; - struct ar5523_rx_desc *desc; - struct ar5523_chunk *chunk; - struct ieee80211_hw *hw = ar->hw; - struct ieee80211_rx_status *rx_status; - u32 rxlen; - int usblen = urb->actual_length; - int hdrlen, pad; - - ar5523_dbg(ar, "%s\n", __func__); - /* sync/async unlink faults aren't errors */ - if (urb->status) { - if (urb->status != -ESHUTDOWN) - ar5523_err(ar, "%s: USB err: %d\n", __func__, - urb->status); - goto skip; - } - - if (usblen < AR5523_MIN_RXBUFSZ) { - ar5523_err(ar, "RX: wrong xfer size (usblen=%d)\n", usblen); - goto skip; - } - - chunk = (struct ar5523_chunk *) data->skb->data; - - if (((chunk->flags & UATH_CFLAGS_FINAL) == 0) || - chunk->seqnum != 0) { - ar5523_dbg(ar, "RX: No final flag. s: %d f: %02x l: %d\n", - chunk->seqnum, chunk->flags, - be16_to_cpu(chunk->length)); - goto skip; - } - - /* Rx descriptor is located at the end, 32-bit aligned */ - desc = (struct ar5523_rx_desc *) - (data->skb->data + usblen - sizeof(struct ar5523_rx_desc)); - - rxlen = be32_to_cpu(desc->len); - if (rxlen > ar->rxbufsz) { - ar5523_dbg(ar, "RX: Bad descriptor (len=%d)\n", - be32_to_cpu(desc->len)); - goto skip; - } - - if (!rxlen) { - ar5523_dbg(ar, "RX: rxlen is 0\n"); - goto skip; - } - - if (be32_to_cpu(desc->status) != 0) { - ar5523_dbg(ar, "Bad RX status (0x%x len = %d). Skip\n", - be32_to_cpu(desc->status), be32_to_cpu(desc->len)); - goto skip; - } - - skb_reserve(data->skb, sizeof(*chunk)); - skb_put(data->skb, rxlen - sizeof(struct ar5523_rx_desc)); - - hdrlen = ieee80211_get_hdrlen_from_skb(data->skb); - if (!IS_ALIGNED(hdrlen, 4)) { - ar5523_dbg(ar, "eek, alignment workaround activated\n"); - pad = ALIGN(hdrlen, 4) - hdrlen; - memmove(data->skb->data + pad, data->skb->data, hdrlen); - skb_pull(data->skb, pad); - skb_put(data->skb, pad); - } - - rx_status = IEEE80211_SKB_RXCB(data->skb); - memset(rx_status, 0, sizeof(*rx_status)); - rx_status->freq = be32_to_cpu(desc->channel); - rx_status->band = hw->conf.channel->band; - rx_status->signal = -95 + be32_to_cpu(desc->rssi); - - ieee80211_rx_irqsafe(hw, data->skb); - data->skb = NULL; - -skip: - if (data->skb) { - dev_kfree_skb_irq(data->skb); - data->skb = NULL; - } - - ar5523_rx_data_put(ar, data); - if (atomic_inc_return(&ar->rx_data_free_cnt) >= - AR5523_RX_DATA_REFILL_COUNT && - test_bit(AR5523_HW_UP, &ar->flags)) - queue_work(ar->wq, &ar->rx_refill_work); -} - -static void ar5523_rx_refill_work(struct work_struct *work) -{ - struct ar5523 *ar = container_of(work, struct ar5523, rx_refill_work); - struct ar5523_rx_data *data; - unsigned long flags; - int error; - - ar5523_dbg(ar, "%s\n", __func__); - do { - spin_lock_irqsave(&ar->rx_data_list_lock, flags); - - if (!list_empty(&ar->rx_data_free)) - data = (struct ar5523_rx_data *) ar->rx_data_free.next; - else - data = NULL; - spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); - - if (!data) - goto done; - - data->skb = alloc_skb(ar->rxbufsz, GFP_KERNEL); - if (!data->skb) { - ar5523_err(ar, "could not allocate rx skbuff\n"); - return; - } - - usb_fill_bulk_urb(data->urb, ar->dev, - ar5523_data_rx_pipe(ar->dev), data->skb->data, - ar->rxbufsz, ar5523_data_rx_cb, data); - - spin_lock_irqsave(&ar->rx_data_list_lock, flags); - list_move(&data->list, &ar->rx_data_used); - spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); - atomic_dec(&ar->rx_data_free_cnt); - - error = usb_submit_urb(data->urb, GFP_KERNEL); - if (error) { - kfree_skb(data->skb); - if (error != -ENODEV) - ar5523_err(ar, "Err sending rx data urb %d\n", - error); - ar5523_rx_data_put(ar, data); - atomic_inc(&ar->rx_data_free_cnt); - return; - } - - } while (true); -done: - return; -} - -static void ar5523_cancel_rx_bufs(struct ar5523 *ar) -{ - struct ar5523_rx_data *data; - unsigned long flags; - - do { - spin_lock_irqsave(&ar->rx_data_list_lock, flags); - if (!list_empty(&ar->rx_data_used)) - data = (struct ar5523_rx_data *) ar->rx_data_used.next; - else - data = NULL; - spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); - - if (!data) - break; - - usb_kill_urb(data->urb); - list_move(&data->list, &ar->rx_data_free); - atomic_inc(&ar->rx_data_free_cnt); - } while (data); -} - -static void ar5523_free_rx_bufs(struct ar5523 *ar) -{ - struct ar5523_rx_data *data; - - ar5523_cancel_rx_bufs(ar); - while (!list_empty(&ar->rx_data_free)) { - data = (struct ar5523_rx_data *) ar->rx_data_free.next; - list_del(&data->list); - usb_free_urb(data->urb); - } -} - -static int ar5523_alloc_rx_bufs(struct ar5523 *ar) -{ - int i; - - for (i = 0; i < AR5523_RX_DATA_COUNT; i++) { - struct ar5523_rx_data *data = &ar->rx_data[i]; - - data->ar = ar; - data->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!data->urb) { - ar5523_err(ar, "could not allocate rx data urb\n"); - goto err; - } - list_add_tail(&data->list, &ar->rx_data_free); - atomic_inc(&ar->rx_data_free_cnt); - } - return 0; - -err: - ar5523_free_rx_bufs(ar); - return -ENOMEM; -} - -static void ar5523_data_tx_pkt_put(struct ar5523 *ar) -{ - atomic_dec(&ar->tx_nr_total); - if (!atomic_dec_return(&ar->tx_nr_pending)) { - del_timer(&ar->tx_wd_timer); - wake_up(&ar->tx_flush_waitq); - } - - if (atomic_read(&ar->tx_nr_total) < AR5523_TX_DATA_RESTART_COUNT) { - ar5523_dbg(ar, "restart tx queue\n"); - ieee80211_wake_queues(ar->hw); - } -} - -static void ar5523_data_tx_cb(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); - struct ar5523_tx_data *data = (struct ar5523_tx_data *) - txi->driver_data; - struct ar5523 *ar = data->ar; - unsigned long flags; - - ar5523_dbg(ar, "data tx urb completed: %d\n", urb->status); - - spin_lock_irqsave(&ar->tx_data_list_lock, flags); - list_del(&data->list); - spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); - - if (urb->status) { - ar5523_dbg(ar, "%s: urb status: %d\n", __func__, urb->status); - ar5523_data_tx_pkt_put(ar); - ieee80211_free_txskb(ar->hw, skb); - } else { - skb_pull(skb, sizeof(struct ar5523_tx_desc) + sizeof(__be32)); - ieee80211_tx_status_irqsafe(ar->hw, skb); - } - usb_free_urb(urb); -} - -static void ar5523_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); - struct ar5523_tx_data *data = (struct ar5523_tx_data *) - txi->driver_data; - struct ar5523 *ar = hw->priv; - unsigned long flags; - - ar5523_dbg(ar, "tx called\n"); - if (atomic_inc_return(&ar->tx_nr_total) >= AR5523_TX_DATA_COUNT) { - ar5523_dbg(ar, "tx queue full\n"); - ar5523_dbg(ar, "stop queues (tot %d pend %d)\n", - atomic_read(&ar->tx_nr_total), - atomic_read(&ar->tx_nr_pending)); - ieee80211_stop_queues(hw); - } - - data->skb = skb; - - spin_lock_irqsave(&ar->tx_data_list_lock, flags); - list_add_tail(&data->list, &ar->tx_queue_pending); - spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); - - ieee80211_queue_work(ar->hw, &ar->tx_work); -} - -static void ar5523_tx_work_locked(struct ar5523 *ar) -{ - struct ar5523_tx_data *data; - struct ar5523_tx_desc *desc; - struct ar5523_chunk *chunk; - struct ieee80211_tx_info *txi; - struct urb *urb; - struct sk_buff *skb; - int error = 0, paylen; - u32 txqid; - unsigned long flags; - - BUILD_BUG_ON(sizeof(struct ar5523_tx_data) > - IEEE80211_TX_INFO_DRIVER_DATA_SIZE); - - ar5523_dbg(ar, "%s\n", __func__); - do { - spin_lock_irqsave(&ar->tx_data_list_lock, flags); - if (!list_empty(&ar->tx_queue_pending)) { - data = (struct ar5523_tx_data *) - ar->tx_queue_pending.next; - list_del(&data->list); - } else - data = NULL; - spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); - - if (!data) - break; - - skb = data->skb; - txqid = 0; - txi = IEEE80211_SKB_CB(skb); - paylen = skb->len; - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - ar5523_err(ar, "Failed to allocate TX urb\n"); - ieee80211_free_txskb(ar->hw, skb); - continue; - } - - data->ar = ar; - data->urb = urb; - - desc = (struct ar5523_tx_desc *)skb_push(skb, sizeof(*desc)); - chunk = (struct ar5523_chunk *)skb_push(skb, sizeof(*chunk)); - - chunk->seqnum = 0; - chunk->flags = UATH_CFLAGS_FINAL; - chunk->length = cpu_to_be16(skb->len); - - desc->msglen = cpu_to_be32(skb->len); - desc->msgid = AR5523_DATA_ID; - desc->buflen = cpu_to_be32(paylen); - desc->type = cpu_to_be32(WDCMSG_SEND); - desc->flags = cpu_to_be32(UATH_TX_NOTIFY); - - if (test_bit(AR5523_CONNECTED, &ar->flags)) - desc->connid = cpu_to_be32(AR5523_ID_BSS); - else - desc->connid = cpu_to_be32(AR5523_ID_BROADCAST); - - if (txi->flags & IEEE80211_TX_CTL_USE_MINRATE) - txqid |= UATH_TXQID_MINRATE; - - desc->txqid = cpu_to_be32(txqid); - - urb->transfer_flags = URB_ZERO_PACKET; - usb_fill_bulk_urb(urb, ar->dev, ar5523_data_tx_pipe(ar->dev), - skb->data, skb->len, ar5523_data_tx_cb, skb); - - spin_lock_irqsave(&ar->tx_data_list_lock, flags); - list_add_tail(&data->list, &ar->tx_queue_submitted); - spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); - mod_timer(&ar->tx_wd_timer, jiffies + AR5523_TX_WD_TIMEOUT); - atomic_inc(&ar->tx_nr_pending); - - ar5523_dbg(ar, "TX Frame (%d pending)\n", - atomic_read(&ar->tx_nr_pending)); - error = usb_submit_urb(urb, GFP_KERNEL); - if (error) { - ar5523_err(ar, "error %d when submitting tx urb\n", - error); - spin_lock_irqsave(&ar->tx_data_list_lock, flags); - list_del(&data->list); - spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); - atomic_dec(&ar->tx_nr_pending); - ar5523_data_tx_pkt_put(ar); - usb_free_urb(urb); - ieee80211_free_txskb(ar->hw, skb); - } - } while (true); -} - -static void ar5523_tx_work(struct work_struct *work) -{ - struct ar5523 *ar = container_of(work, struct ar5523, tx_work); - - ar5523_dbg(ar, "%s\n", __func__); - mutex_lock(&ar->mutex); - ar5523_tx_work_locked(ar); - mutex_unlock(&ar->mutex); -} - -static void ar5523_tx_wd_timer(unsigned long arg) -{ - struct ar5523 *ar = (struct ar5523 *) arg; - - ar5523_dbg(ar, "TX watchdog timer triggered\n"); - ieee80211_queue_work(ar->hw, &ar->tx_wd_work); -} - -static void ar5523_tx_wd_work(struct work_struct *work) -{ - struct ar5523 *ar = container_of(work, struct ar5523, tx_wd_work); - - /* Occasionally the TX queues stop responding. The only way to - * recover seems to be to reset the dongle. - */ - - mutex_lock(&ar->mutex); - ar5523_err(ar, "TX queue stuck (tot %d pend %d)\n", - atomic_read(&ar->tx_nr_total), - atomic_read(&ar->tx_nr_pending)); - - ar5523_err(ar, "Will restart dongle.\n"); - ar5523_cmd_write(ar, WDCMSG_TARGET_RESET, NULL, 0, 0); - mutex_unlock(&ar->mutex); -} - -static void ar5523_flush_tx(struct ar5523 *ar) -{ - ar5523_tx_work_locked(ar); - - /* Don't waste time trying to flush if USB is disconnected */ - if (test_bit(AR5523_USB_DISCONNECTED, &ar->flags)) - return; - if (!wait_event_timeout(ar->tx_flush_waitq, - !atomic_read(&ar->tx_nr_pending), AR5523_FLUSH_TIMEOUT)) - ar5523_err(ar, "flush timeout (tot %d pend %d)\n", - atomic_read(&ar->tx_nr_total), - atomic_read(&ar->tx_nr_pending)); -} - -static void ar5523_free_tx_cmd(struct ar5523 *ar) -{ - struct ar5523_tx_cmd *cmd = &ar->tx_cmd; - - usb_free_coherent(ar->dev, AR5523_MAX_RXCMDSZ, cmd->buf_tx, - cmd->urb_tx->transfer_dma); - usb_free_urb(cmd->urb_tx); -} - -static int ar5523_alloc_tx_cmd(struct ar5523 *ar) -{ - struct ar5523_tx_cmd *cmd = &ar->tx_cmd; - - cmd->ar = ar; - init_completion(&cmd->done); - - cmd->urb_tx = usb_alloc_urb(0, GFP_KERNEL); - if (!cmd->urb_tx) { - ar5523_err(ar, "could not allocate urb\n"); - return -ENOMEM; - } - cmd->buf_tx = usb_alloc_coherent(ar->dev, AR5523_MAX_TXCMDSZ, - GFP_KERNEL, - &cmd->urb_tx->transfer_dma); - if (!cmd->buf_tx) { - usb_free_urb(cmd->urb_tx); - return -ENOMEM; - } - return 0; -} - -/* - * This function is called periodically (every second) when associated to - * query device statistics. - */ -static void ar5523_stat_work(struct work_struct *work) -{ - struct ar5523 *ar = container_of(work, struct ar5523, stat_work.work); - int error; - - ar5523_dbg(ar, "%s\n", __func__); - mutex_lock(&ar->mutex); - - /* - * Send request for statistics asynchronously once a second. This - * seems to be important. Throughput is a lot better if this is done. - */ - error = ar5523_cmd_write(ar, WDCMSG_TARGET_GET_STATS, NULL, 0, 0); - if (error) - ar5523_err(ar, "could not query stats, error %d\n", error); - mutex_unlock(&ar->mutex); - ieee80211_queue_delayed_work(ar->hw, &ar->stat_work, HZ); -} - -/* - * Interface routines to the mac80211 stack. - */ -static int ar5523_start(struct ieee80211_hw *hw) -{ - struct ar5523 *ar = hw->priv; - int error; - __be32 val; - - ar5523_dbg(ar, "start called\n"); - - mutex_lock(&ar->mutex); - val = cpu_to_be32(0); - ar5523_cmd_write(ar, WDCMSG_BIND, &val, sizeof(val), 0); - - /* set MAC address */ - ar5523_config_multi(ar, CFG_MAC_ADDR, &ar->hw->wiphy->perm_addr, - ETH_ALEN); - - /* XXX honor net80211 state */ - ar5523_config(ar, CFG_RATE_CONTROL_ENABLE, 0x00000001); - ar5523_config(ar, CFG_DIVERSITY_CTL, 0x00000001); - ar5523_config(ar, CFG_ABOLT, 0x0000003f); - ar5523_config(ar, CFG_WME_ENABLED, 0x00000000); - - ar5523_config(ar, CFG_SERVICE_TYPE, 1); - ar5523_config(ar, CFG_TP_SCALE, 0x00000000); - ar5523_config(ar, CFG_TPC_HALF_DBM5, 0x0000003c); - ar5523_config(ar, CFG_TPC_HALF_DBM2, 0x0000003c); - ar5523_config(ar, CFG_OVERRD_TX_POWER, 0x00000000); - ar5523_config(ar, CFG_GMODE_PROTECTION, 0x00000000); - ar5523_config(ar, CFG_GMODE_PROTECT_RATE_INDEX, 0x00000003); - ar5523_config(ar, CFG_PROTECTION_TYPE, 0x00000000); - ar5523_config(ar, CFG_MODE_CTS, 0x00000002); - - error = ar5523_cmd_read(ar, WDCMSG_TARGET_START, NULL, 0, - &val, sizeof(val), AR5523_CMD_FLAG_MAGIC); - if (error) { - ar5523_dbg(ar, "could not start target, error %d\n", error); - goto err; - } - ar5523_dbg(ar, "WDCMSG_TARGET_START returns handle: 0x%x\n", - be32_to_cpu(val)); - - ar5523_switch_chan(ar); - - val = cpu_to_be32(TARGET_DEVICE_AWAKE); - ar5523_cmd_write(ar, WDCMSG_SET_PWR_MODE, &val, sizeof(val), 0); - /* XXX? check */ - ar5523_cmd_write(ar, WDCMSG_RESET_KEY_CACHE, NULL, 0, 0); - - set_bit(AR5523_HW_UP, &ar->flags); - queue_work(ar->wq, &ar->rx_refill_work); - - /* enable Rx */ - ar5523_set_rxfilter(ar, 0, UATH_FILTER_OP_INIT); - ar5523_set_rxfilter(ar, - UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | - UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON, - UATH_FILTER_OP_SET); - - ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_ON); - ar5523_dbg(ar, "start OK\n"); - -err: - mutex_unlock(&ar->mutex); - return error; -} - -static void ar5523_stop(struct ieee80211_hw *hw) -{ - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "stop called\n"); - - cancel_delayed_work_sync(&ar->stat_work); - mutex_lock(&ar->mutex); - clear_bit(AR5523_HW_UP, &ar->flags); - - ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); - ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_OFF); - - ar5523_cmd_write(ar, WDCMSG_TARGET_STOP, NULL, 0, 0); - - del_timer_sync(&ar->tx_wd_timer); - cancel_work_sync(&ar->tx_wd_work); - cancel_work_sync(&ar->rx_refill_work); - ar5523_cancel_rx_bufs(ar); - mutex_unlock(&ar->mutex); -} - -static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct ar5523 *ar = hw->priv; - int ret; - - ar5523_dbg(ar, "set_rts_threshold called\n"); - mutex_lock(&ar->mutex); - - ret = ar5523_config(ar, CFG_USER_RTS_THRESHOLD, value); - - mutex_unlock(&ar->mutex); - return ret; -} - -static void ar5523_flush(struct ieee80211_hw *hw, bool drop) -{ - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "flush called\n"); - ar5523_flush_tx(ar); -} - -static int ar5523_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "add interface called\n"); - - if (ar->vif) { - ar5523_dbg(ar, "invalid add_interface\n"); - return -EOPNOTSUPP; - } - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - ar->vif = vif; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -static void ar5523_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "remove interface called\n"); - ar->vif = NULL; -} - -static int ar5523_hwconfig(struct ieee80211_hw *hw, u32 changed) -{ - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "config called\n"); - mutex_lock(&ar->mutex); - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ar5523_dbg(ar, "Do channel switch\n"); - ar5523_flush_tx(ar); - ar5523_switch_chan(ar); - } - mutex_unlock(&ar->mutex); - return 0; -} - -static int ar5523_get_wlan_mode(struct ar5523 *ar, - struct ieee80211_bss_conf *bss_conf) -{ - struct ieee80211_supported_band *band; - int bit; - struct ieee80211_sta *sta; - u32 sta_rate_set; - - band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; - sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); - if (!sta) { - ar5523_info(ar, "STA not found!\n"); - return WLAN_MODE_11b; - } - sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; - - for (bit = 0; bit < band->n_bitrates; bit++) { - if (sta_rate_set & 1) { - int rate = band->bitrates[bit].bitrate; - switch (rate) { - case 60: - case 90: - case 120: - case 180: - case 240: - case 360: - case 480: - case 540: - return WLAN_MODE_11g; - } - } - sta_rate_set >>= 1; - } - return WLAN_MODE_11b; -} - -static void ar5523_create_rateset(struct ar5523 *ar, - struct ieee80211_bss_conf *bss_conf, - struct ar5523_cmd_rateset *rs, - bool basic) -{ - struct ieee80211_supported_band *band; - struct ieee80211_sta *sta; - int bit, i = 0; - u32 sta_rate_set, basic_rate_set; - - sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); - basic_rate_set = bss_conf->basic_rates; - if (!sta) { - ar5523_info(ar, "STA not found. Cannot set rates\n"); - sta_rate_set = bss_conf->basic_rates; - } else - sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; - - ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); - - band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; - for (bit = 0; bit < band->n_bitrates; bit++) { - BUG_ON(i >= AR5523_MAX_NRATES); - ar5523_dbg(ar, "Considering rate %d : %d\n", - band->bitrates[bit].hw_value, sta_rate_set & 1); - if (sta_rate_set & 1) { - rs->set[i] = band->bitrates[bit].hw_value; - if (basic_rate_set & 1 && basic) - rs->set[i] |= 0x80; - i++; - } - sta_rate_set >>= 1; - basic_rate_set >>= 1; - } - - rs->length = i; -} - -static int ar5523_set_basic_rates(struct ar5523 *ar, - struct ieee80211_bss_conf *bss) -{ - struct ar5523_cmd_rates rates; - - memset(&rates, 0, sizeof(rates)); - rates.connid = cpu_to_be32(2); /* XXX */ - rates.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); - ar5523_create_rateset(ar, bss, &rates.rateset, true); - - return ar5523_cmd_write(ar, WDCMSG_SET_BASIC_RATE, &rates, - sizeof(rates), 0); -} - -static int ar5523_create_connection(struct ar5523 *ar, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss) -{ - struct ar5523_cmd_create_connection create; - int wlan_mode; - - memset(&create, 0, sizeof(create)); - create.connid = cpu_to_be32(2); - create.bssid = cpu_to_be32(0); - /* XXX packed or not? */ - create.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); - - ar5523_create_rateset(ar, bss, &create.connattr.rateset, false); - - wlan_mode = ar5523_get_wlan_mode(ar, bss); - create.connattr.wlanmode = cpu_to_be32(wlan_mode); - - return ar5523_cmd_write(ar, WDCMSG_CREATE_CONNECTION, &create, - sizeof(create), 0); -} - -static int ar5523_write_associd(struct ar5523 *ar, - struct ieee80211_bss_conf *bss) -{ - struct ar5523_cmd_set_associd associd; - - memset(&associd, 0, sizeof(associd)); - associd.defaultrateix = cpu_to_be32(0); /* XXX */ - associd.associd = cpu_to_be32(bss->aid); - associd.timoffset = cpu_to_be32(0x3b); /* XXX */ - memcpy(associd.bssid, bss->bssid, ETH_ALEN); - return ar5523_cmd_write(ar, WDCMSG_WRITE_ASSOCID, &associd, - sizeof(associd), 0); -} - -static void ar5523_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss, - u32 changed) -{ - struct ar5523 *ar = hw->priv; - int error; - - ar5523_dbg(ar, "bss_info_changed called\n"); - mutex_lock(&ar->mutex); - - if (!(changed & BSS_CHANGED_ASSOC)) - goto out_unlock; - - if (bss->assoc) { - error = ar5523_create_connection(ar, vif, bss); - if (error) { - ar5523_err(ar, "could not create connection\n"); - goto out_unlock; - } - - error = ar5523_set_basic_rates(ar, bss); - if (error) { - ar5523_err(ar, "could not set negotiated rate set\n"); - goto out_unlock; - } - - error = ar5523_write_associd(ar, bss); - if (error) { - ar5523_err(ar, "could not set association\n"); - goto out_unlock; - } - - /* turn link LED on */ - ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_ON); - set_bit(AR5523_CONNECTED, &ar->flags); - ieee80211_queue_delayed_work(hw, &ar->stat_work, HZ); - - } else { - cancel_delayed_work(&ar->stat_work); - clear_bit(AR5523_CONNECTED, &ar->flags); - ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); - } - -out_unlock: - mutex_unlock(&ar->mutex); - -} - -#define AR5523_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_OTHER_BSS) - -static void ar5523_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) -{ - struct ar5523 *ar = hw->priv; - u32 filter = 0; - - ar5523_dbg(ar, "configure_filter called\n"); - mutex_lock(&ar->mutex); - ar5523_flush_tx(ar); - - *total_flags &= AR5523_SUPPORTED_FILTERS; - - /* The filters seems strange. UATH_FILTER_RX_BCAST and - * UATH_FILTER_RX_MCAST does not result in those frames being RXed. - * The only way I have found to get [mb]cast frames seems to be - * to set UATH_FILTER_RX_PROM. */ - filter |= UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | - UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON | - UATH_FILTER_RX_PROM; - - ar5523_set_rxfilter(ar, 0, UATH_FILTER_OP_INIT); - ar5523_set_rxfilter(ar, filter, UATH_FILTER_OP_SET); - - mutex_unlock(&ar->mutex); -} - -static const struct ieee80211_ops ar5523_ops = { - .start = ar5523_start, - .stop = ar5523_stop, - .tx = ar5523_tx, - .set_rts_threshold = ar5523_set_rts_threshold, - .add_interface = ar5523_add_interface, - .remove_interface = ar5523_remove_interface, - .config = ar5523_hwconfig, - .bss_info_changed = ar5523_bss_info_changed, - .configure_filter = ar5523_configure_filter, - .flush = ar5523_flush, -}; - -static int ar5523_host_available(struct ar5523 *ar) -{ - struct ar5523_cmd_host_available setup; - - /* inform target the host is available */ - setup.sw_ver_major = cpu_to_be32(ATH_SW_VER_MAJOR); - setup.sw_ver_minor = cpu_to_be32(ATH_SW_VER_MINOR); - setup.sw_ver_patch = cpu_to_be32(ATH_SW_VER_PATCH); - setup.sw_ver_build = cpu_to_be32(ATH_SW_VER_BUILD); - return ar5523_cmd_read(ar, WDCMSG_HOST_AVAILABLE, - &setup, sizeof(setup), NULL, 0, 0); -} - -static int ar5523_get_devstatus(struct ar5523 *ar) -{ - u8 macaddr[ETH_ALEN]; - int error; - - /* retrieve MAC address */ - error = ar5523_get_status(ar, ST_MAC_ADDR, macaddr, ETH_ALEN); - if (error) { - ar5523_err(ar, "could not read MAC address\n"); - return error; - } - - SET_IEEE80211_PERM_ADDR(ar->hw, macaddr); - - error = ar5523_get_status(ar, ST_SERIAL_NUMBER, - &ar->serial[0], sizeof(ar->serial)); - if (error) { - ar5523_err(ar, "could not read device serial number\n"); - return error; - } - return 0; -} - -#define AR5523_SANE_RXBUFSZ 2000 - -static int ar5523_get_max_rxsz(struct ar5523 *ar) -{ - int error; - __be32 rxsize; - - /* Get max rx size */ - error = ar5523_get_status(ar, ST_WDC_TRANSPORT_CHUNK_SIZE, &rxsize, - sizeof(rxsize)); - if (error != 0) { - ar5523_err(ar, "could not read max RX size\n"); - return error; - } - - ar->rxbufsz = be32_to_cpu(rxsize); - - if (!ar->rxbufsz || ar->rxbufsz > AR5523_SANE_RXBUFSZ) { - ar5523_err(ar, "Bad rxbufsz from device. Using %d instead\n", - AR5523_SANE_RXBUFSZ); - ar->rxbufsz = AR5523_SANE_RXBUFSZ; - } - - ar5523_dbg(ar, "Max RX buf size: %d\n", ar->rxbufsz); - return 0; -} - -/* - * This is copied from rtl818x, but we should probably move this - * to common code as in OpenBSD. - */ -static const struct ieee80211_rate ar5523_rates[] = { - { .bitrate = 10, .hw_value = 2, }, - { .bitrate = 20, .hw_value = 4 }, - { .bitrate = 55, .hw_value = 11, }, - { .bitrate = 110, .hw_value = 22, }, - { .bitrate = 60, .hw_value = 12, }, - { .bitrate = 90, .hw_value = 18, }, - { .bitrate = 120, .hw_value = 24, }, - { .bitrate = 180, .hw_value = 36, }, - { .bitrate = 240, .hw_value = 48, }, - { .bitrate = 360, .hw_value = 72, }, - { .bitrate = 480, .hw_value = 96, }, - { .bitrate = 540, .hw_value = 108, }, -}; - -static const struct ieee80211_channel ar5523_channels[] = { - { .center_freq = 2412 }, - { .center_freq = 2417 }, - { .center_freq = 2422 }, - { .center_freq = 2427 }, - { .center_freq = 2432 }, - { .center_freq = 2437 }, - { .center_freq = 2442 }, - { .center_freq = 2447 }, - { .center_freq = 2452 }, - { .center_freq = 2457 }, - { .center_freq = 2462 }, - { .center_freq = 2467 }, - { .center_freq = 2472 }, - { .center_freq = 2484 }, -}; - -static int ar5523_init_modes(struct ar5523 *ar) -{ - BUILD_BUG_ON(sizeof(ar->channels) != sizeof(ar5523_channels)); - BUILD_BUG_ON(sizeof(ar->rates) != sizeof(ar5523_rates)); - - memcpy(ar->channels, ar5523_channels, sizeof(ar5523_channels)); - memcpy(ar->rates, ar5523_rates, sizeof(ar5523_rates)); - - ar->band.band = IEEE80211_BAND_2GHZ; - ar->band.channels = ar->channels; - ar->band.n_channels = ARRAY_SIZE(ar5523_channels); - ar->band.bitrates = ar->rates; - ar->band.n_bitrates = ARRAY_SIZE(ar5523_rates); - ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar->band; - return 0; -} - -/* - * Load the MIPS R4000 microcode into the device. Once the image is loaded, - * the device will detach itself from the bus and reattach later with a new - * product Id (a la ezusb). - */ -static int ar5523_load_firmware(struct usb_device *dev) -{ - struct ar5523_fwblock *txblock, *rxblock; - const struct firmware *fw; - void *fwbuf; - int len, offset; - int foolen; /* XXX(hch): handle short transfers */ - int error = -ENXIO; - - if (request_firmware(&fw, AR5523_FIRMWARE_FILE, &dev->dev)) { - dev_err(&dev->dev, "no firmware found: %s\n", - AR5523_FIRMWARE_FILE); - return -ENOENT; - } - - txblock = kmalloc(sizeof(*txblock), GFP_KERNEL); - if (!txblock) - goto out; - - rxblock = kmalloc(sizeof(*rxblock), GFP_KERNEL); - if (!rxblock) - goto out_free_txblock; - - fwbuf = kmalloc(AR5523_MAX_FWBLOCK_SIZE, GFP_KERNEL); - if (!fwbuf) - goto out_free_rxblock; - - memset(txblock, 0, sizeof(struct ar5523_fwblock)); - txblock->flags = cpu_to_be32(AR5523_WRITE_BLOCK); - txblock->total = cpu_to_be32(fw->size); - - offset = 0; - len = fw->size; - while (len > 0) { - int mlen = min(len, AR5523_MAX_FWBLOCK_SIZE); - - txblock->remain = cpu_to_be32(len - mlen); - txblock->len = cpu_to_be32(mlen); - - /* send firmware block meta-data */ - error = usb_bulk_msg(dev, ar5523_cmd_tx_pipe(dev), - txblock, sizeof(*txblock), &foolen, - AR5523_CMD_TIMEOUT); - if (error) { - dev_err(&dev->dev, - "could not send firmware block info\n"); - goto out_free_fwbuf; - } - - /* send firmware block data */ - memcpy(fwbuf, fw->data + offset, mlen); - error = usb_bulk_msg(dev, ar5523_data_tx_pipe(dev), - fwbuf, mlen, &foolen, - AR5523_DATA_TIMEOUT); - if (error) { - dev_err(&dev->dev, - "could not send firmware block data\n"); - goto out_free_fwbuf; - } - - /* wait for ack from firmware */ - error = usb_bulk_msg(dev, ar5523_cmd_rx_pipe(dev), - rxblock, sizeof(*rxblock), &foolen, - AR5523_CMD_TIMEOUT); - if (error) { - dev_err(&dev->dev, - "could not read firmware answer\n"); - goto out_free_fwbuf; - } - - len -= mlen; - offset += mlen; - } - - /* - * Set the error to -ENXIO to make sure we continue probing for - * a driver. - */ - error = -ENXIO; - - out_free_fwbuf: - kfree(fwbuf); - out_free_rxblock: - kfree(rxblock); - out_free_txblock: - kfree(txblock); - out: - release_firmware(fw); - return error; -} - -static int ar5523_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - struct ieee80211_hw *hw; - struct ar5523 *ar; - int error = -ENOMEM; - - /* - * Load firmware if the device requires it. This will return - * -ENXIO on success and we'll get called back afer the usb - * id changes to indicate that the firmware is present. - */ - if (id->driver_info & AR5523_FLAG_PRE_FIRMWARE) - return ar5523_load_firmware(dev); - - - hw = ieee80211_alloc_hw(sizeof(*ar), &ar5523_ops); - if (!hw) - goto out; - SET_IEEE80211_DEV(hw, &intf->dev); - - ar = hw->priv; - ar->hw = hw; - ar->dev = dev; - mutex_init(&ar->mutex); - - INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work); - init_timer(&ar->tx_wd_timer); - setup_timer(&ar->tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar); - INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work); - INIT_WORK(&ar->tx_work, ar5523_tx_work); - INIT_LIST_HEAD(&ar->tx_queue_pending); - INIT_LIST_HEAD(&ar->tx_queue_submitted); - spin_lock_init(&ar->tx_data_list_lock); - atomic_set(&ar->tx_nr_total, 0); - atomic_set(&ar->tx_nr_pending, 0); - init_waitqueue_head(&ar->tx_flush_waitq); - - atomic_set(&ar->rx_data_free_cnt, 0); - INIT_WORK(&ar->rx_refill_work, ar5523_rx_refill_work); - INIT_LIST_HEAD(&ar->rx_data_free); - INIT_LIST_HEAD(&ar->rx_data_used); - spin_lock_init(&ar->rx_data_list_lock); - - ar->wq = create_singlethread_workqueue("ar5523"); - if (!ar->wq) { - ar5523_err(ar, "Could not create wq\n"); - goto out_free_ar; - } - - error = ar5523_alloc_rx_bufs(ar); - if (error) { - ar5523_err(ar, "Could not allocate rx buffers\n"); - goto out_free_wq; - } - - error = ar5523_alloc_rx_cmd(ar); - if (error) { - ar5523_err(ar, "Could not allocate rx command buffers\n"); - goto out_free_rx_bufs; - } - - error = ar5523_alloc_tx_cmd(ar); - if (error) { - ar5523_err(ar, "Could not allocate tx command buffers\n"); - goto out_free_rx_cmd; - } - - error = ar5523_submit_rx_cmd(ar); - if (error) { - ar5523_err(ar, "Failed to submit rx cmd\n"); - goto out_free_tx_cmd; - } - - /* - * We're now ready to send/receive firmware commands. - */ - error = ar5523_host_available(ar); - if (error) { - ar5523_err(ar, "could not initialize adapter\n"); - goto out_cancel_rx_cmd; - } - - error = ar5523_get_max_rxsz(ar); - if (error) { - ar5523_err(ar, "could not get caps from adapter\n"); - goto out_cancel_rx_cmd; - } - - error = ar5523_get_devcap(ar); - if (error) { - ar5523_err(ar, "could not get caps from adapter\n"); - goto out_cancel_rx_cmd; - } - - error = ar5523_get_devstatus(ar); - if (error != 0) { - ar5523_err(ar, "could not get device status\n"); - goto out_cancel_rx_cmd; - } - - ar5523_info(ar, "MAC/BBP AR5523, RF AR%c112\n", - (id->driver_info & AR5523_FLAG_ABG) ? '5' : '2'); - - ar->vif = NULL; - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_HAS_RATE_CONTROL; - hw->extra_tx_headroom = sizeof(struct ar5523_tx_desc) + - sizeof(struct ar5523_chunk); - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - hw->queues = 1; - - error = ar5523_init_modes(ar); - if (error) - goto out_cancel_rx_cmd; - - usb_set_intfdata(intf, hw); - - error = ieee80211_register_hw(hw); - if (error) { - ar5523_err(ar, "could not register device\n"); - goto out_cancel_rx_cmd; - } - - ar5523_info(ar, "Found and initialized AR5523 device\n"); - return 0; - -out_cancel_rx_cmd: - ar5523_cancel_rx_cmd(ar); -out_free_tx_cmd: - ar5523_free_tx_cmd(ar); -out_free_rx_cmd: - ar5523_free_rx_cmd(ar); -out_free_rx_bufs: - ar5523_free_rx_bufs(ar); -out_free_wq: - destroy_workqueue(ar->wq); -out_free_ar: - ieee80211_free_hw(hw); -out: - return error; -} - -static void ar5523_disconnect(struct usb_interface *intf) -{ - struct ieee80211_hw *hw = usb_get_intfdata(intf); - struct ar5523 *ar = hw->priv; - - ar5523_dbg(ar, "detaching\n"); - set_bit(AR5523_USB_DISCONNECTED, &ar->flags); - - ieee80211_unregister_hw(hw); - - ar5523_cancel_rx_cmd(ar); - ar5523_free_tx_cmd(ar); - ar5523_free_rx_cmd(ar); - ar5523_free_rx_bufs(ar); - - destroy_workqueue(ar->wq); - - ieee80211_free_hw(hw); - usb_set_intfdata(intf, NULL); -} - -#define AR5523_DEVICE_UG(vendor, device) \ - { USB_DEVICE((vendor), (device)) }, \ - { USB_DEVICE((vendor), (device) + 1), \ - .driver_info = AR5523_FLAG_PRE_FIRMWARE } -#define AR5523_DEVICE_UX(vendor, device) \ - { USB_DEVICE((vendor), (device)), \ - .driver_info = AR5523_FLAG_ABG }, \ - { USB_DEVICE((vendor), (device) + 1), \ - .driver_info = AR5523_FLAG_ABG|AR5523_FLAG_PRE_FIRMWARE } - -static struct usb_device_id ar5523_id_table[] = { - AR5523_DEVICE_UG(0x168c, 0x0001), /* Atheros / AR5523 */ - AR5523_DEVICE_UG(0x0cf3, 0x0001), /* Atheros2 / AR5523_1 */ - AR5523_DEVICE_UG(0x0cf3, 0x0003), /* Atheros2 / AR5523_2 */ - AR5523_DEVICE_UX(0x0cf3, 0x0005), /* Atheros2 / AR5523_3 */ - AR5523_DEVICE_UG(0x0d8e, 0x7801), /* Conceptronic / AR5523_1 */ - AR5523_DEVICE_UX(0x0d8e, 0x7811), /* Conceptronic / AR5523_2 */ - AR5523_DEVICE_UX(0x2001, 0x3a00), /* Dlink / DWLAG132 */ - AR5523_DEVICE_UG(0x2001, 0x3a02), /* Dlink / DWLG132 */ - AR5523_DEVICE_UX(0x2001, 0x3a04), /* Dlink / DWLAG122 */ - AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ - AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ - AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 - (CyberTAN Technology) */ - AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ - AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ - AR5523_DEVICE_UG(0x0d8e, 0x7802), /* Globalsun / AR5523_3 */ - AR5523_DEVICE_UX(0x0846, 0x4300), /* Netgear / WG111U */ - AR5523_DEVICE_UG(0x0846, 0x4250), /* Netgear / WG111T */ - AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */ - AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1 */ - AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */ - AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / TEW444UBEU */ - AR5523_DEVICE_UG(0x1435, 0x0826), /* Wistronneweb / AR5523_1 */ - AR5523_DEVICE_UX(0x1435, 0x0828), /* Wistronneweb / AR5523_2 */ - AR5523_DEVICE_UG(0x0cde, 0x0012), /* Zcom / AR5523 */ - AR5523_DEVICE_UG(0x1385, 0x4250), /* Netgear3 / WG111T (2) */ - AR5523_DEVICE_UG(0x1385, 0x5f00), /* Netgear / WPN111 */ - AR5523_DEVICE_UG(0x1385, 0x5f02), /* Netgear / WPN111 */ - { } -}; -MODULE_DEVICE_TABLE(usb, ar5523_id_table); - -static struct usb_driver ar5523_driver = { - .name = "ar5523", - .id_table = ar5523_id_table, - .probe = ar5523_probe, - .disconnect = ar5523_disconnect, -}; - -module_usb_driver(ar5523_driver); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523.h b/trunk/drivers/net/wireless/ath/ar5523/ar5523.h deleted file mode 100644 index 00c6fd346d48..000000000000 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2006 Damien Bergamini - * Copyright (c) 2006 Sam Leffler, Errno Consulting - * Copyright (c) 2007 Christoph Hellwig - * Copyright (c) 2008-2009 Weongyo Jeong - * Copyright (c) 2012 Pontus Fuchs - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define AR5523_FLAG_PRE_FIRMWARE (1 << 0) -#define AR5523_FLAG_ABG (1 << 1) - -#define AR5523_FIRMWARE_FILE "ar5523.bin" - -#define AR5523_CMD_TX_PIPE 0x01 -#define AR5523_DATA_TX_PIPE 0x02 -#define AR5523_CMD_RX_PIPE 0x81 -#define AR5523_DATA_RX_PIPE 0x82 - -#define ar5523_cmd_tx_pipe(dev) \ - usb_sndbulkpipe((dev), AR5523_CMD_TX_PIPE) -#define ar5523_data_tx_pipe(dev) \ - usb_sndbulkpipe((dev), AR5523_DATA_TX_PIPE) -#define ar5523_cmd_rx_pipe(dev) \ - usb_rcvbulkpipe((dev), AR5523_CMD_RX_PIPE) -#define ar5523_data_rx_pipe(dev) \ - usb_rcvbulkpipe((dev), AR5523_DATA_RX_PIPE) - -#define AR5523_DATA_TIMEOUT 10000 -#define AR5523_CMD_TIMEOUT 1000 - -#define AR5523_TX_DATA_COUNT 8 -#define AR5523_TX_DATA_RESTART_COUNT 2 -#define AR5523_RX_DATA_COUNT 16 -#define AR5523_RX_DATA_REFILL_COUNT 8 - -#define AR5523_CMD_ID 1 -#define AR5523_DATA_ID 2 - -#define AR5523_TX_WD_TIMEOUT (HZ * 2) -#define AR5523_FLUSH_TIMEOUT (HZ * 3) - -enum AR5523_flags { - AR5523_HW_UP, - AR5523_USB_DISCONNECTED, - AR5523_CONNECTED -}; - -struct ar5523_tx_cmd { - struct ar5523 *ar; - struct urb *urb_tx; - void *buf_tx; - void *odata; - int olen; - int flags; - int res; - struct completion done; -}; - -/* This struct is placed in tx_info->driver_data. It must not be larger - * than IEEE80211_TX_INFO_DRIVER_DATA_SIZE. - */ -struct ar5523_tx_data { - struct list_head list; - struct ar5523 *ar; - struct sk_buff *skb; - struct urb *urb; -}; - -struct ar5523_rx_data { - struct list_head list; - struct ar5523 *ar; - struct urb *urb; - struct sk_buff *skb; -}; - -struct ar5523 { - struct usb_device *dev; - struct ieee80211_hw *hw; - - unsigned long flags; - struct mutex mutex; - struct workqueue_struct *wq; - - struct ar5523_tx_cmd tx_cmd; - - struct delayed_work stat_work; - - struct timer_list tx_wd_timer; - struct work_struct tx_wd_work; - struct work_struct tx_work; - struct list_head tx_queue_pending; - struct list_head tx_queue_submitted; - spinlock_t tx_data_list_lock; - wait_queue_head_t tx_flush_waitq; - - /* Queued + Submitted TX frames */ - atomic_t tx_nr_total; - - /* Submitted TX frames */ - atomic_t tx_nr_pending; - - void *rx_cmd_buf; - struct urb *rx_cmd_urb; - - struct ar5523_rx_data rx_data[AR5523_RX_DATA_COUNT]; - spinlock_t rx_data_list_lock; - struct list_head rx_data_free; - struct list_head rx_data_used; - atomic_t rx_data_free_cnt; - - struct work_struct rx_refill_work; - - unsigned int rxbufsz; - u8 serial[16]; - - struct ieee80211_channel channels[14]; - struct ieee80211_rate rates[12]; - struct ieee80211_supported_band band; - struct ieee80211_vif *vif; -}; - -/* flags for sending firmware commands */ -#define AR5523_CMD_FLAG_READ (1 << 1) -#define AR5523_CMD_FLAG_MAGIC (1 << 2) - -#define ar5523_dbg(ar, format, arg...) \ - dev_dbg(&(ar)->dev->dev, format, ## arg) - -/* On USB hot-unplug there can be a lot of URBs in flight and they'll all - * fail. Instead of dealing with them in every possible place just surpress - * any messages on USB disconnect. - */ -#define ar5523_err(ar, format, arg...) \ -do { \ - if (!test_bit(AR5523_USB_DISCONNECTED, &ar->flags)) { \ - dev_err(&(ar)->dev->dev, format, ## arg); \ - } \ -} while (0) -#define ar5523_info(ar, format, arg...) \ - dev_info(&(ar)->dev->dev, format, ## arg) diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h b/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h deleted file mode 100644 index 0fe2c803f48f..000000000000 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2006 Damien Bergamini - * Copyright (c) 2006 Sam Leffler, Errno Consulting - * Copyright (c) 2007 Christoph Hellwig - * Copyright (c) 2008-2009 Weongyo Jeong - * Copyright (c) 2012 Pontus Fuchs - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* all fields are big endian */ -struct ar5523_fwblock { - __be32 flags; -#define AR5523_WRITE_BLOCK (1 << 4) - - __be32 len; -#define AR5523_MAX_FWBLOCK_SIZE 2048 - - __be32 total; - __be32 remain; - __be32 rxtotal; - __be32 pad[123]; -} __packed; - -#define AR5523_MAX_RXCMDSZ 1024 -#define AR5523_MAX_TXCMDSZ 1024 - -struct ar5523_cmd_hdr { - __be32 len; - __be32 code; -/* NB: these are defined for rev 1.5 firmware; rev 1.6 is different */ -/* messages from Host -> Target */ -#define WDCMSG_HOST_AVAILABLE 0x01 -#define WDCMSG_BIND 0x02 -#define WDCMSG_TARGET_RESET 0x03 -#define WDCMSG_TARGET_GET_CAPABILITY 0x04 -#define WDCMSG_TARGET_SET_CONFIG 0x05 -#define WDCMSG_TARGET_GET_STATUS 0x06 -#define WDCMSG_TARGET_GET_STATS 0x07 -#define WDCMSG_TARGET_START 0x08 -#define WDCMSG_TARGET_STOP 0x09 -#define WDCMSG_TARGET_ENABLE 0x0a -#define WDCMSG_TARGET_DISABLE 0x0b -#define WDCMSG_CREATE_CONNECTION 0x0c -#define WDCMSG_UPDATE_CONNECT_ATTR 0x0d -#define WDCMSG_DELETE_CONNECT 0x0e -#define WDCMSG_SEND 0x0f -#define WDCMSG_FLUSH 0x10 -/* messages from Target -> Host */ -#define WDCMSG_STATS_UPDATE 0x11 -#define WDCMSG_BMISS 0x12 -#define WDCMSG_DEVICE_AVAIL 0x13 -#define WDCMSG_SEND_COMPLETE 0x14 -#define WDCMSG_DATA_AVAIL 0x15 -#define WDCMSG_SET_PWR_MODE 0x16 -#define WDCMSG_BMISS_ACK 0x17 -#define WDCMSG_SET_LED_STEADY 0x18 -#define WDCMSG_SET_LED_BLINK 0x19 -/* more messages */ -#define WDCMSG_SETUP_BEACON_DESC 0x1a -#define WDCMSG_BEACON_INIT 0x1b -#define WDCMSG_RESET_KEY_CACHE 0x1c -#define WDCMSG_RESET_KEY_CACHE_ENTRY 0x1d -#define WDCMSG_SET_KEY_CACHE_ENTRY 0x1e -#define WDCMSG_SET_DECOMP_MASK 0x1f -#define WDCMSG_SET_REGULATORY_DOMAIN 0x20 -#define WDCMSG_SET_LED_STATE 0x21 -#define WDCMSG_WRITE_ASSOCID 0x22 -#define WDCMSG_SET_STA_BEACON_TIMERS 0x23 -#define WDCMSG_GET_TSF 0x24 -#define WDCMSG_RESET_TSF 0x25 -#define WDCMSG_SET_ADHOC_MODE 0x26 -#define WDCMSG_SET_BASIC_RATE 0x27 -#define WDCMSG_MIB_CONTROL 0x28 -#define WDCMSG_GET_CHANNEL_DATA 0x29 -#define WDCMSG_GET_CUR_RSSI 0x2a -#define WDCMSG_SET_ANTENNA_SWITCH 0x2b -#define WDCMSG_USE_SHORT_SLOT_TIME 0x2f -#define WDCMSG_SET_POWER_MODE 0x30 -#define WDCMSG_SETUP_PSPOLL_DESC 0x31 -#define WDCMSG_SET_RX_MULTICAST_FILTER 0x32 -#define WDCMSG_RX_FILTER 0x33 -#define WDCMSG_PER_CALIBRATION 0x34 -#define WDCMSG_RESET 0x35 -#define WDCMSG_DISABLE 0x36 -#define WDCMSG_PHY_DISABLE 0x37 -#define WDCMSG_SET_TX_POWER_LIMIT 0x38 -#define WDCMSG_SET_TX_QUEUE_PARAMS 0x39 -#define WDCMSG_SETUP_TX_QUEUE 0x3a -#define WDCMSG_RELEASE_TX_QUEUE 0x3b -#define WDCMSG_SET_DEFAULT_KEY 0x43 - - __u32 priv; /* driver private data, - don't care about endianess */ - __be32 magic; - __be32 reserved2[4]; -}; - -struct ar5523_cmd_host_available { - __be32 sw_ver_major; - __be32 sw_ver_minor; - __be32 sw_ver_patch; - __be32 sw_ver_build; -} __packed; - -#define ATH_SW_VER_MAJOR 1 -#define ATH_SW_VER_MINOR 5 -#define ATH_SW_VER_PATCH 0 -#define ATH_SW_VER_BUILD 9999 - -struct ar5523_chunk { - u8 seqnum; /* sequence number for ordering */ - u8 flags; -#define UATH_CFLAGS_FINAL 0x01 /* final chunk of a msg */ -#define UATH_CFLAGS_RXMSG 0x02 /* chunk contains rx completion */ -#define UATH_CFLAGS_DEBUG 0x04 /* for debugging */ - __be16 length; /* chunk size in bytes */ - /* chunk data follows */ -} __packed; - -/* - * Message format for a WDCMSG_DATA_AVAIL message from Target to Host. - */ -struct ar5523_rx_desc { - __be32 len; /* msg length including header */ - __be32 code; /* WDCMSG_DATA_AVAIL */ - __be32 gennum; /* generation number */ - __be32 status; /* start of RECEIVE_INFO */ -#define UATH_STATUS_OK 0 -#define UATH_STATUS_STOP_IN_PROGRESS 1 -#define UATH_STATUS_CRC_ERR 2 -#define UATH_STATUS_PHY_ERR 3 -#define UATH_STATUS_DECRYPT_CRC_ERR 4 -#define UATH_STATUS_DECRYPT_MIC_ERR 5 -#define UATH_STATUS_DECOMP_ERR 6 -#define UATH_STATUS_KEY_ERR 7 -#define UATH_STATUS_ERR 8 - __be32 tstamp_low; /* low-order 32-bits of rx timestamp */ - __be32 tstamp_high; /* high-order 32-bits of rx timestamp */ - __be32 framelen; /* frame length */ - __be32 rate; /* rx rate code */ - __be32 antenna; - __be32 rssi; - __be32 channel; - __be32 phyerror; - __be32 connix; /* key table ix for bss traffic */ - __be32 decrypterror; - __be32 keycachemiss; - __be32 pad; /* XXX? */ -} __packed; - -struct ar5523_tx_desc { - __be32 msglen; - u32 msgid; /* msg id (supplied by host) */ - __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ - __be32 txqid; /* tx queue id and flags */ -#define UATH_TXQID_MASK 0x0f -#define UATH_TXQID_MINRATE 0x10 /* use min tx rate */ -#define UATH_TXQID_FF 0x20 /* content is fast frame */ - __be32 connid; /* tx connection id */ -#define UATH_ID_INVALID 0xffffffff /* for sending prior to connection */ - __be32 flags; /* non-zero if response desired */ -#define UATH_TX_NOTIFY (1 << 24) /* f/w will send a UATH_NOTIF_TX */ - __be32 buflen; /* payload length */ -} __packed; - - -#define AR5523_ID_BSS 2 -#define AR5523_ID_BROADCAST 0xffffffff - -/* structure for command UATH_CMD_WRITE_MAC */ -struct ar5523_write_mac { - __be32 reg; - __be32 len; - u8 data[32]; -} __packed; - -struct ar5523_cmd_rateset { - __u8 length; -#define AR5523_MAX_NRATES 32 - __u8 set[AR5523_MAX_NRATES]; -}; - -struct ar5523_cmd_set_associd { /* AR5523_WRITE_ASSOCID */ - __be32 defaultrateix; - __be32 associd; - __be32 timoffset; - __be32 turboprime; - __u8 bssid[6]; -} __packed; - -/* structure for command WDCMSG_RESET */ -struct ar5523_cmd_reset { - __be32 flags; /* channel flags */ -#define UATH_CHAN_TURBO 0x0100 -#define UATH_CHAN_CCK 0x0200 -#define UATH_CHAN_OFDM 0x0400 -#define UATH_CHAN_2GHZ 0x1000 -#define UATH_CHAN_5GHZ 0x2000 - __be32 freq; /* channel frequency */ - __be32 maxrdpower; - __be32 cfgctl; - __be32 twiceantennareduction; - __be32 channelchange; - __be32 keeprccontent; -} __packed; - -/* structure for command WDCMSG_SET_BASIC_RATE */ -struct ar5523_cmd_rates { - __be32 connid; - __be32 keeprccontent; - __be32 size; - struct ar5523_cmd_rateset rateset; -} __packed; - -enum { - WLAN_MODE_NONE = 0, - WLAN_MODE_11b, - WLAN_MODE_11a, - WLAN_MODE_11g, - WLAN_MODE_11a_TURBO, - WLAN_MODE_11g_TURBO, - WLAN_MODE_11a_TURBO_PRIME, - WLAN_MODE_11g_TURBO_PRIME, - WLAN_MODE_11a_XR, - WLAN_MODE_11g_XR, -}; - -struct ar5523_cmd_connection_attr { - __be32 longpreambleonly; - struct ar5523_cmd_rateset rateset; - __be32 wlanmode; -} __packed; - -/* structure for command AR5523_CREATE_CONNECTION */ -struct ar5523_cmd_create_connection { - __be32 connid; - __be32 bssid; - __be32 size; - struct ar5523_cmd_connection_attr connattr; -} __packed; - -struct ar5523_cmd_ledsteady { /* WDCMSG_SET_LED_STEADY */ - __be32 lednum; -#define UATH_LED_LINK 0 -#define UATH_LED_ACTIVITY 1 - __be32 ledmode; -#define UATH_LED_OFF 0 -#define UATH_LED_ON 1 -} __packed; - -struct ar5523_cmd_ledblink { /* WDCMSG_SET_LED_BLINK */ - __be32 lednum; - __be32 ledmode; - __be32 blinkrate; - __be32 slowmode; -} __packed; - -struct ar5523_cmd_ledstate { /* WDCMSG_SET_LED_STATE */ - __be32 connected; -} __packed; - -struct ar5523_cmd_txq_attr { - __be32 priority; - __be32 aifs; - __be32 logcwmin; - __be32 logcwmax; - __be32 bursttime; - __be32 mode; - __be32 qflags; -} __packed; - -struct ar5523_cmd_txq_setup { /* WDCMSG_SETUP_TX_QUEUE */ - __be32 qid; - __be32 len; - struct ar5523_cmd_txq_attr attr; -} __packed; - -struct ar5523_cmd_rx_filter { /* WDCMSG_RX_FILTER */ - __be32 bits; -#define UATH_FILTER_RX_UCAST 0x00000001 -#define UATH_FILTER_RX_MCAST 0x00000002 -#define UATH_FILTER_RX_BCAST 0x00000004 -#define UATH_FILTER_RX_CONTROL 0x00000008 -#define UATH_FILTER_RX_BEACON 0x00000010 /* beacon frames */ -#define UATH_FILTER_RX_PROM 0x00000020 /* promiscuous mode */ -#define UATH_FILTER_RX_PHY_ERR 0x00000040 /* phy errors */ -#define UATH_FILTER_RX_PHY_RADAR 0x00000080 /* radar phy errors */ -#define UATH_FILTER_RX_XR_POOL 0x00000400 /* XR group polls */ -#define UATH_FILTER_RX_PROBE_REQ 0x00000800 - __be32 op; -#define UATH_FILTER_OP_INIT 0x0 -#define UATH_FILTER_OP_SET 0x1 -#define UATH_FILTER_OP_CLEAR 0x2 -#define UATH_FILTER_OP_TEMP 0x3 -#define UATH_FILTER_OP_RESTORE 0x4 -} __packed; - -enum { - CFG_NONE, /* Sentinal to indicate "no config" */ - CFG_REG_DOMAIN, /* Regulatory Domain */ - CFG_RATE_CONTROL_ENABLE, - CFG_DEF_XMIT_DATA_RATE, /* NB: if rate control is not enabled */ - CFG_HW_TX_RETRIES, - CFG_SW_TX_RETRIES, - CFG_SLOW_CLOCK_ENABLE, - CFG_COMP_PROC, - CFG_USER_RTS_THRESHOLD, - CFG_XR2NORM_RATE_THRESHOLD, - CFG_XRMODE_SWITCH_COUNT, - CFG_PROTECTION_TYPE, - CFG_BURST_SEQ_THRESHOLD, - CFG_ABOLT, - CFG_IQ_LOG_COUNT_MAX, - CFG_MODE_CTS, - CFG_WME_ENABLED, - CFG_GPRS_CBR_PERIOD, - CFG_SERVICE_TYPE, - /* MAC Address to use. Overrides EEPROM */ - CFG_MAC_ADDR, - CFG_DEBUG_EAR, - CFG_INIT_REGS, - /* An ID for use in error & debug messages */ - CFG_DEBUG_ID, - CFG_COMP_WIN_SZ, - CFG_DIVERSITY_CTL, - CFG_TP_SCALE, - CFG_TPC_HALF_DBM5, - CFG_TPC_HALF_DBM2, - CFG_OVERRD_TX_POWER, - CFG_USE_32KHZ_CLOCK, - CFG_GMODE_PROTECTION, - CFG_GMODE_PROTECT_RATE_INDEX, - CFG_GMODE_NON_ERP_PREAMBLE, - CFG_WDC_TRANSPORT_CHUNK_SIZE, -}; - -enum { - /* Sentinal to indicate "no capability" */ - CAP_NONE, - CAP_ALL, /* ALL capabilities */ - CAP_TARGET_VERSION, - CAP_TARGET_REVISION, - CAP_MAC_VERSION, - CAP_MAC_REVISION, - CAP_PHY_REVISION, - CAP_ANALOG_5GHz_REVISION, - CAP_ANALOG_2GHz_REVISION, - /* Target supports WDC message debug features */ - CAP_DEBUG_WDCMSG_SUPPORT, - - CAP_REG_DOMAIN, - CAP_COUNTRY_CODE, - CAP_REG_CAP_BITS, - - CAP_WIRELESS_MODES, - CAP_CHAN_SPREAD_SUPPORT, - CAP_SLEEP_AFTER_BEACON_BROKEN, - CAP_COMPRESS_SUPPORT, - CAP_BURST_SUPPORT, - CAP_FAST_FRAMES_SUPPORT, - CAP_CHAP_TUNING_SUPPORT, - CAP_TURBOG_SUPPORT, - CAP_TURBO_PRIME_SUPPORT, - CAP_DEVICE_TYPE, - CAP_XR_SUPPORT, - CAP_WME_SUPPORT, - CAP_TOTAL_QUEUES, - CAP_CONNECTION_ID_MAX, /* Should absorb CAP_KEY_CACHE_SIZE */ - - CAP_LOW_5GHZ_CHAN, - CAP_HIGH_5GHZ_CHAN, - CAP_LOW_2GHZ_CHAN, - CAP_HIGH_2GHZ_CHAN, - - CAP_MIC_AES_CCM, - CAP_MIC_CKIP, - CAP_MIC_TKIP, - CAP_MIC_TKIP_WME, - CAP_CIPHER_AES_CCM, - CAP_CIPHER_CKIP, - CAP_CIPHER_TKIP, - - CAP_TWICE_ANTENNAGAIN_5G, - CAP_TWICE_ANTENNAGAIN_2G, -}; - -enum { - ST_NONE, /* Sentinal to indicate "no status" */ - ST_ALL, - ST_SERVICE_TYPE, - ST_WLAN_MODE, - ST_FREQ, - ST_BAND, - ST_LAST_RSSI, - ST_PS_FRAMES_DROPPED, - ST_CACHED_DEF_ANT, - ST_COUNT_OTHER_RX_ANT, - ST_USE_FAST_DIVERSITY, - ST_MAC_ADDR, - ST_RX_GENERATION_NUM, - ST_TX_QUEUE_DEPTH, - ST_SERIAL_NUMBER, - ST_WDC_TRANSPORT_CHUNK_SIZE, -}; - -enum { - TARGET_DEVICE_AWAKE, - TARGET_DEVICE_SLEEP, - TARGET_DEVICE_PWRDN, - TARGET_DEVICE_PWRSAVE, - TARGET_DEVICE_SUSPEND, - TARGET_DEVICE_RESUME, -}; - -/* this is in net/ieee80211.h, but that conflicts with the mac80211 headers */ -#define IEEE80211_2ADDR_LEN 16 - -#define AR5523_MIN_RXBUFSZ \ - (((sizeof(__be32) + IEEE80211_2ADDR_LEN + \ - sizeof(struct ar5523_rx_desc)) + 3) & ~3) diff --git a/trunk/drivers/net/wireless/ath/ath5k/ahb.c b/trunk/drivers/net/wireless/ath/ath5k/ahb.c index 8e8bcc7a4805..aec33cc207fd 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath5k/ahb.c @@ -236,4 +236,17 @@ static struct platform_driver ath_ahb_driver = { }, }; -module_platform_driver(ath_ahb_driver); +static int __init +ath5k_ahb_init(void) +{ + return platform_driver_register(&ath_ahb_driver); +} + +static void __exit +ath5k_ahb_exit(void) +{ + platform_driver_unregister(&ath_ahb_driver); +} + +module_init(ath5k_ahb_init); +module_exit(ath5k_ahb_exit); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index cdd19232960c..9f31cfa56cc0 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -511,9 +511,8 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah, ath5k_vif_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic( - ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath5k_vif_iter, &iter_data); + ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, + &iter_data); memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN); ah->opmode = iter_data.opmode; @@ -3046,9 +3045,8 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah) iter_data.need_set_hw_addr = false; iter_data.found_active = true; - ieee80211_iterate_active_interfaces_atomic( - ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath5k_vif_iter, &iter_data); + ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, + &iter_data); return iter_data.any_assoc; } diff --git a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 1ea8c8795c8e..7a28538e6e05 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -452,9 +452,8 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, iter_data.hw_macaddr = NULL; iter_data.n_stas = 0; iter_data.need_set_hw_addr = false; - ieee80211_iterate_active_interfaces_atomic( - ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath5k_vif_iter, &iter_data); + ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, + &iter_data); /* Set up RX Filter */ if (iter_data.n_stas > 1) { diff --git a/trunk/drivers/net/wireless/ath/ath5k/reset.c b/trunk/drivers/net/wireless/ath/ath5k/reset.c index 4084b1076286..0c2dd4771c36 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/reset.c +++ b/trunk/drivers/net/wireless/ath/ath5k/reset.c @@ -789,9 +789,9 @@ ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel) * (I don't think it supports 44MHz) */ /* On 2425 initvals TURBO_SHORT is not present */ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - turbo = AR5K_PHY_TURBO_MODE; - if (ah->ah_radio != AR5K_RF2425) - turbo |= AR5K_PHY_TURBO_SHORT; + turbo = AR5K_PHY_TURBO_MODE | + (ah->ah_radio == AR5K_RF2425) ? 0 : + AR5K_PHY_TURBO_SHORT; } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { if (ah->ah_radio == AR5K_RF5413) { mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Kconfig b/trunk/drivers/net/wireless/ath/ath6kl/Kconfig index 26c4b7220859..d755a5e7ed20 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/trunk/drivers/net/wireless/ath/ath6kl/Kconfig @@ -30,12 +30,3 @@ config ATH6KL_DEBUG depends on ATH6KL ---help--- Enables debug support - -config ATH6KL_REGDOMAIN - bool "Atheros ath6kl regdomain support" - depends on ATH6KL - depends on CFG80211_CERTIFICATION_ONUS - ---help--- - Enabling this makes it possible to change the regdomain in - the firmware. This can be only enabled if regulatory requirements - are taken into account. diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Makefile b/trunk/drivers/net/wireless/ath/ath6kl/Makefile index cab0ec0d5380..8cae8886f17d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/Makefile +++ b/trunk/drivers/net/wireless/ath/ath6kl/Makefile @@ -34,7 +34,6 @@ ath6kl_core-y += main.o ath6kl_core-y += txrx.o ath6kl_core-y += wmi.o ath6kl_core-y += core.o -ath6kl_core-y += recovery.o ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c index 83d8c5eabbee..7089f8160ad5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -147,15 +147,15 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; - if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags)) + if (ar->state != ATH6KL_STATE_SCHED_SCAN) return false; del_timer_sync(&vif->sched_scan_timer); - if (ar->state == ATH6KL_STATE_RECOVERY) - return true; + ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_AWAKE); - ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false); + ar->state = ATH6KL_STATE_ON; return true; } @@ -301,7 +301,7 @@ static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif) static bool ath6kl_is_wpa_ie(const u8 *pos) { - return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && + return pos[0] == WLAN_EID_WPA && pos[1] >= 4 && pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 && pos[5] == 0x01; } @@ -369,13 +369,17 @@ static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type) { switch (type) { case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: *nw_type = INFRA_NETWORK; break; case NL80211_IFTYPE_ADHOC: *nw_type = ADHOC_NETWORK; break; case NL80211_IFTYPE_AP: + *nw_type = AP_NETWORK; + break; + case NL80211_IFTYPE_P2P_CLIENT: + *nw_type = INFRA_NETWORK; + break; case NL80211_IFTYPE_P2P_GO: *nw_type = AP_NETWORK; break; @@ -1027,15 +1031,30 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, vif->scan_req = request; - ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, - WMI_LONG_SCAN, force_fg_scan, - false, 0, - ATH6KL_FG_SCAN_INTERVAL, - n_channels, channels, - request->no_cck, - request->rates); + if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, + ar->fw_capabilities)) { + /* + * If capable of doing P2P mgmt operations using + * station interface, send additional information like + * supported rates to advertise and xmit rates for + * probe requests + */ + ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, + WMI_LONG_SCAN, force_fg_scan, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels, + request->no_cck, + request->rates); + } else { + ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, + WMI_LONG_SCAN, force_fg_scan, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels); + } if (ret) { - ath6kl_err("failed to start scan: %d\n", ret); + ath6kl_err("wmi_startscan_cmd failed\n"); vif->scan_req = NULL; } @@ -1365,8 +1384,11 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) return 0; } +/* + * The type nl80211_tx_power_setting replaces the following + * data type from 2.6.36 onwards +*/ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, - struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm) { @@ -1401,9 +1423,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, return 0; } -static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, - struct wireless_dev *wdev, - int *dbm) +static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) { struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); struct ath6kl_vif *vif; @@ -1869,7 +1889,7 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, struct cfg80211_wowlan *wow, u32 *filter) { int ret, pos; - u8 mask[WOW_PATTERN_SIZE]; + u8 mask[WOW_MASK_SIZE]; u16 i; /* Configure the patterns that we received from the user. */ @@ -2087,16 +2107,33 @@ static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif) return ret; } -static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, - struct cfg80211_wowlan *wow, u32 *filter) +static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) { - struct ath6kl *ar = vif->ar; struct in_device *in_dev; struct in_ifaddr *ifa; + struct ath6kl_vif *vif; int ret; + u32 filter = 0; u16 i, bmiss_time; - __be32 ips[MAX_IP_ADDRS]; u8 index = 0; + __be32 ips[MAX_IP_ADDRS]; + + /* The FW currently can't support multi-vif WoW properly. */ + if (ar->num_vif > 1) + return -EIO; + + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (!test_bit(CONNECTED, &vif->flags)) + return -ENOTCONN; + + if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) + return -EINVAL; if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, @@ -2118,7 +2155,7 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, * the user. */ if (wow) - ret = ath6kl_wow_usr(ar, vif, wow, filter); + ret = ath6kl_wow_usr(ar, vif, wow, &filter); else if (vif->nw_type == AP_NETWORK) ret = ath6kl_wow_ap(ar, vif); else @@ -2153,10 +2190,12 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, return ret; } + ar->state = ATH6KL_STATE_SUSPENDING; + /* Setup own IP addr for ARP agent. */ in_dev = __in_dev_get_rtnl(vif->ndev); if (!in_dev) - return 0; + goto skip_arp; ifa = in_dev->ifa_list; memset(&ips, 0, sizeof(ips)); @@ -2179,61 +2218,41 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, return ret; } - return ret; -} - -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) -{ - struct ath6kl_vif *first_vif, *vif; - int ret = 0; - u32 filter = 0; - bool connected = false; - - /* enter / leave wow suspend on first vif always */ - first_vif = ath6kl_vif_first(ar); - if (WARN_ON(unlikely(!first_vif)) || - !ath6kl_cfg80211_ready(first_vif)) - return -EIO; - - if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) - return -EINVAL; - - /* install filters for each connected vif */ - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (!test_bit(CONNECTED, &vif->flags) || - !ath6kl_cfg80211_ready(vif)) - continue; - connected = true; - - ret = ath6kl_wow_suspend_vif(vif, wow, &filter); - if (ret) - break; - } - spin_unlock_bh(&ar->list_lock); - - if (!connected) - return -ENOTCONN; - else if (ret) - return ret; - - ar->state = ATH6KL_STATE_SUSPENDING; - - ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx, +skip_arp: + ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, filter, WOW_HOST_REQ_DELAY); if (ret) return ret; - return ath6kl_cfg80211_host_sleep(ar, first_vif); + ret = ath6kl_cfg80211_host_sleep(ar, vif); + if (ret) + return ret; + + return 0; } -static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) +static int ath6kl_wow_resume(struct ath6kl *ar) { - struct ath6kl *ar = vif->ar; + struct ath6kl_vif *vif; int ret; + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + ar->state = ATH6KL_STATE_RESUMING; + + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_AWAKE); + if (ret) { + ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", + ret); + ar->state = ATH6KL_STATE_WOW; + return ret; + } + if (vif->nw_type != AP_NETWORK) { ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); @@ -2251,11 +2270,13 @@ static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) return ret; } + ar->state = ATH6KL_STATE_ON; + if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, ar->fw_capabilities)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, - vif->fw_vif_idx, true); + vif->fw_vif_idx, true); if (ret) return ret; } @@ -2265,48 +2286,6 @@ static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) return 0; } -static int ath6kl_wow_resume(struct ath6kl *ar) -{ - struct ath6kl_vif *vif; - int ret; - - vif = ath6kl_vif_first(ar); - if (WARN_ON(unlikely(!vif)) || - !ath6kl_cfg80211_ready(vif)) - return -EIO; - - ar->state = ATH6KL_STATE_RESUMING; - - ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, - ATH6KL_HOST_MODE_AWAKE); - if (ret) { - ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", - ret); - goto cleanup; - } - - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (!test_bit(CONNECTED, &vif->flags) || - !ath6kl_cfg80211_ready(vif)) - continue; - ret = ath6kl_wow_resume_vif(vif); - if (ret) - break; - } - spin_unlock_bh(&ar->list_lock); - - if (ret) - goto cleanup; - - ar->state = ATH6KL_STATE_ON; - return 0; - -cleanup: - ar->state = ATH6KL_STATE_WOW; - return ret; -} - static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) { struct ath6kl_vif *vif; @@ -2443,6 +2422,13 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, break; + case ATH6KL_CFG_SUSPEND_SCHED_SCAN: + /* + * Nothing needed for schedule scan, firmware is already in + * wow mode and sleeping most of the time. + */ + break; + default: break; } @@ -2490,6 +2476,9 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) } break; + case ATH6KL_STATE_SCHED_SCAN: + break; + default: break; } @@ -2506,23 +2495,14 @@ static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy, { struct ath6kl *ar = wiphy_priv(wiphy); - ath6kl_recovery_suspend(ar); - return ath6kl_hif_suspend(ar, wow); } static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) { struct ath6kl *ar = wiphy_priv(wiphy); - int err; - err = ath6kl_hif_resume(ar); - if (err) - return err; - - ath6kl_recovery_resume(ar); - - return 0; + return ath6kl_hif_resume(ar); } /* @@ -2759,7 +2739,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, int res; int i, ret; u16 rsn_capab = 0; - int inactivity_timeout = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); @@ -2896,15 +2875,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, } if (info->inactivity_timeout) { - - inactivity_timeout = info->inactivity_timeout; - - if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS) - inactivity_timeout = DIV_ROUND_UP(inactivity_timeout, - 60); - res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx, - inactivity_timeout); + info->inactivity_timeout); if (res < 0) return res; } @@ -2926,7 +2898,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, WLAN_EID_RSN, WMI_RSN_IE_CAPB, (const u8 *) &rsn_capab, sizeof(rsn_capab)); - vif->rsn_capab = rsn_capab; if (res < 0) return res; } @@ -3240,7 +3211,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); u16 interval; - int ret, rssi_thold; + int ret; if (ar->state != ATH6KL_STATE_ON) return -EIO; @@ -3248,6 +3219,10 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, if (vif->sme_state != SME_DISCONNECTED) return -EBUSY; + /* The FW currently can't support multi-vif WoW properly. */ + if (ar->num_vif > 1) + return -EIO; + ath6kl_cfg80211_scan_complete_event(vif, true); ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, @@ -3269,23 +3244,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, return ret; } - if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, - ar->fw_capabilities)) { - if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF) - rssi_thold = 0; - else if (request->rssi_thold < -127) - rssi_thold = -127; - else - rssi_thold = request->rssi_thold; - - ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx, - rssi_thold); - if (ret) { - ath6kl_err("failed to set RSSI threshold for scan\n"); - return ret; - } - } - /* fw uses seconds, also make sure that it's >0 */ interval = max_t(u16, 1, request->interval / 1000); @@ -3293,6 +3251,15 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, interval, interval, vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); + ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_WOW_MODE_ENABLE, + WOW_FILTER_SSID, + WOW_HOST_REQ_DELAY); + if (ret) { + ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret); + return ret; + } + /* this also clears IE in fw if it's not set */ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_REQ, @@ -3303,13 +3270,17 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, return ret; } - ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true); - if (ret) + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_ASLEEP); + if (ret) { + ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n", + ret); return ret; + } - set_bit(SCHED_SCANNING, &vif->flags); + ar->state = ATH6KL_STATE_SCHED_SCAN; - return 0; + return ret; } static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, @@ -3338,27 +3309,6 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, mask); } -static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy, - struct net_device *dev, - u32 rate, u32 pkts, u32 intvl) -{ - struct ath6kl *ar = ath6kl_priv(dev); - struct ath6kl_vif *vif = netdev_priv(dev); - - if (vif->nw_type != INFRA_NETWORK || - !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities)) - return -EOPNOTSUPP; - - if (vif->sme_state != SME_CONNECTED) - return -ENOTCONN; - - /* save this since the firmware won't report the interval */ - vif->txe_intvl = intvl; - - return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx, - rate, pkts, intvl); -} - static const struct ieee80211_txrx_stypes ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_STATION] = { @@ -3425,7 +3375,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .sched_scan_start = ath6kl_cfg80211_sscan_start, .sched_scan_stop = ath6kl_cfg80211_sscan_stop, .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, - .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config, }; void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) @@ -3446,22 +3395,16 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) break; } - if (vif->ar->state != ATH6KL_STATE_RECOVERY && - (test_bit(CONNECTED, &vif->flags) || - test_bit(CONNECT_PEND, &vif->flags))) + if (test_bit(CONNECTED, &vif->flags) || + test_bit(CONNECT_PEND, &vif->flags)) ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); vif->sme_state = SME_DISCONNECTED; clear_bit(CONNECTED, &vif->flags); clear_bit(CONNECT_PEND, &vif->flags); - /* Stop netdev queues, needed during recovery */ - netif_stop_queue(vif->ndev); - netif_carrier_off(vif->ndev); - /* disable scanning */ - if (vif->ar->state != ATH6KL_STATE_RECOVERY && - ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, + if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) ath6kl_warn("failed to disable scan during stop\n"); @@ -3473,7 +3416,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) struct ath6kl_vif *vif; vif = ath6kl_vif_first(ar); - if (!vif && ar->state != ATH6KL_STATE_RECOVERY) { + if (!vif) { /* save the current power mode before enabling power save */ ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; @@ -3491,56 +3434,6 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ath6kl_cfg80211_stop(vif); } -static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ath6kl *ar = wiphy_priv(wiphy); - u32 rates[IEEE80211_NUM_BANDS]; - int ret, i; - - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n", - request->alpha2[0], request->alpha2[1], - request->intersect ? " intersect" : "", - request->processed ? " processed" : "", - request->initiator, request->user_reg_hint_type); - - /* - * As firmware is not able intersect regdoms, we can only listen to - * cellular hints. - */ - if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) - return -EOPNOTSUPP; - - ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2); - if (ret) { - ath6kl_err("failed to set regdomain: %d\n", ret); - return ret; - } - - /* - * Firmware will apply the regdomain change only after a scan is - * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been - * changed. - */ - - for (i = 0; i < IEEE80211_NUM_BANDS; i++) - if (wiphy->bands[i]) - rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; - - - ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false, - false, 0, ATH6KL_FG_SCAN_INTERVAL, - 0, NULL, false, rates); - if (ret) { - ath6kl_err("failed to start scan for a regdomain change: %d\n", - ret); - return ret; - } - - return 0; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif); @@ -3613,13 +3506,9 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); - if (fw_vif_idx != 0) { + if (fw_vif_idx != 0) ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) | 0x2; - if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, - ar->fw_capabilities)) - ndev->dev_addr[4] ^= 0x80; - } init_netdev(ndev); @@ -3673,12 +3562,6 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) BIT(NL80211_IFTYPE_P2P_CLIENT); } - if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) && - test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) { - wiphy->reg_notifier = ath6kl_cfg80211_reg_notify; - ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS; - } - /* max num of ssids that can be probed during scanning */ wiphy->max_scan_ssids = MAX_PROBED_SSIDS; @@ -3724,7 +3607,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) ath6kl_band_5ghz.ht_cap.ht_supported = false; } - if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) { + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) { ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; @@ -3763,12 +3646,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities)) + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, ar->fw_capabilities)) - ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; + ar->wiphy->features = NL80211_FEATURE_INACTIVITY_TIMER; ar->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h index e5e70f3a8ca8..780f77775a91 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -22,6 +22,7 @@ enum ath6kl_cfg_suspend_mode { ATH6KL_CFG_SUSPEND_DEEPSLEEP, ATH6KL_CFG_SUSPEND_CUTPOWER, ATH6KL_CFG_SUSPEND_WOW, + ATH6KL_CFG_SUSPEND_SCHED_SCAN, }; struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.c b/trunk/drivers/net/wireless/ath/ath6kl/core.c index 4b46adbe8c92..82c4dd2a960e 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.c @@ -33,8 +33,6 @@ static unsigned int wow_mode; static unsigned int uart_debug; static unsigned int ath6kl_p2p; static unsigned int testmode; -static unsigned int recovery_enable; -static unsigned int heart_beat_poll; module_param(debug_mask, uint, 0644); module_param(suspend_mode, uint, 0644); @@ -42,12 +40,6 @@ module_param(wow_mode, uint, 0644); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); -module_param(recovery_enable, uint, 0644); -module_param(heart_beat_poll, uint, 0644); -MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error"); -MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \ - "polling. This also specifies the polling interval in" \ - "msecs. Set reocvery_enable for this to be effective"); void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) { @@ -210,17 +202,6 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", __func__, wdev->netdev->name, wdev->netdev, ar); - ar->fw_recovery.enable = !!recovery_enable; - if (!ar->fw_recovery.enable) - return ret; - - if (heart_beat_poll && - test_bit(ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, - ar->fw_capabilities)) - ar->fw_recovery.hb_poll = heart_beat_poll; - - ath6kl_recovery_init(ar); - return ret; err_rxbuf_cleanup: @@ -310,8 +291,6 @@ void ath6kl_core_cleanup(struct ath6kl *ar) { ath6kl_hif_power_off(ar); - ath6kl_recovery_cleanup(ar); - destroy_workqueue(ar->ath6kl_wq); if (ar->htc_target) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h index 189d8faf8c87..cec49a31029a 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h @@ -115,27 +115,6 @@ enum ath6kl_fw_capability { */ ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, - /* Firmware supports filtering BSS results by RSSI */ - ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, - - /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */ - ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, - - /* Firmware supports TX error rate notification */ - ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, - - /* supports WMI_SET_REGDOMAIN_CMDID command */ - ATH6KL_FW_CAPABILITY_REGDOMAIN, - - /* Firmware supports sched scan decoupled from host sleep */ - ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, - - /* - * Firmware capability for hang detection through heart beat - * challenge messages. - */ - ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, - /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; @@ -149,15 +128,11 @@ struct ath6kl_fw_ie { }; enum ath6kl_hw_flags { - ATH6KL_HW_64BIT_RATES = BIT(0), - ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1), - ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2), - ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3), + ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), }; #define ATH6KL_FW_API2_FILE "fw-2.bin" #define ATH6KL_FW_API3_FILE "fw-3.bin" -#define ATH6KL_FW_API4_FILE "fw-4.bin" /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba @@ -211,13 +186,6 @@ enum ath6kl_hw_flags { #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ AR6004_HW_1_2_FW_DIR "/bdata.bin" -/* AR6004 1.3 definitions */ -#define AR6004_HW_1_3_VERSION 0x31c8088a -#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3" -#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin" -#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" -#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" - /* Per STA data, used in AP mode */ #define STA_PS_AWAKE BIT(0) #define STA_PS_SLEEP BIT(1) @@ -568,7 +536,6 @@ enum ath6kl_vif_state { HOST_SLEEP_MODE_CMD_PROCESSED, NETDEV_MCAST_ALL_ON, NETDEV_MCAST_ALL_OFF, - SCHED_SCANNING, }; struct ath6kl_vif { @@ -613,13 +580,11 @@ struct ath6kl_vif { u16 assoc_bss_beacon_int; u16 listen_intvl_t; u16 bmiss_time_t; - u32 txe_intvl; u16 bg_scan_period; u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; struct wmi_connect_cmd profile; - u16 rsn_capab; struct list_head mc_filter; }; @@ -644,7 +609,6 @@ enum ath6kl_dev_state { SKIP_SCAN, ROAM_TBL_PEND, FIRST_BOOT, - RECOVERY_CLEANUP, }; enum ath6kl_state { @@ -655,16 +619,7 @@ enum ath6kl_state { ATH6KL_STATE_DEEPSLEEP, ATH6KL_STATE_CUTPOWER, ATH6KL_STATE_WOW, - ATH6KL_STATE_RECOVERY, -}; - -/* Fw error recovery */ -#define ATH6KL_HB_RESP_MISS_THRES 5 - -enum ath6kl_fw_err { - ATH6KL_FW_ASSERT, - ATH6KL_FW_HB_RESP_FAILURE, - ATH6KL_FW_EP_FULL, + ATH6KL_STATE_SCHED_SCAN, }; struct ath6kl { @@ -724,7 +679,6 @@ struct ath6kl { struct ath6kl_req_key ap_mode_bkey; struct sk_buff_head mcastpsq; u32 want_ch_switch; - u16 last_ch; /* * FIXME: protects access to mcastpsq but is actually useless as @@ -810,17 +764,6 @@ struct ath6kl { bool wiphy_registered; - struct ath6kl_fw_recovery { - struct work_struct recovery_work; - unsigned long err_reason; - unsigned long hb_poll; - struct timer_list hb_timer; - u32 seq_num; - bool hb_pending; - u8 hb_misscnt; - bool enable; - } fw_recovery; - #ifdef CONFIG_ATH6KL_DEBUG struct { struct sk_buff_head fwlog_queue; @@ -956,12 +899,4 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type); void ath6kl_core_cleanup(struct ath6kl *ar); void ath6kl_core_destroy(struct ath6kl *ar); -/* Fw error recovery */ -void ath6kl_init_hw_restart(struct ath6kl *ar); -void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason); -void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie); -void ath6kl_recovery_init(struct ath6kl *ar); -void ath6kl_recovery_cleanup(struct ath6kl *ar); -void ath6kl_recovery_suspend(struct ath6kl *ar); -void ath6kl_recovery_resume(struct ath6kl *ar); #endif /* CORE_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.h b/trunk/drivers/net/wireless/ath/ath6kl/debug.h index f97cd4ead543..49639d8266c2 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.h @@ -44,7 +44,6 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_SUSPEND = BIT(20), ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_USB_BULK = BIT(22), - ATH6KL_DBG_RECOVERY = BIT(23), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif.c b/trunk/drivers/net/wireless/ath/ath6kl/hif.c index a6b614421fa4..68ed6c2665b7 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/hif.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/hif.c @@ -136,7 +136,6 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) ath6kl_hif_dump_fw_crash(dev->ar); ath6kl_read_fwlogs(dev->ar); - ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT); return ret; } @@ -339,7 +338,8 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev) status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS, reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); - WARN_ON(status); + if (status) + WARN_ON(1); return status; } @@ -383,7 +383,8 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS, reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); - WARN_ON(status); + if (status) + WARN_ON(1); return status; } @@ -694,6 +695,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); + /* usb doesn't support enabling interrupts */ + /* FIXME: remove check once USB support is implemented */ + if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) + return 0; + status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c index fbb78dfe078f..cd0e1ba410d6 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -2492,8 +2492,7 @@ static int ath6kl_htc_mbox_conn_service(struct htc_target *target, max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); } - if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED || - assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) { + if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) { status = -ENOMEM; goto fail_tx; } @@ -2656,6 +2655,12 @@ static int ath6kl_htc_mbox_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; + /* FIXME: remove once USB support is implemented */ + if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ath6kl_err("HTC doesn't support USB yet. Patience!\n"); + return -EOPNOTSUPP; + } + /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2885,7 +2890,9 @@ static void ath6kl_htc_mbox_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - ath6kl_hif_cleanup_scatter(target->dev->ar); + /* FIXME: remove check once USB support is implemented */ + if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, &target->free_ctrl_txbuf, list) { diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c index ba6bd497b787..f9626c723693 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -374,8 +374,9 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, packet = list_first_entry(txq, struct htc_packet, list); - /* move to local queue */ - list_move_tail(&packet->list, &send_queue); + list_del(&packet->list); + /* insert into local queue */ + list_add_tail(&packet->list, &send_queue); } /* @@ -398,10 +399,11 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, * for cleanup */ } else { /* callback wants to keep this packet, - * move from caller's queue to the send - * queue */ - list_move_tail(&packet->list, - &send_queue); + * remove from caller's queue */ + list_del(&packet->list); + /* put it in the send queue */ + list_add_tail(&packet->list, + &send_queue); } } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c index f21fa322e5ca..f90b5db741cf 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/init.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c @@ -42,7 +42,7 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 6912, .refclk_hz = 26000000, .uarttx_pin = 8, - .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, + .flags = 0, /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, @@ -68,7 +68,7 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, .testscript_addr = 0x57ef74, - .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, + .flags = 0, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x433900, .refclk_hz = 26000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_0_FW_DIR, @@ -114,8 +113,8 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x43d400, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, + .fw = { .dir = AR6004_HW_1_1_FW_DIR, .fw = AR6004_HW_1_1_FIRMWARE_FILE, @@ -134,8 +133,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x435c00, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_2_FW_DIR, @@ -144,28 +142,6 @@ static const struct ath6kl_hw hw_list[] = { .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, }, - { - .id = AR6004_HW_1_3_VERSION, - .name = "ar6004 hw 1.3", - .dataset_patch_addr = 0x437860, - .app_load_addr = 0x1234, - .board_ext_data_addr = 0x437000, - .reserved_ram_size = 7168, - .board_addr = 0x436400, - .refclk_hz = 40000000, - .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS | - ATH6KL_HW_MAP_LP_ENDPOINT, - - .fw = { - .dir = AR6004_HW_1_3_FW_DIR, - .fw = AR6004_HW_1_3_FIRMWARE_FILE, - }, - - .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE, - .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE, - }, }; /* @@ -361,7 +337,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar) if (ath6kl_connectservice(ar, &connect, "WMI DATA BK")) return -EIO; - /* connect to Video service, map this to HI PRI */ + /* connect to Video service, map this to to HI PRI */ connect.svc_id = WMI_DATA_VI_SVC; if (ath6kl_connectservice(ar, &connect, "WMI DATA VI")) return -EIO; @@ -1112,12 +1088,6 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; - ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE); - if (ret == 0) { - ar->fw_api = 4; - goto out; - } - ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { ar->fw_api = 3; @@ -1431,7 +1401,8 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; /* WAR to avoid SDIO CRC err */ - if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) { + if (ar->version.target_ver == AR6003_HW_2_0_VERSION || + ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); param = 0x28; @@ -1549,7 +1520,7 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type) return NULL; } -static int __ath6kl_init_hw_start(struct ath6kl *ar) +int ath6kl_init_hw_start(struct ath6kl *ar) { long timeleft; int ret, i; @@ -1645,6 +1616,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) goto err_htc_stop; } + ar->state = ATH6KL_STATE_ON; + return 0; err_htc_stop: @@ -1657,18 +1630,7 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) return ret; } -int ath6kl_init_hw_start(struct ath6kl *ar) -{ - int err; - - err = __ath6kl_init_hw_start(ar); - if (err) - return err; - ar->state = ATH6KL_STATE_ON; - return 0; -} - -static int __ath6kl_init_hw_stop(struct ath6kl *ar) +int ath6kl_init_hw_stop(struct ath6kl *ar) { int ret; @@ -1684,35 +1646,9 @@ static int __ath6kl_init_hw_stop(struct ath6kl *ar) if (ret) ath6kl_warn("failed to power off hif: %d\n", ret); - return 0; -} - -int ath6kl_init_hw_stop(struct ath6kl *ar) -{ - int err; - - err = __ath6kl_init_hw_stop(ar); - if (err) - return err; ar->state = ATH6KL_STATE_OFF; - return 0; -} -void ath6kl_init_hw_restart(struct ath6kl *ar) -{ - clear_bit(WMI_READY, &ar->flag); - - ath6kl_cfg80211_stop_all(ar); - - if (__ath6kl_init_hw_stop(ar)) { - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n"); - return; - } - - if (__ath6kl_init_hw_start(ar)) { - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n"); - return; - } + return 0; } /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c index bd50b6b7b492..c189e28e86a9 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/main.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c @@ -293,17 +293,13 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) } address = TARG_VTOP(ar->target_type, debug_hdr_addr); - ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); - if (ret) - goto out; + ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_hdr.dbuf_addr)); firstbuf = address; dropped = le32_to_cpu(debug_hdr.dropped); - ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); - if (ret) - goto out; + ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); loop = 100; @@ -326,8 +322,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_buf.next)); - ret = ath6kl_diag_read(ar, address, &debug_buf, - sizeof(debug_buf)); + ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); if (ret) goto out; @@ -441,9 +436,12 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) break; } - if (ar->last_ch != channel) + if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { + ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); /* we actually don't know the phymode, default to HT20 */ - ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20); + ath6kl_cfg80211_ch_switch_notify(vif, channel, + WMI_11G_HT20); + } ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); set_bit(CONNECTED, &vif->flags); @@ -608,18 +606,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) switch (vif->nw_type) { case AP_NETWORK: - /* - * reconfigure any saved RSN IE capabilites in the beacon / - * probe response to stay in sync with the supplicant. - */ - if (vif->rsn_capab && - test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, - ar->fw_capabilities)) - ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx, - WLAN_EID_RSN, WMI_RSN_IE_CAPB, - (const u8 *) &vif->rsn_capab, - sizeof(vif->rsn_capab)); - return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &vif->profile); default: @@ -642,9 +628,6 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel) if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) res = ath6kl_commit_ch_switch(vif, channel); - /* if channel switch failed, oh well we tried */ - ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); - if (res) ath6kl_err("channel switch failed nw_type %d res %d\n", vif->nw_type, res); @@ -998,25 +981,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, if (vif->nw_type == AP_NETWORK) { /* disconnect due to other STA vif switching channels */ if (reason == BSS_DISCONNECTED && - prot_reason_status == WMI_AP_REASON_STA_ROAM) { + prot_reason_status == WMI_AP_REASON_STA_ROAM) ar->want_ch_switch |= 1 << vif->fw_vif_idx; - /* bail back to this channel if STA vif fails connect */ - ar->last_ch = le16_to_cpu(vif->profile.ch); - } - - if (prot_reason_status == WMI_AP_REASON_MAX_STA) { - /* send max client reached notification to user space */ - cfg80211_conn_failed(vif->ndev, bssid, - NL80211_CONN_FAIL_MAX_CLIENTS, - GFP_KERNEL); - } - - if (prot_reason_status == WMI_AP_REASON_ACL) { - /* send blocked client notification to user space */ - cfg80211_conn_failed(vif->ndev, bssid, - NL80211_CONN_FAIL_BLOCKED_CLIENT, - GFP_KERNEL); - } if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) return; @@ -1075,9 +1041,6 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } } - /* restart disconnected concurrent vifs waiting for new channel */ - ath6kl_check_ch_switch(ar, ar->last_ch); - /* update connect & link status atomically */ spin_lock_bh(&vif->if_lock); clear_bit(CONNECTED, &vif->flags); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/recovery.c b/trunk/drivers/net/wireless/ath/ath6kl/recovery.c deleted file mode 100644 index 3a8d5e97dc8e..000000000000 --- a/trunk/drivers/net/wireless/ath/ath6kl/recovery.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "core.h" -#include "cfg80211.h" -#include "debug.h" - -static void ath6kl_recovery_work(struct work_struct *work) -{ - struct ath6kl *ar = container_of(work, struct ath6kl, - fw_recovery.recovery_work); - - ar->state = ATH6KL_STATE_RECOVERY; - - del_timer_sync(&ar->fw_recovery.hb_timer); - - ath6kl_init_hw_restart(ar); - - ar->state = ATH6KL_STATE_ON; - clear_bit(WMI_CTRL_EP_FULL, &ar->flag); - - ar->fw_recovery.err_reason = 0; - - if (ar->fw_recovery.hb_poll) - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason) -{ - if (!ar->fw_recovery.enable) - return; - - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Fw error detected, reason:%d\n", - reason); - - set_bit(reason, &ar->fw_recovery.err_reason); - - if (!test_bit(RECOVERY_CLEANUP, &ar->flag) && - ar->state != ATH6KL_STATE_RECOVERY) - queue_work(ar->ath6kl_wq, &ar->fw_recovery.recovery_work); -} - -void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie) -{ - if (cookie == ar->fw_recovery.seq_num) - ar->fw_recovery.hb_pending = false; -} - -static void ath6kl_recovery_hb_timer(unsigned long data) -{ - struct ath6kl *ar = (struct ath6kl *) data; - int err; - - if (test_bit(RECOVERY_CLEANUP, &ar->flag) || - (ar->state == ATH6KL_STATE_RECOVERY)) - return; - - if (ar->fw_recovery.hb_pending) - ar->fw_recovery.hb_misscnt++; - else - ar->fw_recovery.hb_misscnt = 0; - - if (ar->fw_recovery.hb_misscnt > ATH6KL_HB_RESP_MISS_THRES) { - ar->fw_recovery.hb_misscnt = 0; - ar->fw_recovery.seq_num = 0; - ar->fw_recovery.hb_pending = false; - ath6kl_recovery_err_notify(ar, ATH6KL_FW_HB_RESP_FAILURE); - return; - } - - ar->fw_recovery.seq_num++; - ar->fw_recovery.hb_pending = true; - - err = ath6kl_wmi_get_challenge_resp_cmd(ar->wmi, - ar->fw_recovery.seq_num, 0); - if (err) - ath6kl_warn("Failed to send hb challenge request, err:%d\n", - err); - - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_init(struct ath6kl *ar) -{ - struct ath6kl_fw_recovery *recovery = &ar->fw_recovery; - - clear_bit(RECOVERY_CLEANUP, &ar->flag); - INIT_WORK(&recovery->recovery_work, ath6kl_recovery_work); - recovery->seq_num = 0; - recovery->hb_misscnt = 0; - ar->fw_recovery.hb_pending = false; - ar->fw_recovery.hb_timer.function = ath6kl_recovery_hb_timer; - ar->fw_recovery.hb_timer.data = (unsigned long) ar; - init_timer_deferrable(&ar->fw_recovery.hb_timer); - - if (ar->fw_recovery.hb_poll) - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_cleanup(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - set_bit(RECOVERY_CLEANUP, &ar->flag); - - del_timer_sync(&ar->fw_recovery.hb_timer); - cancel_work_sync(&ar->fw_recovery.recovery_work); -} - -void ath6kl_recovery_suspend(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - ath6kl_recovery_cleanup(ar); - - if (!ar->fw_recovery.err_reason) - return; - - /* Process pending fw error detection */ - ar->fw_recovery.err_reason = 0; - WARN_ON(ar->state != ATH6KL_STATE_ON); - ar->state = ATH6KL_STATE_RECOVERY; - ath6kl_init_hw_restart(ar); - ar->state = ATH6KL_STATE_ON; -} - -void ath6kl_recovery_resume(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - clear_bit(RECOVERY_CLEANUP, &ar->flag); - - if (!ar->fw_recovery.hb_poll) - return; - - ar->fw_recovery.hb_pending = false; - ar->fw_recovery.seq_num = 0; - ar->fw_recovery.hb_misscnt = 0; - mod_timer(&ar->fw_recovery.hb_timer, - jiffies + msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} diff --git a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c index d111980d44c0..05b95405f7b5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c @@ -709,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct htc_target *target = ar->htc_target; - int ret = 0; + int ret; bool virt_scat = false; if (ar_sdio->scatter_enabled) @@ -844,6 +844,22 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) bool try_deepsleep = false; int ret; + if (ar->state == ATH6KL_STATE_SCHED_SCAN) { + ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + + ret = ath6kl_cfg80211_suspend(ar, + ATH6KL_CFG_SUSPEND_SCHED_SCAN, + NULL); + if (ret) + goto cut_pwr; + + return 0; + } + if (ar->suspend_mode == WLAN_POWER_STATE_WOW || (!ar->suspend_mode && wow)) { @@ -926,13 +942,13 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) case ATH6KL_STATE_WOW: break; - case ATH6KL_STATE_SUSPENDING: + case ATH6KL_STATE_SCHED_SCAN: break; - case ATH6KL_STATE_RESUMING: + case ATH6KL_STATE_SUSPENDING: break; - case ATH6KL_STATE_RECOVERY: + case ATH6KL_STATE_RESUMING: break; } @@ -1446,6 +1462,3 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c index 78b369286579..7dfa0fd86d7b 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c @@ -288,16 +288,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, int status = 0; struct ath6kl_cookie *cookie = NULL; - if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { - dev_kfree_skb(skb); + if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) return -EACCES; - } - - if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED || - eid >= ENDPOINT_MAX)) { - status = -EINVAL; - goto fail_ctrl_tx; - } spin_lock_bh(&ar->lock); @@ -599,7 +591,6 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, */ set_bit(WMI_CTRL_EP_FULL, &ar->flag); ath6kl_err("wmi ctrl ep is full\n"); - ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL); return action; } @@ -704,31 +695,22 @@ void ath6kl_tx_complete(struct htc_target *target, list); list_del(&packet->list); - if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED || - packet->endpoint >= ENDPOINT_MAX)) - continue; - ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; - if (WARN_ON_ONCE(!ath6kl_cookie)) - continue; + if (!ath6kl_cookie) + goto fatal; status = packet->status; skb = ath6kl_cookie->skb; eid = packet->endpoint; map_no = ath6kl_cookie->map_no; - if (WARN_ON_ONCE(!skb || !skb->data)) { - dev_kfree_skb(skb); - ath6kl_free_cookie(ar, ath6kl_cookie); - continue; - } + if (!skb || !skb->data) + goto fatal; __skb_queue_tail(&skb_queue, skb); - if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) { - ath6kl_free_cookie(ar, ath6kl_cookie); - continue; - } + if (!status && (packet->act_len != skb->len)) + goto fatal; ar->tx_pending[eid]--; @@ -810,6 +792,11 @@ void ath6kl_tx_complete(struct htc_target *target, wake_up(&ar->event_wq); return; + +fatal: + WARN_ON(1); + spin_unlock_bh(&ar->lock); + return; } void ath6kl_tx_data_cleanup(struct ath6kl *ar) @@ -898,11 +885,8 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) break; packet = (struct htc_packet *) skb->head; - if (!IS_ALIGNED((unsigned long) skb->data, 4)) { - size_t len = skb_headlen(skb); + if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); - skb_set_tail_pointer(skb, len); - } set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_BUFFER_SIZE, endpoint); packet->skb = skb; @@ -924,11 +908,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count) return; packet = (struct htc_packet *) skb->head; - if (!IS_ALIGNED((unsigned long) skb->data, 4)) { - size_t len = skb_headlen(skb); + if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); - skb_set_tail_pointer(skb, len); - } set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_AMSDU_BUFFER_SIZE, 0); packet->skb = skb; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/usb.c b/trunk/drivers/net/wireless/ath/ath6kl/usb.c index 62bcc0d5bc23..3740c3d6ab88 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/usb.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/usb.c @@ -185,10 +185,9 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, for (i = 0; i < urb_cnt; i++) { urb_context = kzalloc(sizeof(struct ath6kl_urb_context), GFP_KERNEL); - if (urb_context == NULL) { - status = -ENOMEM; - goto fail_alloc_pipe_resources; - } + if (urb_context == NULL) + /* FIXME: set status to -ENOMEM */ + break; urb_context->pipe = pipe; @@ -205,7 +204,6 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, pipe->logical_pipe_num, pipe->usb_pipe_handle, pipe->urb_alloc); -fail_alloc_pipe_resources: return status; } @@ -805,11 +803,7 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; break; case WMI_DATA_VI_SVC: - - if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; - else - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; + *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; /* * Disable rxdata2 directly, it will be enabled * if FW enable rxdata2 @@ -817,11 +811,7 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; break; case WMI_DATA_VO_SVC: - - if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; - else - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; + *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP; /* * Disable rxdata2 directly, it will be enabled * if FW enable rxdata2 @@ -1206,14 +1196,7 @@ static struct usb_driver ath6kl_usb_driver = { static int ath6kl_usb_init(void) { - int ret; - - ret = usb_register(&ath6kl_usb_driver); - if (ret) { - ath6kl_err("usb registration failed: %d\n", ret); - return ret; - } - + usb_register(&ath6kl_usb_driver); return 0; } @@ -1237,6 +1220,3 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c index 55ccf9770339..c30ab4b11d61 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c @@ -936,12 +936,8 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) regpair = ath6kl_get_regpair((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code); - if (regpair) - ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", - regpair->regDmnEnum); - else - ath6kl_warn("Regpair not found reg_code 0x%0x\n", - reg_code); + ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", + regpair->regDmnEnum); } if (country && wmi->parent_dev->wiphy_registered) { @@ -1120,7 +1116,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, * the timer would not ever fire if the scan interval is short * enough. */ - if (test_bit(SCHED_SCANNING, &vif->flags) && + if (ar->state == ATH6KL_STATE_SCHED_SCAN && !timer_pending(&vif->sched_scan_timer)) { mod_timer(&vif->sched_scan_timer, jiffies + msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); @@ -1174,9 +1170,6 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) rate = RATE_AUTO; } else { index = reply->rate_index & 0x7f; - if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1))) - return -EINVAL; - sgi = (reply->rate_index & 0x80) ? 1 : 0; rate = wmi_rate_tbl[index][sgi]; } @@ -1538,68 +1531,6 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len, return 0; } -static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) -{ - struct wmi_txe_notify_event *ev; - u32 rate, pkts; - - if (len < sizeof(*ev)) - return -EINVAL; - - if (vif->sme_state != SME_CONNECTED) - return -ENOTCONN; - - ev = (struct wmi_txe_notify_event *) datap; - rate = le32_to_cpu(ev->rate); - pkts = le32_to_cpu(ev->pkts); - - ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n", - vif->bssid, rate, pkts, vif->txe_intvl); - - cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts, - rate, vif->txe_intvl, GFP_KERNEL); - - return 0; -} - -int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, - u32 rate, u32 pkts, u32 intvl) -{ - struct sk_buff *skb; - struct wmi_txe_notify_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_txe_notify_cmd *) skb->data; - cmd->rate = cpu_to_le32(rate); - cmd->pkts = cpu_to_le32(pkts); - cmd->intvl = cpu_to_le32(intvl); - - return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID, - NO_SYNC_WMIFLAG); -} - -int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) -{ - struct sk_buff *skb; - struct wmi_set_rssi_filter_cmd *cmd; - int ret; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_rssi_filter_cmd *) skb->data; - cmd->rssi = rssi; - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSSI_FILTER_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi, struct wmi_snr_threshold_params_cmd *snr_cmd) { @@ -1746,11 +1677,8 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, int ret; u16 info1; - if (WARN_ON(skb == NULL || - (if_idx > (wmi->parent_dev->vif_max - 1)))) { - dev_kfree_skb(skb); + if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1)))) return -EINVAL; - } ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", cmd_id, skb->len, sync_flag); @@ -1905,59 +1833,6 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) return ret; } -/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use - * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P - * mgmt operations using station interface. - */ -static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, - enum wmi_scan_type scan_type, - u32 force_fgscan, u32 is_legacy, - u32 home_dwell_time, - u32 force_scan_interval, - s8 num_chan, u16 *ch_list) -{ - struct sk_buff *skb; - struct wmi_start_scan_cmd *sc; - s8 size; - int i, ret; - - size = sizeof(struct wmi_start_scan_cmd); - - if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) - return -EINVAL; - - if (num_chan > WMI_MAX_CHANNELS) - return -EINVAL; - - if (num_chan) - size += sizeof(u16) * (num_chan - 1); - - skb = ath6kl_wmi_get_new_buf(size); - if (!skb) - return -ENOMEM; - - sc = (struct wmi_start_scan_cmd *) skb->data; - sc->scan_type = scan_type; - sc->force_fg_scan = cpu_to_le32(force_fgscan); - sc->is_legacy = cpu_to_le32(is_legacy); - sc->home_dwell_time = cpu_to_le32(home_dwell_time); - sc->force_scan_intvl = cpu_to_le32(force_scan_interval); - sc->num_ch = num_chan; - - for (i = 0; i < num_chan; i++) - sc->ch_list[i] = cpu_to_le16(ch_list[i]); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, - NO_SYNC_WMIFLAG); - - return ret; -} - -/* - * beginscan supports (compared to old startscan) P2P mgmt operations using - * station interface, send additional information like supported rates to - * advertise and xmit rates for probe requests - */ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, enum wmi_scan_type scan_type, u32 force_fgscan, u32 is_legacy, @@ -1973,15 +1848,6 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, int num_rates; u32 ratemask; - if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { - return ath6kl_wmi_startscan_cmd(wmi, if_idx, - scan_type, force_fgscan, - is_legacy, home_dwell_time, - force_scan_interval, - num_chan, ch_list); - } - size = sizeof(struct wmi_begin_scan_cmd); if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) @@ -2034,24 +1900,50 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, return ret; } -int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable) +/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use + * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P + * mgmt operations using station interface. + */ +int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, + enum wmi_scan_type scan_type, + u32 force_fgscan, u32 is_legacy, + u32 home_dwell_time, u32 force_scan_interval, + s8 num_chan, u16 *ch_list) { struct sk_buff *skb; - struct wmi_enable_sched_scan_cmd *sc; - int ret; + struct wmi_start_scan_cmd *sc; + s8 size; + int i, ret; - skb = ath6kl_wmi_get_new_buf(sizeof(*sc)); + size = sizeof(struct wmi_start_scan_cmd); + + if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) + return -EINVAL; + + if (num_chan > WMI_MAX_CHANNELS) + return -EINVAL; + + if (num_chan) + size += sizeof(u16) * (num_chan - 1); + + skb = ath6kl_wmi_get_new_buf(size); if (!skb) return -ENOMEM; - ath6kl_dbg(ATH6KL_DBG_WMI, "%s scheduled scan on vif %d\n", - enable ? "enabling" : "disabling", if_idx); - sc = (struct wmi_enable_sched_scan_cmd *) skb->data; - sc->enable = enable ? 1 : 0; + sc = (struct wmi_start_scan_cmd *) skb->data; + sc->scan_type = scan_type; + sc->force_fg_scan = cpu_to_le32(force_fgscan); + sc->is_legacy = cpu_to_le32(is_legacy); + sc->home_dwell_time = cpu_to_le32(home_dwell_time); + sc->force_scan_intvl = cpu_to_le32(force_scan_interval); + sc->num_ch = num_chan; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_ENABLE_SCHED_SCAN_CMDID, + for (i = 0; i < num_chan; i++) + sc->ch_list[i] = cpu_to_le16(ch_list[i]); + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG); + return ret; } @@ -2383,10 +2275,8 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb, struct wmi_data_hdr *data_hdr; int ret; - if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) { - dev_kfree_skb(skb); + if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) return -EINVAL; - } skb_push(skb, sizeof(struct wmi_data_hdr)); @@ -2423,8 +2313,10 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) spin_unlock_bh(&wmi->lock); skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; + if (!skb) { + ret = -ENOMEM; + goto free_skb; + } cmd = (struct wmi_sync_cmd *) skb->data; @@ -2447,7 +2339,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) * then do not send the Synchronize cmd on the control ep */ if (ret) - goto free_cmd_skb; + goto free_skb; /* * Send sync cmd followed by sync data messages on all @@ -2457,12 +2349,15 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) NO_SYNC_WMIFLAG); if (ret) - goto free_data_skb; + goto free_skb; + + /* cmd buffer sent, we no longer own it */ + skb = NULL; for (index = 0; index < num_pri_streams; index++) { if (WARN_ON(!data_sync_bufs[index].skb)) - goto free_data_skb; + break; ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, data_sync_bufs[index]. @@ -2471,20 +2366,17 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb, ep_id, if_idx); - data_sync_bufs[index].skb = NULL; - if (ret) - goto free_data_skb; - } + break; - return 0; + data_sync_bufs[index].skb = NULL; + } -free_cmd_skb: +free_skb: /* free up any resources left over (possibly due to an error) */ if (skb) dev_kfree_skb(skb); -free_data_skb: for (index = 0; index < num_pri_streams; index++) { if (data_sync_bufs[index].skb != NULL) { dev_kfree_skb((struct sk_buff *)data_sync_bufs[index]. @@ -2726,13 +2618,11 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, { struct sk_buff *skb; int ret, mode, band; - u64 mcsrate, ratemask[ATH6KL_NUM_BANDS]; + u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; struct wmi_set_tx_select_rates64_cmd *cmd; memset(&ratemask, 0, sizeof(ratemask)); - - /* only check 2.4 and 5 GHz bands, skip the rest */ - for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { /* copy legacy rate mask */ ratemask[band] = mask->control[band].legacy; if (band == IEEE80211_BAND_5GHZ) @@ -2778,13 +2668,11 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, { struct sk_buff *skb; int ret, mode, band; - u32 mcsrate, ratemask[ATH6KL_NUM_BANDS]; + u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; struct wmi_set_tx_select_rates32_cmd *cmd; memset(&ratemask, 0, sizeof(ratemask)); - - /* only check 2.4 and 5 GHz bands, skip the rest */ - for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { /* copy legacy rate mask */ ratemask[band] = mask->control[band].legacy; if (band == IEEE80211_BAND_5GHZ) @@ -2828,7 +2716,7 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, { struct ath6kl *ar = wmi->parent_dev; - if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); else return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); @@ -3251,40 +3139,12 @@ int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) return ret; } -int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2) -{ - struct sk_buff *skb; - struct wmi_set_regdomain_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_regdomain_cmd *) skb->data; - memcpy(cmd->iso_name, alpha2, 2); - - return ath6kl_wmi_cmd_send(wmi, 0, skb, - WMI_SET_REGDOMAIN_CMDID, - NO_SYNC_WMIFLAG); -} - s32 ath6kl_wmi_get_rate(s8 rate_index) { - u8 sgi = 0; - if (rate_index == RATE_AUTO) return 0; - /* SGI is stored as the MSB of the rate_index */ - if (rate_index & RATE_INDEX_MSB) { - rate_index &= RATE_INDEX_WITHOUT_SGI_MASK; - sgi = 1; - } - - if (WARN_ON(rate_index > RATE_MCS_7_40)) - rate_index = RATE_MCS_7_40; - - return wmi_rate_tbl[(u32) rate_index][sgi]; + return wmi_rate_tbl[(u32) rate_index][0]; } static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, @@ -3774,19 +3634,6 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout) NO_SYNC_WMIFLAG); } -static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap, - int len) -{ - struct wmix_hb_challenge_resp_cmd *cmd; - - if (len < sizeof(struct wmix_hb_challenge_resp_cmd)) - return; - - cmd = (struct wmix_hb_challenge_resp_cmd *) datap; - ath6kl_recovery_hb_event(wmi->parent_dev, - le32_to_cpu(cmd->cookie)); -} - static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) { struct wmix_cmd_hdr *cmd; @@ -3811,7 +3658,6 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) switch (id) { case WMIX_HB_CHALLENGE_RESP_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n"); - ath6kl_wmi_hb_challenge_resp_event(wmi, datap, len); break; case WMIX_DBGLOG_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len); @@ -3904,9 +3750,6 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, case WMI_RX_ACTION_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); - case WMI_TXE_NOTIFY_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n"); - return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif); default: ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); return -EINVAL; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h index 98b1755e67f4..43339aca585d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h @@ -48,7 +48,7 @@ #define A_BAND_24GHZ 0 #define A_BAND_5GHZ 1 -#define ATH6KL_NUM_BANDS 2 +#define A_NUM_BANDS 2 /* in ms */ #define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 @@ -628,20 +628,6 @@ enum wmi_cmd_id { WMI_SET_MCASTRATE, WMI_STA_BMISS_ENHANCE_CMDID, - - WMI_SET_REGDOMAIN_CMDID, - - WMI_SET_RSSI_FILTER_CMDID, - - WMI_SET_KEEP_ALIVE_EXT, - - WMI_VOICE_DETECTION_ENABLE_CMDID, - - WMI_SET_TXE_NOTIFY_CMDID, - - WMI_SET_RECOVERY_TEST_PARAMETER_CMDID, /*0xf094*/ - - WMI_ENABLE_SCHED_SCAN_CMDID, }; enum wmi_mgmt_frame_type { @@ -857,7 +843,7 @@ struct wmi_begin_scan_cmd { u8 scan_type; /* Supported rates to advertise in the probe request frames */ - struct wmi_supp_rates supp_rates[ATH6KL_NUM_BANDS]; + struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS]; /* how many channels follow */ u8 num_ch; @@ -955,11 +941,6 @@ struct wmi_scan_params_cmd { __le32 max_dfsch_act_time; } __packed; -/* WMI_ENABLE_SCHED_SCAN_CMDID */ -struct wmi_enable_sched_scan_cmd { - u8 enable; -} __packed; - /* WMI_SET_BSS_FILTER_CMDID */ enum wmi_bss_filter { /* no beacons forwarded */ @@ -1051,11 +1032,6 @@ struct wmi_sta_bmiss_enhance_cmd { u8 enable; } __packed; -struct wmi_set_regdomain_cmd { - u8 length; - u8 iso_name[2]; -} __packed; - /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -1300,11 +1276,6 @@ struct wmi_snr_threshold_params_cmd { u8 reserved[3]; } __packed; -/* Don't report BSSs with signal (RSSI) below this threshold */ -struct wmi_set_rssi_filter_cmd { - s8 rssi; -} __packed; - enum wmi_preamble_policy { WMI_IGNORE_BARKER_IN_ERP = 0, WMI_FOLLOW_BARKER_IN_ERP, @@ -1484,20 +1455,6 @@ enum wmi_event_id { WMI_P2P_CAPABILITIES_EVENTID, WMI_RX_ACTION_EVENTID, WMI_P2P_INFO_EVENTID, - - /* WPS Events */ - WMI_WPS_GET_STATUS_EVENTID, - WMI_WPS_PROFILE_EVENTID, - - /* more P2P events */ - WMI_NOA_INFO_EVENTID, - WMI_OPPPS_INFO_EVENTID, - WMI_PORT_STATUS_EVENTID, - - /* 802.11w */ - WMI_GET_RSN_CAP_EVENTID, - - WMI_TXE_NOTIFY_EVENTID, }; struct wmi_ready_event_2 { @@ -1792,9 +1749,6 @@ struct rx_stats { a_sle32 ucast_rate; } __packed; -#define RATE_INDEX_WITHOUT_SGI_MASK 0x7f -#define RATE_INDEX_MSB 0x80 - struct tkip_ccmp_stats { __le32 tkip_local_mic_fail; __le32 tkip_cnter_measures_invoked; @@ -2065,6 +2019,7 @@ struct wmi_set_ie_cmd { #define WOW_MAX_FILTERS_PER_LIST 4 #define WOW_PATTERN_SIZE 64 +#define WOW_MASK_SIZE 64 #define MAC_MAX_FILTERS_PER_LIST 4 @@ -2073,7 +2028,7 @@ struct wow_filter { u8 wow_filter_id; u8 wow_filter_size; u8 wow_filter_offset; - u8 wow_filter_mask[WOW_PATTERN_SIZE]; + u8 wow_filter_mask[WOW_MASK_SIZE]; u8 wow_filter_pattern[WOW_PATTERN_SIZE]; } __packed; @@ -2132,19 +2087,6 @@ struct wmi_del_wow_pattern_cmd { __le16 filter_id; } __packed; -/* WMI_SET_TXE_NOTIFY_CMDID */ -struct wmi_txe_notify_cmd { - __le32 rate; - __le32 pkts; - __le32 intvl; -} __packed; - -/* WMI_TXE_NOTIFY_EVENTID */ -struct wmi_txe_notify_event { - __le32 rate; - __le32 pkts; -} __packed; - /* WMI_SET_AKMP_PARAMS_CMD */ struct wmi_pmkid { @@ -2563,6 +2505,11 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, u16 channel); int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx); +int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, + enum wmi_scan_type scan_type, + u32 force_fgscan, u32 is_legacy, + u32 home_dwell_time, u32 force_scan_interval, + s8 num_chan, u16 *ch_list); int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, enum wmi_scan_type scan_type, @@ -2570,7 +2517,6 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, u32 home_dwell_time, u32 force_scan_interval, s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates); -int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable); int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, u16 fg_end_sec, u16 bg_sec, @@ -2646,7 +2592,6 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, const u8 *mask); int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); -int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); @@ -2655,9 +2600,6 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, u8 *filter, bool add_filter); int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); -int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, - u32 rate, u32 pkts, u32 intvl); -int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2); /* AP mode uAPSD */ int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); @@ -2716,8 +2658,6 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout); void ath6kl_wmi_sscan_timer(unsigned long ptr); -int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source); - struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); void *ath6kl_wmi_init(struct ath6kl *devt); void ath6kl_wmi_shutdown(struct wmi *wmi); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 6f7cf49eff4d..89bf94d4d8a1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -534,107 +534,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = { static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec}, + {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, + {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, + {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, + {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, + {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec}, + {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, + {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, + {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000}, - {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501}, - {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, + {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, + {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, + {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, + {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352}, - {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584}, - {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd7625..84b558d126ca 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -276,11 +276,6 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) offset_array[i], REG_READ(ah, offset_array[i])); - if (AR_SREV_9565(ah) && - (iCoff == 63 || qCoff == 63 || - iCoff == -63 || qCoff == -63)) - return; - REG_RMW_FIELD(ah, offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, iCoff); @@ -891,74 +886,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); } -static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) -{ - int offset[8], total = 0, test; - int agc_out, i; - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON, 0x0); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); - - for (i = 6; i > 0; i--) { - offset[i] = BIT(i - 1); - test = total + offset[i]; - - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, - test); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, - test); - udelay(100); - agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_OUT); - offset[i] = (agc_out) ? 0 : 1; - total += (offset[i] << (i - 1)); - } - - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON_OVR, 0); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); -} - static bool ar9003_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1057,14 +984,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT); - if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { - for (i = 0; i < AR9300_MAX_CHAINS; i++) { - if (!(ah->rxchainmask & (1 << i))) - continue; - ar9003_hw_manual_peak_cal(ah, i, - IS_CHAN_2GHZ(chan)); - } - } } if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c86cb6400040..5bbe5057ba18 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -18,7 +18,6 @@ #include "hw.h" #include "ar9003_phy.h" #include "ar9003_eeprom.h" -#include "ar9003_mci.h" #define COMP_HDR_LEN 4 #define COMP_CKSUM_LEN 2 @@ -42,6 +41,7 @@ static int ar9003_hw_power_interpolate(int32_t x, int32_t *px, int32_t *py, u_int16_t np); + static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, @@ -2989,7 +2989,7 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, case EEP_PAPRD: if (AR_SREV_9462(ah)) return false; - if (!ah->config.enable_paprd) + if (!ah->config.enable_paprd); return false; return !!(pBase->featureEnable & BIT(5)); case EEP_CHAIN_MASK_REDUCE: @@ -3601,7 +3601,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE * SWITCH_TABLE_COM_SPDT_WLAN_IDLE */ - if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) { + if (AR_SREV_9462_20_OR_LATER(ah)) { value = ar9003_switch_com_spdt_get(ah, is2ghz); REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_SWITCH_TABLE_COM_SPDT_ALL, value); @@ -5037,28 +5037,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, case CTL_5GHT20: case CTL_2GHT20: for (i = ALL_TARGET_HT20_0_8_16; - i <= ALL_TARGET_HT20_23; i++) { + i <= ALL_TARGET_HT20_23; i++) pPwrArray[i] = (u8)min((u16)pPwrArray[i], minCtlPower); - if (ath9k_hw_mci_is_enabled(ah)) - pPwrArray[i] = - (u8)min((u16)pPwrArray[i], - ar9003_mci_get_max_txpower(ah, - pCtlMode[ctlMode])); - } break; case CTL_5GHT40: case CTL_2GHT40: for (i = ALL_TARGET_HT40_0_8_16; - i <= ALL_TARGET_HT40_23; i++) { + i <= ALL_TARGET_HT40_23; i++) pPwrArray[i] = (u8)min((u16)pPwrArray[i], minCtlPower); - if (ath9k_hw_mci_is_enabled(ah)) - pPwrArray[i] = - (u8)min((u16)pPwrArray[i], - ar9003_mci_get_max_txpower(ah, - pCtlMode[ctlMode])); - } break; default: break; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 74fd3977feeb..1a36fa262639 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -35,6 +35,12 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { +#define AR9462_BB_CTX_COEFJ(x) \ + ar9462_##x##_baseband_core_txfir_coeff_japan_2484 + +#define AR9462_BBC_TXIFR_COEFFJ \ + ar9462_2p0_baseband_core_txfir_coeff_japan_2484 + if (AR_SREV_9330_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -64,10 +70,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9331_modes_lowest_ob_db_tx_gain_1p1); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9331_1p1_baseband_core_txfir_coeff_japan_2484); - /* additional clock settings */ if (ah->is_clk_25mhz) INIT_INI_ARRAY(&ah->iniAdditional, @@ -104,10 +106,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9331_modes_lowest_ob_db_tx_gain_1p2); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9331_1p2_baseband_core_txfir_coeff_japan_2484); - /* additional clock settings */ if (ah->is_clk_25mhz) INIT_INI_ARRAY(&ah->iniAdditional, @@ -182,10 +180,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485_modes_lowest_ob_db_tx_gain_1_1); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9485_1_1_baseband_core_txfir_coeff_japan_2484); - /* Load PCIE SERDES settings from INI */ /* Awake Setting */ @@ -225,17 +219,19 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* Awake -> Sleep Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9462_pciephy_clkreq_disable_L1_2p0); + ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); /* Sleep -> Awake Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9462_pciephy_clkreq_disable_L1_2p0); + ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); /* Fast clock modal settings */ INIT_INI_ARRAY(&ah->iniModesFastClock, ar9462_modes_fast_clock_2p0); INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9462_2p0_baseband_core_txfir_coeff_japan_2484); + AR9462_BB_CTX_COEFJ(2p0)); + + INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ); } else if (AR_SREV_9550(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -332,9 +328,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ar9565_1p0_Modes_lowest_ob_db_tx_gain_table); INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9565_1p0_pciephy_clkreq_disable_L1); + ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9565_1p0_pciephy_clkreq_disable_L1); + ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); INIT_INI_ARRAY(&ah->iniModesFastClock, ar9565_1p0_modes_fast_clock); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 8dd069259e7b..44c202ce6c66 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -714,6 +714,7 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) return true; } +EXPORT_SYMBOL(ar9003_mci_start_reset); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata) @@ -749,9 +750,6 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, mci_hw->bt_state = MCI_BT_AWAKE; - REG_CLR_BIT(ah, AR_PHY_TIMING4, - 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT); - if (caldata) { caldata->done_txiqcal_once = false; caldata->done_txclcal_once = false; @@ -761,9 +759,6 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_init_cal(ah, chan)) return -EIO; - REG_SET_BIT(ah, AR_PHY_TIMING4, - 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT); - exit: ar9003_mci_enable_interrupt(ah); return 0; @@ -804,9 +799,6 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); - if (AR_SREV_9565(ah)) - REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1); - if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, @@ -826,7 +818,7 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 regval, i; + u32 regval; ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", is_full_sleep, is_2g); @@ -855,18 +847,11 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | SM(1, AR_BTCOEX_CTRL_PA_SHARED) | SM(1, AR_BTCOEX_CTRL_LNA_SHARED) | + SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | + SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) | SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - if (AR_SREV_9565(ah)) { - regval |= SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) | - SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, - AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1); - } else { - regval |= SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | - SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK); - } REG_WRITE(ah, AR_BTCOEX_CTRL, regval); @@ -880,24 +865,9 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); - /* Set the time out to 3.125ms (5 BT slots) */ - REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090); - - /* concurrent tx priority */ - if (mci->config & ATH_MCI_CONFIG_CONCUR_TX) { - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, - AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, - AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_REDUCE_TXPWR, 0); - for (i = 0; i < 8; i++) - REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), 0x7f7f7f7f); - } - regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV); REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval); REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN); @@ -940,9 +910,6 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, mci->ready = true; ar9003_mci_prep_interface(ah); - if (AR_SREV_9565(ah)) - REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL, - AR_MCI_DBG_CNT_CTRL_ENABLE, 0); if (en_int) ar9003_mci_enable_interrupt(ah); @@ -1061,9 +1028,7 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) ar9003_mci_osla_setup(ah, true); - - if (AR_SREV_9462(ah)) - REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); + REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); } else { ar9003_mci_send_lna_take(ah, true); udelay(5); @@ -1205,7 +1170,7 @@ EXPORT_SYMBOL(ar9003_mci_cleanup); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 value = 0, tsf; + u32 value = 0; u8 query_type; switch (state_type) { @@ -1263,14 +1228,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) ar9003_mci_send_coex_bt_status_query(ah, true, query_type); break; case MCI_STATE_RECOVER_RX: - tsf = ath9k_hw_gettsf32(ah); - if ((tsf - mci->last_recovery) <= MCI_RECOVERY_DUR_TSF) { - ath_dbg(ath9k_hw_common(ah), MCI, - "(MCI) ignore Rx recovery\n"); - break; - } - ath_dbg(ath9k_hw_common(ah), MCI, "(MCI) RECOVER RX\n"); - mci->last_recovery = tsf; ar9003_mci_prep_interface(ah); mci->query_bt = true; mci->need_flush_btinfo = true; @@ -1469,17 +1426,3 @@ void ar9003_mci_send_wlan_channels(struct ath_hw *ah) ar9003_mci_send_coex_wlan_channels(ah, true); } EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); - -u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode) -{ - if (!ah->btcoex_hw.mci.concur_tx) - goto out; - - if (ctlmode == CTL_2GHT20) - return ATH_BTCOEX_HT20_MAX_TXPOWER; - else if (ctlmode == CTL_2GHT40) - return ATH_BTCOEX_HT40_MAX_TXPOWER; - -out: - return -1; -} diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 66d7ab9f920d..2a2d01889613 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -18,7 +18,6 @@ #define AR9003_MCI_H #define MCI_FLAG_DISABLE_TIMESTAMP 0x00000001 /* Disable time stamp */ -#define MCI_RECOVERY_DUR_TSF (100 * 1000) /* 100 ms */ /* Default remote BT device MCI COEX version */ #define MCI_GPM_COEX_MAJOR_VERSION_DEFAULT 3 @@ -126,7 +125,6 @@ enum ath_mci_gpm_coex_profile_type { MCI_GPM_COEX_PROFILE_HID, MCI_GPM_COEX_PROFILE_BNEP, MCI_GPM_COEX_PROFILE_VOICE, - MCI_GPM_COEX_PROFILE_A2DPVO, MCI_GPM_COEX_PROFILE_MAX }; @@ -198,6 +196,7 @@ enum mci_state_type { MCI_STATE_SEND_WLAN_COEX_VERSION, MCI_STATE_SEND_VERSION_QUERY, MCI_STATE_SEND_STATUS_QUERY, + MCI_STATE_SET_CONCUR_TX_PRI, MCI_STATE_RECOVER_RX, MCI_STATE_NEED_FTP_STOMP, MCI_STATE_DEBUG, @@ -279,7 +278,6 @@ void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah); void ar9003_mci_check_gpm_offset(struct ath_hw *ah); -u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode); #else @@ -326,10 +324,6 @@ static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) { } -static inline u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode) -{ - return -1; -} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e8..759f5f5a7154 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -784,7 +784,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); if (chan->channel == 2484) - ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1); + ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 4c3d06de7111..9a48e3d2f231 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -32,7 +32,6 @@ #define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c) #define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc) #define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0) -#define AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT 16 #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 @@ -698,6 +697,13 @@ #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 +#define AR_PHY_65NM_CH0_RXTX1 0x16100 +#define AR_PHY_65NM_CH0_RXTX2 0x16104 +#define AR_PHY_65NM_CH1_RXTX1 0x16500 +#define AR_PHY_65NM_CH1_RXTX2 0x16504 +#define AR_PHY_65NM_CH2_RXTX1 0x16900 +#define AR_PHY_65NM_CH2_RXTX2 0x16904 + #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL 0xf000 @@ -1279,43 +1285,4 @@ #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 -/* Manual Peak detector calibration */ -#define AR_PHY_65NM_BASE 0x16000 -#define AR_PHY_65NM_RXRF_GAINSTAGES(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0x8) -#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE 0x80000000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE_S 31 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC 0x00000002 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC_S 1 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR 0x70000000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_S 28 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR 0x03800000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_S 23 - -#define AR_PHY_65NM_RXTX2(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0x104) -#define AR_PHY_65NM_RXTX2_RXON_OVR 0x00001000 -#define AR_PHY_65NM_RXTX2_RXON_OVR_S 12 -#define AR_PHY_65NM_RXTX2_RXON 0x00000800 -#define AR_PHY_65NM_RXTX2_RXON_S 11 - -#define AR_PHY_65NM_RXRF_AGC(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0xc) -#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE 0x80000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE_S 31 -#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR 0x40000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR_S 30 -#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR 0x20000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR_S 29 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR 0x1E000000 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR_S 25 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR 0x00078000 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR_S 15 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR 0x01F80000 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR_S 19 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR 0x00007e00 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR_S 9 -#define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 -#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 - #endif /* AR9003_PHY_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index ccc42a71b436..58f30f65c6b6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, - {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index a3710f3bb90c..fb4497fc7a3d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -18,7 +18,7 @@ #ifndef INITVALS_9485_H #define INITVALS_9485_H -/* AR9485 1.1 */ +/* AR9485 1.0 */ #define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble @@ -31,11 +31,6 @@ static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { /* Addr allmodes */ - {0x00009e00, 0x037216a0}, - {0x00009e04, 0x00182020}, - {0x00009e18, 0x00000000}, - {0x00009e2c, 0x00004121}, - {0x00009e44, 0x02282324}, {0x0000a000, 0x00060005}, {0x0000a004, 0x00810080}, {0x0000a008, 0x00830082}, @@ -169,11 +164,6 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, @@ -208,22 +198,6 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -260,193 +234,9 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; -static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; +#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 -static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; +#define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1 #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 @@ -455,19 +245,19 @@ static const u32 ar9485_1_1[][2] = { {0x0000a580, 0x00000000}, {0x0000a584, 0x00000000}, {0x0000a588, 0x00000000}, - {0x0000a58c, 0x01804000}, - {0x0000a590, 0x02808a02}, - {0x0000a594, 0x0340ca02}, - {0x0000a598, 0x0340cd03}, - {0x0000a59c, 0x0340cd03}, - {0x0000a5a0, 0x06415304}, - {0x0000a5a4, 0x04c11905}, - {0x0000a5a8, 0x06415905}, - {0x0000a5ac, 0x06415905}, - {0x0000a5b0, 0x06415905}, - {0x0000a5b4, 0x06415905}, - {0x0000a5b8, 0x06415905}, - {0x0000a5bc, 0x06415905}, + {0x0000a58c, 0x00000000}, + {0x0000a590, 0x00000000}, + {0x0000a594, 0x00000000}, + {0x0000a598, 0x00000000}, + {0x0000a59c, 0x00000000}, + {0x0000a5a0, 0x00000000}, + {0x0000a5a4, 0x00000000}, + {0x0000a5a8, 0x00000000}, + {0x0000a5ac, 0x00000000}, + {0x0000a5b0, 0x00000000}, + {0x0000a5b4, 0x00000000}, + {0x0000a5b8, 0x00000000}, + {0x0000a5bc, 0x00000000}, }; static const u32 ar9485_1_1_radio_core[][2] = { @@ -550,7 +340,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x00009880, 0x201fff00}, {0x00009884, 0x00001042}, {0x000098a4, 0x00200400}, - {0x000098b0, 0x32840bbe}, + {0x000098b0, 0x52440bbe}, {0x000098d0, 0x004b6a8e}, {0x000098d4, 0x00000820}, {0x000098dc, 0x00000000}, @@ -572,7 +362,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x00009d18, 0x00000000}, {0x00009d1c, 0x00000000}, {0x00009e08, 0x0038233c}, - {0x00009e24, 0x992bb515}, + {0x00009e24, 0x9927b515}, {0x00009e28, 0x12ef0200}, {0x00009e30, 0x06336f77}, {0x00009e34, 0x6af6532f}, @@ -637,7 +427,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x0000a408, 0x0e79e5c6}, {0x0000a40c, 0x00820820}, {0x0000a414, 0x1ce739cf}, - {0x0000a418, 0x2d0021ce}, + {0x0000a418, 0x2d0019ce}, {0x0000a41c, 0x1ce739ce}, {0x0000a420, 0x000001ce}, {0x0000a424, 0x1ce739ce}, @@ -653,8 +443,8 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x0000a44c, 0x00000001}, {0x0000a450, 0x00010000}, {0x0000a5c4, 0xbfad9d74}, - {0x0000a5c8, 0x00480605}, - {0x0000a5cc, 0x00002e37}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, {0x0000a760, 0x03020100}, {0x0000a764, 0x09080504}, {0x0000a768, 0x0d0c0b0a}, @@ -674,22 +464,17 @@ static const u32 ar9485_1_1_baseband_core[][2] = { static const u32 ar9485_common_rx_gain_1_1[][2] = { /* Addr allmodes */ - {0x00009e00, 0x03721b20}, - {0x00009e04, 0x00082020}, - {0x00009e18, 0x0300501e}, - {0x00009e2c, 0x00002e21}, - {0x00009e44, 0x02182324}, - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, {0x0000a02c, 0x03850384}, {0x0000a030, 0x03890388}, {0x0000a034, 0x038b038a}, @@ -711,15 +496,15 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x18181818}, - {0x0000a084, 0x18181818}, - {0x0000a088, 0x18181818}, - {0x0000a08c, 0x18181818}, - {0x0000a090, 0x18181818}, - {0x0000a094, 0x18181818}, - {0x0000a098, 0x17181818}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, {0x0000a0a4, 0x00000000}, {0x0000a0a8, 0x00000000}, {0x0000a0ac, 0x00000000}, @@ -727,22 +512,22 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x22072208}, - {0x0000a0c4, 0x22052206}, - {0x0000a0c8, 0x22032204}, - {0x0000a0cc, 0x22012202}, - {0x0000a0d0, 0x221f2200}, - {0x0000a0d4, 0x221d221e}, - {0x0000a0d8, 0x33023303}, - {0x0000a0dc, 0x33003301}, - {0x0000a0e0, 0x331e331f}, - {0x0000a0e4, 0x4402331d}, - {0x0000a0e8, 0x44004401}, - {0x0000a0ec, 0x441e441f}, - {0x0000a0f0, 0x55025503}, - {0x0000a0f4, 0x55005501}, - {0x0000a0f8, 0x551e551f}, - {0x0000a0fc, 0x6602551d}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, {0x0000a100, 0x66006601}, {0x0000a104, 0x661e661f}, {0x0000a108, 0x7703661d}, @@ -851,12 +636,17 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, @@ -1060,6 +850,4 @@ static const u32 ar9485_1_1_mac_core[][2] = { {0x000083d0, 0x000301ff}, }; -#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 - #endif /* INITVALS_9485_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h index 0c2ac0c6dc89..843e79f67ff2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h @@ -768,9 +768,9 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = { {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; -static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = { +static const u32 ar9565_1p0_pciephy_pll_on_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18213ede}, + {0x00018c00, 0x18212ede}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0003780c}, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 80bab1b8447a..dfe6a4707fd2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -129,10 +129,10 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, #define ATH_TXMAXTRY 13 #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 ATH_AGGR_DELIM_SZ 4 #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ @@ -259,10 +259,13 @@ struct ath_atx_tid { }; struct ath_node { +#ifdef CONFIG_ATH9K_DEBUGFS + struct list_head list; /* for sc->nodes */ +#endif struct ieee80211_sta *sta; /* station struct we're part of */ struct ieee80211_vif *vif; /* interface with which we're associated */ struct ath_atx_tid tid[WME_NUM_TID]; - struct ath_atx_ac ac[IEEE80211_NUM_ACS]; + struct ath_atx_ac ac[WME_NUM_AC]; int ps_key; u16 maxampdu; @@ -296,9 +299,9 @@ struct ath_tx { struct list_head txbuf; struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; struct ath_descdma txdma; - struct ath_txq *txq_map[IEEE80211_NUM_ACS]; - u32 txq_max_pending[IEEE80211_NUM_ACS]; - u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; + struct ath_txq *txq_map[WME_NUM_AC]; + u32 txq_max_pending[WME_NUM_AC]; + u16 max_aggr_framelen[WME_NUM_AC][4][32]; }; struct ath_rx_edma { @@ -434,7 +437,6 @@ void ath9k_set_beacon(struct ath_softc *sc); #define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ -#define ATH_ANI_MAX_SKIP_COUNT 10 #define ATH_PAPRD_TIMEOUT 100 /* msecs */ #define ATH_PLL_WORK_INTERVAL 100 @@ -458,12 +460,6 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); /* BTCOEX */ /**********/ -#define ATH_DUMP_BTCOEX(_s, _val) \ - do { \ - len += snprintf(buf + len, size - len, \ - "%20s : %10d\n", _s, (_val)); \ - } while (0) - enum bt_op_flags { BT_OP_PRIORITY_DETECTED, BT_OP_SCAN, @@ -482,10 +478,8 @@ struct ath_btcoex { u32 btscan_no_stomp; /* in usec */ u32 duty_cycle; u32 bt_wait_time; - int rssi_count; struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ struct ath_mci_profile mci; - u8 stomp_audio; }; #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT @@ -498,7 +492,6 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); -int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size); #else static inline int ath9k_init_btcoex(struct ath_softc *sc) { @@ -525,10 +518,6 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) { } -static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - return 0; -} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ struct ath9k_wow_pattern { @@ -653,7 +642,6 @@ enum sc_op_flags { #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) #define PS_WAIT_FOR_TX_ACK BIT(3) #define PS_BEACON_SYNC BIT(4) -#define PS_WAIT_FOR_ANI BIT(5) struct ath_rate_table; @@ -720,6 +708,9 @@ struct ath_softc { #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; + spinlock_t nodes_lock; + struct list_head nodes; /* basically, stations */ + unsigned int tx_complete_poll_work_seen; #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; diff --git a/trunk/drivers/net/wireless/ath/ath9k/beacon.c b/trunk/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a3..1b48414dca95 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/beacon.c @@ -46,7 +46,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc) qi.tqi_cwmax = 0; } else { /* Adhoc mode; important thing is to use 2x cwmin. */ - txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; if (ah->slottime == ATH9K_SLOT_TIME_20) diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c index 9963b0bf9f72..419e9a3f2fed 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c @@ -49,7 +49,6 @@ static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX] { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ - { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */ }; void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) @@ -196,7 +195,7 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah) ah->btcoex_hw.mci.need_flush_btinfo = false; ah->btcoex_hw.mci.wlan_cal_seq = 0; ah->btcoex_hw.mci.wlan_cal_done = 0; - ah->btcoex_hw.mci.config = (AR_SREV_9462(ah)) ? 0x2201 : 0xa4c1; + ah->btcoex_hw.mci.config = 0x2201; } EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci); @@ -219,45 +218,27 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, enum ath_stomp_type stomp_type) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; - u8 txprio_shift[] = { 24, 16, 16, 0 }; /* tx priority weight */ - bool concur_tx = (mci_hw->concur_tx && btcoex_hw->tx_prio[stomp_type]); - const u32 *weight = ar9003_wlan_weights[stomp_type]; - int i; - if (!AR_SREV_9300_20_OR_LATER(ah)) { - btcoex_hw->bt_coex_weights = - SM(bt_weight, AR_BTCOEX_BT_WGHT) | - SM(wlan_weight, AR_BTCOEX_WL_WGHT); - return; - } + if (AR_SREV_9300_20_OR_LATER(ah)) { + const u32 *weight = ar9003_wlan_weights[stomp_type]; + int i; - if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { - enum ath_stomp_type stype = - ((stomp_type == ATH_BTCOEX_STOMP_LOW) && - btcoex_hw->mci.stomp_ftp) ? - ATH_BTCOEX_STOMP_LOW_FTP : stomp_type; - weight = mci_wlan_weights[stype]; - } + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { + if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && + btcoex_hw->mci.stomp_ftp) + stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; + weight = mci_wlan_weights[stomp_type]; + } - for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { - btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; - btcoex_hw->wlan_weight[i] = weight[i]; - if (concur_tx && i) { - btcoex_hw->wlan_weight[i] &= - ~(0xff << txprio_shift[i-1]); - btcoex_hw->wlan_weight[i] |= - (btcoex_hw->tx_prio[stomp_type] << - txprio_shift[i-1]); + for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { + btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; + btcoex_hw->wlan_weight[i] = weight[i]; } + } else { + btcoex_hw->bt_coex_weights = + SM(bt_weight, AR_BTCOEX_BT_WGHT) | + SM(wlan_weight, AR_BTCOEX_WL_WGHT); } - /* Last WLAN weight has to be adjusted wrt tx priority */ - if (concur_tx) { - btcoex_hw->wlan_weight[i-1] &= ~(0xff << txprio_shift[i-1]); - btcoex_hw->wlan_weight[i-1] |= (btcoex_hw->tx_prio[stomp_type] - << txprio_shift[i-1]); - } - } EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); @@ -404,13 +385,3 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, } } EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); - -void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio) -{ - struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; - int i; - - for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) - btcoex->tx_prio[i] = stomp_txprio[i]; -} -EXPORT_SYMBOL(ath9k_hw_btcoex_set_concur_txprio); diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h index 6de26ea5d5fa..385197ad79b0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h @@ -39,9 +39,6 @@ #define ATH_BTCOEX_RX_WAIT_TIME 100 #define ATH_BTCOEX_STOMP_FTP_THRESH 5 -#define ATH_BTCOEX_HT20_MAX_TXPOWER 0x14 -#define ATH_BTCOEX_HT40_MAX_TXPOWER 0x10 - #define AR9300_NUM_BT_WEIGHTS 4 #define AR9300_NUM_WLAN_WEIGHTS 4 /* Defines the BT AR_BT_COEX_WGHT used */ @@ -50,7 +47,6 @@ enum ath_stomp_type { ATH_BTCOEX_STOMP_LOW, ATH_BTCOEX_STOMP_NONE, ATH_BTCOEX_STOMP_LOW_FTP, - ATH_BTCOEX_STOMP_AUDIO, ATH_BTCOEX_STOMP_MAX }; @@ -88,8 +84,6 @@ struct ath9k_hw_mci { u8 bt_ver_minor; u8 bt_state; u8 stomp_ftp; - bool concur_tx; - u32 last_recovery; }; struct ath_btcoex_hw { @@ -104,7 +98,6 @@ struct ath_btcoex_hw { u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ u32 bt_weight[AR9300_NUM_BT_WEIGHTS]; u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; - u8 tx_prio[ATH_BTCOEX_STOMP_MAX]; }; void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah); @@ -119,6 +112,5 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, void ath9k_hw_btcoex_disable(struct ath_hw *ah); void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type); -void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio); #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/calib.c b/trunk/drivers/net/wireless/ath/ath9k/calib.c index f3448a032e6f..e5cceb077574 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/calib.c @@ -410,7 +410,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, ah->caldata->channel = chan->channel; ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; - ah->caldata->chanmode = chan->chanmode; h = ah->caldata->nfCalHist; default_nf = ath9k_hw_get_default_nf(ah, chan); for (i = 0; i < NUM_NF_READINGS; i++) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/common.h b/trunk/drivers/net/wireless/ath/ath9k/common.h index 76b543900314..ad14fecc76c6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/common.h +++ b/trunk/drivers/net/wireless/ath/ath9k/common.h @@ -28,6 +28,13 @@ #define WME_MAX_BA WME_BA_BMP_SIZE #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) +/* These must match mac80211 skb queue mapping numbers */ +#define WME_AC_VO 0 +#define WME_AC_VI 1 +#define WME_AC_BE 2 +#define WME_AC_BK 3 +#define WME_NUM_AC 4 + #define ATH_RSSI_DUMMY_MARKER 0x127 #define ATH_RSSI_LPF_LEN 10 #define RSSI_LPF_THRESHOLD -20 diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c index 939308c25712..6727b566d294 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c @@ -512,19 +512,62 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; +#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum +#define PR(str, elem) \ + do { \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \ + if (len >= size) \ + goto done; \ +} while(0) + +#define PRX(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \ + if (len >= size) \ + goto done; \ +} while(0) + +#define PRQLE(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13i%11i%10i%10i\n", str, \ + list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \ + if (len >= size) \ + goto done; \ +} while (0) + static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 2048; + unsigned int len = 0, size = 8000; + int i; ssize_t retval = 0; + char tmp[32]; buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - len += sprintf(buf, "%30s %10s%10s%10s\n\n", + len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" + " poll-work-seen: %u\n" + "%30s %10s%10s%10s\n\n", + ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, + sc->tx_complete_poll_work_seen, "BE", "BK", "VI", "VO"); PR("MPDUs Queued: ", queued); @@ -544,11 +587,62 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DELIM Underrun: ", delim_underrun); PR("TX-Pkts-All: ", tx_pkts_all); PR("TX-Bytes-All: ", tx_bytes_all); - PR("HW-put-tx-buf: ", puttxbuf); - PR("HW-tx-start: ", txstart); - PR("HW-tx-proc-desc: ", txprocdesc); + PR("hw-put-tx-buf: ", puttxbuf); + PR("hw-tx-start: ", txstart); + PR("hw-tx-proc-desc: ", txprocdesc); PR("TX-Failed: ", txfailed); + len += snprintf(buf + len, size - len, + "%s%11p%11p%10p%10p\n", "txq-memory-address:", + sc->tx.txq_map[WME_AC_BE], + sc->tx.txq_map[WME_AC_BK], + sc->tx.txq_map[WME_AC_VI], + sc->tx.txq_map[WME_AC_VO]); + if (len >= size) + goto done; + + PRX("axq-qnum: ", axq_qnum); + PRX("axq-depth: ", axq_depth); + PRX("axq-ampdu_depth: ", axq_ampdu_depth); + PRX("axq-stopped ", stopped); + PRX("tx-in-progress ", axq_tx_inprogress); + PRX("pending-frames ", pending_frames); + PRX("txq_headidx: ", txq_headidx); + PRX("txq_tailidx: ", txq_headidx); + + PRQLE("axq_q empty: ", axq_q); + PRQLE("axq_acq empty: ", axq_acq); + for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { + snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); + PRQLE(tmp, txq_fifo[i]); + } + + /* Print out more detailed queue-info */ + for (i = 0; i <= WME_AC_BK; i++) { + struct ath_txq *txq = &(sc->tx.txq[i]); + struct ath_atx_ac *ac; + struct ath_atx_tid *tid; + if (len >= size) + goto done; + spin_lock_bh(&txq->axq_lock); + if (!list_empty(&txq->axq_acq)) { + ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, + list); + len += snprintf(buf + len, size - len, + "txq[%i] first-ac: %p sched: %i\n", + i, ac, ac->sched); + if (list_empty(&ac->tid_q) || (len >= size)) + goto done_for; + tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, + list); + len += snprintf(buf + len, size - len, + " first-tid: %p sched: %i paused: %i\n", + tid, tid->sched, tid->paused); + } + done_for: + spin_unlock_bh(&txq->axq_lock); + } +done: if (len > size) len = size; @@ -558,41 +652,62 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, return retval; } -static ssize_t read_file_queues(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t read_file_stations(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_txq *txq; char *buf; - unsigned int len = 0, size = 1024; + unsigned int len = 0, size = 64000; + struct ath_node *an = NULL; ssize_t retval = 0; - int i; - char *qname[4] = {"VO", "VI", "BE", "BK"}; + int q; buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - txq = sc->tx.txq_map[i]; - len += snprintf(buf + len, size - len, "(%s): ", qname[i]); - - ath_txq_lock(sc, txq); - - len += snprintf(buf + len, size - len, "%s: %d ", - "qnum", txq->axq_qnum); - len += snprintf(buf + len, size - len, "%s: %2d ", - "qdepth", txq->axq_depth); - len += snprintf(buf + len, size - len, "%s: %2d ", - "ampdu-depth", txq->axq_ampdu_depth); - len += snprintf(buf + len, size - len, "%s: %3d ", - "pending", txq->pending_frames); - len += snprintf(buf + len, size - len, "%s: %d\n", - "stopped", txq->stopped); + len += snprintf(buf + len, size - len, + "Stations:\n" + " tid: addr sched paused buf_q-empty an ac baw\n" + " ac: addr sched tid_q-empty txq\n"); + + spin_lock(&sc->nodes_lock); + list_for_each_entry(an, &sc->nodes, list) { + unsigned short ma = an->maxampdu; + if (ma == 0) + ma = 65535; /* see ath_lookup_rate */ + len += snprintf(buf + len, size - len, + "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n", + an->vif->addr, an->sta->addr, ma, + (unsigned int)(an->mpdudensity)); + if (len >= size) + goto done; + + for (q = 0; q < WME_NUM_TID; q++) { + struct ath_atx_tid *tid = &(an->tid[q]); + len += snprintf(buf + len, size - len, + " tid: %p %s %s %i %p %p %hu\n", + tid, tid->sched ? "sched" : "idle", + tid->paused ? "paused" : "running", + skb_queue_empty(&tid->buf_q), + tid->an, tid->ac, tid->baw_size); + if (len >= size) + goto done; + } - ath_txq_unlock(sc, txq); + for (q = 0; q < WME_NUM_AC; q++) { + struct ath_atx_ac *ac = &(an->ac[q]); + len += snprintf(buf + len, size - len, + " ac: %p %s %i %p\n", + ac, ac->sched ? "sched" : "idle", + list_empty(&ac->tid_q), ac->txq); + if (len >= size) + goto done; + } } +done: + spin_unlock(&sc->nodes_lock); if (len > size) len = size; @@ -722,9 +837,6 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%17s: %2d\n", "PLL RX Hang", sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - len += snprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "MCI Reset", - sc->debug.stats.reset[RESET_TYPE_MCI]); if (len > sizeof(buf)) len = sizeof(buf); @@ -807,8 +919,8 @@ static const struct file_operations fops_xmit = { .llseek = default_llseek, }; -static const struct file_operations fops_queues = { - .read = read_file_queues, +static const struct file_operations fops_stations = { + .read = read_file_stations, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -1474,41 +1586,6 @@ static const struct file_operations fops_samps = { #endif -#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT -static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - u32 len = 0, size = 1500; - char *buf; - size_t retval; - - buf = kzalloc(size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - if (!sc->sc_ah->common.btcoex_enabled) { - len = snprintf(buf, size, "%s\n", - "BTCOEX is disabled"); - goto exit; - } - - len = ath9k_dump_btcoex(sc, buf, size); -exit: - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - - return retval; -} - -static const struct file_operations fops_btcoex = { - .read = read_file_btcoex, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; -#endif - int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -1532,16 +1609,16 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_interrupt); debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_xmit); - debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, - &fops_queues); debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_BK]); + &sc->tx.txq_max_pending[WME_AC_BK]); debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_BE]); + &sc->tx.txq_max_pending[WME_AC_BE]); debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_VI]); + &sc->tx.txq_max_pending[WME_AC_VI]); debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_VO]); + &sc->tx.txq_max_pending[WME_AC_VO]); + debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_stations); debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_misc); debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, @@ -1581,9 +1658,6 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); debugfs_create_file("diversity", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_ant_diversity); -#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT - debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, - &fops_btcoex); -#endif + return 0; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.h b/trunk/drivers/net/wireless/ath/ath9k/debug.h index f9bee18de5a0..2ed9785a38fa 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.h +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.h @@ -41,7 +41,6 @@ enum ath_reset_type { RESET_TYPE_PLL_HANG, RESET_TYPE_MAC_HANG, RESET_TYPE_BEACON_STUCK, - RESET_TYPE_MCI, __RESET_TYPE_MAX }; @@ -179,21 +178,6 @@ struct ath_tx_stats { u32 txfailed; }; -/* - * Various utility macros to print TX/Queue counters. - */ -#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum -#define TXSTATS sc->debug.stats.txstats -#define PR(str, elem) \ - do { \ - len += snprintf(buf + len, size - len, \ - "%s%13u%11u%10u%10u\n", str, \ - TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ - } while(0) - #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) /** @@ -242,7 +226,7 @@ struct ath_rx_stats { struct ath_stats { struct ath_interrupt_stats istats; - struct ath_tx_stats txstats[IEEE80211_NUM_ACS]; + struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; struct ath_rx_stats rxstats; struct ath_dfs_stats dfs_stats; u32 reset[__RESET_TYPE_MAX]; diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 24877b00cbf4..ea2a6cf7ef23 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c @@ -42,15 +42,10 @@ struct radar_types { #define MIN_PPB_THRESH 50 #define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) #define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) -/* percentage of pulse width tolerance */ -#define WIDTH_TOLERANCE 5 -#define WIDTH_LOWER(X) ((X*(100-WIDTH_TOLERANCE)+50)/100) -#define WIDTH_UPPER(X) ((X*(100+WIDTH_TOLERANCE)+50)/100) #define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \ { \ - ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ - (PRF2PRI(PMAX) - PRI_TOLERANCE), \ + ID, WMIN, WMAX, (PRF2PRI(PMAX) - PRI_TOLERANCE), \ (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \ PPB_THRESH(PPB), PRI_TOLERANCE, \ } @@ -279,7 +274,7 @@ static bool dpd_set_domain(struct dfs_pattern_detector *dpd, static struct dfs_pattern_detector default_dpd = { .exit = dpd_exit, - .set_dfs_domain = dpd_set_domain, + .set_domain = dpd_set_domain, .add_pulse = dpd_add_pulse, .region = NL80211_DFS_UNSET, }; @@ -296,11 +291,10 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) *dpd = default_dpd; INIT_LIST_HEAD(&dpd->channel_detectors); - if (dpd->set_dfs_domain(dpd, region)) + if (dpd->set_domain(dpd, region)) return dpd; pr_err("Could not set DFS domain to %d. ", region); - kfree(dpd); return NULL; } EXPORT_SYMBOL(dfs_pattern_detector_init); diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h index cda52f39f28a..fd0328a30995 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h @@ -62,7 +62,7 @@ struct radar_detector_specs { /** * struct dfs_pattern_detector - DFS pattern detector * @exit(): destructor - * @set_dfs_domain(): set DFS domain, resets detector lines upon domain changes + * @set_domain(): set DFS domain, resets detector lines upon domain changes * @add_pulse(): add radar pulse to detector, returns true on detection * @region: active DFS region, NL80211_DFS_UNSET until set * @num_radar_types: number of different radar types @@ -72,7 +72,7 @@ struct radar_detector_specs { */ struct dfs_pattern_detector { void (*exit)(struct dfs_pattern_detector *dpd); - bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd, + bool (*set_domain)(struct dfs_pattern_detector *dpd, enum nl80211_dfs_regions region); bool (*add_pulse)(struct dfs_pattern_detector *dpd, struct pulse_event *pe); diff --git a/trunk/drivers/net/wireless/ath/ath9k/gpio.c b/trunk/drivers/net/wireless/ath/ath9k/gpio.c index 4b412aaf4f36..d9ed141a053e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/gpio.c @@ -187,24 +187,6 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) } } -static void ath_mci_ftp_adjust(struct ath_softc *sc) -{ - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath_mci_profile *mci = &btcoex->mci; - struct ath_hw *ah = sc->sc_ah; - - if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { - if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && - (mci->num_pan || mci->num_other_acl)) - ah->btcoex_hw.mci.stomp_ftp = - (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); - else - ah->btcoex_hw.mci.stomp_ftp = false; - btcoex->bt_wait_time = 0; - sc->rx.num_pkts = 0; - } -} - /* * This is the master bt coex timer which runs for every * 45ms, bt traffic will be given priority during 55% of this @@ -215,46 +197,41 @@ static void ath_btcoex_period_timer(unsigned long data) struct ath_softc *sc = (struct ath_softc *) data; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; - enum ath_stomp_type stomp_type; + struct ath_mci_profile *mci = &btcoex->mci; u32 timer_period; + bool is_btscan; unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP) { - btcoex->bt_wait_time += btcoex->btcoex_period; spin_unlock_irqrestore(&sc->sc_pm_lock, flags); goto skip_hw_wakeup; } spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - ath9k_mci_update_rssi(sc); - ath9k_ps_wakeup(sc); - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) ath_detect_bt_priority(sc); + is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) - ath_mci_ftp_adjust(sc); + btcoex->bt_wait_time += btcoex->btcoex_period; + if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { + if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && + (mci->num_pan || mci->num_other_acl)) + ah->btcoex_hw.mci.stomp_ftp = + (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); + else + ah->btcoex_hw.mci.stomp_ftp = false; + btcoex->bt_wait_time = 0; + sc->rx.num_pkts = 0; + } spin_lock_bh(&btcoex->btcoex_lock); - stomp_type = btcoex->bt_stomp_type; - timer_period = btcoex->btcoex_no_stomp; - - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) { - if (test_bit(BT_OP_SCAN, &btcoex->op_flags)) { - stomp_type = ATH_BTCOEX_STOMP_ALL; - timer_period = btcoex->btscan_no_stomp; - } - } else if (btcoex->stomp_audio >= 5) { - stomp_type = ATH_BTCOEX_STOMP_AUDIO; - btcoex->stomp_audio = 0; - } + ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : + btcoex->bt_stomp_type); - ath9k_hw_btcoex_bt_stomp(ah, stomp_type); ath9k_hw_btcoex_enable(ah); - spin_unlock_bh(&btcoex->btcoex_lock); /* @@ -266,16 +243,17 @@ static void ath_btcoex_period_timer(unsigned long data) if (btcoex->hw_timer_enabled) ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); + timer_period = is_btscan ? btcoex->btscan_no_stomp : + btcoex->btcoex_no_stomp; ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, timer_period * 10); btcoex->hw_timer_enabled = true; } ath9k_ps_restore(sc); - skip_hw_wakeup: - mod_timer(&btcoex->period_timer, - jiffies + msecs_to_jiffies(btcoex->btcoex_period)); + timer_period = btcoex->btcoex_period; + mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); } /* @@ -295,10 +273,9 @@ static void ath_btcoex_no_stomp_timer(void *arg) spin_lock_bh(&btcoex->btcoex_lock); if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || - (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && - test_bit(BT_OP_SCAN, &btcoex->op_flags))) + test_bit(BT_OP_SCAN, &btcoex->op_flags)) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); - else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) + else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); ath9k_hw_btcoex_enable(ah); @@ -474,7 +451,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) r = ath_init_btcoex_timer(sc); if (r) return -1; - txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; if (ath9k_hw_mci_is_enabled(ah)) { @@ -497,71 +474,4 @@ int ath9k_init_btcoex(struct ath_softc *sc) return 0; } -static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath_mci_profile *mci = &btcoex->mci; - struct ath_hw *ah = sc->sc_ah; - struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - u32 len = 0; - int i; - - ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); - ATH_DUMP_BTCOEX("MGMT", mci->num_mgmt); - ATH_DUMP_BTCOEX("SCO", mci->num_sco); - ATH_DUMP_BTCOEX("A2DP", mci->num_a2dp); - ATH_DUMP_BTCOEX("HID", mci->num_hid); - ATH_DUMP_BTCOEX("PAN", mci->num_pan); - ATH_DUMP_BTCOEX("ACL", mci->num_other_acl); - ATH_DUMP_BTCOEX("BDR", mci->num_bdr); - ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); - ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); - ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); - ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); - ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); - ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); - ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count); - - len += snprintf(buf + len, size - len, "BT Weights: "); - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - len += snprintf(buf + len, size - len, "%08x ", - btcoex_hw->bt_weight[i]); - len += snprintf(buf + len, size - len, "\n"); - len += snprintf(buf + len, size - len, "WLAN Weights: "); - for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - len += snprintf(buf + len, size - len, "%08x ", - btcoex_hw->wlan_weight[i]); - len += snprintf(buf + len, size - len, "\n"); - len += snprintf(buf + len, size - len, "Tx Priorities: "); - for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) - len += snprintf(buf + len, size - len, "%08x ", - btcoex_hw->tx_prio[i]); - - len += snprintf(buf + len, size - len, "\n"); - - return len; -} - -static int ath9k_dump_legacy_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - - struct ath_btcoex *btcoex = &sc->btcoex; - u32 len = 0; - - ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); - ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); - ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); - ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); - - return len; -} - -int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - if (ath9k_hw_mci_is_enabled(sc->sc_ah)) - return ath9k_dump_mci_btcoex(sc, buf, size); - else - return ath9k_dump_legacy_btcoex(sc, buf, size); -} - #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c index f5dda84176c3..924c4616c3d9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -38,7 +38,6 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ - { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ { USB_DEVICE(0x0cf3, 0x7015), diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index 96bfb18078fa..b30596fcf73a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -331,7 +331,7 @@ struct ath_tx_stats { u32 skb_success; u32 skb_failed; u32 cab_queued; - u32 queue_stats[IEEE80211_NUM_ACS]; + u32 queue_stats[WME_NUM_AC]; }; struct ath_rx_stats { @@ -493,7 +493,7 @@ struct ath9k_htc_priv { int beaconq; int cabq; - int hwq_map[IEEE80211_NUM_ACS]; + int hwq_map[WME_NUM_AC]; #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index d0ce1f5bba10..f42d2eb6af99 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -33,7 +33,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { - int qnum = priv->hwq_map[IEEE80211_AC_BE]; + int qnum = priv->hwq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, qnum, &qi_be); @@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, (priv->num_sta_vif > 1) && (vif->type == NL80211_IFTYPE_STATION)) { beacon_configured = false; - ieee80211_iterate_active_interfaces_atomic( - priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_htc_beacon_iter, &beacon_configured); + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_beacon_iter, + &beacon_configured); if (beacon_configured) { ath_dbg(common, CONFIG, diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 87110de577ef..3035deb7a0cd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -218,16 +218,16 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BE queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); + priv->debug.tx_stats.queue_stats[WME_AC_BE]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BK queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); + priv->debug.tx_stats.queue_stats[WME_AC_BK]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "VI queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); + priv->debug.tx_stats.queue_stats[WME_AC_VI]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "VO queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); + priv->debug.tx_stats.queue_stats[WME_AC_VO]); if (len > sizeof(buf)) len = sizeof(buf); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 105582d6b714..0eacfc13c915 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -207,7 +207,7 @@ void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product) priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; ath9k_hw_btcoex_init_3wire(priv->ah); ath_htc_init_btcoex_work(priv); - qnum = priv->hwq_map[IEEE80211_AC_BE]; + qnum = priv->hwq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(priv->ah, qnum); break; default: diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 05d5ba66cac3..d98255eb1b9a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -549,20 +549,20 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BE)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { ath_err(common, "Unable to setup xmit queue for BE traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BK)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { ath_err(common, "Unable to setup xmit queue for BK traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VI)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { ath_err(common, "Unable to setup xmit queue for VI traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VO)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { ath_err(common, "Unable to setup xmit queue for VO traffic\n"); goto err; } @@ -694,20 +694,6 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, return ret; } -static const struct ieee80211_iface_limit if_limits[] = { - { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT) }, - { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO) }, -}; - -static const struct ieee80211_iface_combination if_comb = { - .limits = if_limits, - .n_limits = ARRAY_SIZE(if_limits), - .max_interfaces = 2, - .num_different_channels = 1, -}; - static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, struct ieee80211_hw *hw) { @@ -730,9 +716,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT); - hw->wiphy->iface_combinations = &if_comb; - hw->wiphy->n_iface_combinations = 1; - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9c07a8fa5134..ca78e33ca23e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -127,9 +127,8 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv) priv->rearm_ani = false; priv->reconfig_beacon = false; - ieee80211_iterate_active_interfaces_atomic( - priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_htc_vif_iter, priv); + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_vif_iter, priv); if (priv->rearm_ani) ath9k_htc_start_ani(priv); @@ -166,9 +165,8 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic( - priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_htc_bssid_iter, &iter_data); + ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter, + &iter_data); memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ath_hw_setbssidmask(common); @@ -1038,6 +1036,26 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (priv->nvifs >= ATH9K_HTC_MAX_VIF) { + mutex_unlock(&priv->mutex); + return -ENOBUFS; + } + + if (priv->num_ibss_vif || + (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { + ath_err(common, "IBSS coexistence with other modes is not allowed\n"); + mutex_unlock(&priv->mutex); + return -ENOBUFS; + } + + if (((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) && + ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) { + ath_err(common, "Max. number of beaconing interfaces reached\n"); + mutex_unlock(&priv->mutex); + return -ENOBUFS; + } + ath9k_htc_ps_wakeup(priv); memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); @@ -1146,9 +1164,8 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, */ if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) { priv->rearm_ani = false; - ieee80211_iterate_active_interfaces_atomic( - priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_htc_vif_iter, priv); + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_vif_iter, priv); if (!priv->rearm_ani) ath9k_htc_stop_ani(priv); } @@ -1349,7 +1366,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, struct ath9k_tx_queue_info qi; int ret = 0, qnum; - if (queue >= IEEE80211_NUM_ACS) + if (queue >= WME_NUM_AC) return 0; mutex_lock(&priv->mutex); @@ -1376,7 +1393,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, } if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && - (qnum == priv->hwq_map[IEEE80211_AC_BE])) + (qnum == priv->hwq_map[WME_AC_BE])) ath9k_htc_beaconq_config(priv); out: ath9k_htc_ps_restore(priv); @@ -1469,9 +1486,8 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) { if (priv->num_sta_assoc_vif == 1) { - ieee80211_iterate_active_interfaces_atomic( - priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_htc_bss_iter, priv); + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_bss_iter, priv); ath9k_htc_set_bssid(priv); } } diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 3a22d17a2615..06cdcb772d78 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -21,10 +21,10 @@ /******/ static const int subtype_txq_to_hwq[] = { - [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, - [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, - [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, - [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, }; #define ATH9K_HTC_INIT_TXQ(subtype) do { \ @@ -41,15 +41,15 @@ int get_hw_qnum(u16 queue, int *hwq_map) { switch (queue) { case 0: - return hwq_map[IEEE80211_AC_VO]; + return hwq_map[WME_AC_VO]; case 1: - return hwq_map[IEEE80211_AC_VI]; + return hwq_map[WME_AC_VI]; case 2: - return hwq_map[IEEE80211_AC_BE]; + return hwq_map[WME_AC_BE]; case 3: - return hwq_map[IEEE80211_AC_BK]; + return hwq_map[WME_AC_BK]; default: - return hwq_map[IEEE80211_AC_BE]; + return hwq_map[WME_AC_BE]; } } @@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, switch (qnum) { case 0: - TX_QSTAT_INC(IEEE80211_AC_VO); + TX_QSTAT_INC(WME_AC_VO); epid = priv->data_vo_ep; break; case 1: - TX_QSTAT_INC(IEEE80211_AC_VI); + TX_QSTAT_INC(WME_AC_VI); epid = priv->data_vi_ep; break; case 2: - TX_QSTAT_INC(IEEE80211_AC_BE); + TX_QSTAT_INC(WME_AC_BE); epid = priv->data_be_ep; break; case 3: default: - TX_QSTAT_INC(IEEE80211_AC_BK); + TX_QSTAT_INC(WME_AC_BK); epid = priv->data_bk_ep; break; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index e06bcec655a7..8e1559aba495 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: ret = ath9k_hw_set_reset_power_on(ah); - if (ret) + if (!ret) ah->reset_power_on = true; break; case ATH9K_RESET_WARM: @@ -2153,6 +2153,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) AR_RTC_FORCE_WAKE_EN); udelay(50); + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_set_power_awake(ah); + for (i = POWER_UP_TIME / 50; i > 0; i--) { val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; if (val == AR_RTC_STATUS_ON) @@ -2168,9 +2171,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) return false; } - if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_set_power_awake(ah); - REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); return true; @@ -2561,6 +2561,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; } + if (AR_SREV_9485_10(ah)) { + pCap->pcie_lcr_extsync_en = true; + pCap->pcie_lcr_offset = 0x80; + } + if (ath9k_hw_dfs_tested(ah)) pCap->hw_caps |= ATH9K_HW_CAP_DFS; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 3636dabf03e1..dbc1b7a4cbfd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -273,6 +273,8 @@ struct ath9k_hw_capabilities { u8 rx_status_len; u8 tx_desc_len; u8 txs_len; + u16 pcie_lcr_offset; + bool pcie_lcr_extsync_en; }; struct ath9k_ops_config { @@ -399,7 +401,6 @@ enum ath9k_int { struct ath9k_hw_cal_data { u16 channel; u32 channelFlags; - u32 chanmode; int32_t CalValid; int8_t iCoff; int8_t qCoff; @@ -833,7 +834,6 @@ struct ath_hw { int coarse_low[5]; int firpwr[5]; enum ath9k_ani_cmd ani_function; - u32 ani_skip_count; #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex_hw btcoex_hw; @@ -875,6 +875,7 @@ struct ath_hw { struct ar5416IniArray iniModesTxGain; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; + struct ar5416IniArray ini_japan2484; struct ar5416IniArray iniModes_9271_ANI_reg; struct ar5416IniArray ini_radio_post_sys2ant; @@ -927,6 +928,7 @@ struct ath_bus_ops { void (*read_cachesize)(struct ath_common *common, int *csz); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); + void (*extn_synch_en)(struct ath_common *common); void (*aspm_init)(struct ath_common *common); }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index 80cae53a33e5..fad3ccd5cd91 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -435,7 +435,7 @@ static int ath9k_init_queues(struct ath_softc *sc) sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - for (i = 0; i < IEEE80211_NUM_ACS; i++) { + for (i = 0; i < WME_NUM_AC; i++) { sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); sc->tx.txq_map[i]->mac80211_qnum = i; sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; @@ -563,6 +563,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock_init(&sc->nodes_lock); + INIT_LIST_HEAD(&sc->nodes); +#endif #ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock_init(&sc->debug.samp_lock); #endif @@ -683,7 +687,6 @@ static const struct ieee80211_iface_combination if_comb = { .n_limits = ARRAY_SIZE(if_limits), .max_interfaces = 2048, .num_different_channels = 1, - .beacon_int_infra_match = true, }; void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) diff --git a/trunk/drivers/net/wireless/ath/ath9k/link.c b/trunk/drivers/net/wireless/ath/ath9k/link.c index fc6b075ad635..7b88b9c39ccd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/link.c +++ b/trunk/drivers/net/wireless/ath/ath9k/link.c @@ -27,6 +27,9 @@ void ath_tx_complete_poll_work(struct work_struct *work) struct ath_txq *txq; int i; bool needreset = false; +#ifdef CONFIG_ATH9K_DEBUGFS + sc->tx_complete_poll_work_seen++; +#endif for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) { @@ -208,7 +211,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int int time_left; memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txctl.txq = sc->tx.txq_map[WME_AC_BE]; memset(tx_info, 0, sizeof(*tx_info)); tx_info->band = hw->conf.channel->band; @@ -347,18 +350,8 @@ void ath_ani_calibrate(unsigned long data) ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; /* Only calibrate if awake */ - if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) { - if (++ah->ani_skip_count >= ATH_ANI_MAX_SKIP_COUNT) { - spin_lock_irqsave(&sc->sc_pm_lock, flags); - sc->ps_flags |= PS_WAIT_FOR_ANI; - spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - } + if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) goto set_timer; - } - ah->ani_skip_count = 0; - spin_lock_irqsave(&sc->sc_pm_lock, flags); - sc->ps_flags &= ~PS_WAIT_FOR_ANI; - spin_unlock_irqrestore(&sc->sc_pm_lock, flags); ath9k_ps_wakeup(sc); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 0653dbc99e31..dd45edfa6bae 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -131,8 +131,7 @@ void ath9k_ps_restore(struct ath_softc *sc) !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK | - PS_WAIT_FOR_ANI))) { + PS_WAIT_FOR_TX_ACK))) { mode = ATH9K_PM_NETWORK_SLEEP; if (ath9k_hw_btcoex_is_enabled(sc->sc_ah)) ath9k_btcoex_stop_gen_timer(sc); @@ -293,10 +292,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, goto out; } - if (ath9k_hw_mci_is_enabled(sc->sc_ah) && - (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) - ath9k_mci_set_txpower(sc, true, false); - if (!ath_complete_reset(sc, true)) r = -EIO; @@ -331,6 +326,11 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, u8 density; an = (struct ath_node *)sta->drv_priv; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_add(&an->list, &sc->nodes); + spin_unlock(&sc->nodes_lock); +#endif an->sta = sta; an->vif = vif; @@ -347,6 +347,13 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) { struct ath_node *an = (struct ath_node *)sta->drv_priv; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_del(&an->list); + spin_unlock(&sc->nodes_lock); + an->sta = NULL; +#endif + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_tx_node_cleanup(sc, an); } @@ -482,6 +489,17 @@ irqreturn_t ath_isr(int irq, void *dev) if (status & SCHED_INTR) sched = true; +#ifdef CONFIG_PM_SLEEP + if (status & ATH9K_INT_BMISS) { + if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { + ath_dbg(common, ANY, "during WoW we got a BMISS\n"); + atomic_inc(&sc->wow_got_bmiss_intr); + atomic_dec(&sc->wow_sleep_proc_intr); + } + ath_dbg(common, INTERRUPT, "beacon miss interrupt\n"); + } +#endif + /* * If a FATAL or RXORN interrupt is received, we have to reset the * chip immediately. @@ -500,15 +518,7 @@ irqreturn_t ath_isr(int irq, void *dev) goto chip_reset; } -#ifdef CONFIG_PM_SLEEP - if (status & ATH9K_INT_BMISS) { - if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { - ath_dbg(common, ANY, "during WoW we got a BMISS\n"); - atomic_inc(&sc->wow_got_bmiss_intr); - atomic_dec(&sc->wow_sleep_proc_intr); - } - } -#endif + if (status & ATH9K_INT_SWBA) tasklet_schedule(&sc->bcon_tasklet); @@ -671,6 +681,9 @@ static int ath9k_start(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) + common->bus_ops->extn_synch_en(common); + mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); @@ -906,9 +919,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, ath9k_vif_iter(iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic( - sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_vif_iter, iter_data); + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, + iter_data); } /* Called with sc->mutex held. */ @@ -958,9 +970,8 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, if (ah->opmode == NL80211_IFTYPE_STATION && old_opmode == NL80211_IFTYPE_AP && test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { - ieee80211_iterate_active_interfaces_atomic( - sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_sta_vif_iter, sc); + ieee80211_iterate_active_interfaces_atomic(sc->hw, + ath9k_sta_vif_iter, sc); } } @@ -1313,7 +1324,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, struct ath9k_tx_queue_info qi; int ret = 0; - if (queue >= IEEE80211_NUM_ACS) + if (queue >= WME_NUM_AC) return 0; txq = sc->tx.txq_map[queue]; @@ -1438,9 +1449,6 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - if (ath9k_hw_mci_is_enabled(sc->sc_ah)) - ath9k_mci_update_wlan_channels(sc, false); - ath_dbg(common, CONFIG, "Primary Station interface: %pM, BSSID: %pM\n", vif->addr, common->curbssid); @@ -1489,17 +1497,14 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, clear_bit(SC_OP_BEACONS, &sc->sc_flags); } - ieee80211_iterate_active_interfaces_atomic( - sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - ath9k_bss_assoc_iter, sc); + ieee80211_iterate_active_interfaces_atomic(sc->hw, + ath9k_bss_assoc_iter, sc); if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && ah->opmode == NL80211_IFTYPE_STATION) { memset(common->curbssid, 0, ETH_ALEN); common->curaid = 0; ath9k_hw_write_associd(sc->sc_ah); - if (ath9k_hw_mci_is_enabled(sc->sc_ah)) - ath9k_mci_update_wlan_channels(sc, true); } } @@ -1941,12 +1946,13 @@ static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, return 0; } +#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) #define AWDATA(elem) \ do { \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ } while (0) #define AWDATA_RX(elem) \ @@ -1961,14 +1967,14 @@ static void ath9k_get_et_stats(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; int i = 0; - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all); - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all); + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); AWDATA_RX(rx_pkts_all); AWDATA_RX(rx_bytes_all); diff --git a/trunk/drivers/net/wireless/ath/ath9k/mci.c b/trunk/drivers/net/wireless/ath/ath9k/mci.c index 706378ea3ba2..ec2d7c807567 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/mci.c @@ -43,7 +43,6 @@ static bool ath_mci_add_profile(struct ath_common *common, struct ath_mci_profile_info *info) { struct ath_mci_profile_info *entry; - u8 voice_priority[] = { 110, 110, 110, 112, 110, 110, 114, 116, 118 }; if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && (info->type == MCI_GPM_COEX_PROFILE_VOICE)) @@ -60,12 +59,6 @@ static bool ath_mci_add_profile(struct ath_common *common, memcpy(entry, info, 10); INC_PROF(mci, info); list_add_tail(&entry->list, &mci->info); - if (info->type == MCI_GPM_COEX_PROFILE_VOICE) { - if (info->voice_type < sizeof(voice_priority)) - mci->voice_priority = voice_priority[info->voice_type]; - else - mci->voice_priority = 110; - } return true; } @@ -157,7 +150,7 @@ static void ath_mci_update_scheme(struct ath_softc *sc) * For single PAN/FTP profile, allocate 35% for BT * to improve WLAN throughput. */ - btcoex->duty_cycle = AR_SREV_9565(sc->sc_ah) ? 40 : 35; + btcoex->duty_cycle = 35; btcoex->btcoex_period = 53; ath_dbg(common, MCI, "Single PAN/FTP bt period %d ms dutycycle %d\n", @@ -207,6 +200,23 @@ static void ath_mci_update_scheme(struct ath_softc *sc) ath9k_btcoex_timer_resume(sc); } +static void ath_mci_wait_btcal_done(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + /* Stop tx & rx */ + ieee80211_stop_queues(sc->hw); + ath_stoprecv(sc); + ath_drain_all_txq(sc, false); + + /* Wait for cal done */ + ar9003_mci_start_reset(ah, ah->curchan); + + /* Resume tx & rx */ + ath_startrecv(sc); + ieee80211_wake_queues(sc->hw); +} + static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; @@ -218,7 +228,7 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) case MCI_GPM_BT_CAL_REQ: if (mci_hw->bt_state == MCI_BT_AWAKE) { mci_hw->bt_state = MCI_BT_CAL_START; - ath9k_queue_reset(sc, RESET_TYPE_MCI); + ath_mci_wait_btcal_done(sc); } ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); break; @@ -240,57 +250,6 @@ static void ath9k_mci_work(struct work_struct *work) ath_mci_update_scheme(sc); } -static void ath_mci_update_stomp_txprio(u8 cur_txprio, u8 *stomp_prio) -{ - if (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_NONE]) - stomp_prio[ATH_BTCOEX_STOMP_NONE] = cur_txprio; - - if (cur_txprio > stomp_prio[ATH_BTCOEX_STOMP_ALL]) - stomp_prio[ATH_BTCOEX_STOMP_ALL] = cur_txprio; - - if ((cur_txprio > ATH_MCI_HI_PRIO) && - (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_LOW])) - stomp_prio[ATH_BTCOEX_STOMP_LOW] = cur_txprio; -} - -static void ath_mci_set_concur_txprio(struct ath_softc *sc) -{ - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath_mci_profile *mci = &btcoex->mci; - u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */ - - if (mci->num_mgmt) { - stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO; - if (!mci->num_pan && !mci->num_other_acl) - stomp_txprio[ATH_BTCOEX_STOMP_NONE] = - ATH_MCI_INQUIRY_PRIO; - } else { - u8 prof_prio[] = { 50, 90, 94, 52 };/* RFCOMM, A2DP, HID, PAN */ - - stomp_txprio[ATH_BTCOEX_STOMP_LOW] = - stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0xff; - - if (mci->num_sco) - ath_mci_update_stomp_txprio(mci->voice_priority, - stomp_txprio); - if (mci->num_other_acl) - ath_mci_update_stomp_txprio(prof_prio[0], stomp_txprio); - if (mci->num_a2dp) - ath_mci_update_stomp_txprio(prof_prio[1], stomp_txprio); - if (mci->num_hid) - ath_mci_update_stomp_txprio(prof_prio[2], stomp_txprio); - if (mci->num_pan) - ath_mci_update_stomp_txprio(prof_prio[3], stomp_txprio); - - if (stomp_txprio[ATH_BTCOEX_STOMP_NONE] == 0xff) - stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0; - - if (stomp_txprio[ATH_BTCOEX_STOMP_LOW] == 0xff) - stomp_txprio[ATH_BTCOEX_STOMP_LOW] = 0; - } - ath9k_hw_btcoex_set_concur_txprio(sc->sc_ah, stomp_txprio); -} - static u8 ath_mci_process_profile(struct ath_softc *sc, struct ath_mci_profile_info *info) { @@ -322,7 +281,6 @@ static u8 ath_mci_process_profile(struct ath_softc *sc, } else ath_mci_del_profile(common, mci, entry); - ath_mci_set_concur_txprio(sc); return 1; } @@ -356,7 +314,6 @@ static u8 ath_mci_process_status(struct ath_softc *sc, mci->num_mgmt++; } while (++i < ATH_MCI_MAX_PROFILE); - ath_mci_set_concur_txprio(sc); if (old_num_mgmt != mci->num_mgmt) return 1; @@ -561,8 +518,6 @@ void ath_mci_intr(struct ath_softc *sc) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; while (more_data == MCI_GPM_MORE) { - if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) - return; pgpm = mci->gpm_buf.bf_addr; offset = ar9003_mci_get_next_gpm_offset(ah, false, @@ -645,130 +600,3 @@ void ath_mci_enable(struct ath_softc *sc) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) sc->sc_ah->imask |= ATH9K_INT_MCI; } - -void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - struct ath9k_channel *chan = ah->curchan; - u32 channelmap[] = {0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff}; - int i; - s16 chan_start, chan_end; - u16 wlan_chan; - - if (!chan || !IS_CHAN_2GHZ(chan)) - return; - - if (allow_all) - goto send_wlan_chan; - - wlan_chan = chan->channel - 2402; - - chan_start = wlan_chan - 10; - chan_end = wlan_chan + 10; - - if (chan->chanmode == CHANNEL_G_HT40PLUS) - chan_end += 20; - else if (chan->chanmode == CHANNEL_G_HT40MINUS) - chan_start -= 20; - - /* adjust side band */ - chan_start -= 7; - chan_end += 7; - - if (chan_start <= 0) - chan_start = 0; - if (chan_end >= ATH_MCI_NUM_BT_CHANNELS) - chan_end = ATH_MCI_NUM_BT_CHANNELS - 1; - - ath_dbg(ath9k_hw_common(ah), MCI, - "WLAN current channel %d mask BT channel %d - %d\n", - wlan_chan, chan_start, chan_end); - - for (i = chan_start; i < chan_end; i++) - MCI_GPM_CLR_CHANNEL_BIT(&channelmap, i); - -send_wlan_chan: - /* update and send wlan channels info to BT */ - for (i = 0; i < 4; i++) - mci->wlan_channels[i] = channelmap[i]; - ar9003_mci_send_wlan_channels(ah); - ar9003_mci_state(ah, MCI_STATE_SEND_VERSION_QUERY); -} - -void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, - bool concur_tx) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; - bool old_concur_tx = mci_hw->concur_tx; - - if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) { - mci_hw->concur_tx = false; - return; - } - - if (!IS_CHAN_2GHZ(ah->curchan)) - return; - - if (setchannel) { - struct ath9k_hw_cal_data *caldata = &sc->caldata; - if ((caldata->chanmode == CHANNEL_G_HT40PLUS) && - (ah->curchan->channel > caldata->channel) && - (ah->curchan->channel <= caldata->channel + 20)) - return; - if ((caldata->chanmode == CHANNEL_G_HT40MINUS) && - (ah->curchan->channel < caldata->channel) && - (ah->curchan->channel >= caldata->channel - 20)) - return; - mci_hw->concur_tx = false; - } else - mci_hw->concur_tx = concur_tx; - - if (old_concur_tx != mci_hw->concur_tx) - ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); -} - -static void ath9k_mci_stomp_audio(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath_mci_profile *mci = &btcoex->mci; - - if (!mci->num_sco && !mci->num_a2dp) - return; - - if (ah->stats.avgbrssi > 25) { - btcoex->stomp_audio = 0; - return; - } - - btcoex->stomp_audio++; -} -void ath9k_mci_update_rssi(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; - - ath9k_mci_stomp_audio(sc); - - if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) - return; - - if (ah->stats.avgbrssi >= 40) { - if (btcoex->rssi_count < 0) - btcoex->rssi_count = 0; - if (++btcoex->rssi_count >= ATH_MCI_CONCUR_TX_SWITCH) { - btcoex->rssi_count = 0; - ath9k_mci_set_txpower(sc, false, true); - } - } else { - if (btcoex->rssi_count > 0) - btcoex->rssi_count = 0; - if (--btcoex->rssi_count <= -ATH_MCI_CONCUR_TX_SWITCH) { - btcoex->rssi_count = 0; - ath9k_mci_set_txpower(sc, false, false); - } - } -} diff --git a/trunk/drivers/net/wireless/ath/ath9k/mci.h b/trunk/drivers/net/wireless/ath/ath9k/mci.h index 06958837620c..fc14eea034eb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mci.h +++ b/trunk/drivers/net/wireless/ath/ath9k/mci.h @@ -32,27 +32,6 @@ #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ ATH_MCI_MAX_SCO_PROFILE) -#define ATH_MCI_INQUIRY_PRIO 62 -#define ATH_MCI_HI_PRIO 60 -#define ATH_MCI_NUM_BT_CHANNELS 79 -#define ATH_MCI_CONCUR_TX_SWITCH 5 - -#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \ - do { \ - if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ - *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ - (_bt_chan / 8)) |= (1 << (_bt_chan & 7)); \ - } \ - } while (0) - -#define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan) \ - do { \ - if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ - *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ - (_bt_chan / 8)) &= ~(1 << (_bt_chan & 7));\ - } \ - } while (0) - #define INC_PROF(_mci, _info) do { \ switch (_info->type) { \ case MCI_GPM_COEX_PROFILE_RFCOMM:\ @@ -70,7 +49,6 @@ _mci->num_pan++; \ break; \ case MCI_GPM_COEX_PROFILE_VOICE: \ - case MCI_GPM_COEX_PROFILE_A2DPVO:\ _mci->num_sco++; \ break; \ default: \ @@ -95,7 +73,6 @@ _mci->num_pan--; \ break; \ case MCI_GPM_COEX_PROFILE_VOICE: \ - case MCI_GPM_COEX_PROFILE_A2DPVO:\ _mci->num_sco--; \ break; \ default: \ @@ -136,7 +113,6 @@ struct ath_mci_profile { u8 num_pan; u8 num_other_acl; u8 num_bdr; - u8 voice_priority; }; struct ath_mci_buf { @@ -154,25 +130,13 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci); int ath_mci_setup(struct ath_softc *sc); void ath_mci_cleanup(struct ath_softc *sc); void ath_mci_intr(struct ath_softc *sc); -void ath9k_mci_update_rssi(struct ath_softc *sc); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT void ath_mci_enable(struct ath_softc *sc); -void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all); -void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, - bool concur_tx); #else static inline void ath_mci_enable(struct ath_softc *sc) { } -static inline void ath9k_mci_update_wlan_channels(struct ath_softc *sc, - bool allow_all) -{ -} -static inline void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, - bool concur_tx) -{ -} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif /* MCI_H*/ diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index 9553203ee624..f088f4bf9a26 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -96,6 +96,17 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) return true; } +static void ath_pci_extn_synch_enable(struct ath_common *common) +{ + struct ath_softc *sc = (struct ath_softc *) common->priv; + struct pci_dev *pdev = to_pci_dev(sc->dev); + u8 lnkctl; + + pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl); + lnkctl |= PCI_EXP_LNKCTL_ES; + pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); +} + /* Need to be called after we discover btcoex capabilities */ static void ath_pci_aspm_init(struct ath_common *common) { @@ -142,6 +153,7 @@ static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath_pci_read_cachesize, .eeprom_read = ath_pci_eeprom_read, + .extn_synch_en = ath_pci_extn_synch_enable, .aspm_init = ath_pci_aspm_init, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index 714558d1ba78..27ed80b54881 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -982,6 +982,16 @@ static void ath_rc_update_per(struct ath_softc *sc, } } +static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, + int xretries, int retries, u8 per) +{ + struct ath_rc_stats *stats = &rc->rcstats[rix]; + + stats->xretries += xretries; + stats->retries += retries; + stats->per = per; +} + static void ath_rc_update_ht(struct ath_softc *sc, struct ath_rate_priv *ath_rc_priv, struct ieee80211_tx_info *tx_info, @@ -1055,6 +1065,14 @@ static void ath_rc_update_ht(struct ath_softc *sc, } +static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) +{ + struct ath_rc_stats *stats; + + stats = &rc->rcstats[final_rate]; + stats->success++; +} + static void ath_rc_tx_status(struct ath_softc *sc, struct ath_rate_priv *ath_rc_priv, struct sk_buff *skb) @@ -1332,25 +1350,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, } } -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) - -void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) -{ - struct ath_rc_stats *stats; - - stats = &rc->rcstats[final_rate]; - stats->success++; -} - -void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per) -{ - struct ath_rc_stats *stats = &rc->rcstats[rix]; - - stats->xretries += xretries; - stats->retries += retries; - stats->per = per; -} +#ifdef CONFIG_ATH9K_DEBUGFS static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1428,17 +1428,10 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) { struct ath_rate_priv *rc = priv_sta; - rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO, - dir, rc, &fops_rcstat); -} - -static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta) -{ - struct ath_rate_priv *rc = priv_sta; - debugfs_remove(rc->debugfs_rcstats); + debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); } -#endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */ +#endif /* CONFIG_ATH9K_DEBUGFS */ static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { @@ -1483,10 +1476,8 @@ static struct rate_control_ops ath_rate_ops = { .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, .free_sta = ath_rate_free_sta, - -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) +#ifdef CONFIG_ATH9K_DEBUGFS .add_sta_debugfs = ath_rate_add_sta_debugfs, - .remove_sta_debugfs = ath_rate_remove_sta_debugfs, #endif }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.h b/trunk/drivers/net/wireless/ath/ath9k/rc.h index 267dbfcfaa96..268e67dc5fb2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.h @@ -211,26 +211,10 @@ struct ath_rate_priv { struct ath_rateset neg_ht_rates; const struct ath_rate_table *rate_table; -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) struct dentry *debugfs_rcstats; struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; -#endif }; -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) -void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate); -void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per); -#else -static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) -{ -} -static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per) -{ -} -#endif - #ifdef CONFIG_ATH9K_RATE_CONTROL int ath_rate_control_register(void); void ath_rate_control_unregister(void); diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index a04028bce28b..83d16e7ed272 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -1105,10 +1105,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) else rs.is_mybeacon = false; - if (ieee80211_is_data_present(hdr->frame_control) && - !ieee80211_is_qos_nullfunc(hdr->frame_control)) - sc->rx.num_pkts++; - + sc->rx.num_pkts++; ath_debug_stat_rx(sc, &rs); /* diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h index ad3c82c09177..4e6760f8596d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/reg.h +++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h @@ -907,6 +907,10 @@ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) +#define AR_SREV_9462_20_OR_LATER(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ + ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) + #define AR_SREV_9565(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) @@ -2311,8 +2315,6 @@ enum { #define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2)) #define AR_BTCOEX_WL_LNA 0x1940 #define AR_BTCOEX_RFGAIN_CTRL 0x1944 -#define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF -#define AR_BTCOEX_WL_LNA_TIMEOUT_S 0 #define AR_BTCOEX_CTRL2 0x1948 #define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800 @@ -2358,11 +2360,4 @@ enum { #define AR_GLB_SWREG_DISCONT_MODE 0x2002c #define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 -#define AR_MCI_MISC 0x1a74 -#define AR_MCI_MISC_HW_FIX_EN 0x00000001 -#define AR_MCI_MISC_HW_FIX_EN_S 0 -#define AR_MCI_DBG_CNT_CTRL 0x1a78 -#define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001 -#define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0 - #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/wow.c b/trunk/drivers/net/wireless/ath/ath9k/wow.c index 9f8563091bea..a483d518758c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/wow.c +++ b/trunk/drivers/net/wireless/ath/ath9k/wow.c @@ -118,7 +118,7 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); - if (AR_SREV_9462_20(ah)) { + if (AR_SREV_9462_20_OR_LATER(ah)) { /* AR9462 2.0 has an extra descriptor word (time based * discard) compared to other chips */ REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 34130943f9de..378bd70256b2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); - bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -394,7 +393,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; - bool rc_update = true, isba; + bool rc_update = true; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; @@ -438,17 +437,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; - isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted - * - * Only BlockAcks have a TID and therefore normal Acks cannot be - * checked */ - if (isba && tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1354,10 +1349,10 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) struct ath_hw *ah = sc->sc_ah; struct ath9k_tx_queue_info qi; static const int subtype_txq_to_hwq[] = { - [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, - [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, - [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, - [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, }; int axq_qnum, i; @@ -1779,7 +1774,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; - bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); @@ -2319,8 +2313,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_txq_lock(sc, txq); - TX_STAT_INC(txq->axq_qnum, txprocdesc); - if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { ath_txq_unlock(sc, txq); return; @@ -2466,7 +2458,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) } for (acno = 0, ac = &an->ac[acno]; - acno < IEEE80211_NUM_ACS; acno++, ac++) { + acno < WME_NUM_AC; acno++, ac++) { ac->sched = false; ac->txq = sc->tx.txq_map[acno]; INIT_LIST_HEAD(&ac->tid_q); diff --git a/trunk/drivers/net/wireless/ath/carl9170/fw.c b/trunk/drivers/net/wireless/ath/carl9170/fw.c index aaebecd19e59..24ac2876a733 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/fw.c +++ b/trunk/drivers/net/wireless/ath/carl9170/fw.c @@ -28,6 +28,11 @@ #include "fwcmd.h" #include "version.h" +#define MAKE_STR(symbol) #symbol +#define TO_STR(symbol) MAKE_STR(symbol) +#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) +MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); + static const u8 otus_magic[4] = { OTUS_MAGIC }; static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], diff --git a/trunk/drivers/net/wireless/ath/carl9170/mac.c b/trunk/drivers/net/wireless/ath/carl9170/mac.c index 24d75ab94f0d..e3b1b6e87760 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/mac.c +++ b/trunk/drivers/net/wireless/ath/carl9170/mac.c @@ -343,24 +343,7 @@ int carl9170_set_operating_mode(struct ar9170 *ar) break; } } else { - /* - * Enable monitor mode - * - * rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; - * sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; - * - * When the hardware is in SNIFFER_PROMISC mode, - * it generates spurious ACKs for every incoming - * frame. This confuses every peer in the - * vicinity and the network throughput will suffer - * badly. - * - * Hence, the hardware will be put into station - * mode and just the rx filters are disabled. - */ - cam_mode |= AR9170_MAC_CAM_STA; - rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; - mac_addr = common->macaddr; + mac_addr = NULL; bssid = NULL; } rcu_read_unlock(); @@ -372,6 +355,8 @@ int carl9170_set_operating_mode(struct ar9170 *ar) enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; if (ar->sniffer_enabled) { + rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; + sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; } diff --git a/trunk/drivers/net/wireless/ath/carl9170/rx.c b/trunk/drivers/net/wireless/ath/carl9170/rx.c index 6d22382875bc..a0b723078547 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/rx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/rx.c @@ -164,6 +164,9 @@ void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) struct carl9170_rsp *cmd = buf; struct ieee80211_vif *vif; + if (carl9170_check_sequence(ar, cmd->hdr.seq)) + return; + if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) carl9170_cmd_callback(ar, len, buf); @@ -660,35 +663,6 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, return false; } -static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len, - struct ieee80211_rx_status *status) -{ - struct sk_buff *skb; - - /* (driver) frame trap handler - * - * Because power-saving mode handing has to be implemented by - * the driver/firmware. We have to check each incoming beacon - * from the associated AP, if there's new data for us (either - * broadcast/multicast or unicast) we have to react quickly. - * - * So, if you have you want to add additional frame trap - * handlers, this would be the perfect place! - */ - - carl9170_ps_beacon(ar, buf, len); - - carl9170_ba_check(ar, buf, len); - - skb = carl9170_rx_copy_data(buf, len); - if (!skb) - return -ENOMEM; - - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - ieee80211_rx(ar->hw, skb); - return 0; -} - /* * If the frame alignment is right (or the kernel has * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there @@ -698,12 +672,14 @@ static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len, * mode, and we need to observe the proper ordering, * this is non-trivial. */ -static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) + +static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) { struct ar9170_rx_head *head; struct ar9170_rx_macstatus *mac; struct ar9170_rx_phystatus *phy = NULL; struct ieee80211_rx_status status; + struct sk_buff *skb; int mpdu_len; u8 mac_status; @@ -815,10 +791,18 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) if (phy) carl9170_rx_phy_status(ar, phy, &status); - if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status)) + carl9170_ps_beacon(ar, buf, mpdu_len); + + carl9170_ba_check(ar, buf, mpdu_len); + + skb = carl9170_rx_copy_data(buf, mpdu_len); + if (!skb) goto drop; + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx(ar->hw, skb); return; + drop: ar->rx_dropped++; } @@ -836,9 +820,6 @@ static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, if (unlikely(i > resplen)) break; - if (carl9170_check_sequence(ar, cmd->hdr.seq)) - break; - carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); } @@ -870,7 +851,7 @@ static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len) if (i == 12) carl9170_rx_untie_cmds(ar, buf, len); else - carl9170_rx_untie_data(ar, buf, len); + carl9170_handle_mpdu(ar, buf, len); } static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) diff --git a/trunk/drivers/net/wireless/ath/carl9170/usb.c b/trunk/drivers/net/wireless/ath/carl9170/usb.c index 307bc0ddff99..888152ce3eca 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/usb.c +++ b/trunk/drivers/net/wireless/ath/carl9170/usb.c @@ -295,13 +295,6 @@ static void carl9170_usb_rx_irq_complete(struct urb *urb) goto resubmit; } - /* - * While the carl9170 firmware does not use this EP, the - * firmware loader in the EEPROM unfortunately does. - * Therefore we need to be ready to handle out-of-band - * responses and traps in case the firmware crashed and - * the loader took over again. - */ carl9170_handle_command_response(ar, urb->transfer_buffer, urb->actual_length); diff --git a/trunk/drivers/net/wireless/ath/hw.c b/trunk/drivers/net/wireless/ath/hw.c index 39e8a590d7fc..19befb331073 100644 --- a/trunk/drivers/net/wireless/ath/hw.c +++ b/trunk/drivers/net/wireless/ath/hw.c @@ -20,8 +20,8 @@ #include "ath.h" #include "reg.h" -#define REG_READ (common->ops->read) -#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) +#define REG_READ (common->ops->read) +#define REG_WRITE (common->ops->write) /** * ath_hw_set_bssid_mask - filter out bssids we listen @@ -119,8 +119,8 @@ void ath_hw_setbssidmask(struct ath_common *common) { void *ah = common->ah; - REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); - REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); + REG_WRITE(ah, get_unaligned_le32(common->bssidmask), AR_BSSMSKL); + REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); } EXPORT_SYMBOL(ath_hw_setbssidmask); @@ -139,7 +139,7 @@ void ath_hw_cycle_counters_update(struct ath_common *common) void *ah = common->ah; /* freeze */ - REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); + REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC); /* read */ cycles = REG_READ(ah, AR_CCCNT); @@ -148,13 +148,13 @@ void ath_hw_cycle_counters_update(struct ath_common *common) tx = REG_READ(ah, AR_TFCNT); /* clear */ - REG_WRITE(ah, AR_CCCNT, 0); - REG_WRITE(ah, AR_RFCNT, 0); - REG_WRITE(ah, AR_RCCNT, 0); - REG_WRITE(ah, AR_TFCNT, 0); + REG_WRITE(ah, 0, AR_CCCNT); + REG_WRITE(ah, 0, AR_RFCNT); + REG_WRITE(ah, 0, AR_RCCNT); + REG_WRITE(ah, 0, AR_TFCNT); /* unfreeze */ - REG_WRITE(ah, AR_MIBC, 0); + REG_WRITE(ah, 0, AR_MIBC); /* update all cycle counters here */ common->cc_ani.cycles += cycles; diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index ddd6a4f78097..73730e94e0ac 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -4652,7 +4652,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) switch (dev->dev->bus_type) { #ifdef CONFIG_B43_BCMA case B43_BUS_BCMA: - bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], + bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, dev->dev->bdev, true); break; #endif @@ -5404,8 +5404,6 @@ static void b43_bcma_remove(struct bcma_device *core) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (!wldev->fw.ucode.data) - return; /* NULL if firmware never loaded */ if (wl->current_dev == wldev && wl->hw_registred) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); @@ -5480,8 +5478,6 @@ static void b43_ssb_remove(struct ssb_device *sdev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (!wldev->fw.ucode.data) - return; /* NULL if firmware never loaded */ if (wl->current_dev == wldev && wl->hw_registred) { b43_leds_stop(wldev); ieee80211_unregister_hw(wl->hw); diff --git a/trunk/drivers/net/wireless/brcm80211/Kconfig b/trunk/drivers/net/wireless/brcm80211/Kconfig index 1d92d874ebb6..c9d811eb6556 100644 --- a/trunk/drivers/net/wireless/brcm80211/Kconfig +++ b/trunk/drivers/net/wireless/brcm80211/Kconfig @@ -55,16 +55,13 @@ config BRCMFMAC_USB IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to use the driver for an USB wireless card. -config BRCM_TRACING - bool "Broadcom device tracing" - depends on BRCMSMAC || BRCMFMAC +config BRCMISCAN + bool "Broadcom I-Scan (OBSOLETE)" + depends on BRCMFMAC ---help--- - If you say Y here, the Broadcom wireless drivers will register - with ftrace to dump event information into the trace ringbuffer. - Tracing can be enabled at runtime to aid in debugging wireless - issues. This option adds a small amount of overhead when tracing - is disabled. If unsure, say Y to allow developers to better help - you when wireless problems occur. + This option enables the I-Scan method. By default fullmac uses the + new E-Scan method which uses less memory in firmware and gives no + limitation on the number of scan results. config BRCMDBG bool "Broadcom driver debug functions" diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 1a6661a9f008..9d5170b6df50 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -24,8 +24,6 @@ ccflags-y += -D__CHECK_ENDIAN__ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += \ wl_cfg80211.o \ - fwil.o \ - fweh.o \ dhd_cdc.o \ dhd_common.o \ dhd_linux.o diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 334ddab4a8c5..3b2c4c20e7fc 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -42,8 +42,7 @@ #ifdef CONFIG_BRCMFMAC_SDIO_OOB static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) { - struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); brcmf_dbg(INTR, "oob intr triggered\n"); @@ -72,7 +71,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, sdiodev->irq_flags, "brcmf_oob_intr", - &sdiodev->func[1]->dev); + &sdiodev->func[1]->card->dev); if (ret != 0) return ret; spin_lock_init(&sdiodev->irq_en_lock); @@ -85,8 +84,6 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) return ret; sdiodev->irq_wake = true; - sdio_claim_host(sdiodev->func[1]); - /* must configure SDIO_CCCR_IENx to enable irq */ data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; @@ -98,8 +95,6 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) data |= SDIO_SEPINT_ACT_HI; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); - sdio_release_host(sdiodev->func[1]); - return 0; } @@ -107,16 +102,14 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(TRACE, "Entering\n"); - sdio_claim_host(sdiodev->func[1]); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); - sdio_release_host(sdiodev->func[1]); if (sdiodev->irq_wake) { disable_irq_wake(sdiodev->irq); sdiodev->irq_wake = false; } - free_irq(sdiodev->irq, &sdiodev->func[1]->dev); + free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); sdiodev->irq_en = false; return 0; @@ -124,8 +117,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) #else /* CONFIG_BRCMFMAC_SDIO_OOB */ static void brcmf_sdio_irqhandler(struct sdio_func *func) { - struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); brcmf_dbg(INTR, "ib intr triggered\n"); @@ -257,7 +249,9 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) int retval; brcmf_dbg(INFO, "addr:0x%08x\n", addr); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(INFO, "data:0x%02x\n", data); if (ret) @@ -272,7 +266,9 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) int retval; brcmf_dbg(INFO, "addr:0x%08x\n", addr); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(INFO, "data:0x%08x\n", data); if (ret) @@ -287,7 +283,9 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + sdio_release_host(sdiodev->func[1]); if (ret) *ret = retval; @@ -299,7 +297,9 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + sdio_release_host(sdiodev->func[1]); if (ret) *ret = retval; @@ -364,6 +364,8 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pkt->len); + sdio_claim_host(sdiodev->func[1]); + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); if (err) @@ -374,6 +376,8 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, fn, addr, pkt); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -387,6 +391,8 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pktq->qlen); + sdio_claim_host(sdiodev->func[1]); + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); if (err) @@ -397,6 +403,8 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, pktq); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -438,6 +446,8 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; + sdio_claim_host(sdiodev->func[1]); + if (bar0 != sdiodev->sbwad) { err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); if (err) @@ -457,6 +467,8 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, addr, pkt); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -498,8 +510,10 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) brcmf_dbg(TRACE, "Enter\n"); /* issue abort cmd52 command through F0 */ + sdio_claim_host(sdiodev->func[1]); brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, &t_func); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(TRACE, "Exit\n"); return 0; @@ -516,6 +530,9 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) regs = SI_ENUM_BASE; + /* Report the BAR, to fix if needed */ + sdiodev->sbwad = SI_ENUM_BASE; + /* try to attach to the target device */ sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); if (!sdiodev->bus) { @@ -534,8 +551,6 @@ EXPORT_SYMBOL(brcmf_sdio_probe); int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) { - sdiodev->bus_if->state = BRCMF_BUS_DOWN; - if (sdiodev->bus) { brcmf_sdbrcm_disconnect(sdiodev->bus); sdiodev->bus = NULL; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index a80050223710..c3247d5b3c22 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -372,7 +372,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) } /* Enable Function 1 */ + sdio_claim_host(sdiodev->func[1]); err_ret = sdio_enable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); if (err_ret) brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); @@ -391,14 +393,16 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) sdiodev->num_funcs = 2; sdio_claim_host(sdiodev->func[1]); - err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); + sdio_release_host(sdiodev->func[1]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); goto out; } + sdio_claim_host(sdiodev->func[2]); err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); + sdio_release_host(sdiodev->func[2]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); goto out; @@ -407,7 +411,6 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) brcmf_sdioh_enablefuncs(sdiodev); out: - sdio_release_host(sdiodev->func[1]); brcmf_dbg(TRACE, "Done\n"); return err_ret; } @@ -456,106 +459,95 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ static int brcmf_ops_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) + const struct sdio_device_id *id) { - int err; + int ret = 0; struct brcmf_sdio_dev *sdiodev; struct brcmf_bus *bus_if; brcmf_dbg(TRACE, "Enter\n"); - brcmf_dbg(TRACE, "Class=%x\n", func->class); - brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(TRACE, "Function#: %d\n", func->num); - - /* Consume func num 1 but dont do anything with it. */ - if (func->num == 1) - return 0; - - /* Ignore anything but func 2 */ - if (func->num != 2) - return -ENODEV; - - bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); - if (!bus_if) - return -ENOMEM; - sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); - if (!sdiodev) { - kfree(bus_if); - return -ENOMEM; + brcmf_dbg(TRACE, "func->class=%x\n", func->class); + brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); + + if (func->num == 1) { + if (dev_get_drvdata(&func->card->dev)) { + brcmf_dbg(ERROR, "card private drvdata occupied\n"); + return -ENXIO; + } + bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); + if (!bus_if) + return -ENOMEM; + sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); + if (!sdiodev) { + kfree(bus_if); + return -ENOMEM; + } + sdiodev->func[0] = func; + sdiodev->func[1] = func; + sdiodev->bus_if = bus_if; + bus_if->bus_priv.sdio = sdiodev; + bus_if->type = SDIO_BUS; + bus_if->align = BRCMF_SDALIGN; + dev_set_drvdata(&func->card->dev, sdiodev); + + atomic_set(&sdiodev->suspend, false); + init_waitqueue_head(&sdiodev->request_byte_wait); + init_waitqueue_head(&sdiodev->request_word_wait); + init_waitqueue_head(&sdiodev->request_chain_wait); + init_waitqueue_head(&sdiodev->request_buffer_wait); } - sdiodev->func[0] = func->card->sdio_func[0]; - sdiodev->func[1] = func->card->sdio_func[0]; - sdiodev->func[2] = func; + if (func->num == 2) { + sdiodev = dev_get_drvdata(&func->card->dev); + if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) + return -ENODEV; - sdiodev->bus_if = bus_if; - bus_if->bus_priv.sdio = sdiodev; - bus_if->align = BRCMF_SDALIGN; - dev_set_drvdata(&func->dev, bus_if); - dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); - sdiodev->dev = &sdiodev->func[1]->dev; + ret = brcmf_sdio_getintrcfg(sdiodev); + if (ret) + return ret; + sdiodev->func[2] = func; - atomic_set(&sdiodev->suspend, false); - init_waitqueue_head(&sdiodev->request_byte_wait); - init_waitqueue_head(&sdiodev->request_word_wait); - init_waitqueue_head(&sdiodev->request_chain_wait); - init_waitqueue_head(&sdiodev->request_buffer_wait); - err = brcmf_sdio_getintrcfg(sdiodev); - if (err) - goto fail; - - brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); - err = brcmf_sdio_probe(sdiodev); - if (err) { - brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err); - goto fail; + bus_if = sdiodev->bus_if; + sdiodev->dev = &func->dev; + dev_set_drvdata(&func->dev, bus_if); + + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); + ret = brcmf_sdio_probe(sdiodev); } - brcmf_dbg(TRACE, "F2 init completed...\n"); - return 0; -fail: - dev_set_drvdata(&func->dev, NULL); - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - kfree(sdiodev); - kfree(bus_if); - return err; + return ret; } static void brcmf_ops_sdio_remove(struct sdio_func *func) { struct brcmf_bus *bus_if; struct brcmf_sdio_dev *sdiodev; - brcmf_dbg(TRACE, "Enter\n"); - brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(TRACE, "Function: %d\n", func->num); + brcmf_dbg(INFO, "func->class=%x\n", func->class); + brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num); - if (func->num != 1 && func->num != 2) - return; - - bus_if = dev_get_drvdata(&func->dev); - if (bus_if) { + if (func->num == 2) { + bus_if = dev_get_drvdata(&func->dev); sdiodev = bus_if->bus_priv.sdio; + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); brcmf_sdio_remove(sdiodev); - - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - dev_set_drvdata(&sdiodev->func[2]->dev, NULL); - + dev_set_drvdata(&func->card->dev, NULL); + dev_set_drvdata(&func->dev, NULL); kfree(bus_if); kfree(sdiodev); } - - brcmf_dbg(TRACE, "Exit\n"); } #ifdef CONFIG_PM_SLEEP static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct sdio_func *func = dev_to_sdio_func(dev); + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); int ret = 0; brcmf_dbg(TRACE, "\n"); @@ -581,8 +573,8 @@ static int brcmf_sdio_suspend(struct device *dev) static int brcmf_sdio_resume(struct device *dev) { - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct sdio_func *func = dev_to_sdio_func(dev); + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); brcmf_sdio_wdtmr_enable(sdiodev, true); atomic_set(&sdiodev->suspend, false); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 24bc4e3e162b..17e7ae73e008 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -23,8 +23,6 @@ #define BRCMF_VERSION_STR "4.218.248.5" -#include "fweh.h" - /******************************************************************************* * IO codes that are interpreted by dongle firmware ******************************************************************************/ @@ -40,11 +38,8 @@ #define BRCMF_C_GET_SSID 25 #define BRCMF_C_SET_SSID 26 #define BRCMF_C_GET_CHANNEL 29 -#define BRCMF_C_SET_CHANNEL 30 #define BRCMF_C_GET_SRL 31 -#define BRCMF_C_SET_SRL 32 #define BRCMF_C_GET_LRL 33 -#define BRCMF_C_SET_LRL 34 #define BRCMF_C_GET_RADIO 37 #define BRCMF_C_SET_RADIO 38 #define BRCMF_C_GET_PHYTYPE 39 @@ -63,7 +58,6 @@ #define BRCMF_C_SET_COUNTRY 84 #define BRCMF_C_GET_PM 85 #define BRCMF_C_SET_PM 86 -#define BRCMF_C_GET_CURR_RATESET 114 #define BRCMF_C_GET_AP 117 #define BRCMF_C_SET_AP 118 #define BRCMF_C_GET_RSSI 127 @@ -71,7 +65,6 @@ #define BRCMF_C_SET_WSEC 134 #define BRCMF_C_GET_PHY_NOISE 135 #define BRCMF_C_GET_BSS_INFO 136 -#define BRCMF_C_GET_PHYLIST 180 #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 @@ -107,8 +100,29 @@ #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 +#define BRCMF_SCAN_ACTION_START 1 +#define BRCMF_SCAN_ACTION_CONTINUE 2 +#define WL_SCAN_ACTION_ABORT 3 + +#define BRCMF_ISCAN_REQ_VERSION 1 + +/* brcmf_iscan_results status values */ +#define BRCMF_SCAN_RESULTS_SUCCESS 0 +#define BRCMF_SCAN_RESULTS_PARTIAL 1 +#define BRCMF_SCAN_RESULTS_PENDING 2 +#define BRCMF_SCAN_RESULTS_ABORTED 3 +#define BRCMF_SCAN_RESULTS_NO_MEM 4 + +/* Indicates this key is using soft encrypt */ +#define WL_SOFT_KEY (1 << 0) /* primary (ie tx) key */ #define BRCMF_PRIMARY_KEY (1 << 1) +/* Reserved for backward compat */ +#define WL_KF_RES_4 (1 << 4) +/* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) +/* Indicates a group key for a IBSS PEER */ +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* For supporting multiple interfaces */ #define BRCMF_MAX_IFS 16 @@ -116,6 +130,10 @@ #define DOT11_BSSTYPE_ANY 2 #define DOT11_MAX_DEFAULT_KEYS 4 +#define BRCMF_EVENT_MSG_LINK 0x01 +#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 +#define BRCMF_EVENT_MSG_GROUP 0x04 + #define BRCMF_ESCAN_REQ_VERSION 1 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 @@ -123,6 +141,108 @@ #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ #define BRCMF_STA_ASSOC 0x10 /* Associated */ +struct brcmf_event_msg { + __be16 version; + __be16 flags; + __be32 event_type; + __be32 status; + __be32 reason; + __be32 auth_type; + __be32 datalen; + u8 addr[ETH_ALEN]; + char ifname[IFNAMSIZ]; + u8 ifidx; + u8 bsscfgidx; +} __packed; + +struct brcm_ethhdr { + u16 subtype; + u16 length; + u8 version; + u8 oui[3]; + u16 usr_subtype; +} __packed; + +struct brcmf_event { + struct ethhdr eth; + struct brcm_ethhdr hdr; + struct brcmf_event_msg msg; +} __packed; + +/* event codes sent by the dongle to this driver */ +#define BRCMF_E_SET_SSID 0 +#define BRCMF_E_JOIN 1 +#define BRCMF_E_START 2 +#define BRCMF_E_AUTH 3 +#define BRCMF_E_AUTH_IND 4 +#define BRCMF_E_DEAUTH 5 +#define BRCMF_E_DEAUTH_IND 6 +#define BRCMF_E_ASSOC 7 +#define BRCMF_E_ASSOC_IND 8 +#define BRCMF_E_REASSOC 9 +#define BRCMF_E_REASSOC_IND 10 +#define BRCMF_E_DISASSOC 11 +#define BRCMF_E_DISASSOC_IND 12 +#define BRCMF_E_QUIET_START 13 +#define BRCMF_E_QUIET_END 14 +#define BRCMF_E_BEACON_RX 15 +#define BRCMF_E_LINK 16 +#define BRCMF_E_MIC_ERROR 17 +#define BRCMF_E_NDIS_LINK 18 +#define BRCMF_E_ROAM 19 +#define BRCMF_E_TXFAIL 20 +#define BRCMF_E_PMKID_CACHE 21 +#define BRCMF_E_RETROGRADE_TSF 22 +#define BRCMF_E_PRUNE 23 +#define BRCMF_E_AUTOAUTH 24 +#define BRCMF_E_EAPOL_MSG 25 +#define BRCMF_E_SCAN_COMPLETE 26 +#define BRCMF_E_ADDTS_IND 27 +#define BRCMF_E_DELTS_IND 28 +#define BRCMF_E_BCNSENT_IND 29 +#define BRCMF_E_BCNRX_MSG 30 +#define BRCMF_E_BCNLOST_MSG 31 +#define BRCMF_E_ROAM_PREP 32 +#define BRCMF_E_PFN_NET_FOUND 33 +#define BRCMF_E_PFN_NET_LOST 34 +#define BRCMF_E_RESET_COMPLETE 35 +#define BRCMF_E_JOIN_START 36 +#define BRCMF_E_ROAM_START 37 +#define BRCMF_E_ASSOC_START 38 +#define BRCMF_E_IBSS_ASSOC 39 +#define BRCMF_E_RADIO 40 +#define BRCMF_E_PSM_WATCHDOG 41 +#define BRCMF_E_PROBREQ_MSG 44 +#define BRCMF_E_SCAN_CONFIRM_IND 45 +#define BRCMF_E_PSK_SUP 46 +#define BRCMF_E_COUNTRY_CODE_CHANGED 47 +#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 +#define BRCMF_E_ICV_ERROR 49 +#define BRCMF_E_UNICAST_DECODE_ERROR 50 +#define BRCMF_E_MULTICAST_DECODE_ERROR 51 +#define BRCMF_E_TRACE 52 +#define BRCMF_E_IF 54 +#define BRCMF_E_RSSI 56 +#define BRCMF_E_PFN_SCAN_COMPLETE 57 +#define BRCMF_E_EXTLOG_MSG 58 +#define BRCMF_E_ACTION_FRAME 59 +#define BRCMF_E_ACTION_FRAME_COMPLETE 60 +#define BRCMF_E_PRE_ASSOC_IND 61 +#define BRCMF_E_PRE_REASSOC_IND 62 +#define BRCMF_E_CHANNEL_ADOPTED 63 +#define BRCMF_E_AP_STARTED 64 +#define BRCMF_E_DFS_AP_STOP 65 +#define BRCMF_E_DFS_AP_RESUME 66 +#define BRCMF_E_RESERVED1 67 +#define BRCMF_E_RESERVED2 68 +#define BRCMF_E_ESCAN_RESULT 69 +#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 +#define BRCMF_E_DCS_REQUEST 73 + +#define BRCMF_E_FIFO_CREDIT_MAP 74 + +#define BRCMF_E_LAST 75 + #define BRCMF_E_STATUS_SUCCESS 0 #define BRCMF_E_STATUS_FAIL 1 #define BRCMF_E_STATUS_TIMEOUT 2 @@ -198,12 +318,6 @@ #define BRCMF_E_LINK_ASSOC_REC 3 #define BRCMF_E_LINK_BSSCFG_DIS 4 -/* Small, medium and maximum buffer size for dcmd - */ -#define BRCMF_DCMD_SMLEN 256 -#define BRCMF_DCMD_MEDLEN 1536 -#define BRCMF_DCMD_MAXLEN 8192 - /* Pattern matching filter. Specifies an offset within received packets to * start matching, the pattern to match, the size of the pattern, and a bitmask * that indicates which bits within the pattern should be matched. @@ -283,7 +397,7 @@ struct brcm_rateset_le { /* # rates in this set */ __le32 count; /* rates in 500kbps units w/hi bit set if basic */ - u8 rates[BRCMF_MAXRATES_IN_SET]; + u8 rates[WL_NUMRATES]; }; struct brcmf_ssid { @@ -332,6 +446,14 @@ struct brcmf_scan_params_le { __le16 channel_list[1]; /* list of chanspecs */ }; +/* incremental scan struct */ +struct brcmf_iscan_params_le { + __le32 version; + __le16 action; + __le16 scan_duration; + struct brcmf_scan_params_le params_le; +}; + struct brcmf_scan_results { u32 buflen; u32 version; @@ -339,6 +461,12 @@ struct brcmf_scan_results { struct brcmf_bss_info_le bss_info_le[]; }; +struct brcmf_scan_results_le { + __le32 buflen; + __le32 version; + __le32 count; +}; + struct brcmf_escan_params_le { __le32 version; __le16 action; @@ -374,6 +502,23 @@ struct brcmf_join_params { struct brcmf_assoc_params_le params_le; }; +/* incremental scan results struct */ +struct brcmf_iscan_results { + union { + u32 status; + __le32 status_le; + }; + union { + struct brcmf_scan_results results; + struct brcmf_scan_results_le results_le; + }; +}; + +/* size of brcmf_iscan_results not including variable length array */ +#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ + (sizeof(struct brcmf_scan_results) + \ + offsetof(struct brcmf_iscan_results, results)) + struct brcmf_wsec_key { u32 index; /* key index */ u32 len; /* key length */ @@ -478,6 +623,7 @@ struct brcmf_pub { u8 wme_dp; /* wme discard priority */ /* Dongle media info */ + bool iswl; /* Dongle-resident driver is wl */ unsigned long drv_version; /* Version of dongle-resident driver */ u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ @@ -505,26 +651,26 @@ struct brcmf_pub { int in_suspend; /* flag set to 1 when early suspend called */ int dtim_skip; /* dtim skip , default 0 means wake each dtim */ + /* Pkt filter defination */ + char *pktfilter[100]; + int pktfilter_count; + + u8 country_code[BRCM_CNTRY_BUF_SZ]; + char eventmask[BRCMF_EVENTING_MASK_LEN]; + struct brcmf_if *iflist[BRCMF_MAX_IFS]; struct mutex proto_block; - unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; + struct work_struct setmacaddr_work; + struct work_struct multicast_work; u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; - wait_queue_head_t pend_8021x_wait; - - struct brcmf_fweh_info fweh; #ifdef DEBUG struct dentry *dbgfs_dir; #endif }; -struct bcmevent_name { - uint event; - const char *name; -}; - struct brcmf_if_event { u8 ifidx; u8 action; @@ -532,54 +678,47 @@ struct brcmf_if_event { u8 bssidx; }; -/* forward declaration */ -struct brcmf_cfg80211_vif; - -/** - * struct brcmf_if - interface control information. - * - * @drvr: points to device related information. - * @vif: points to cfg80211 specific interface information. - * @ndev: associated network device. - * @stats: interface specific network statistics. - * @idx: interface index in device firmware. - * @bssidx: index of bss associated with this interface. - * @mac_addr: assigned mac address. - */ -struct brcmf_if { - struct brcmf_pub *drvr; - struct brcmf_cfg80211_vif *vif; - struct net_device *ndev; - struct net_device_stats stats; - struct work_struct setmacaddr_work; - struct work_struct multicast_work; - int idx; - s32 bssidx; - u8 mac_addr[ETH_ALEN]; +struct bcmevent_name { + uint event; + const char *name; }; -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 uint brcmf_c_mkiovar(char *name, char *data, uint datalen, + char *buf, uint len); +extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, + char *buf, uint buflen, s32 bssidx); + extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); +extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); +extern int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd); + /* Return pointer to interface name */ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); /* Query dongle */ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); -extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); -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); +#ifdef DEBUG +extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); +#endif /* DEBUG */ + +extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); +extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, + void *pktdata, struct brcmf_event_msg *, + void **data_ptr); + extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); +extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); +extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, + int enable, int master_mode); + +#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */ +#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */ +#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */ + #endif /* _BRCMF_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index b8f248797f62..9b8ee19ea55d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -45,6 +45,7 @@ struct brcmf_bus_dcmd { /* interface structure between common and bus layer */ struct brcmf_bus { + u8 type; /* bus type */ union { struct brcmf_sdio_dev *sdio; struct brcmf_usbdev *usb; @@ -84,7 +85,7 @@ 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_frame(struct device *dev, u8 ifidx, +extern void brcmf_rx_frame(struct device *dev, int ifidx, struct sk_buff_head *rxlist); static inline void brcmf_rx_packet(struct device *dev, int ifidx, struct sk_buff *pkt) @@ -110,6 +111,9 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, extern int brcmf_bus_start(struct device *dev); +extern int brcmf_add_if(struct device *dev, int ifidx, + char *name, u8 *mac_addr); + #ifdef CONFIG_BRCMFMAC_SDIO extern void brcmf_sdio_exit(void); extern void brcmf_sdio_init(void); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index 87536d38a4ca..a5c15cac5e7d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include @@ -275,6 +277,76 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, return ret; } +int +brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, + int len) +{ + struct brcmf_proto *prot = drvr->prot; + int ret = -1; + + if (drvr->bus_if->state == BRCMF_BUS_DOWN) { + brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); + return ret; + } + mutex_lock(&drvr->proto_block); + + brcmf_dbg(TRACE, "Enter\n"); + + if (len > BRCMF_DCMD_MAXLEN) + goto done; + + if (prot->pending == true) { + brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", + dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd, + (unsigned long)prot->lastcmd); + if (dcmd->cmd == BRCMF_C_SET_VAR || + dcmd->cmd == BRCMF_C_GET_VAR) + brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf); + + goto done; + } + + prot->pending = true; + prot->lastcmd = dcmd->cmd; + if (dcmd->set) + ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd, + dcmd->buf, len); + else { + ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd, + dcmd->buf, len); + if (ret > 0) + dcmd->used = ret - + sizeof(struct brcmf_proto_cdc_dcmd); + } + + if (ret >= 0) + ret = 0; + else { + struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + /* len == needed when set/query fails from dongle */ + dcmd->needed = le32_to_cpu(msg->len); + } + + /* Intercept the wme_dp dongle cmd here */ + if (!ret && dcmd->cmd == BRCMF_C_SET_VAR && + !strcmp(dcmd->buf, "wme_dp")) { + int slen; + __le32 val = 0; + + slen = strlen("wme_dp") + 1; + if (len >= (int)(slen + sizeof(int))) + memcpy(&val, (char *)dcmd->buf + slen, sizeof(int)); + drvr->wme_dp = (u8) le32_to_cpu(val); + } + + prot->pending = false; + +done: + mutex_unlock(&drvr->proto_block); + + return ret; +} + static bool pkt_sum_needed(struct sk_buff *skb) { return skb->ip_summed == CHECKSUM_PARTIAL; @@ -386,6 +458,35 @@ void brcmf_proto_detach(struct brcmf_pub *drvr) drvr->prot = NULL; } +int brcmf_proto_init(struct brcmf_pub *drvr) +{ + int ret = 0; + char buf[128]; + + brcmf_dbg(TRACE, "Enter\n"); + + mutex_lock(&drvr->proto_block); + + /* Get the device MAC address */ + strcpy(buf, "cur_etheraddr"); + ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, + buf, sizeof(buf)); + if (ret < 0) { + mutex_unlock(&drvr->proto_block); + return ret; + } + memcpy(drvr->mac, buf, ETH_ALEN); + + mutex_unlock(&drvr->proto_block); + + ret = brcmf_c_preinit_dcmds(drvr); + + /* Always assumes wl for now */ + drvr->iswl = true; + + return ret; +} + void brcmf_proto_stop(struct brcmf_pub *drvr) { /* Nothing to do for CDC */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index eee7175f1515..15c5db5752d1 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -18,21 +18,28 @@ #include #include +#include #include +#include +#include #include #include #include "dhd.h" #include "dhd_bus.h" #include "dhd_proto.h" #include "dhd_dbg.h" -#include "fwil.h" -#define PKTFILTER_BUF_SIZE 128 +#define BRCM_OUI "\x00\x10\x18" +#define DOT11_OUI_LEN 3 +#define BCMILCP_BCM_SUBTYPE_EVENT 1 +#define PKTFILTER_BUF_SIZE 2048 #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ -#define BRCMF_DEFAULT_BCN_TIMEOUT 3 -#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 -#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 -#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" + +#define MSGTRACE_VERSION 1 + +#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u) +#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ + offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) #ifdef DEBUG static const char brcmf_version[] = @@ -43,6 +50,89 @@ static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR; #endif +/* Message trace header */ +struct msgtrace_hdr { + u8 version; + u8 spare; + __be16 len; /* Len of the trace */ + __be32 seqnum; /* Sequence number of message. Useful + * if the messsage has been lost + * because of DMA error or a bus reset + * (ex: SDIO Func2) + */ + __be32 discarded_bytes; /* Number of discarded bytes because of + trace overflow */ + __be32 discarded_printf; /* Number of discarded printf + because of trace overflow */ +} __packed; + + +uint +brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) +{ + uint len; + + len = strlen(name) + 1; + + if ((len + datalen) > buflen) + return 0; + + strncpy(buf, name, buflen); + + /* append data onto the end of the name string */ + if (data && datalen) { + memcpy(&buf[len], data, datalen); + len += datalen; + } + + return len; +} + +uint +brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, + char *buf, uint buflen, s32 bssidx) +{ + const s8 *prefix = "bsscfg:"; + s8 *p; + u32 prefixlen; + u32 namelen; + u32 iolen; + __le32 bssidx_le; + + if (bssidx == 0) + return brcmf_c_mkiovar(name, data, datalen, buf, buflen); + + prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */ + namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */ + iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen; + + if (buflen < 0 || iolen > (u32)buflen) { + brcmf_dbg(ERROR, "buffer is too short\n"); + return 0; + } + + p = buf; + + /* copy prefix, no null */ + memcpy(p, prefix, prefixlen); + p += prefixlen; + + /* copy iovar name including null */ + memcpy(p, name, namelen); + p += namelen; + + /* bss config index as first data */ + bssidx_le = cpu_to_le32(bssidx); + memcpy(p, &bssidx_le, sizeof(bssidx_le)); + p += sizeof(bssidx_le); + + /* parameter buffer follows */ + if (datalen) + memcpy(p, data, datalen); + + return iolen; + +} bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) @@ -94,6 +184,399 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } +#ifdef DEBUG +static void +brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) +{ + uint i, status, reason; + bool group = false, flush_txq = false, link = false; + char *auth_str, *event_name; + unsigned char *buf; + char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; + static struct { + uint event; + char *event_name; + } event_names[] = { + { + BRCMF_E_SET_SSID, "SET_SSID"}, { + BRCMF_E_JOIN, "JOIN"}, { + BRCMF_E_START, "START"}, { + BRCMF_E_AUTH, "AUTH"}, { + BRCMF_E_AUTH_IND, "AUTH_IND"}, { + BRCMF_E_DEAUTH, "DEAUTH"}, { + BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { + BRCMF_E_ASSOC, "ASSOC"}, { + BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { + BRCMF_E_REASSOC, "REASSOC"}, { + BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { + BRCMF_E_DISASSOC, "DISASSOC"}, { + BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { + BRCMF_E_QUIET_START, "START_QUIET"}, { + BRCMF_E_QUIET_END, "END_QUIET"}, { + BRCMF_E_BEACON_RX, "BEACON_RX"}, { + BRCMF_E_LINK, "LINK"}, { + BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { + BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { + BRCMF_E_ROAM, "ROAM"}, { + BRCMF_E_TXFAIL, "TXFAIL"}, { + BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { + BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { + BRCMF_E_PRUNE, "PRUNE"}, { + BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { + BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { + BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { + BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { + BRCMF_E_DELTS_IND, "DELTS_IND"}, { + BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { + BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { + BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { + BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { + BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { + BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { + BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { + BRCMF_E_JOIN_START, "JOIN_START"}, { + BRCMF_E_ROAM_START, "ROAM_START"}, { + BRCMF_E_ASSOC_START, "ASSOC_START"}, { + BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { + BRCMF_E_RADIO, "RADIO"}, { + BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { + BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { + BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { + BRCMF_E_PSK_SUP, "PSK_SUP"}, { + BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { + BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { + BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { + BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { + BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { + BRCMF_E_TRACE, "TRACE"}, { + BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { + BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { + BRCMF_E_IF, "IF"}, { + BRCMF_E_RSSI, "RSSI"}, { + BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, { + BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"} + }; + uint event_type, flags, auth_type, datalen; + static u32 seqnum_prev; + struct msgtrace_hdr hdr; + u32 nblost; + char *s, *p; + + event_type = be32_to_cpu(event->event_type); + flags = be16_to_cpu(event->flags); + status = be32_to_cpu(event->status); + reason = be32_to_cpu(event->reason); + auth_type = be32_to_cpu(event->auth_type); + datalen = be32_to_cpu(event->datalen); + /* debug dump of event messages */ + sprintf(eabuf, "%pM", event->addr); + + event_name = "UNKNOWN"; + for (i = 0; i < ARRAY_SIZE(event_names); i++) { + if (event_names[i].event == event_type) + event_name = event_names[i].event_name; + } + + brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type); + brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", + flags, status, reason, auth_type, eabuf); + + if (flags & BRCMF_EVENT_MSG_LINK) + link = true; + if (flags & BRCMF_EVENT_MSG_GROUP) + group = true; + if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) + flush_txq = true; + + switch (event_type) { + case BRCMF_E_START: + case BRCMF_E_DEAUTH: + case BRCMF_E_DISASSOC: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_ASSOC: + case BRCMF_E_REASSOC: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n", + event_name, eabuf, (int)reason); + else + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n", + event_name, eabuf, (int)status); + break; + + case BRCMF_E_DEAUTH_IND: + case BRCMF_E_DISASSOC_IND: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n", + event_name, eabuf, (int)reason); + break; + + case BRCMF_E_AUTH: + case BRCMF_E_AUTH_IND: + if (auth_type == WLAN_AUTH_OPEN) + auth_str = "Open System"; + else if (auth_type == WLAN_AUTH_SHARED_KEY) + auth_str = "Shared Key"; + else { + sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); + auth_str = err_msg; + } + if (event_type == BRCMF_E_AUTH_IND) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_FAIL) { + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", + event_name, eabuf, auth_str, (int)reason); + } + + break; + + case BRCMF_E_JOIN: + case BRCMF_E_ROAM: + case BRCMF_E_SET_SSID: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name); + else if (status == BRCMF_E_STATUS_NO_NETWORKS) + brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n", + event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n", + event_name, (int)status); + break; + + case BRCMF_E_BEACON_RX: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n", + event_name, status); + break; + + case BRCMF_E_LINK: + brcmf_dbg(EVENT, "MACEVENT: %s %s\n", + event_name, link ? "UP" : "DOWN"); + break; + + case BRCMF_E_MIC_ERROR: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n", + event_name, eabuf, group, flush_txq); + break; + + case BRCMF_E_ICV_ERROR: + case BRCMF_E_UNICAST_DECODE_ERROR: + case BRCMF_E_MULTICAST_DECODE_ERROR: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_TXFAIL: + brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf); + break; + + case BRCMF_E_SCAN_COMPLETE: + case BRCMF_E_PMKID_CACHE: + brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); + break; + + case BRCMF_E_ESCAN_RESULT: + brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); + datalen = 0; + break; + + case BRCMF_E_PFN_NET_FOUND: + case BRCMF_E_PFN_NET_LOST: + case BRCMF_E_PFN_SCAN_COMPLETE: + brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name); + break; + + case BRCMF_E_PSK_SUP: + case BRCMF_E_PRUNE: + brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n", + event_name, (int)status, (int)reason); + break; + + case BRCMF_E_TRACE: + buf = (unsigned char *) event_data; + memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); + + if (hdr.version != MSGTRACE_VERSION) { + brcmf_dbg(ERROR, + "MACEVENT: %s [unsupported version --> brcmf" + " version:%d dongle version:%d]\n", + event_name, MSGTRACE_VERSION, hdr.version); + /* Reset datalen to avoid display below */ + datalen = 0; + break; + } + + /* There are 2 bytes available at the end of data */ + *(buf + sizeof(struct msgtrace_hdr) + + be16_to_cpu(hdr.len)) = '\0'; + + if (be32_to_cpu(hdr.discarded_bytes) + || be32_to_cpu(hdr.discarded_printf)) + brcmf_dbg(ERROR, + "WLC_E_TRACE: [Discarded traces in dongle -->" + " discarded_bytes %d discarded_printf %d]\n", + be32_to_cpu(hdr.discarded_bytes), + be32_to_cpu(hdr.discarded_printf)); + + nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; + if (nblost > 0) + brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum " + " %d nblost %d\n", be32_to_cpu(hdr.seqnum), + nblost); + seqnum_prev = be32_to_cpu(hdr.seqnum); + + /* Display the trace buffer. Advance from \n to \n to + * avoid display big + * printf (issue with Linux printk ) + */ + p = (char *)&buf[sizeof(struct msgtrace_hdr)]; + while ((s = strstr(p, "\n")) != NULL) { + *s = '\0'; + pr_debug("%s\n", p); + p = s + 1; + } + pr_debug("%s\n", p); + + /* Reset datalen to avoid display below */ + datalen = 0; + break; + + case BRCMF_E_RSSI: + brcmf_dbg(EVENT, "MACEVENT: %s %d\n", + event_name, be32_to_cpu(*((__be32 *)event_data))); + break; + + default: + brcmf_dbg(EVENT, + "MACEVENT: %s %d, MAC %s, status %d, reason %d, " + "auth %d\n", event_name, event_type, eabuf, + (int)status, (int)reason, (int)auth_type); + break; + } + + /* show any appended data */ + brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data"); +} +#endif /* DEBUG */ + +int +brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, + struct brcmf_event_msg *event, void **data_ptr) +{ + /* check whether packet is a BRCM event pkt */ + struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; + struct brcmf_if_event *ifevent; + char *event_data; + u32 type, status; + u16 flags; + int evlen; + + if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { + brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); + return -EBADE; + } + + /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ + if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != + BCMILCP_BCM_SUBTYPE_EVENT) { + brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); + return -EBADE; + } + + *data_ptr = &pvt_data[1]; + event_data = *data_ptr; + + /* memcpy since BRCM event pkt may be unaligned. */ + memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); + + type = get_unaligned_be32(&event->event_type); + flags = get_unaligned_be16(&event->flags); + status = get_unaligned_be32(&event->status); + evlen = get_unaligned_be32(&event->datalen) + + sizeof(struct brcmf_event); + + switch (type) { + case BRCMF_E_IF: + ifevent = (struct brcmf_if_event *) event_data; + brcmf_dbg(TRACE, "if event\n"); + + if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { + if (ifevent->action == BRCMF_E_IF_ADD) + brcmf_add_if(drvr->dev, ifevent->ifidx, + event->ifname, + pvt_data->eth.h_dest); + else + brcmf_del_if(drvr, ifevent->ifidx); + } else { + brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", + ifevent->ifidx, event->ifname); + } + + /* send up the if event: btamp user needs it */ + *ifidx = brcmf_ifname2idx(drvr, event->ifname); + break; + + /* These are what external supplicant/authenticator wants */ + case BRCMF_E_LINK: + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + case BRCMF_E_DISASSOC_IND: + case BRCMF_E_MIC_ERROR: + default: + /* Fall through: this should get _everything_ */ + + *ifidx = brcmf_ifname2idx(drvr, event->ifname); + brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", + type, flags, status); + + /* put it back to BRCMF_E_NDIS_LINK */ + if (type == BRCMF_E_NDIS_LINK) { + u32 temp1; + __be32 temp2; + + temp1 = get_unaligned_be32(&event->event_type); + brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", + temp1); + + temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK); + memcpy((void *)(&pvt_data->msg.event_type), &temp2, + sizeof(pvt_data->msg.event_type)); + } + break; + } + +#ifdef DEBUG + if (BRCMF_EVENT_ON()) + brcmf_c_show_host_event(event, event_data); +#endif /* DEBUG */ + + return 0; +} + /* Convert user's input in hex pattern to byte-size mask */ static int brcmf_c_pattern_atoh(char *src, char *dst) { @@ -120,57 +603,90 @@ static int brcmf_c_pattern_atoh(char *src, char *dst) return i; } -static void -brcmf_c_pktfilter_offload_enable(struct brcmf_if *ifp, char *arg, int enable, - int master_mode) +void +brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, + int master_mode) { unsigned long res; - char *argv; + char *argv[8]; + int i = 0; + const char *str; + int buf_len; + int str_len; char *arg_save = NULL, *arg_org = NULL; - s32 err; + int rc; + char buf[128]; struct brcmf_pkt_filter_enable_le enable_parm; + struct brcmf_pkt_filter_enable_le *pkt_filterp; + __le32 mmode_le; - arg_save = kstrdup(arg, GFP_ATOMIC); + arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) goto fail; arg_org = arg_save; + memcpy(arg_save, arg, strlen(arg) + 1); - argv = strsep(&arg_save, " "); + argv[i] = strsep(&arg_save, " "); - if (argv == NULL) { + i = 0; + if (NULL == argv[i]) { brcmf_dbg(ERROR, "No args provided\n"); goto fail; } + str = "pkt_filter_enable"; + str_len = strlen(str); + strncpy(buf, str, str_len); + buf[str_len] = '\0'; + buf_len = str_len + 1; + + pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1); + /* Parse packet filter id. */ enable_parm.id = 0; - if (!kstrtoul(argv, 0, &res)) + if (!kstrtoul(argv[i], 0, &res)) enable_parm.id = cpu_to_le32((u32)res); - /* Enable/disable the specified filter. */ + /* Parse enable/disable value. */ enable_parm.enable = cpu_to_le32(enable); - err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable", &enable_parm, - sizeof(enable_parm)); - if (err) - brcmf_dbg(ERROR, "Set pkt_filter_enable error (%d)\n", err); + buf_len += sizeof(enable_parm); + memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); - /* Control the master mode */ - err = brcmf_fil_iovar_int_set(ifp, "pkt_filter_mode", master_mode); - if (err) - brcmf_dbg(ERROR, "Set pkt_filter_mode error (%d)\n", err); + /* Enable/disable the specified filter. */ + rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); + rc = rc >= 0 ? 0 : rc; + if (rc) + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); + else + brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); + + /* Contorl the master mode */ + mmode_le = cpu_to_le32(master_mode); + brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf, + sizeof(buf)); + rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, + sizeof(buf)); + rc = rc >= 0 ? 0 : rc; + if (rc) + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); fail: kfree(arg_org); } -static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) +void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) { - struct brcmf_pkt_filter_le *pkt_filter; + const char *str; + struct brcmf_pkt_filter_le pkt_filter; + struct brcmf_pkt_filter_le *pkt_filterp; unsigned long res; int buf_len; - s32 err; + int str_len; + int rc; u32 mask_size; u32 pattern_size; char *argv[8], *buf = NULL; @@ -188,64 +704,104 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) goto fail; argv[i] = strsep(&arg_save, " "); - while (argv[i]) { - i++; - if (i >= 8) { - brcmf_dbg(ERROR, "Too many parameters\n"); - goto fail; - } + while (argv[i++]) argv[i] = strsep(&arg_save, " "); - } - if (i != 6) { - brcmf_dbg(ERROR, "Not enough args provided %d\n", i); + i = 0; + if (NULL == argv[i]) { + brcmf_dbg(ERROR, "No args provided\n"); goto fail; } - pkt_filter = (struct brcmf_pkt_filter_le *)buf; + str = "pkt_filter_add"; + strcpy(buf, str); + str_len = strlen(str); + buf_len = str_len + 1; + + pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1); /* Parse packet filter id. */ - pkt_filter->id = 0; - if (!kstrtoul(argv[0], 0, &res)) - pkt_filter->id = cpu_to_le32((u32)res); + pkt_filter.id = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.id = cpu_to_le32((u32)res); + + if (NULL == argv[++i]) { + brcmf_dbg(ERROR, "Polarity not provided\n"); + goto fail; + } /* Parse filter polarity. */ - pkt_filter->negate_match = 0; - if (!kstrtoul(argv[1], 0, &res)) - pkt_filter->negate_match = cpu_to_le32((u32)res); + pkt_filter.negate_match = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.negate_match = cpu_to_le32((u32)res); + + if (NULL == argv[++i]) { + brcmf_dbg(ERROR, "Filter type not provided\n"); + goto fail; + } /* Parse filter type. */ - pkt_filter->type = 0; - if (!kstrtoul(argv[2], 0, &res)) - pkt_filter->type = cpu_to_le32((u32)res); + pkt_filter.type = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.type = cpu_to_le32((u32)res); + + if (NULL == argv[++i]) { + brcmf_dbg(ERROR, "Offset not provided\n"); + goto fail; + } /* Parse pattern filter offset. */ - pkt_filter->u.pattern.offset = 0; - if (!kstrtoul(argv[3], 0, &res)) - pkt_filter->u.pattern.offset = cpu_to_le32((u32)res); + pkt_filter.u.pattern.offset = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.u.pattern.offset = cpu_to_le32((u32)res); + + if (NULL == argv[++i]) { + brcmf_dbg(ERROR, "Bitmask not provided\n"); + goto fail; + } /* Parse pattern filter mask. */ - mask_size = brcmf_c_pattern_atoh(argv[4], - (char *)pkt_filter->u.pattern.mask_and_pattern); + mask_size = + brcmf_c_pattern_atoh + (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); + + if (NULL == argv[++i]) { + brcmf_dbg(ERROR, "Pattern not provided\n"); + goto fail; + } /* Parse pattern filter pattern. */ - pattern_size = brcmf_c_pattern_atoh(argv[5], - (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]); + pattern_size = + brcmf_c_pattern_atoh(argv[i], + (char *)&pkt_filterp->u.pattern. + mask_and_pattern[mask_size]); if (mask_size != pattern_size) { brcmf_dbg(ERROR, "Mask and pattern not the same size\n"); goto fail; } - pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); - buf_len = offsetof(struct brcmf_pkt_filter_le, - u.pattern.mask_and_pattern); - buf_len += mask_size + pattern_size; + pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size); + buf_len += BRCMF_PKT_FILTER_FIXED_LEN; + buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); + + /* Keep-alive attributes are set in local + * variable (keep_alive_pkt), and + ** then memcpy'ed into buffer (keep_alive_pktp) since there is no + ** guarantee that the buffer is properly aligned. + */ + memcpy((char *)pkt_filterp, + &pkt_filter, + BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); + + rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); + rc = rc >= 0 ? 0 : rc; - err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, - buf_len); - if (err) - brcmf_dbg(ERROR, "Set pkt_filter_add error (%d)\n", err); + if (rc) + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); + else + brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); fail: kfree(arg_org); @@ -253,125 +809,130 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) kfree(buf); } -int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) +static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) { - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - u8 buf[BRCMF_DCMD_SMLEN]; - char *ptr; - s32 err; + char iovbuf[32]; + int retcode; + __le32 arp_mode_le; + + arp_mode_le = cpu_to_le32(arp_mode); + brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf, + sizeof(iovbuf)); + retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); + retcode = retcode >= 0 ? 0 : retcode; + if (retcode) + brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n", + arp_mode, retcode); + else + brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n", + arp_mode); +} + +static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) +{ + char iovbuf[32]; + int retcode; + __le32 arp_enable_le; + + arp_enable_le = cpu_to_le32(arp_enable); + + brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4, + iovbuf, sizeof(iovbuf)); + retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); + retcode = retcode >= 0 ? 0 : retcode; + if (retcode) + brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n", + arp_enable, retcode); + else + brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n", + arp_enable); +} + +int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) +{ + char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for + "event_msgs" + '\0' + bitvec */ + char buf[128], *ptr; + __le32 roaming_le = cpu_to_le32(1); + __le32 bcn_timeout_le = cpu_to_le32(3); + __le32 scan_assoc_time_le = cpu_to_le32(40); + __le32 scan_unassoc_time_le = cpu_to_le32(40); + int i; struct brcmf_bus_dcmd *cmdlst; struct list_head *cur, *q; - /* retreive mac address */ - err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, - sizeof(ifp->mac_addr)); - if (err < 0) { - brcmf_dbg(ERROR, "Retreiving cur_etheraddr failed, %d\n", - err); - goto done; + mutex_lock(&drvr->proto_block); + + /* Set Country code */ + if (drvr->country_code[0] != 0) { + if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY, + drvr->country_code, + sizeof(drvr->country_code)) < 0) + brcmf_dbg(ERROR, "country code setting failed\n"); } - memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); - strcpy(buf, "ver"); - err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); - if (err < 0) { - brcmf_dbg(ERROR, "Retreiving version information failed, %d\n", - err); - goto done; - } - ptr = (char *)buf; + ptr = buf; + brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf)); + brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); strsep(&ptr, "\n"); /* Print fw version info */ brcmf_dbg(ERROR, "Firmware version = %s\n", buf); - /* - * Setup timeout if Beacons are lost and roam is off to report - * link down - */ - err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", - BRCMF_DEFAULT_BCN_TIMEOUT); - if (err) { - brcmf_dbg(ERROR, "bcn_timeout error (%d)\n", err); - goto done; - } + /* Setup timeout if Beacons are lost and roam is off to report + link down */ + brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf, + sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); /* Enable/Disable build-in roaming to allowed ext supplicant to take - * of romaing - */ - err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1); - if (err) { - brcmf_dbg(ERROR, "roam_off error (%d)\n", err); - goto done; - } - - /* Setup event_msgs, enable E_IF */ - err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, - BRCMF_EVENTING_MASK_LEN); - if (err) { - brcmf_dbg(ERROR, "Get event_msgs error (%d)\n", err); - goto done; - } - setbit(eventmask, BRCMF_E_IF); - err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, - BRCMF_EVENTING_MASK_LEN); - if (err) { - brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); - goto done; + of romaing */ + brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); + + /* Setup event_msgs */ + brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); + + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, + (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, + (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le)); + + /* Set and enable ARP offload feature */ + brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); + brcmf_c_arp_offload_enable(drvr, true); + + /* Set up pkt filter */ + for (i = 0; i < drvr->pktfilter_count; i++) { + brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]); + brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i], + 0, true); } - /* Setup default scan channel time */ - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, - BRCMF_DEFAULT_SCAN_CHANNEL_TIME); - if (err) { - brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", - err); - goto done; - } - - /* Setup default scan unassoc time */ - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, - BRCMF_DEFAULT_SCAN_UNASSOC_TIME); - if (err) { - brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", - err); - goto done; - } - - /* Try to set and enable ARP offload feature, this may fail */ - err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE); - if (err) { - brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", - BRCMF_ARPOL_MODE, err); - err = 0; - } else { - err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1); - if (err) { - brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n", - err); - err = 0; - } else - brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n", - BRCMF_ARPOL_MODE); - } - - /* Setup packet filter */ - brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER); - brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, - 0, true); - /* set bus specific command if there is any */ - list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { + list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) { cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); if (cmdlst->name && cmdlst->param && cmdlst->param_len) { - brcmf_fil_iovar_data_set(ifp, cmdlst->name, - cmdlst->param, - cmdlst->param_len); + brcmf_c_mkiovar(cmdlst->name, cmdlst->param, + cmdlst->param_len, iovbuf, + sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); } list_del(cur); kfree(cmdlst); } -done: - return err; + + mutex_unlock(&drvr->proto_block); + + return 0; } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 7e58e8ce9aba..7f89540b56da 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -14,12 +14,16 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -#include +#include +#include +#include #include +#include #include #include #include "dhd.h" +#include "dhd_bus.h" #include "dhd_dbg.h" static struct dentry *root_folder; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index a0e18a1ceb4b..fb508c2256dd 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -27,11 +27,10 @@ #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_GLOM_VAL 0x0400 +#define BRCMF_EVENT_VAL 0x0800 +#define BRCMF_BTA_VAL 0x1000 +#define BRCMF_ISCAN_VAL 0x2000 #if defined(DEBUG) @@ -57,7 +56,6 @@ do { \ #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) -#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) #else /* (defined DEBUG) || (defined DEBUG) */ @@ -69,7 +67,6 @@ do { \ #define BRCMF_BYTES_ON() 0 #define BRCMF_GLOM_ON() 0 #define BRCMF_EVENT_ON() 0 -#define BRCMF_FIL_ON() 0 #endif /* defined(DEBUG) */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index b6c86b046c15..d7c76ce9d8cb 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -16,11 +16,27 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include #include @@ -29,19 +45,45 @@ #include "dhd_proto.h" #include "dhd_dbg.h" #include "wl_cfg80211.h" -#include "fwil.h" MODULE_AUTHOR("Broadcom Corporation"); -MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); -#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ + +/* Interface control information */ +struct brcmf_if { + struct brcmf_pub *drvr; /* back pointer to brcmf_pub */ + /* OS/stack specifics */ + struct net_device *ndev; + struct net_device_stats stats; + int idx; /* iface idx in dongle */ + u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ +}; /* Error bits */ int brcmf_msg_level = BRCMF_ERROR_VAL; module_param(brcmf_msg_level, int, 0); +int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) +{ + int i = BRCMF_MAX_IFS; + struct brcmf_if *ifp; + + if (name == NULL || *name == '\0') + return 0; + + while (--i > 0) { + ifp = drvr->iflist[i]; + if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) + break; + } + + brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); + + return i; /* default - the primary interface */ +} char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) { @@ -63,33 +105,38 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) static void _brcmf_set_multicast_list(struct work_struct *work) { - struct brcmf_if *ifp; struct net_device *ndev; struct netdev_hw_addr *ha; - u32 cmd_value, cnt; + u32 dcmd_value, cnt; __le32 cnt_le; + __le32 dcmd_le_value; + + struct brcmf_dcmd dcmd; char *buf, *bufp; - u32 buflen; - s32 err; + uint buflen; + int ret; - brcmf_dbg(TRACE, "enter\n"); + struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, + multicast_work); - ifp = container_of(work, struct brcmf_if, multicast_work); - ndev = ifp->ndev; + ndev = drvr->iflist[0]->ndev; + cnt = netdev_mc_count(ndev); /* Determine initial value of allmulti flag */ - cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; + dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; /* Send down the multicast list first. */ - cnt = netdev_mc_count(ndev); - buflen = sizeof(cnt) + (cnt * ETH_ALEN); - buf = kmalloc(buflen, GFP_ATOMIC); - if (!buf) + + buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); + bufp = buf = kmalloc(buflen, GFP_ATOMIC); + if (!bufp) return; - bufp = buf; + + strcpy(bufp, "mcast_list"); + bufp += strlen("mcast_list") + 1; cnt_le = cpu_to_le32(cnt); - memcpy(bufp, &cnt_le, sizeof(cnt_le)); + memcpy(bufp, &cnt_le, sizeof(cnt)); bufp += sizeof(cnt_le); netdev_for_each_mc_addr(ha, ndev) { @@ -100,66 +147,129 @@ static void _brcmf_set_multicast_list(struct work_struct *work) cnt--; } - err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); - if (err < 0) { - brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err); - cmd_value = cnt ? true : cmd_value; + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = buflen; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", + brcmf_ifname(drvr, 0), cnt); + dcmd_value = cnt ? true : dcmd_value; } kfree(buf); - /* - * Now send the allmulti setting. This is based on the setting in the + /* Now send the allmulti setting. This is based on the setting in the * net_device flags, but might be modified above to be turned on if we * were trying to set some addresses and dongle rejected it... */ - err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); - if (err < 0) - brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err); - /*Finally, pick up the PROMISC flag */ - cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); - if (err < 0) - brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n", - err); + buflen = sizeof("allmulti") + sizeof(dcmd_value); + buf = kmalloc(buflen, GFP_ATOMIC); + if (!buf) + return; + + dcmd_le_value = cpu_to_le32(dcmd_value); + + if (!brcmf_c_mkiovar + ("allmulti", (void *)&dcmd_le_value, + sizeof(dcmd_le_value), buf, buflen)) { + brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", + brcmf_ifname(drvr, 0), + (int)sizeof(dcmd_value), buflen); + kfree(buf); + return; + } + + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = buflen; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", + brcmf_ifname(drvr, 0), + le32_to_cpu(dcmd_le_value)); + } + + kfree(buf); + + /* Finally, pick up the PROMISC flag as well, like the NIC + driver does */ + + dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false; + dcmd_le_value = cpu_to_le32(dcmd_value); + + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_PROMISC; + dcmd.buf = &dcmd_le_value; + dcmd.len = sizeof(dcmd_le_value); + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set promisc %d failed\n", + brcmf_ifname(drvr, 0), + le32_to_cpu(dcmd_le_value)); + } } static void _brcmf_set_mac_address(struct work_struct *work) { - struct brcmf_if *ifp; - s32 err; + char buf[32]; + struct brcmf_dcmd dcmd; + int ret; - brcmf_dbg(TRACE, "enter\n"); + struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, + setmacaddr_work); - ifp = container_of(work, struct brcmf_if, setmacaddr_work); - err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, - ETH_ALEN); - if (err < 0) { - brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err); - } else { - brcmf_dbg(TRACE, "MAC address updated to %pM\n", - ifp->mac_addr); - memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + brcmf_dbg(TRACE, "enter\n"); + if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, + ETH_ALEN, buf, 32)) { + brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", + brcmf_ifname(drvr, 0)); + return; } + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = 32; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) + brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", + brcmf_ifname(drvr, 0)); + else + memcpy(drvr->iflist[0]->ndev->dev_addr, + drvr->macvalue, ETH_ALEN); + + return; } static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) { struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; struct sockaddr *sa = (struct sockaddr *)addr; - memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); - schedule_work(&ifp->setmacaddr_work); + memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); + schedule_work(&drvr->setmacaddr_work); return 0; } static void brcmf_netdev_set_multicast_list(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; - schedule_work(&ifp->multicast_work); + schedule_work(&drvr->multicast_work); } static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) @@ -172,7 +282,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Reject if down */ if (!drvr->bus_if->drvr_up || - (drvr->bus_if->state != BRCMF_BUS_DATA)) { + (drvr->bus_if->state == BRCMF_BUS_DOWN)) { brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", drvr->bus_if->drvr_up, drvr->bus_if->state); @@ -250,13 +360,32 @@ void brcmf_txflowblock(struct device *dev, bool state) } } -void brcmf_rx_frame(struct device *dev, u8 ifidx, +static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, + void *pktdata, struct brcmf_event_msg *event, + void **data) +{ + int bcmerror = 0; + + bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); + if (bcmerror != 0) + return bcmerror; + + if (drvr->iflist[*ifidx]->ndev) + brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, + event, *data); + + return bcmerror; +} + +void brcmf_rx_frame(struct device *dev, int ifidx, struct sk_buff_head *skb_list) { unsigned char *eth; uint len; + void *data; struct sk_buff *skb, *pnext; struct brcmf_if *ifp; + struct brcmf_event_msg event; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; @@ -303,7 +432,10 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - brcmf_fweh_process_skb(drvr, skb, &ifidx); + if (ntohs(skb->protocol) == ETH_P_LINK_CTL) + brcmf_host_event(drvr, &ifidx, + skb_mac_header(skb), + &event, &data); if (drvr->iflist[ifidx]) { ifp = drvr->iflist[ifidx]; @@ -339,11 +471,9 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); - if (type == ETH_P_PAE) { + if (type == ETH_P_PAE) atomic_dec(&drvr->pend_8021x_cnt); - if (waitqueue_active(&drvr->pend_8021x_wait)) - wake_up(&drvr->pend_8021x_wait); - } + } static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) @@ -367,26 +497,83 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) return &ifp->stats; } -/* - * Set current toe component enables in toe_ol iovar, - * and set toe global enable iovar - */ -static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) +/* Retrieve current toe component enables, which are kept + as a bitmap in toe_ol iovar */ +static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) +{ + struct brcmf_dcmd dcmd; + __le32 toe_le; + char buf[32]; + int ret; + + memset(&dcmd, 0, sizeof(dcmd)); + + dcmd.cmd = BRCMF_C_GET_VAR; + dcmd.buf = buf; + dcmd.len = (uint) sizeof(buf); + dcmd.set = false; + + strcpy(buf, "toe_ol"); + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + /* Check for older dongle image that doesn't support toe_ol */ + if (ret == -EIO) { + brcmf_dbg(ERROR, "%s: toe not supported by device\n", + brcmf_ifname(drvr, ifidx)); + return -EOPNOTSUPP; + } + + brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; + } + + memcpy(&toe_le, buf, sizeof(u32)); + *toe_ol = le32_to_cpu(toe_le); + return 0; +} + +/* Set current toe component enables in toe_ol iovar, + and set toe global enable iovar */ +static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) { - s32 err; + struct brcmf_dcmd dcmd; + char buf[32]; + int ret; + __le32 toe_le = cpu_to_le32(toe_ol); + + memset(&dcmd, 0, sizeof(dcmd)); + + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = (uint) sizeof(buf); + dcmd.set = true; + + /* Set toe_ol as requested */ + strcpy(buf, "toe_ol"); + memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); - err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); - if (err < 0) { - brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err); - return err; + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; } - err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); - if (err < 0) - brcmf_dbg(ERROR, "Setting toe failed, %d\n", err); + /* Enable toe globally only if any components are enabled. */ + toe_le = cpu_to_le32(toe_ol != 0); - return err; + strcpy(buf, "toe"); + memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); + + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; + } + return 0; } static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, @@ -404,9 +591,8 @@ static const struct ethtool_ops brcmf_ethtool_ops = { .get_drvinfo = brcmf_ethtool_get_drvinfo, }; -static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) +static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) { - struct brcmf_pub *drvr = ifp->drvr; struct ethtool_drvinfo info; char drvname[sizeof(info.driver)]; u32 cmd; @@ -443,9 +629,12 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) brcmf_dbg(ERROR, "dongle is not up\n"); return -ENODEV; } + /* finally, report dongle driver type */ - else + else if (drvr->iswl) sprintf(info.driver, "wl"); + else + sprintf(info.driver, "xx"); sprintf(info.version, "%lu", drvr->drv_version); if (copy_to_user(uaddr, &info, sizeof(info))) @@ -457,7 +646,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) /* Get toe offload components from dongle */ case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); + ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -478,7 +667,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) return -EFAULT; /* Read the current settings, update and write back */ - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); + ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -490,16 +679,18 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) else toe_cmpnt &= ~csum_dir; - ret = brcmf_toe_set(ifp, toe_cmpnt); + ret = brcmf_toe_set(drvr, 0, toe_cmpnt); if (ret < 0) return ret; /* If setting TX checksum mode, tell Linux the new mode */ if (cmd == ETHTOOL_STXCSUM) { if (edata.data) - ifp->ndev->features |= NETIF_F_IP_CSUM; + drvr->iflist[0]->ndev->features |= + NETIF_F_IP_CSUM; else - ifp->ndev->features &= ~NETIF_F_IP_CSUM; + drvr->iflist[0]->ndev->features &= + ~NETIF_F_IP_CSUM; } break; @@ -523,23 +714,80 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, return -1; if (cmd == SIOCETHTOOL) - return brcmf_ethtool(ifp, ifr->ifr_data); + return brcmf_ethtool(drvr, ifr->ifr_data); return -EOPNOTSUPP; } +/* called only from within this driver. Sends a command to the dongle. */ +s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) +{ + struct brcmf_dcmd dcmd; + s32 err = 0; + int buflen = 0; + bool is_set_key_cmd; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; + + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = cmd; + dcmd.buf = arg; + dcmd.len = len; + + if (dcmd.buf != NULL) + buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); + + /* send to dongle (must be up, and wl) */ + if ((drvr->bus_if->state != BRCMF_BUS_DATA)) { + brcmf_dbg(ERROR, "DONGLE_DOWN\n"); + err = -EIO; + goto done; + } + + if (!drvr->iswl) { + err = -EIO; + goto done; + } + + /* + * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and + * set key CMD to prevent M4 encryption. + */ + is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) || + ((dcmd.cmd == BRCMF_C_SET_VAR) && + !(strncmp("wsec_key", dcmd.buf, 9))) || + ((dcmd.cmd == BRCMF_C_SET_VAR) && + !(strncmp("bsscfg:wsec_key", dcmd.buf, 15)))); + if (is_set_key_cmd) + brcmf_netdev_wait_pend8021x(ndev); + + err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen); + +done: + if (err > 0) + err = 0; + + return err; +} + +int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd) +{ + brcmf_dbg(TRACE, "enter: cmd %x buf %p len %d\n", + dcmd->cmd, dcmd->buf, dcmd->len); + + return brcmf_exec_dcmd(ndev, dcmd->cmd, dcmd->buf, dcmd->len); +} + static int brcmf_netdev_stop(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; brcmf_dbg(TRACE, "Enter\n"); - + brcmf_cfg80211_down(drvr->config); if (drvr->bus_if->drvr_up == 0) return 0; - brcmf_cfg80211_down(ndev); - /* Set state and stop OS transmissions */ drvr->bus_if->drvr_up = false; netif_stop_queue(ndev); @@ -554,35 +802,38 @@ static int brcmf_netdev_open(struct net_device *ndev) struct brcmf_bus *bus_if = drvr->bus_if; u32 toe_ol; s32 ret = 0; + uint up = 0; brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); - /* If bus is not ready, can't continue */ - if (bus_if->state != BRCMF_BUS_DATA) { - brcmf_dbg(ERROR, "failed bus is not ready\n"); - return -EAGAIN; - } + if (ifp->idx == 0) { /* do it only for primary eth0 */ + /* If bus is not ready, can't continue */ + if (bus_if->state != BRCMF_BUS_DATA) { + brcmf_dbg(ERROR, "failed bus is not ready\n"); + return -EAGAIN; + } - atomic_set(&drvr->pend_8021x_cnt, 0); + atomic_set(&drvr->pend_8021x_cnt, 0); - memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); + memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); - /* 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) - drvr->iflist[ifp->idx]->ndev->features |= - NETIF_F_IP_CSUM; - else - drvr->iflist[ifp->idx]->ndev->features &= - ~NETIF_F_IP_CSUM; + /* Get current TOE mode from dongle */ + if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 + && (toe_ol & TOE_TX_CSUM_OL) != 0) + drvr->iflist[ifp->idx]->ndev->features |= + NETIF_F_IP_CSUM; + else + 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); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); /* Allow transmit calls */ netif_start_queue(ndev); drvr->bus_if->drvr_up = true; - if (brcmf_cfg80211_up(ndev)) { + if (brcmf_cfg80211_up(drvr->config)) { brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); return -1; } @@ -600,38 +851,48 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { .ndo_set_rx_mode = brcmf_netdev_set_multicast_list }; -static const struct net_device_ops brcmf_netdev_ops_virt = { - .ndo_open = brcmf_cfg80211_up, - .ndo_stop = brcmf_cfg80211_down, - .ndo_get_stats = brcmf_netdev_get_stats, - .ndo_do_ioctl = brcmf_netdev_ioctl_entry, - .ndo_start_xmit = brcmf_netdev_start_xmit, - .ndo_set_mac_address = brcmf_netdev_set_mac_address, - .ndo_set_rx_mode = brcmf_netdev_set_multicast_list -}; - -int brcmf_net_attach(struct brcmf_if *ifp) +static int brcmf_net_attach(struct brcmf_if *ifp) { struct brcmf_pub *drvr = ifp->drvr; struct net_device *ndev; + u8 temp_addr[ETH_ALEN]; + + brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); - brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); - ndev = ifp->ndev; + ndev = drvr->iflist[ifp->idx]->ndev; + ndev->netdev_ops = &brcmf_netdev_ops_pri; - /* set appropriate operations */ - if (!ifp->idx) - ndev->netdev_ops = &brcmf_netdev_ops_pri; + /* + * determine mac address to use + */ + if (is_valid_ether_addr(ifp->mac_addr)) + memcpy(temp_addr, ifp->mac_addr, ETH_ALEN); else - ndev->netdev_ops = &brcmf_netdev_ops_virt; + memcpy(temp_addr, drvr->mac, ETH_ALEN); + + if (ifp->idx == 1) { + brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); + /* ACCESSPOINT INTERFACE CASE */ + temp_addr[0] |= 0X02; /* set bit 2 , + - Locally Administered address */ + } ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; ndev->ethtool_ops = &brcmf_ethtool_ops; drvr->rxsz = ndev->mtu + ndev->hard_header_len + drvr->hdrlen; - /* set the mac address */ - memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); + + /* attach to cfg80211 for primary interface */ + if (!ifp->idx) { + drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr); + if (drvr->config == NULL) { + brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); + goto fail; + } + } if (register_netdev(ndev) != 0) { brcmf_dbg(ERROR, "couldn't register the net device\n"); @@ -647,12 +908,13 @@ int brcmf_net_attach(struct brcmf_if *ifp) return -EBADE; } -struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, - char *name, u8 *addr_mask) +int +brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) { struct brcmf_if *ifp; struct net_device *ndev; - int i; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; brcmf_dbg(TRACE, "idx %d\n", ifidx); @@ -662,24 +924,19 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, * in case we missed the BRCMF_E_IF_DEL event. */ if (ifp) { - brcmf_dbg(ERROR, "ERROR: netdev:%s already exists\n", + brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", ifp->ndev->name); - if (ifidx) { - netif_stop_queue(ifp->ndev); - unregister_netdev(ifp->ndev); - free_netdev(ifp->ndev); - drvr->iflist[ifidx] = NULL; - } else { - brcmf_dbg(ERROR, "ignore IF event\n"); - return ERR_PTR(-EINVAL); - } + netif_stop_queue(ifp->ndev); + unregister_netdev(ifp->ndev); + free_netdev(ifp->ndev); + drvr->iflist[ifidx] = NULL; } /* Allocate netdev, including space for private structure */ ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); if (!ndev) { brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } ifp = netdev_priv(ndev); @@ -687,19 +944,20 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, ifp->drvr = drvr; drvr->iflist[ifidx] = ifp; ifp->idx = ifidx; - ifp->bssidx = bssidx; - - INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); - INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); + if (mac_addr != NULL) + memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); - if (addr_mask != NULL) - for (i = 0; i < ETH_ALEN; i++) - ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; + if (brcmf_net_attach(ifp)) { + brcmf_dbg(ERROR, "brcmf_net_attach failed"); + free_netdev(ifp->ndev); + drvr->iflist[ifidx] = NULL; + return -EOPNOTSUPP; + } - brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", - current->pid, ifp->ndev->name, ifp->mac_addr); + brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", + current->pid, ifp->ndev->name); - return ifp; + return 0; } void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) @@ -724,9 +982,6 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) netif_stop_queue(ifp->ndev); } - cancel_work_sync(&ifp->setmacaddr_work); - cancel_work_sync(&ifp->multicast_work); - unregister_netdev(ifp->ndev); drvr->iflist[ifidx] = NULL; if (ifidx == 0) @@ -765,13 +1020,11 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) goto fail; } - /* attach firmware event handler */ - brcmf_fweh_attach(drvr); + INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); + INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); - init_waitqueue_head(&drvr->pend_8021x_wait); - return ret; fail: @@ -783,9 +1036,10 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) int brcmf_bus_start(struct device *dev) { int ret = -1; + /* Room for "event_msgs" + '\0' + bitvec */ + char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; - struct brcmf_if *ifp; brcmf_dbg(TRACE, "\n"); @@ -796,40 +1050,49 @@ int brcmf_bus_start(struct device *dev) return ret; } - /* add primary networking interface */ - ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); - if (IS_ERR(ifp)) - return PTR_ERR(ifp); - - /* signal bus ready */ - bus_if->state = BRCMF_BUS_DATA; - - /* Bus is ready, do any initialization */ - ret = brcmf_c_preinit_dcmds(ifp); + brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf, + sizeof(iovbuf)); + memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); + + setbit(drvr->eventmask, BRCMF_E_SET_SSID); + setbit(drvr->eventmask, BRCMF_E_PRUNE); + setbit(drvr->eventmask, BRCMF_E_AUTH); + setbit(drvr->eventmask, BRCMF_E_REASSOC); + setbit(drvr->eventmask, BRCMF_E_REASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND); + setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_DISASSOC); + setbit(drvr->eventmask, BRCMF_E_JOIN); + setbit(drvr->eventmask, BRCMF_E_ASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_PSK_SUP); + setbit(drvr->eventmask, BRCMF_E_LINK); + setbit(drvr->eventmask, BRCMF_E_NDIS_LINK); + setbit(drvr->eventmask, BRCMF_E_MIC_ERROR); + setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE); + setbit(drvr->eventmask, BRCMF_E_TXFAIL); + setbit(drvr->eventmask, BRCMF_E_JOIN_START); + setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE); + +/* enable dongle roaming event */ + + drvr->pktfilter_count = 1; + /* Setup filter to allow only unicast */ + drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; + + /* Bus is ready, do any protocol initialization */ + ret = brcmf_proto_init(drvr); if (ret < 0) - goto fail; - - drvr->config = brcmf_cfg80211_attach(drvr); - if (drvr->config == NULL) { - ret = -ENOMEM; - goto fail; - } + return ret; - ret = brcmf_fweh_activate_events(ifp); + /* add primary networking interface */ + ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac); if (ret < 0) - goto fail; - - ret = brcmf_net_attach(ifp); -fail: - if (ret < 0) { - brcmf_dbg(ERROR, "failed: %d\n", ret); - if (drvr->config) - brcmf_cfg80211_detach(drvr->config); - free_netdev(drvr->iflist[0]->ndev); - drvr->iflist[0] = NULL; return ret; - } + /* signal bus ready */ + bus_if->state = BRCMF_BUS_DATA; return 0; } @@ -854,11 +1117,6 @@ void brcmf_detach(struct device *dev) brcmf_dbg(TRACE, "Enter\n"); - if (drvr == NULL) - return; - - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS-1; i > -1; i--) @@ -868,6 +1126,8 @@ void brcmf_detach(struct device *dev) brcmf_bus_detach(drvr); if (drvr->prot) { + cancel_work_sync(&drvr->setmacaddr_work); + cancel_work_sync(&drvr->multicast_work); brcmf_proto_detach(drvr); } @@ -881,20 +1141,63 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) return atomic_read(&drvr->pend_8021x_cnt); } +#define MAX_WAIT_FOR_8021X_TX 10 + int brcmf_netdev_wait_pend8021x(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; - int err; + int timeout = 10 * HZ / 1000; + int ntimes = MAX_WAIT_FOR_8021X_TX; + int pend = brcmf_get_pend_8021x_cnt(drvr); + + while (ntimes && pend) { + if (pend) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(timeout); + set_current_state(TASK_RUNNING); + ntimes--; + } + pend = brcmf_get_pend_8021x_cnt(drvr); + } + return pend; +} - err = wait_event_timeout(drvr->pend_8021x_wait, - !brcmf_get_pend_8021x_cnt(drvr), - msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); +#ifdef DEBUG +int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) +{ + int ret = 0; + struct file *fp; + mm_segment_t old_fs; + loff_t pos = 0; + + /* change to KERNEL_DS address limit */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + + /* open file to write */ + fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); + if (!fp) { + brcmf_dbg(ERROR, "open file error\n"); + ret = -1; + goto exit; + } - WARN_ON(!err); + /* Write buf to file */ + fp->f_op->write(fp, (char __user *)buf, size, &pos); - return !err; +exit: + /* free buf before return */ + kfree(buf); + /* close file before return */ + if (fp) + filp_close(fp, NULL); + /* restore previous address limit */ + set_fs(old_fs); + + return ret; } +#endif /* DEBUG */ static void brcmf_driver_init(struct work_struct *work) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 48fa70302192..6bc4425a8b0f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -27,6 +27,11 @@ extern int brcmf_proto_attach(struct brcmf_pub *drvr); /* Unlink, frees allocated protocol memory (including brcmf_proto) */ extern void brcmf_proto_detach(struct brcmf_pub *drvr); +/* Initialize protocol: sync w/dongle state. + * Sets dongle media info (iswl, drv_version, mac address). + */ +extern int brcmf_proto_init(struct brcmf_pub *drvr); + /* Stop protocol: sync w/dongle state. */ extern void brcmf_proto_stop(struct brcmf_pub *drvr); @@ -36,7 +41,13 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, struct sk_buff *txp); -/* Sets dongle media info (drv_version, mac address). */ -extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +/* Use protocol to issue command to dongle */ +extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, + struct brcmf_dcmd *dcmd, int len); + +extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr); + +extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len); #endif /* _BRCMF_PROTO_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 45725454714d..3564686add9a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -533,11 +533,9 @@ struct brcmf_sdio { u8 *rxbuf; /* Buffer for receiving control packets */ uint rxblen; /* Allocated length of rxbuf */ u8 *rxctl; /* Aligned pointer into rxbuf */ - u8 *rxctl_orig; /* pointer for freeing rxctl */ u8 *databuf; /* Buffer for receiving big glom packet */ u8 *dataptr; /* Aligned pointer into databuf */ uint rxlen; /* Length of valid data in buffer */ - spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ u8 sdpcm_ver; /* Bus protocol reported by dongle */ @@ -584,6 +582,8 @@ struct brcmf_sdio { struct list_head dpc_tsklst; spinlock_t dpc_tl_lock; + struct semaphore sdsem; + const struct firmware *firmware; u32 fw_ptr; @@ -614,12 +614,6 @@ static const uint max_roundup = 512; #define ALIGNMENT 4 -enum brcmf_sdio_frmtype { - BRCMF_SDIO_FT_NORMAL, - BRCMF_SDIO_FT_SUPER, - BRCMF_SDIO_FT_SUB, -}; - static void pkt_align(struct sk_buff *p, int len, int align) { uint datalign; @@ -1037,9 +1031,8 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) } } -static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, - struct brcmf_sdio_read *rd, - enum brcmf_sdio_frmtype type) +static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, + struct brcmf_sdio_read *rd) { u16 len, checksum; u8 rx_seq, fc, tx_seq_max; @@ -1054,26 +1047,17 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, /* All zero means no more to read */ if (!(len | checksum)) { bus->rxpending = false; - return -ENODATA; + return false; } if ((u16)(~(len ^ checksum))) { brcmf_dbg(ERROR, "HW header checksum error\n"); bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); - return -EIO; + return false; } if (len < SDPCM_HDRLEN) { brcmf_dbg(ERROR, "HW header length error\n"); - return -EPROTO; - } - if (type == BRCMF_SDIO_FT_SUPER && - (roundup(len, bus->blocksize) != rd->len)) { - brcmf_dbg(ERROR, "HW superframe header length error\n"); - return -EPROTO; - } - if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { - brcmf_dbg(ERROR, "HW subframe header length error\n"); - return -EPROTO; + return false; } rd->len = len; @@ -1087,33 +1071,15 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, * Byte 5: Maximum Sequence number allow for Tx * Byte 6~7: Reserved */ - if (type == BRCMF_SDIO_FT_SUPER && - SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { - brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); - rd->len = 0; - return -EINVAL; - } rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); - if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && - type != BRCMF_SDIO_FT_SUPER) { + if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL) { brcmf_dbg(ERROR, "HW header length too long\n"); bus->sdiodev->bus_if->dstats.rx_errors++; bus->sdcnt.rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); rd->len = 0; - return -EPROTO; - } - if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { - brcmf_dbg(ERROR, "Wrong channel for superframe\n"); - rd->len = 0; - return -EINVAL; - } - if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && - rd->channel != SDPCM_EVENT_CHANNEL) { - brcmf_dbg(ERROR, "Wrong channel for subframe\n"); - rd->len = 0; - return -EINVAL; + return false; } rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { @@ -1121,7 +1087,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); rd->len = 0; - return -ENXIO; + return false; } if (rd->seq_num != rx_seq) { brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", @@ -1129,9 +1095,6 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, bus->sdcnt.rx_badseq++; rd->seq_num = rx_seq; } - /* no need to check the reset for subframe */ - if (type == BRCMF_SDIO_FT_SUB) - return 0; rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { /* only warm for NON glom packet */ @@ -1155,7 +1118,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, } bus->tx_max = tx_seq_max; - return 0; + return true; } static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) @@ -1163,16 +1126,16 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) u16 dlen, totlen; u8 *dptr, num = 0; - u16 sublen; + u16 sublen, check; struct sk_buff *pfirst, *pnext; int errcode; - u8 doff, sfdoff; + u8 chan, seq, doff, sfdoff; + u8 txmax; int ifidx = 0; bool usechain = bus->use_rxchain; - - struct brcmf_sdio_read rd_new; + u16 next_len; /* If packets, issue read(s) and send up packet chain */ /* Return sequence numbers consumed? */ @@ -1272,7 +1235,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) * read directly into the chained packet, or allocate a large * packet and and copy into the chain. */ - sdio_claim_host(bus->sdiodev->func[1]); if (usechain) { errcode = brcmf_sdcard_recv_chain(bus->sdiodev, bus->sdiodev->sbwad, @@ -1294,7 +1256,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen); errcode = -1; } - sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2rxdata++; /* On failure, kill the superframe, allow a couple retries */ @@ -1303,7 +1264,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen, errcode); bus->sdiodev->bus_if->dstats.rx_errors++; - sdio_claim_host(bus->sdiodev->func[1]); if (bus->glomerr++ < 3) { brcmf_sdbrcm_rxfail(bus, true, true); } else { @@ -1312,7 +1272,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } - sdio_release_host(bus->sdiodev->func[1]); return 0; } @@ -1320,17 +1279,68 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->data, min_t(int, pfirst->len, 48), "SUPERFRAME:\n"); - rd_new.seq_num = rxseq; - rd_new.len = dlen; - sdio_claim_host(bus->sdiodev->func[1]); - errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, - BRCMF_SDIO_FT_SUPER); - sdio_release_host(bus->sdiodev->func[1]); - bus->cur_read.len = rd_new.len_nxtfrm << 4; + /* Validate the superframe header */ + dptr = (u8 *) (pfirst->data); + sublen = get_unaligned_le16(dptr); + check = get_unaligned_le16(dptr + sizeof(u16)); + + chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); + seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); + next_len = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; + if ((next_len << 4) > MAX_RX_DATASZ) { + brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n", + next_len, seq); + next_len = 0; + } + bus->cur_read.len = next_len << 4; + doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); + txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); + + errcode = 0; + if ((u16)~(sublen ^ check)) { + brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n", + sublen, check); + errcode = -1; + } else if (roundup(sublen, bus->blocksize) != dlen) { + brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", + sublen, roundup(sublen, bus->blocksize), + dlen); + errcode = -1; + } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != + SDPCM_GLOM_CHANNEL) { + brcmf_dbg(ERROR, "(superframe): bad channel %d\n", + SDPCM_PACKET_CHANNEL( + &dptr[SDPCM_FRAMETAG_LEN])); + errcode = -1; + } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { + brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n"); + errcode = -1; + } else if ((doff < SDPCM_HDRLEN) || + (doff > (pfirst->len - SDPCM_HDRLEN))) { + brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n", + doff, sublen, pfirst->len, SDPCM_HDRLEN); + errcode = -1; + } + + /* Check sequence number of superframe SW header */ + if (rxseq != seq) { + brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", + seq, rxseq); + bus->sdcnt.rx_badseq++; + rxseq = seq; + } + + /* Check window for sanity */ + if ((u8) (txmax - bus->tx_seq) > 0x40) { + brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n", + txmax, bus->tx_seq); + txmax = bus->tx_seq + 2; + } + bus->tx_max = txmax; /* Remove superframe header, remember offset */ - skb_pull(pfirst, rd_new.dat_offset); - sfdoff = rd_new.dat_offset; + skb_pull(pfirst, doff); + sfdoff = doff; num = 0; /* Validate all the subframe headers */ @@ -1339,22 +1349,40 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (errcode) break; - rd_new.len = pnext->len; - rd_new.seq_num = rxseq++; - sdio_claim_host(bus->sdiodev->func[1]); - errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new, - BRCMF_SDIO_FT_SUB); - sdio_release_host(bus->sdiodev->func[1]); + dptr = (u8 *) (pnext->data); + dlen = (u16) (pnext->len); + sublen = get_unaligned_le16(dptr); + check = get_unaligned_le16(dptr + sizeof(u16)); + chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); + doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), - pnext->data, 32, "subframe:\n"); + dptr, 32, "subframe:\n"); + if ((u16)~(sublen ^ check)) { + brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", + num, sublen, check); + errcode = -1; + } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { + brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n", + num, sublen, dlen); + errcode = -1; + } else if ((chan != SDPCM_DATA_CHANNEL) && + (chan != SDPCM_EVENT_CHANNEL)) { + brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n", + num, chan); + errcode = -1; + } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { + brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n", + num, doff, sublen, SDPCM_HDRLEN); + errcode = -1; + } + /* increase the subframe count */ num++; } if (errcode) { /* Terminate frame on error, request a couple retries */ - sdio_claim_host(bus->sdiodev->func[1]); if (bus->glomerr++ < 3) { /* Restore superframe header space */ skb_push(pfirst, sfdoff); @@ -1365,7 +1393,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } - sdio_release_host(bus->sdiodev->func[1]); bus->cur_read.len = 0; return 0; } @@ -1375,11 +1402,27 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) skb_queue_walk_safe(&bus->glom, pfirst, pnext) { dptr = (u8 *) (pfirst->data); sublen = get_unaligned_le16(dptr); + chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); + seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); + brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", + num, pfirst, pfirst->data, + pfirst->len, sublen, chan, seq); + + /* precondition: chan == SDPCM_DATA_CHANNEL || + chan == SDPCM_EVENT_CHANNEL */ + + if (rxseq != seq) { + brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", + seq, rxseq); + bus->sdcnt.rx_badseq++; + rxseq = seq; + } + rxseq++; + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), - dptr, pfirst->len, - "Rx Subframe Data:\n"); + dptr, dlen, "Rx Subframe Data:\n"); __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); @@ -1406,8 +1449,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->prev); } /* sent any remaining packets up */ - if (bus->glom.qlen) + if (bus->glom.qlen) { + up(&bus->sdsem); brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); + down(&bus->sdsem); + } bus->sdcnt.rxglomframes++; bus->sdcnt.rxglompkts += bus->glom.qlen; @@ -1448,24 +1494,21 @@ static void brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) { uint rdlen, pad; - u8 *buf = NULL, *rbuf; + int sdret; brcmf_dbg(TRACE, "Enter\n"); - if (bus->rxblen) - buf = vzalloc(bus->rxblen); - if (!buf) { - brcmf_dbg(ERROR, "no memory for control frame\n"); - goto done; - } - rbuf = bus->rxbuf; - pad = ((unsigned long)rbuf % BRCMF_SDALIGN); + /* Set rxctl for frame (w/optional alignment) */ + bus->rxctl = bus->rxbuf; + bus->rxctl += BRCMF_FIRSTREAD; + pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); if (pad) - rbuf += (BRCMF_SDALIGN - pad); + bus->rxctl += (BRCMF_SDALIGN - pad); + bus->rxctl -= BRCMF_FIRSTREAD; /* Copy the already-read portion over */ - memcpy(buf, hdr, BRCMF_FIRSTREAD); + memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD); if (len <= BRCMF_FIRSTREAD) goto gotpkt; @@ -1502,11 +1545,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) goto done; } - /* Read remain of frame body */ + /* Read remainder of frame body into the rxctl buffer */ sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, - F2SYNC, rbuf, rdlen); + F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); bus->sdcnt.f2rxdata++; /* Control frame failures need retransmission */ @@ -1516,26 +1559,16 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) bus->sdcnt.rxc_errors++; brcmf_sdbrcm_rxfail(bus, true, true); goto done; - } else - memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); + } gotpkt: brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), - buf, len, "RxCtrl:\n"); + bus->rxctl, len, "RxCtrl:\n"); /* Point to valid data and indicate its length */ - spin_lock_bh(&bus->rxctl_lock); - if (bus->rxctl) { - brcmf_dbg(ERROR, "last control frame is being processed.\n"); - spin_unlock_bh(&bus->rxctl_lock); - vfree(buf); - goto done; - } - bus->rxctl = buf + doff; - bus->rxctl_orig = buf; + bus->rxctl += doff; bus->rxlen = len - doff; - spin_unlock_bh(&bus->rxctl_lock); done: /* Awake any waiters */ @@ -1590,7 +1623,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len_left = rd->len; /* read header first for unknow frame length */ - sdio_claim_host(bus->sdiodev->func[1]); if (!rd->len) { sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, @@ -1603,7 +1635,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) sdret); bus->sdcnt.rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); - sdio_release_host(bus->sdiodev->func[1]); continue; } @@ -1611,9 +1642,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n"); - if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd, - BRCMF_SDIO_FT_NORMAL)) { - sdio_release_host(bus->sdiodev->func[1]); + if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd)) { if (!bus->rxpending) break; else @@ -1629,7 +1658,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len_nxtfrm = 0; /* treat all packet as event if we don't know */ rd->channel = SDPCM_EVENT_CHANNEL; - sdio_release_host(bus->sdiodev->func[1]); continue; } rd->len_left = rd->len > BRCMF_FIRSTREAD ? @@ -1647,7 +1675,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) bus->sdiodev->bus_if->dstats.rx_dropped++; brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(rd->channel)); - sdio_release_host(bus->sdiodev->func[1]); continue; } skb_pull(pkt, head_read); @@ -1656,17 +1683,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2rxdata++; - sdio_release_host(bus->sdiodev->func[1]); if (sdret < 0) { brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", rd->len, rd->channel, sdret); brcmu_pkt_buf_free_skb(pkt); bus->sdiodev->bus_if->dstats.rx_errors++; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(rd->channel)); - sdio_release_host(bus->sdiodev->func[1]); continue; } @@ -1677,9 +1701,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } else { memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); rd_new.seq_num = rd->seq_num; - sdio_claim_host(bus->sdiodev->func[1]); - if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, - BRCMF_SDIO_FT_NORMAL)) { + if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new)) { rd->len = 0; brcmu_pkt_buf_free_skb(pkt); } @@ -1690,11 +1712,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) roundup(rd_new.len, 16) >> 4); rd->len = 0; brcmf_sdbrcm_rxfail(bus, true, true); - sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; } - sdio_release_host(bus->sdiodev->func[1]); rd->len_nxtfrm = rd_new.len_nxtfrm; rd->channel = rd_new.channel; rd->dat_offset = rd_new.dat_offset; @@ -1710,9 +1730,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd_new.seq_num); /* Force retry w/normal header read */ rd->len = 0; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, false, true); - sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; } @@ -1735,9 +1753,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } else { brcmf_dbg(ERROR, "%s: glom superframe w/o " "descriptor!\n", __func__); - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, false, false); - sdio_release_host(bus->sdiodev->func[1]); } /* prepare the descriptor for the next read */ rd->len = rd->len_nxtfrm << 4; @@ -1768,7 +1784,10 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) continue; } + /* Unlock during rx call */ + up(&bus->sdsem); brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); + down(&bus->sdsem); } rxcount = maxframes - rxleft; @@ -1785,6 +1804,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) return rxcount; } +static void +brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) +{ + up(&bus->sdsem); + wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); + down(&bus->sdsem); + return; +} + static void brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) { @@ -1886,7 +1914,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, if (len & (ALIGNMENT - 1)) len = roundup(len, ALIGNMENT); - sdio_claim_host(bus->sdiodev->func[1]); ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2txdata++; @@ -1914,14 +1941,15 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, } } - sdio_release_host(bus->sdiodev->func[1]); if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; done: /* restore pkt buffer pointer before calling tx complete routine */ skb_pull(pkt, SDPCM_HDRLEN + pad); + up(&bus->sdsem); brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); + down(&bus->sdsem); if (free_pkt) brcmu_pkt_buf_free_skb(pkt); @@ -1962,11 +1990,9 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { /* Check device status, signal pending interrupt */ - sdio_claim_host(bus->sdiodev->func[1]); ret = r_sdreg32(bus, &intstatus, offsetof(struct sdpcmd_regs, intstatus)); - sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2txdata++; if (ret != 0) break; @@ -2003,7 +2029,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) bus->watchdog_tsk = NULL; } - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* Enable clock for device interrupts */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); @@ -2037,7 +2063,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) /* Turn off the backplane clock (only) */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - sdio_release_host(bus->sdiodev->func[1]); /* Clear the data packet queues */ brcmu_pktq_flush(&bus->txq, true, NULL, NULL); @@ -2048,14 +2073,14 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) brcmf_sdbrcm_free_glom(bus); /* Clear rx control and wake any waiters */ - spin_lock_bh(&bus->rxctl_lock); bus->rxlen = 0; - spin_unlock_bh(&bus->rxctl_lock); brcmf_sdbrcm_dcmd_resp_wake(bus); /* Reset some F2 state stuff */ bus->rxskip = false; bus->tx_seq = bus->rx_seq = 0; + + up(&bus->sdsem); } #ifdef CONFIG_BRCMFMAC_SDIO_OOB @@ -2139,7 +2164,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* If waiting for HTAVAIL, check status */ if (bus->clkstate == CLK_PENDING) { @@ -2193,7 +2218,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) /* Pending interrupt indicates new device status */ if (atomic_read(&bus->ipend) > 0) { atomic_set(&bus->ipend, 0); + sdio_claim_host(bus->sdiodev->func[1]); err = brcmf_sdio_intr_rstatus(bus); + sdio_release_host(bus->sdiodev->func[1]); } /* Start with leftover status bits */ @@ -2222,8 +2249,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) intstatus |= brcmf_sdbrcm_hostmail(bus); } - sdio_release_host(bus->sdiodev->func[1]); - /* Generally don't ask for these, can get CRC errors... */ if (intstatus & I_WR_OOSYNC) { brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); @@ -2270,7 +2295,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) (bus->clkstate == CLK_AVAIL)) { int i; - sdio_claim_host(bus->sdiodev->func[1]); err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, (u32) bus->ctrl_frame_len); @@ -2304,7 +2328,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) } else { bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; } - sdio_release_host(bus->sdiodev->func[1]); bus->ctrl_frame_stat = false; brcmf_sdbrcm_wait_event_wakeup(bus); } @@ -2334,10 +2357,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) if ((bus->clkstate != CLK_PENDING) && bus->idletime == BRCMF_IDLE_IMMEDIATE) { bus->activity = false; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); } + + up(&bus->sdsem); } static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) @@ -2628,10 +2651,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ + /* Need to lock here to protect txseq and SDIO tx calls */ + down(&bus->sdsem); + /* Make sure backplane clock is on */ - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - sdio_release_host(bus->sdiodev->func[1]); /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ *(__le16 *) frame = cpu_to_le16((u16) msglen); @@ -2654,9 +2678,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) bus->ctrl_frame_buf = frame; bus->ctrl_frame_len = len; - wait_event_interruptible_timeout(bus->ctrl_wait, - !bus->ctrl_frame_stat, - msecs_to_jiffies(2000)); + brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); if (!bus->ctrl_frame_stat) { brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); @@ -2675,9 +2697,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) frame, min_t(u16, len, 16), "TxHdr:\n"); do { - sdio_claim_host(bus->sdiodev->func[1]); ret = brcmf_tx_frame(bus, frame, len); - sdio_release_host(bus->sdiodev->func[1]); } while (ret < 0 && retries++ < TXRETRIES); } @@ -2687,13 +2707,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); bus->activity = false; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); - sdio_release_host(bus->sdiodev->func[1]); } else { spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); } + up(&bus->sdsem); + if (ret) bus->sdcnt.tx_ctlerrs++; else @@ -2723,10 +2743,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, * Read last word in socram to determine * address of sdpcm_shared structure */ - sdio_claim_host(bus->sdiodev->func[1]); rv = brcmf_sdbrcm_membytes(bus, false, shaddr, (u8 *)&addr_le, 4); - sdio_claim_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2745,10 +2763,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, } /* Read hndrte_shared structure */ - sdio_claim_host(bus->sdiodev->func[1]); rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, sizeof(struct sdpcm_shared_le)); - sdio_release_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2851,14 +2867,12 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, if ((sh->flags & SDPCM_SHARED_TRAP) == 0) return 0; - sdio_claim_host(bus->sdiodev->func[1]); error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, sizeof(struct brcmf_trap_info)); if (error < 0) return error; nbytes = brcmf_sdio_dump_console(bus, sh, data, count); - sdio_release_host(bus->sdiodev->func[1]); if (nbytes < 0) return nbytes; @@ -2904,7 +2918,6 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, return 0; } - sdio_claim_host(bus->sdiodev->func[1]); if (sh->assert_file_addr != 0) { error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, (u8 *)file, 80); @@ -2917,7 +2930,6 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, if (error < 0) return error; } - sdio_release_host(bus->sdiodev->func[1]); res = scnprintf(buf, sizeof(buf), "dongle assert: %s:%d: assert(%s)\n", @@ -2930,7 +2942,9 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) int error; struct sdpcm_shared sh; + down(&bus->sdsem); error = brcmf_sdio_readshared(bus, &sh); + up(&bus->sdsem); if (error < 0) return error; @@ -2957,6 +2971,7 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, if (pos != 0) return 0; + down(&bus->sdsem); error = brcmf_sdio_readshared(bus, &sh); if (error < 0) goto done; @@ -2973,6 +2988,7 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, error += nbytes; *ppos += error; done: + up(&bus->sdsem); return error; } @@ -3023,7 +3039,6 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) int timeleft; uint rxlen = 0; bool pending; - u8 *buf; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; @@ -3033,15 +3048,11 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) /* Wait until control frame is available */ timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); - spin_lock_bh(&bus->rxctl_lock); + down(&bus->sdsem); rxlen = bus->rxlen; memcpy(msg, bus->rxctl, min(msglen, rxlen)); - bus->rxctl = NULL; - buf = bus->rxctl_orig; - bus->rxctl_orig = NULL; bus->rxlen = 0; - spin_unlock_bh(&bus->rxctl_lock); - vfree(buf); + up(&bus->sdsem); if (rxlen) { brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", @@ -3377,16 +3388,13 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) { bool ret; - sdio_claim_host(bus->sdiodev->func[1]); - + /* Download the firmware */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); ret = _brcmf_sdbrcm_download_firmware(bus) == 0; brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - sdio_release_host(bus->sdiodev->func[1]); - return ret; } @@ -3415,7 +3423,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) bus->sdcnt.tickcnt = 0; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* Make sure backplane clock is on, needed to generate F2 interrupt */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); @@ -3484,7 +3492,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); exit: - sdio_release_host(bus->sdiodev->func[1]); + up(&bus->sdsem); return ret; } @@ -3531,6 +3539,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) brcmf_dbg(TIMER, "Enter\n"); + down(&bus->sdsem); + /* Poll period: check device if appropriate. */ if (bus->poll && (++bus->polltick >= bus->pollrate)) { u32 intstatus = 0; @@ -3547,11 +3557,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) u8 devpend; spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); - sdio_claim_host(bus->sdiodev->func[1]); devpend = brcmf_sdio_regrb(bus->sdiodev, SDIO_CCCR_INTx, NULL); - sdio_release_host(bus->sdiodev->func[1]); intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); @@ -3576,18 +3584,16 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) } #ifdef DEBUG /* Poll for console output periodically */ - if (bus_if && bus_if->state == BRCMF_BUS_DATA && + if (bus_if->state == BRCMF_BUS_DATA && bus->console_interval != 0) { bus->console.count += BRCMF_WD_POLL_MS; if (bus->console.count >= bus->console_interval) { bus->console.count -= bus->console_interval; - sdio_claim_host(bus->sdiodev->func[1]); /* Make sure backplane clock is on */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); if (brcmf_sdbrcm_readconsole(bus) < 0) /* stop on error */ bus->console_interval = 0; - sdio_release_host(bus->sdiodev->func[1]); } } #endif /* DEBUG */ @@ -3600,13 +3606,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->activity = false; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); } else { - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); } } } + up(&bus->sdsem); + return (atomic_read(&bus->ipend) > 0); } @@ -3701,8 +3707,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) bus->alp_only = true; - sdio_claim_host(bus->sdiodev->func[1]); - pr_debug("F1 signature read @0x18000000=0x%4x\n", brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); @@ -3750,8 +3754,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); - sdio_release_host(bus->sdiodev->func[1]); - brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); /* Locate an appropriately-aligned portion of hdrbuf */ @@ -3767,7 +3769,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) return true; fail: - sdio_release_host(bus->sdiodev->func[1]); return false; } @@ -3775,8 +3776,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); - sdio_claim_host(bus->sdiodev->func[1]); - /* Disable F2 to clear any intermediate frame state on the dongle */ brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); @@ -3787,8 +3786,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) /* Done with backplane-dependent accesses, can drop clock... */ brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - sdio_release_host(bus->sdiodev->func[1]); - /* ...and initialize clock/power states */ bus->clkstate = CLK_SDONLY; bus->idletime = BRCMF_IDLE_INTERVAL; @@ -3844,10 +3841,8 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); if (bus->ci) { - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); brcmf_sdio_chip_detach(&bus->ci); if (bus->vars && bus->varsz) kfree(bus->vars); @@ -3867,8 +3862,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) brcmf_sdio_intr_unregister(bus->sdiodev); cancel_work_sync(&bus->datawork); - if (bus->brcmf_wq) - destroy_workqueue(bus->brcmf_wq); + destroy_workqueue(bus->brcmf_wq); if (bus->sdiodev->bus_if->drvr) { brcmf_detach(bus->sdiodev->dev); @@ -3910,29 +3904,31 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->txminmax = BRCMF_TXMINMAX; bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; - INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); - bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); - if (bus->brcmf_wq == NULL) { - brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); - goto fail; - } - /* attempt to attach to the dongle */ if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); goto fail; } - spin_lock_init(&bus->rxctl_lock); spin_lock_init(&bus->txqlock); init_waitqueue_head(&bus->ctrl_wait); init_waitqueue_head(&bus->dcmd_resp_wait); + bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); + if (bus->brcmf_wq == NULL) { + brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); + goto fail; + } + INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); + /* Set up the watchdog timer */ init_timer(&bus->timer); bus->timer.data = (unsigned long)bus; bus->timer.function = brcmf_sdbrcm_watchdog; + /* Initialize thread based operation and lock */ + sema_init(&bus->sdsem, 1); + /* Initialize watchdog thread */ init_completion(&bus->watchdog_wait); bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, @@ -3995,8 +3991,10 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { - brcmf_dbg(ERROR, "dongle is not responding\n"); - goto fail; + if (ret == -ENOLINK) { + brcmf_dbg(ERROR, "dongle is not responding\n"); + goto fail; + } } return bus; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c deleted file mode 100644 index fa8fc4433417..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include - -#include "brcmu_wifi.h" -#include "brcmu_utils.h" - -#include "dhd.h" -#include "dhd_dbg.h" -#include "fweh.h" -#include "fwil.h" - -/** - * struct brcm_ethhdr - broadcom specific ether header. - * - * @subtype: subtype for this packet. - * @length: TODO: length of appended data. - * @version: version indication. - * @oui: OUI of this packet. - * @usr_subtype: subtype for this OUI. - */ -struct brcm_ethhdr { - __be16 subtype; - __be16 length; - u8 version; - u8 oui[3]; - __be16 usr_subtype; -} __packed; - -struct brcmf_event_msg_be { - __be16 version; - __be16 flags; - __be32 event_type; - __be32 status; - __be32 reason; - __be32 auth_type; - __be32 datalen; - u8 addr[ETH_ALEN]; - char ifname[IFNAMSIZ]; - u8 ifidx; - u8 bsscfgidx; -} __packed; - -/** - * struct brcmf_event - contents of broadcom event packet. - * - * @eth: standard ether header. - * @hdr: broadcom specific ether header. - * @msg: common part of the actual event message. - */ -struct brcmf_event { - struct ethhdr eth; - struct brcm_ethhdr hdr; - struct brcmf_event_msg_be msg; -} __packed; - -/** - * struct brcmf_fweh_queue_item - event item on event queue. - * - * @q: list element for queuing. - * @code: event code. - * @ifidx: interface index related to this event. - * @ifaddr: ethernet address for interface. - * @emsg: common parameters of the firmware event message. - * @data: event specific data part of the firmware event. - */ -struct brcmf_fweh_queue_item { - struct list_head q; - enum brcmf_fweh_event_code code; - u8 ifidx; - u8 ifaddr[ETH_ALEN]; - struct brcmf_event_msg_be emsg; - u8 data[0]; -}; - -/** - * struct brcmf_fweh_event_name - code, name mapping entry. - */ -struct brcmf_fweh_event_name { - enum brcmf_fweh_event_code code; - const char *name; -}; - -#ifdef DEBUG -/* array for mapping code to event name */ -static struct brcmf_fweh_event_name fweh_event_names[] = { - { BRCMF_E_SET_SSID, "SET_SSID" }, - { BRCMF_E_JOIN, "JOIN" }, - { BRCMF_E_START, "START" }, - { BRCMF_E_AUTH, "AUTH" }, - { BRCMF_E_AUTH_IND, "AUTH_IND" }, - { BRCMF_E_DEAUTH, "DEAUTH" }, - { BRCMF_E_DEAUTH_IND, "DEAUTH_IND" }, - { BRCMF_E_ASSOC, "ASSOC" }, - { BRCMF_E_ASSOC_IND, "ASSOC_IND" }, - { BRCMF_E_REASSOC, "REASSOC" }, - { BRCMF_E_REASSOC_IND, "REASSOC_IND" }, - { BRCMF_E_DISASSOC, "DISASSOC" }, - { BRCMF_E_DISASSOC_IND, "DISASSOC_IND" }, - { BRCMF_E_QUIET_START, "START_QUIET" }, - { BRCMF_E_QUIET_END, "END_QUIET" }, - { BRCMF_E_BEACON_RX, "BEACON_RX" }, - { BRCMF_E_LINK, "LINK" }, - { BRCMF_E_MIC_ERROR, "MIC_ERROR" }, - { BRCMF_E_NDIS_LINK, "NDIS_LINK" }, - { BRCMF_E_ROAM, "ROAM" }, - { BRCMF_E_TXFAIL, "TXFAIL" }, - { BRCMF_E_PMKID_CACHE, "PMKID_CACHE" }, - { BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, - { BRCMF_E_PRUNE, "PRUNE" }, - { BRCMF_E_AUTOAUTH, "AUTOAUTH" }, - { BRCMF_E_EAPOL_MSG, "EAPOL_MSG" }, - { BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, - { BRCMF_E_ADDTS_IND, "ADDTS_IND" }, - { BRCMF_E_DELTS_IND, "DELTS_IND" }, - { BRCMF_E_BCNSENT_IND, "BCNSENT_IND" }, - { BRCMF_E_BCNRX_MSG, "BCNRX_MSG" }, - { BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG" }, - { BRCMF_E_ROAM_PREP, "ROAM_PREP" }, - { BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND" }, - { BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST" }, - { BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE" }, - { BRCMF_E_JOIN_START, "JOIN_START" }, - { BRCMF_E_ROAM_START, "ROAM_START" }, - { BRCMF_E_ASSOC_START, "ASSOC_START" }, - { BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC" }, - { BRCMF_E_RADIO, "RADIO" }, - { BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, - { BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG" }, - { BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, - { BRCMF_E_PSK_SUP, "PSK_SUP" }, - { BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED" }, - { BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, - { BRCMF_E_ICV_ERROR, "ICV_ERROR" }, - { BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, - { BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, - { BRCMF_E_TRACE, "TRACE" }, - { BRCMF_E_IF, "IF" }, - { BRCMF_E_RSSI, "RSSI" }, - { BRCMF_E_PFN_SCAN_COMPLETE, "PFN_SCAN_COMPLETE" }, - { BRCMF_E_EXTLOG_MSG, "EXTLOG_MSG" }, - { BRCMF_E_ACTION_FRAME, "ACTION_FRAME" }, - { BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, - { BRCMF_E_PRE_ASSOC_IND, "PRE_ASSOC_IND" }, - { BRCMF_E_PRE_REASSOC_IND, "PRE_REASSOC_IND" }, - { BRCMF_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, - { BRCMF_E_AP_STARTED, "AP_STARTED" }, - { BRCMF_E_DFS_AP_STOP, "DFS_AP_STOP" }, - { BRCMF_E_DFS_AP_RESUME, "DFS_AP_RESUME" }, - { BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT" }, - { BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "ACTION_FRM_OFF_CHAN_CMPLT" }, - { BRCMF_E_DCS_REQUEST, "DCS_REQUEST" }, - { BRCMF_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP"} -}; - -/** - * brcmf_fweh_event_name() - returns name for given event code. - * - * @code: code to lookup. - */ -static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -{ - int i; - for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) { - if (fweh_event_names[i].code == code) - return fweh_event_names[i].name; - } - return "unknown"; -} -#else -static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -{ - return "nodebug"; -} -#endif - -/** - * brcmf_fweh_queue_event() - create and queue event. - * - * @fweh: firmware event handling info. - * @event: event queue entry. - */ -static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh, - struct brcmf_fweh_queue_item *event) -{ - ulong flags; - - spin_lock_irqsave(&fweh->evt_q_lock, flags); - list_add_tail(&event->q, &fweh->event_q); - spin_unlock_irqrestore(&fweh->evt_q_lock, flags); - schedule_work(&fweh->event_work); -} - -static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, - enum brcmf_fweh_event_code code, - struct brcmf_event_msg *emsg, - void *data) -{ - struct brcmf_fweh_info *fweh; - int err = -EINVAL; - - if (ifp) { - fweh = &ifp->drvr->fweh; - - /* handle the event if valid interface and handler */ - if (ifp->ndev && fweh->evt_handler[code]) - err = fweh->evt_handler[code](ifp, emsg, data); - else - brcmf_dbg(ERROR, "unhandled event %d ignored\n", code); - } else { - brcmf_dbg(ERROR, "no interface object\n"); - } - return err; -} - -/** - * brcmf_fweh_handle_if_event() - handle IF event. - * - * @drvr: driver information object. - * @item: queue entry. - * @ifpp: interface object (may change upon ADD action). - */ -static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, - struct brcmf_event_msg *emsg, - void *data) -{ - struct brcmf_if_event *ifevent = data; - struct brcmf_if *ifp; - int err = 0; - - brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n", - ifevent->action, ifevent->ifidx, - ifevent->bssidx, ifevent->flags); - - if (ifevent->ifidx >= BRCMF_MAX_IFS) { - brcmf_dbg(ERROR, "invalid interface index: %u\n", - ifevent->ifidx); - return; - } - - ifp = drvr->iflist[ifevent->ifidx]; - - if (ifevent->action == BRCMF_E_IF_ADD) { - brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, - emsg->addr); - ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, - emsg->ifname, emsg->addr); - if (IS_ERR(ifp)) - return; - - if (!drvr->fweh.evt_handler[BRCMF_E_IF]) - err = brcmf_net_attach(ifp); - } - - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); - - if (ifevent->action == BRCMF_E_IF_DEL) - brcmf_del_if(drvr, ifevent->ifidx); -} - -/** - * brcmf_fweh_dequeue_event() - get event from the queue. - * - * @fweh: firmware event handling info. - */ -static struct brcmf_fweh_queue_item * -brcmf_fweh_dequeue_event(struct brcmf_fweh_info *fweh) -{ - struct brcmf_fweh_queue_item *event = NULL; - ulong flags; - - spin_lock_irqsave(&fweh->evt_q_lock, flags); - if (!list_empty(&fweh->event_q)) { - event = list_first_entry(&fweh->event_q, - struct brcmf_fweh_queue_item, q); - list_del(&event->q); - } - spin_unlock_irqrestore(&fweh->evt_q_lock, flags); - - return event; -} - -/** - * brcmf_fweh_event_worker() - firmware event worker. - * - * @work: worker object. - */ -static void brcmf_fweh_event_worker(struct work_struct *work) -{ - struct brcmf_pub *drvr; - struct brcmf_if *ifp; - struct brcmf_fweh_info *fweh; - struct brcmf_fweh_queue_item *event; - int err = 0; - struct brcmf_event_msg_be *emsg_be; - struct brcmf_event_msg emsg; - - fweh = container_of(work, struct brcmf_fweh_info, event_work); - drvr = container_of(fweh, struct brcmf_pub, fweh); - - while ((event = brcmf_fweh_dequeue_event(fweh))) { - ifp = drvr->iflist[event->ifidx]; - - brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n", - brcmf_fweh_event_name(event->code), event->code, - event->emsg.ifidx, event->emsg.bsscfgidx, - event->emsg.addr); - - /* convert event message */ - emsg_be = &event->emsg; - emsg.version = be16_to_cpu(emsg_be->version); - emsg.flags = be16_to_cpu(emsg_be->flags); - emsg.event_code = event->code; - emsg.status = be32_to_cpu(emsg_be->status); - emsg.reason = be32_to_cpu(emsg_be->reason); - emsg.auth_type = be32_to_cpu(emsg_be->auth_type); - emsg.datalen = be32_to_cpu(emsg_be->datalen); - memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); - memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); - emsg.ifidx = emsg_be->ifidx; - emsg.bsscfgidx = emsg_be->bsscfgidx; - - brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", - emsg.version, emsg.flags, emsg.status, emsg.reason); - brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, - min_t(u32, emsg.datalen, 64), - "appended:"); - - /* special handling of interface event */ - if (event->code == BRCMF_E_IF) { - brcmf_fweh_handle_if_event(drvr, &emsg, event->data); - goto event_free; - } - - err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, - event->data); - if (err) { - brcmf_dbg(ERROR, "event handler failed (%d)\n", - event->code); - err = 0; - } -event_free: - kfree(event); - } -} - -/** - * brcmf_fweh_attach() - initialize firmware event handling. - * - * @drvr: driver information object. - */ -void brcmf_fweh_attach(struct brcmf_pub *drvr) -{ - struct brcmf_fweh_info *fweh = &drvr->fweh; - INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); - spin_lock_init(&fweh->evt_q_lock); - INIT_LIST_HEAD(&fweh->event_q); -} - -/** - * brcmf_fweh_detach() - cleanup firmware event handling. - * - * @drvr: driver information object. - */ -void brcmf_fweh_detach(struct brcmf_pub *drvr) -{ - struct brcmf_fweh_info *fweh = &drvr->fweh; - struct brcmf_if *ifp = drvr->iflist[0]; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - - if (ifp) { - /* clear all events */ - memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); - (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", - eventmask, - BRCMF_EVENTING_MASK_LEN); - } - /* cancel the worker */ - cancel_work_sync(&fweh->event_work); - WARN_ON(!list_empty(&fweh->event_q)); - memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); -} - -/** - * brcmf_fweh_register() - register handler for given event code. - * - * @drvr: driver information object. - * @code: event code. - * @handler: handler for the given event code. - */ -int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, - brcmf_fweh_handler_t handler) -{ - if (drvr->fweh.evt_handler[code]) { - brcmf_dbg(ERROR, "event code %d already registered\n", code); - return -ENOSPC; - } - drvr->fweh.evt_handler[code] = handler; - brcmf_dbg(TRACE, "event handler registered for %s\n", - brcmf_fweh_event_name(code)); - return 0; -} - -/** - * brcmf_fweh_unregister() - remove handler for given code. - * - * @drvr: driver information object. - * @code: event code. - */ -void brcmf_fweh_unregister(struct brcmf_pub *drvr, - enum brcmf_fweh_event_code code) -{ - brcmf_dbg(TRACE, "event handler cleared for %s\n", - brcmf_fweh_event_name(code)); - drvr->fweh.evt_handler[code] = NULL; -} - -/** - * brcmf_fweh_activate_events() - enables firmware events registered. - * - * @ifp: primary interface object. - */ -int brcmf_fweh_activate_events(struct brcmf_if *ifp) -{ - int i, err; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - - for (i = 0; i < BRCMF_E_LAST; i++) { - if (ifp->drvr->fweh.evt_handler[i]) { - brcmf_dbg(EVENT, "enable event %s\n", - brcmf_fweh_event_name(i)); - setbit(eventmask, i); - } - } - - /* want to handle IF event as well */ - brcmf_dbg(EVENT, "enable event IF\n"); - setbit(eventmask, BRCMF_E_IF); - - err = brcmf_fil_iovar_data_set(ifp, "event_msgs", - eventmask, BRCMF_EVENTING_MASK_LEN); - if (err) - brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); - - return err; -} - -/** - * brcmf_fweh_process_event() - process skb as firmware event. - * - * @drvr: driver information object. - * @event_packet: event packet to process. - * @ifidx: index of the firmware interface (may change). - * - * If the packet buffer contains a firmware event message it will - * dispatch the event to a registered handler (using worker). - */ -void brcmf_fweh_process_event(struct brcmf_pub *drvr, - struct brcmf_event *event_packet, u8 *ifidx) -{ - enum brcmf_fweh_event_code code; - struct brcmf_fweh_info *fweh = &drvr->fweh; - struct brcmf_fweh_queue_item *event; - gfp_t alloc_flag = GFP_KERNEL; - void *data; - u32 datalen; - - /* get event info */ - code = get_unaligned_be32(&event_packet->msg.event_type); - datalen = get_unaligned_be32(&event_packet->msg.datalen); - *ifidx = event_packet->msg.ifidx; - data = &event_packet[1]; - - if (code >= BRCMF_E_LAST) - return; - - if (code != BRCMF_E_IF && !fweh->evt_handler[code]) - return; - - if (in_interrupt()) - alloc_flag = GFP_ATOMIC; - - event = kzalloc(sizeof(*event) + datalen, alloc_flag); - if (!event) - return; - - event->code = code; - event->ifidx = *ifidx; - - /* use memcpy to get aligned event message */ - memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); - memcpy(event->data, data, datalen); - memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); - - brcmf_fweh_queue_event(fweh, event); -} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h deleted file mode 100644 index b39246a630df..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifndef FWEH_H_ -#define FWEH_H_ - -#include -#include -#include -#include - -/* formward declarations */ -struct brcmf_pub; -struct brcmf_if; -struct brcmf_cfg80211_info; -struct brcmf_event; - -/* firmware event codes sent by the dongle */ -enum brcmf_fweh_event_code { - BRCMF_E_SET_SSID = 0, - BRCMF_E_JOIN = 1, - BRCMF_E_START = 2, - BRCMF_E_AUTH = 3, - BRCMF_E_AUTH_IND = 4, - BRCMF_E_DEAUTH = 5, - BRCMF_E_DEAUTH_IND = 6, - BRCMF_E_ASSOC = 7, - BRCMF_E_ASSOC_IND = 8, - BRCMF_E_REASSOC = 9, - BRCMF_E_REASSOC_IND = 10, - BRCMF_E_DISASSOC = 11, - BRCMF_E_DISASSOC_IND = 12, - BRCMF_E_QUIET_START = 13, - BRCMF_E_QUIET_END = 14, - BRCMF_E_BEACON_RX = 15, - BRCMF_E_LINK = 16, - BRCMF_E_MIC_ERROR = 17, - BRCMF_E_NDIS_LINK = 18, - BRCMF_E_ROAM = 19, - BRCMF_E_TXFAIL = 20, - BRCMF_E_PMKID_CACHE = 21, - BRCMF_E_RETROGRADE_TSF = 22, - BRCMF_E_PRUNE = 23, - BRCMF_E_AUTOAUTH = 24, - BRCMF_E_EAPOL_MSG = 25, - BRCMF_E_SCAN_COMPLETE = 26, - BRCMF_E_ADDTS_IND = 27, - BRCMF_E_DELTS_IND = 28, - BRCMF_E_BCNSENT_IND = 29, - BRCMF_E_BCNRX_MSG = 30, - BRCMF_E_BCNLOST_MSG = 31, - BRCMF_E_ROAM_PREP = 32, - BRCMF_E_PFN_NET_FOUND = 33, - BRCMF_E_PFN_NET_LOST = 34, - BRCMF_E_RESET_COMPLETE = 35, - BRCMF_E_JOIN_START = 36, - BRCMF_E_ROAM_START = 37, - BRCMF_E_ASSOC_START = 38, - BRCMF_E_IBSS_ASSOC = 39, - BRCMF_E_RADIO = 40, - BRCMF_E_PSM_WATCHDOG = 41, - BRCMF_E_PROBREQ_MSG = 44, - BRCMF_E_SCAN_CONFIRM_IND = 45, - BRCMF_E_PSK_SUP = 46, - BRCMF_E_COUNTRY_CODE_CHANGED = 47, - BRCMF_E_EXCEEDED_MEDIUM_TIME = 48, - BRCMF_E_ICV_ERROR = 49, - BRCMF_E_UNICAST_DECODE_ERROR = 50, - BRCMF_E_MULTICAST_DECODE_ERROR = 51, - BRCMF_E_TRACE = 52, - BRCMF_E_IF = 54, - BRCMF_E_RSSI = 56, - BRCMF_E_PFN_SCAN_COMPLETE = 57, - BRCMF_E_EXTLOG_MSG = 58, - BRCMF_E_ACTION_FRAME = 59, - BRCMF_E_ACTION_FRAME_COMPLETE = 60, - BRCMF_E_PRE_ASSOC_IND = 61, - BRCMF_E_PRE_REASSOC_IND = 62, - BRCMF_E_CHANNEL_ADOPTED = 63, - BRCMF_E_AP_STARTED = 64, - BRCMF_E_DFS_AP_STOP = 65, - BRCMF_E_DFS_AP_RESUME = 66, - BRCMF_E_ESCAN_RESULT = 69, - BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70, - BRCMF_E_DCS_REQUEST = 73, - BRCMF_E_FIFO_CREDIT_MAP = 74, - BRCMF_E_LAST -}; - -/* flags field values in struct brcmf_event_msg */ -#define BRCMF_EVENT_MSG_LINK 0x01 -#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 -#define BRCMF_EVENT_MSG_GROUP 0x04 - -/** - * definitions for event packet validation. - */ -#define BRCMF_EVENT_OUI_OFFSET 19 -#define BRCM_OUI "\x00\x10\x18" -#define DOT11_OUI_LEN 3 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 - - -/** - * struct brcmf_event_msg - firmware event message. - * - * @version: version information. - * @flags: event flags. - * @event_code: firmware event code. - * @status: status information. - * @reason: reason code. - * @auth_type: authentication type. - * @datalen: lenght of event data buffer. - * @addr: ether address. - * @ifname: interface name. - * @ifidx: interface index. - * @bsscfgidx: bsscfg index. - */ -struct brcmf_event_msg { - u16 version; - u16 flags; - u32 event_code; - u32 status; - u32 reason; - s32 auth_type; - u32 datalen; - u8 addr[ETH_ALEN]; - char ifname[IFNAMSIZ]; - u8 ifidx; - u8 bsscfgidx; -}; - -typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data); - -/** - * struct brcmf_fweh_info - firmware event handling information. - * - * @event_work: event worker. - * @evt_q_lock: lock for event queue protection. - * @event_q: event queue. - * @evt_handler: registered event handlers. - */ -struct brcmf_fweh_info { - struct work_struct event_work; - struct spinlock evt_q_lock; - struct list_head event_q; - int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data); -}; - -void brcmf_fweh_attach(struct brcmf_pub *drvr); -void brcmf_fweh_detach(struct brcmf_pub *drvr); -int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, - int (*handler)(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data)); -void brcmf_fweh_unregister(struct brcmf_pub *drvr, - enum brcmf_fweh_event_code code); -int brcmf_fweh_activate_events(struct brcmf_if *ifp); -void brcmf_fweh_process_event(struct brcmf_pub *drvr, - struct brcmf_event *event_packet, u8 *ifidx); - -static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, - struct sk_buff *skb, u8 *ifidx) -{ - struct brcmf_event *event_packet; - u8 *data; - u16 usr_stype; - - /* only process events when protocol matches */ - if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) - return; - - /* check for BRCM oui match */ - event_packet = (struct brcmf_event *)skb_mac_header(skb); - data = (u8 *)event_packet; - data += BRCMF_EVENT_OUI_OFFSET; - if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) - return; - - /* final match on usr_subtype */ - data += DOT11_OUI_LEN; - usr_stype = get_unaligned_be16(data); - if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) - return; - - brcmf_fweh_process_event(drvr, event_packet, ifidx); -} - -#endif /* FWEH_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c deleted file mode 100644 index 51a14505197a..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* FWIL is the Firmware Interface Layer. In this module the support functions - * are located to set and get variables to and from the firmware. - */ - -#include -#include -#include -#include -#include "dhd.h" -#include "dhd_bus.h" -#include "dhd_dbg.h" -#include "fwil.h" - - -#define MAX_HEX_DUMP_LEN 64 - - -static s32 -brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) -{ - struct brcmf_pub *drvr = ifp->drvr; - s32 err; - - if (drvr->bus_if->state != BRCMF_BUS_DATA) { - brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); - return -EIO; - } - - if (data != NULL) - len = min_t(uint, len, BRCMF_DCMD_MAXLEN); - if (set) - err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len); - else - err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data, - len); - - if (err >= 0) - err = 0; - else - brcmf_dbg(ERROR, "Failed err=%d\n", err); - - return err; -} - -s32 -brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) -{ - s32 err; - - mutex_lock(&ifp->drvr->proto_block); - - brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); - mutex_unlock(&ifp->drvr->proto_block); - - return err; -} - -s32 -brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) -{ - s32 err; - - mutex_lock(&ifp->drvr->proto_block); - err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); - - brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - mutex_unlock(&ifp->drvr->proto_block); - - return err; -} - - -s32 -brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data) -{ - s32 err; - __le32 data_le = cpu_to_le32(data); - - mutex_lock(&ifp->drvr->proto_block); - err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true); - mutex_unlock(&ifp->drvr->proto_block); - - return err; -} - -s32 -brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data) -{ - s32 err; - __le32 data_le = cpu_to_le32(*data); - - mutex_lock(&ifp->drvr->proto_block); - err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false); - mutex_unlock(&ifp->drvr->proto_block); - *data = le32_to_cpu(data_le); - - return err; -} - -static u32 -brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen) -{ - u32 len; - - len = strlen(name) + 1; - - if ((len + datalen) > buflen) - return 0; - - memcpy(buf, name, len); - - /* append data onto the end of the name string */ - if (data && datalen) - memcpy(&buf[len], data, datalen); - - return len + datalen; -} - - -s32 -brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, - u32 len) -{ - struct brcmf_pub *drvr = ifp->drvr; - s32 err; - u32 buflen; - - mutex_lock(&drvr->proto_block); - - brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, - sizeof(drvr->proto_buf)); - if (buflen) { - err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf, - buflen, true); - } else { - err = -EPERM; - brcmf_dbg(ERROR, "Creating iovar failed\n"); - } - - mutex_unlock(&drvr->proto_block); - return err; -} - -s32 -brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, - u32 len) -{ - struct brcmf_pub *drvr = ifp->drvr; - s32 err; - u32 buflen; - - mutex_lock(&drvr->proto_block); - - buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, - sizeof(drvr->proto_buf)); - if (buflen) { - err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, - buflen, false); - if (err == 0) - memcpy(data, drvr->proto_buf, len); - } else { - err = -EPERM; - brcmf_dbg(ERROR, "Creating iovar failed\n"); - } - - brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - mutex_unlock(&drvr->proto_block); - return err; -} - -s32 -brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data) -{ - __le32 data_le = cpu_to_le32(data); - - return brcmf_fil_iovar_data_set(ifp, name, &data_le, sizeof(data_le)); -} - -s32 -brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data) -{ - __le32 data_le = cpu_to_le32(*data); - s32 err; - - err = brcmf_fil_iovar_data_get(ifp, name, &data_le, sizeof(data_le)); - if (err == 0) - *data = le32_to_cpu(data_le); - return err; -} - -static u32 -brcmf_create_bsscfg(s32 bssidx, char *name, char *data, u32 datalen, char *buf, - u32 buflen) -{ - const s8 *prefix = "bsscfg:"; - s8 *p; - u32 prefixlen; - u32 namelen; - u32 iolen; - __le32 bssidx_le; - - if (bssidx == 0) - return brcmf_create_iovar(name, data, datalen, buf, buflen); - - prefixlen = strlen(prefix); - namelen = strlen(name) + 1; /* lengh of iovar name + null */ - iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen; - - if (buflen < iolen) { - brcmf_dbg(ERROR, "buffer is too short\n"); - return 0; - } - - p = buf; - - /* copy prefix, no null */ - memcpy(p, prefix, prefixlen); - p += prefixlen; - - /* copy iovar name including null */ - memcpy(p, name, namelen); - p += namelen; - - /* bss config index as first data */ - bssidx_le = cpu_to_le32(bssidx); - memcpy(p, &bssidx_le, sizeof(bssidx_le)); - p += sizeof(bssidx_le); - - /* parameter buffer follows */ - if (datalen) - memcpy(p, data, datalen); - - return iolen; -} - -s32 -brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, - void *data, u32 len) -{ - struct brcmf_pub *drvr = ifp->drvr; - s32 err; - u32 buflen; - - mutex_lock(&drvr->proto_block); - - brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, - drvr->proto_buf, sizeof(drvr->proto_buf)); - if (buflen) { - err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf, - buflen, true); - } else { - err = -EPERM; - brcmf_dbg(ERROR, "Creating bsscfg failed\n"); - } - - mutex_unlock(&drvr->proto_block); - return err; -} - -s32 -brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, - void *data, u32 len) -{ - struct brcmf_pub *drvr = ifp->drvr; - s32 err; - u32 buflen; - - mutex_lock(&drvr->proto_block); - - buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, - drvr->proto_buf, sizeof(drvr->proto_buf)); - if (buflen) { - err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, - buflen, false); - if (err == 0) - memcpy(data, drvr->proto_buf, len); - } else { - err = -EPERM; - brcmf_dbg(ERROR, "Creating bsscfg failed\n"); - } - brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); - - mutex_unlock(&drvr->proto_block); - return err; - -} - -s32 -brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data) -{ - __le32 data_le = cpu_to_le32(data); - - return brcmf_fil_bsscfg_data_set(ifp, name, &data_le, - sizeof(data_le)); -} - -s32 -brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data) -{ - __le32 data_le = cpu_to_le32(*data); - s32 err; - - err = brcmf_fil_bsscfg_data_get(ifp, name, &data_le, - sizeof(data_le)); - if (err == 0) - *data = le32_to_cpu(data_le); - return err; -} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.h deleted file mode 100644 index 16eb8202fb1e..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _fwil_h_ -#define _fwil_h_ - -s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); -s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); -s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); -s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data); - -s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, - u32 len); -s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, - u32 len); -s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data); -s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data); - -s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, void *data, - u32 len); -s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, void *data, - u32 len); -s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data); -s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data); - -#endif /* _fwil_h_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 39a5baa92f21..a2b4b1e71017 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -14,12 +14,24 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include @@ -30,11 +42,14 @@ #define IOCTL_RESP_TIMEOUT 2000 -#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ -#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 +#define BRCMF_USB_SYNC_TIMEOUT 300 /* ms */ +#define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ +#define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle has boot up */ +#define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */ + #define BRCMF_USB_NRXQ 50 #define BRCMF_USB_NTXQ 50 @@ -55,6 +70,16 @@ #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" +enum usbdev_suspend_state { + USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow + suspend */ + USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be + * suspended. Wating PM to + * suspend the device + */ + USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ +}; + struct brcmf_usb_image { struct list_head list; s8 *fwname; @@ -75,8 +100,10 @@ struct brcmf_usbdev_info { struct list_head rx_postq; struct list_head tx_freeq; struct list_head tx_postq; + enum usbdev_suspend_state suspend_state; uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; + bool activity; int rx_low_watermark; int tx_low_watermark; int tx_high_watermark; @@ -89,6 +116,10 @@ struct brcmf_usbdev_info { u8 *image; /* buffer for combine fw and nvram */ int image_len; + wait_queue_head_t wait; + bool waitdone; + int sync_urb_status; + struct usb_device *usbdev; struct device *dev; @@ -100,6 +131,7 @@ struct brcmf_usbdev_info { int ctl_urb_status; int ctl_completed; wait_queue_head_t ioctl_resp_wait; + wait_queue_head_t ctrl_wait; ulong ctl_op; struct urb *bulk_urb; /* used for FW download */ @@ -144,7 +176,6 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) static void brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) { - brcmf_dbg(USB, "Enter, status=%d\n", status); if (unlikely(devinfo == NULL)) return; @@ -172,7 +203,6 @@ brcmf_usb_ctlread_complete(struct urb *urb) struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - brcmf_dbg(USB, "Enter\n"); devinfo->ctl_urb_actual_length = urb->actual_length; brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, urb->status); @@ -184,22 +214,33 @@ brcmf_usb_ctlwrite_complete(struct urb *urb) struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - brcmf_dbg(USB, "Enter\n"); brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, urb->status); } +static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state) +{ + return 0; +} + static int brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; - brcmf_dbg(USB, "Enter\n"); if (devinfo == NULL || buf == NULL || len == 0 || devinfo->ctl_urb == NULL) return -EINVAL; + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + + devinfo->activity = true; size = len; devinfo->ctl_write.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; @@ -227,7 +268,6 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) int ret; u16 size; - brcmf_dbg(USB, "Enter\n"); if ((devinfo == NULL) || (buf == NULL) || (len == 0) || (devinfo->ctl_urb == NULL)) return -EINVAL; @@ -261,9 +301,10 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; + } if (test_and_set_bit(0, &devinfo->ctl_op)) return -EIO; @@ -290,10 +331,10 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; - + } if (test_and_set_bit(0, &devinfo->ctl_op)) return -EIO; @@ -418,8 +459,6 @@ static void brcmf_usb_tx_complete(struct urb *urb) struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; struct brcmf_usbdev_info *devinfo = req->devinfo; - brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, - req->skb); brcmf_usb_del_fromq(devinfo, req); if (urb->status == 0) devinfo->bus_pub.bus->dstats.tx_packets++; @@ -445,7 +484,6 @@ static void brcmf_usb_rx_complete(struct urb *urb) struct sk_buff *skb; 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; @@ -459,7 +497,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) return; } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { skb_put(skb, urb->actual_length); if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { brcmf_dbg(ERROR, "rx protocol error\n"); @@ -512,8 +550,8 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo) { struct brcmf_usbreq *req; - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { - brcmf_dbg(ERROR, "bus is not up=%d\n", devinfo->bus_pub.state); + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + brcmf_dbg(ERROR, "bus is not up\n"); return; } while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) @@ -526,24 +564,29 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; int old_state; - brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", - devinfo->bus_pub.state, state); if (devinfo->bus_pub.state == state) return; old_state = devinfo->bus_pub.state; - devinfo->bus_pub.state = state; + brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", + old_state, state); + + /* Don't update state if it's PnP firmware re-download */ + if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */ + devinfo->bus_pub.state = state; + + if ((old_state == BCMFMAC_USB_STATE_SLEEP) + && (state == BCMFMAC_USB_STATE_UP)) { + brcmf_usb_rx_fill_all(devinfo); + } /* update state of upper layer */ - if (state == BRCMFMAC_USB_STATE_DOWN) { - brcmf_dbg(USB, "DBUS is down\n"); + if (state == BCMFMAC_USB_STATE_DOWN) { + brcmf_dbg(INFO, "DBUS is down\n"); bcmf_bus->state = BRCMF_BUS_DOWN; - } else if (state == BRCMFMAC_USB_STATE_UP) { - brcmf_dbg(USB, "DBUS is up\n"); - bcmf_bus->state = BRCMF_BUS_DATA; } else { - brcmf_dbg(USB, "DBUS current state=%d\n", state); + brcmf_dbg(INFO, "DBUS current state=%d\n", state); } } @@ -552,32 +595,30 @@ brcmf_usb_intr_complete(struct urb *urb) { struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - int err; - - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); + bool killed; if (devinfo == NULL) return; if (unlikely(urb->status)) { - if (urb->status == -ENOENT || - urb->status == -ESHUTDOWN || - urb->status == -ENODEV) { - brcmf_usb_state_change(devinfo, - BRCMFMAC_USB_STATE_DOWN); + if (devinfo->suspend_state == + USBOS_SUSPEND_STATE_SUSPEND_PENDING) + killed = true; + + if ((urb->status == -ENOENT && (!killed)) + || urb->status == -ESHUTDOWN || + urb->status == -ENODEV) { + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); } } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) { + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); return; } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { - err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); - if (err) - brcmf_dbg(ERROR, "usb_submit_urb, err=%d\n", err); - } + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) + usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); } static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) @@ -586,9 +627,10 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) struct brcmf_usbreq *req; int ret; - brcmf_dbg(USB, "Enter, skb=%p\n", skb); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; + } req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, &devinfo->tx_freecount); @@ -628,16 +670,25 @@ static int brcmf_usb_up(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); u16 ifnum; - int ret; - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) return 0; + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + } + devinfo->activity = true; + /* Success, indicate devinfo is fully up */ - brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP); + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); if (devinfo->intr_urb) { + int ret; + usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, devinfo->intr_pipe, &devinfo->intr, @@ -682,14 +733,14 @@ static void brcmf_usb_down(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); if (devinfo == NULL) return; - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) + brcmf_dbg(TRACE, "enter\n"); + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) return; - brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); if (devinfo->intr_urb) usb_kill_urb(devinfo->intr_urb); @@ -703,14 +754,34 @@ static void brcmf_usb_down(struct device *dev) brcmf_usb_free_q(&devinfo->rx_postq, true); } +static int +brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time) +{ + int ret; + int err = 0; + int ms = time; + + ret = wait_event_interruptible_timeout(devinfo->wait, + devinfo->waitdone == true, (ms * HZ / 1000)); + + if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) { + brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n", + ret, devinfo->sync_urb_status); + err = -EINVAL; + } + devinfo->waitdone = false; + return err; +} + static void brcmf_usb_sync_complete(struct urb *urb) { struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - devinfo->ctl_completed = true; - brcmf_usb_ioctl_resp_wake(devinfo); + devinfo->waitdone = true; + wake_up_interruptible(&devinfo->wait); + devinfo->sync_urb_status = urb->status; } static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, @@ -742,7 +813,6 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, (void *) tmpbuf, size, (usb_complete_t)brcmf_usb_sync_complete, devinfo); - devinfo->ctl_completed = false; ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); if (ret < 0) { brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); @@ -750,11 +820,11 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, return false; } - ret = brcmf_usb_ioctl_resp_wait(devinfo); + ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); memcpy(buffer, tmpbuf, buflen); kfree(tmpbuf); - return ret; + return (ret == 0); } static bool @@ -763,25 +833,27 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) struct bootrom_id_le id; u32 chipid, chiprev; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return false; /* Check if firmware downloaded already by querying runtime ID */ id.chip = cpu_to_le32(0xDEAD); - brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); chipid = le32_to_cpu(id.chip); chiprev = le32_to_cpu(id.chiprev); if ((chipid & 0x4300) == 0x4300) - brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev); + brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); else - brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev); + brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); if (chipid == BRCMF_POSTBOOT_ID) { - brcmf_dbg(USB, "firmware already downloaded\n"); - brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); + brcmf_dbg(INFO, "firmware already downloaded\n"); + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); return false; } else { devinfo->bus_pub.devid = chipid; @@ -794,29 +866,38 @@ static int brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) { struct bootrom_id_le id; - u32 loop_cnt; + u16 wait = 0, wait_time; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); + + if (devinfo == NULL) + return -EINVAL; - loop_cnt = 0; - do { - mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); - loop_cnt++; + /* Give dongle chance to boot */ + wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; + while (wait < BRCMF_USB_DLIMAGE_LIMIT) { + mdelay(wait_time); + wait += wait_time; id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ - brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) break; - } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); + } if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { - brcmf_dbg(USB, "postboot chip 0x%x/rev 0x%x\n", - le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); + brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", + wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); - brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); + + /* XXX this wait may not be necessary */ + mdelay(BRCMF_USB_RESETCFG_SPINWAIT); return 0; } else { brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", - BRCMF_USB_RESET_GETVER_SPINWAIT * loop_cnt); + wait); return -EINVAL; } } @@ -837,14 +918,13 @@ brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len) devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET; - devinfo->ctl_completed = false; ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC); if (ret) { brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); return ret; } - ret = brcmf_usb_ioctl_resp_wait(devinfo); - return (ret == 0); + ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); + return ret; } static int @@ -855,8 +935,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) struct rdl_state_le state; u32 rdlstate, rdlbytes; int err = 0; - - brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); + brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); if (bulkchunk == NULL) { @@ -931,7 +1010,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) fail: kfree(bulkchunk); - brcmf_dbg(USB, "Exit, err=%d\n", err); + brcmf_dbg(TRACE, "err=%d\n", err); return err; } @@ -939,7 +1018,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) { int err; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return -EINVAL; @@ -949,10 +1028,10 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) err = brcmf_usb_dl_writeimage(devinfo, fw, len); if (err == 0) - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_DONE; + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; else - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_FAIL; - brcmf_dbg(USB, "Exit, err=%d\n", err); + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; + brcmf_dbg(TRACE, "exit: err=%d\n", err); return err; } @@ -961,7 +1040,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) { struct rdl_state_le state; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (!devinfo) return -EINVAL; @@ -984,7 +1063,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) brcmf_dbg(ERROR, "Dongle not runnable\n"); return -EINVAL; } - brcmf_dbg(USB, "Exit\n"); + brcmf_dbg(TRACE, "exit\n"); return 0; } @@ -1011,7 +1090,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) int devid, chiprev; int err; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return -ENODEV; @@ -1039,7 +1118,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) { - brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); + brcmf_dbg(TRACE, "devinfo %p\n", devinfo); /* free the URBS */ brcmf_usb_free_q(&devinfo->rx_freeq, false); @@ -1074,7 +1153,6 @@ static int check_file(const u8 *headers) struct trx_header_le *trx; int actual_len = -1; - brcmf_dbg(USB, "Enter\n"); /* Extract trx header */ trx = (struct trx_header_le *) headers; if (trx->magic != cpu_to_le32(TRX_MAGIC)) @@ -1096,7 +1174,6 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) struct brcmf_usb_image *fw_image; int err; - brcmf_dbg(USB, "Enter\n"); switch (devinfo->bus_pub.devid) { case 43143: fwname = BRCMF_USB_43143_FW_NAME; @@ -1113,7 +1190,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) return -EINVAL; break; } - brcmf_dbg(USB, "Loading FW %s\n", fwname); + list_for_each_entry(fw_image, &fw_image_list, list) { if (fw_image->fwname == fwname) { devinfo->image = fw_image->image; @@ -1158,13 +1235,10 @@ static struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, int nrxq, int ntxq) { - brcmf_dbg(USB, "Enter\n"); - devinfo->bus_pub.nrxq = nrxq; devinfo->rx_low_watermark = nrxq / 2; devinfo->bus_pub.devinfo = devinfo; devinfo->bus_pub.ntxq = ntxq; - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN; /* flow control when too many tx urbs posted */ devinfo->tx_low_watermark = ntxq / 4; @@ -1210,10 +1284,11 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, goto error; } + init_waitqueue_head(&devinfo->wait); if (!brcmf_usb_dlneeded(devinfo)) return &devinfo->bus_pub; - brcmf_dbg(USB, "Start fw downloading\n"); + brcmf_dbg(TRACE, "start fw downloading\n"); if (brcmf_usb_get_fw(devinfo)) goto error; @@ -1228,14 +1303,14 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, return NULL; } -static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) +static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, + const char *desc, u32 bustype, u32 hdrlen) { struct brcmf_bus *bus = NULL; struct brcmf_usbdev *bus_pub = NULL; int ret; struct device *dev = devinfo->dev; - brcmf_dbg(USB, "Enter\n"); bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); if (!bus_pub) return -ENODEV; @@ -1252,18 +1327,19 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->brcmf_bus_stop = brcmf_usb_down; bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; + bus->type = bustype; bus->bus_priv.usb = bus_pub; dev_set_drvdata(dev, bus); /* Attach to the common driver interface */ - ret = brcmf_attach(0, dev); + ret = brcmf_attach(hdrlen, dev); if (ret) { - brcmf_dbg(ERROR, "brcmf_attach failed\n"); + brcmf_dbg(ERROR, "dhd_attach failed\n"); goto fail; } ret = brcmf_bus_start(dev); - if (ret) { + if (ret == -ENOLINK) { brcmf_dbg(ERROR, "dongle is not responding\n"); brcmf_detach(dev); goto fail; @@ -1282,7 +1358,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) { if (!devinfo) return; - brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); + brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo); brcmf_detach(devinfo->dev); kfree(devinfo->bus_pub.bus); @@ -1300,7 +1376,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) u8 endpoint_num; struct brcmf_usbdev_info *devinfo; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); if (devinfo == NULL) @@ -1401,11 +1477,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; if (usb->speed == USB_SPEED_HIGH) - brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); + brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); else - brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); + brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); - ret = brcmf_usb_probe_cb(devinfo); + ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0); if (ret) goto fail; @@ -1425,55 +1501,40 @@ brcmf_usb_disconnect(struct usb_interface *intf) { struct brcmf_usbdev_info *devinfo; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); brcmf_usb_disconnect_cb(devinfo); kfree(devinfo); - brcmf_dbg(USB, "Exit\n"); } /* - * only need to signal the bus being down and update the state. + * only need to signal the bus being down and update the suspend state. */ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) { struct usb_device *usb = interface_to_usbdev(intf); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - brcmf_dbg(USB, "Enter\n"); - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; - brcmf_detach(&usb->dev); + brcmf_dbg(TRACE, "enter\n"); + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; + devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; return 0; } /* - * (re-) start the bus. + * mark suspend state active and crank up the bus. */ static int brcmf_usb_resume(struct usb_interface *intf) { struct usb_device *usb = interface_to_usbdev(intf); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - brcmf_dbg(USB, "Enter\n"); - if (!brcmf_attach(0, devinfo->dev)) - return brcmf_bus_start(&usb->dev); - + brcmf_dbg(TRACE, "enter\n"); + devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; + brcmf_bus_start(&usb->dev); return 0; } -static int brcmf_usb_reset_resume(struct usb_interface *intf) -{ - struct usb_device *usb = interface_to_usbdev(intf); - struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - - brcmf_dbg(USB, "Enter\n"); - - if (!brcmf_usb_fw_download(devinfo)) - return brcmf_usb_resume(intf); - - return -EIO; -} - #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c #define BRCMF_USB_DEVICE_ID_43143 0xbd1e #define BRCMF_USB_DEVICE_ID_43236 0xbd17 @@ -1493,6 +1554,7 @@ MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); +/* TODO: suspend and resume entries */ static struct usb_driver brcmf_usbdrvr = { .name = KBUILD_MODNAME, .probe = brcmf_usb_probe, @@ -1500,7 +1562,6 @@ static struct usb_driver brcmf_usbdrvr = { .id_table = brcmf_usb_devid_table, .suspend = brcmf_usb_suspend, .resume = brcmf_usb_resume, - .reset_resume = brcmf_usb_reset_resume, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, }; @@ -1518,14 +1579,12 @@ static void brcmf_release_fw(struct list_head *q) void brcmf_usb_exit(void) { - brcmf_dbg(USB, "Enter\n"); usb_deregister(&brcmf_usbdrvr); brcmf_release_fw(&fw_image_list); } void brcmf_usb_init(void) { - brcmf_dbg(USB, "Enter\n"); INIT_LIST_HEAD(&fw_image_list); usb_register(&brcmf_usbdrvr); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h index f483a8c9945b..acfa5e89872f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h @@ -17,11 +17,19 @@ #define BRCMFMAC_USB_H enum brcmf_usb_state { - BRCMFMAC_USB_STATE_DOWN, - BRCMFMAC_USB_STATE_DL_FAIL, - BRCMFMAC_USB_STATE_DL_DONE, - BRCMFMAC_USB_STATE_UP, - BRCMFMAC_USB_STATE_SLEEP + BCMFMAC_USB_STATE_DL_PENDING, + BCMFMAC_USB_STATE_DL_DONE, + BCMFMAC_USB_STATE_UP, + BCMFMAC_USB_STATE_DOWN, + BCMFMAC_USB_STATE_PNP_FWDL, + BCMFMAC_USB_STATE_DISCONNECT, + BCMFMAC_USB_STATE_SLEEP +}; + +enum brcmf_usb_pnp_state { + BCMFMAC_USB_PNP_DISCONNECT, + BCMFMAC_USB_PNP_SLEEP, + BCMFMAC_USB_PNP_RESUME, }; struct brcmf_stats { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 769c134c6618..c1abaa6db59e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -19,7 +19,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include +#include +#include +#include +#include #include +#include +#include #include #include @@ -28,7 +35,6 @@ #include #include "dhd.h" #include "wl_cfg80211.h" -#include "fwil.h" #define BRCMF_SCAN_IE_LEN_MAX 2048 #define BRCMF_PNO_VERSION 2 @@ -42,8 +48,6 @@ #define BRCMF_PNO_SCAN_COMPLETE 1 #define BRCMF_PNO_SCAN_INCOMPLETE 0 -#define BRCMF_IFACE_MAX_CNT 2 - #define TLV_LEN_OFF 1 /* length offset */ #define TLV_HDR_LEN 2 /* header length */ #define TLV_BODY_OFF 2 /* body offset */ @@ -87,13 +91,16 @@ #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) +static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; + static u32 brcmf_dbg_level = WL_DBG_ERR; -static bool check_vif_up(struct brcmf_cfg80211_vif *vif) +static bool check_sys_up(struct wiphy *wiphy) { - if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { - WL_INFO("device is not ready : status (%lu)\n", - vif->sme_state); + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + if (!test_bit(WL_STATUS_READY, &cfg->status)) { + WL_INFO("device is not ready : status (%d)\n", + (int)cfg->status); return false; } return true; @@ -384,29 +391,55 @@ static u8 brcmf_mw_to_qdbm(u16 mw) return qdbm; } -static u16 channel_to_chanspec(struct ieee80211_channel *ch) +/* function for reading/writing a single u32 from/to the dongle */ +static int +brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par) { - u16 chanspec; + int err; + __le32 par_le = cpu_to_le32(*par); - chanspec = ieee80211_frequency_to_channel(ch->center_freq); - chanspec &= WL_CHANSPEC_CHAN_MASK; + err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32)); + *par = le32_to_cpu(par_le); - if (ch->band == IEEE80211_BAND_2GHZ) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; + return err; +} - if (ch->flags & IEEE80211_CHAN_NO_HT40) { - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - } else { - chanspec |= WL_CHANSPEC_BW_40; - if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS) - chanspec |= WL_CHANSPEC_CTL_SB_LOWER; - else - chanspec |= WL_CHANSPEC_CTL_SB_UPPER; - } - return chanspec; +static s32 +brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name, + void *param, s32 paramlen, + void *buf, s32 buflen, s32 bssidx) +{ + s32 err = -ENOMEM; + u32 len; + + len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, + buf, buflen, bssidx); + BUG_ON(!len); + if (len > 0) + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len); + if (err) + WL_ERR("error (%d)\n", err); + + return err; +} + +static s32 +brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name, + void *param, s32 paramlen, + void *buf, s32 buflen, s32 bssidx) +{ + s32 err = -ENOMEM; + u32 len; + + len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, + buf, buflen, bssidx); + BUG_ON(!len); + if (len > 0) + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len); + if (err) + WL_ERR("error (%d)\n", err); + + return err; } static void convert_key_from_CPU(struct brcmf_wsec_key *key, @@ -424,17 +457,18 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key, } static int -send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key) +send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx, + struct net_device *ndev, struct brcmf_wsec_key *key) { int err; struct brcmf_wsec_key_le key_le; convert_key_from_CPU(key, &key_le); - brcmf_netdev_wait_pend8021x(ndev); - - err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le, - sizeof(key_le)); + err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, + sizeof(key_le), + cfg->extra_buf, + WL_EXTRA_BUF_MAX, bssidx); if (err) WL_ERR("wsec_key error (%d)\n", err); @@ -446,7 +480,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); s32 infra = 0; s32 ap = 0; @@ -478,11 +511,17 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, } if (ap) { - set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); + set_bit(WL_STATUS_AP_CREATING, &cfg->status); + if (!cfg->ap_info) + cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), + GFP_KERNEL); + if (!cfg->ap_info) { + err = -ENOMEM; + goto done; + } WL_INFO("IF Type = AP\n"); } else { - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), - BRCMF_C_SET_INFRA, infra); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); if (err) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); err = -EAGAIN; @@ -500,13 +539,99 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, return err; } +static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val) +{ + s8 buf[BRCMF_DCMD_SMLEN]; + u32 len; + s32 err = 0; + __le32 val_le; + + val_le = cpu_to_le32(val); + len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf, + sizeof(buf)); + BUG_ON(!len); + + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len); + if (err) + WL_ERR("error (%d)\n", err); + + return err; +} + +static s32 +brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval) +{ + union { + s8 buf[BRCMF_DCMD_SMLEN]; + __le32 val; + } var; + u32 len; + u32 data_null; + s32 err = 0; + + len = + brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), + sizeof(var.buf)); + BUG_ON(!len); + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len); + if (err) + WL_ERR("error (%d)\n", err); + + *retval = le32_to_cpu(var.val); + + return err; +} + +static s32 +brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val, + s32 bssidx) +{ + s8 buf[BRCMF_DCMD_SMLEN]; + __le32 val_le; + + val_le = cpu_to_le32(val); + + return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le, + sizeof(val_le), buf, sizeof(buf), + bssidx); +} + +static s32 +brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val, + s32 bssidx) +{ + s8 buf[BRCMF_DCMD_SMLEN]; + s32 err; + __le32 val_le; + + memset(buf, 0, sizeof(buf)); + err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf, + sizeof(buf), bssidx); + if (err == 0) { + memcpy(&val_le, buf, sizeof(val_le)); + *val = le32_to_cpu(val_le); + } + return err; +} + + +/* + * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this + * should return the ndev matching bssidx. + */ +static s32 +brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev) +{ + return 0; +} + static void brcmf_set_mpc(struct net_device *ndev, int mpc) { - struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); - if (check_vif_up(ifp->vif)) { - err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc); + if (test_bit(WL_STATUS_READY, &cfg->status)) { + err = brcmf_dev_intvar_set(ndev, "mpc", mpc); if (err) { WL_ERR("fail to set mpc\n"); return; @@ -515,6 +640,209 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc) } } +static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, + struct brcmf_ssid *ssid) +{ + memcpy(params_le->bssid, ether_bcast, ETH_ALEN); + params_le->bss_type = DOT11_BSSTYPE_ANY; + params_le->scan_type = 0; + params_le->channel_num = 0; + params_le->nprobes = cpu_to_le32(-1); + params_le->active_time = cpu_to_le32(-1); + params_le->passive_time = cpu_to_le32(-1); + params_le->home_time = cpu_to_le32(-1); + if (ssid && ssid->SSID_len) { + params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len); + memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len); + } +} + +static s32 +brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param, + s32 paramlen, void *bufptr, s32 buflen) +{ + s32 iolen; + + iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen); + BUG_ON(!iolen); + + return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen); +} + +static s32 +brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param, + s32 paramlen, void *bufptr, s32 buflen) +{ + s32 iolen; + + iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen); + BUG_ON(!iolen); + + return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen); +} + +static s32 +brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, + struct brcmf_ssid *ssid, u16 action) +{ + s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + + offsetof(struct brcmf_iscan_params_le, params_le); + struct brcmf_iscan_params_le *params; + s32 err = 0; + + if (ssid && ssid->SSID_len) + params_size += sizeof(struct brcmf_ssid); + params = kzalloc(params_size, GFP_KERNEL); + if (!params) + return -ENOMEM; + BUG_ON(params_size >= BRCMF_DCMD_SMLEN); + + brcmf_iscan_prep(¶ms->params_le, ssid); + + params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); + params->action = cpu_to_le16(action); + params->scan_duration = cpu_to_le16(0); + + err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size, + iscan->dcmd_buf, BRCMF_DCMD_SMLEN); + if (err) { + if (err == -EBUSY) + WL_INFO("system busy : iscan canceled\n"); + else + WL_ERR("error (%d)\n", err); + } + + kfree(params); + return err; +} + +static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + struct net_device *ndev = cfg_to_ndev(cfg); + struct brcmf_ssid ssid; + __le32 passive_scan; + s32 err = 0; + + /* Broadcast scan by default */ + memset(&ssid, 0, sizeof(ssid)); + + iscan->state = WL_ISCAN_STATE_SCANING; + + passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); + err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN, + &passive_scan, sizeof(passive_scan)); + if (err) { + WL_ERR("error (%d)\n", err); + return err; + } + brcmf_set_mpc(ndev, 0); + cfg->iscan_kickstart = true; + err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); + if (err) { + brcmf_set_mpc(ndev, 1); + cfg->iscan_kickstart = false; + return err; + } + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + return err; +} + +static s32 +brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request, + struct cfg80211_ssid *this_ssid) +{ + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct cfg80211_ssid *ssids; + struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; + __le32 passive_scan; + bool iscan_req; + bool spec_scan; + s32 err = 0; + u32 SSID_len; + + if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("Scanning already : status (%lu)\n", cfg->status); + return -EAGAIN; + } + if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { + WL_ERR("Scanning being aborted : status (%lu)\n", + cfg->status); + return -EAGAIN; + } + if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { + WL_ERR("Connecting : status (%lu)\n", + cfg->status); + return -EAGAIN; + } + + iscan_req = false; + spec_scan = false; + if (request) { + /* scan bss */ + ssids = request->ssids; + if (cfg->iscan_on && (!ssids || !ssids->ssid_len)) + iscan_req = true; + } else { + /* scan in ibss */ + /* we don't do iscan in ibss */ + ssids = this_ssid; + } + + cfg->scan_request = request; + set_bit(WL_STATUS_SCANNING, &cfg->status); + if (iscan_req) { + err = brcmf_do_iscan(cfg); + if (!err) + return err; + else + goto scan_out; + } else { + WL_SCAN("ssid \"%s\", ssid_len (%d)\n", + ssids->ssid, ssids->ssid_len); + memset(&sr->ssid_le, 0, sizeof(sr->ssid_le)); + SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len); + sr->ssid_le.SSID_len = cpu_to_le32(0); + if (SSID_len) { + memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len); + sr->ssid_le.SSID_len = cpu_to_le32(SSID_len); + spec_scan = true; + } else { + WL_SCAN("Broadcast scan\n"); + } + + passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, + &passive_scan, sizeof(passive_scan)); + if (err) { + WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); + goto scan_out; + } + brcmf_set_mpc(ndev, 0); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le, + sizeof(sr->ssid_le)); + if (err) { + if (err == -EBUSY) + WL_INFO("system busy : scan for \"%s\" " + "canceled\n", sr->ssid_le.SSID); + else + WL_ERR("WLC_SCAN error (%d)\n", err); + + brcmf_set_mpc(ndev, 1); + goto scan_out; + } + } + + return 0; + +scan_out: + clear_bit(WL_STATUS_SCANNING, &cfg->status); + cfg->scan_request = NULL; + return err; +} + static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, struct cfg80211_scan_request *request) { @@ -523,10 +851,12 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, s32 i; s32 offset; u16 chanspec; + u16 channel; + struct ieee80211_channel *req_channel; char *ptr; struct brcmf_ssid_le ssid_le; - memset(params_le->bssid, 0xFF, ETH_ALEN); + memcpy(params_le->bssid, ether_bcast, ETH_ALEN); params_le->bss_type = DOT11_BSSTYPE_ANY; params_le->scan_type = 0; params_le->channel_num = 0; @@ -546,9 +876,30 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels); if (n_channels > 0) { for (i = 0; i < n_channels; i++) { - chanspec = channel_to_chanspec(request->channels[i]); + chanspec = 0; + req_channel = request->channels[i]; + channel = ieee80211_frequency_to_channel( + req_channel->center_freq); + if (req_channel->band == IEEE80211_BAND_2GHZ) + chanspec |= WL_CHANSPEC_BAND_2G; + else + chanspec |= WL_CHANSPEC_BAND_5G; + + if (req_channel->flags & IEEE80211_CHAN_NO_HT40) { + chanspec |= WL_CHANSPEC_BW_20; + chanspec |= WL_CHANSPEC_CTL_SB_NONE; + } else { + chanspec |= WL_CHANSPEC_BW_40; + if (req_channel->flags & + IEEE80211_CHAN_NO_HT40PLUS) + chanspec |= WL_CHANSPEC_CTL_SB_LOWER; + else + chanspec |= WL_CHANSPEC_CTL_SB_UPPER; + } + + chanspec |= (channel & WL_CHANSPEC_CHAN_MASK); WL_SCAN("Chan : %d, Channel spec: %x\n", - request->channels[i]->hw_value, chanspec); + channel, chanspec); params_le->channel_list[i] = cpu_to_le16(chanspec); } } else { @@ -615,7 +966,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, /* Do a scan abort to stop the driver's scan engine */ WL_SCAN("ABORT scan in firmware\n"); memset(¶ms_le, 0, sizeof(params_le)); - memset(params_le.bssid, 0xFF, ETH_ALEN); + memcpy(params_le.bssid, ether_bcast, ETH_ALEN); params_le.bss_type = DOT11_BSSTYPE_ANY; params_le.scan_type = 0; params_le.channel_num = cpu_to_le32(1); @@ -626,8 +977,8 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, /* Scan is aborted by setting channel_list[0] to -1 */ params_le.channel_list[0] = cpu_to_le16(-1); /* E-Scan (or anyother type) can be aborted by SCAN */ - err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN, - ¶ms_le, sizeof(params_le)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, ¶ms_le, + sizeof(params_le)); if (err) WL_ERR("Scan abort failed\n"); } @@ -647,7 +998,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, cfg80211_scan_done(scan_request, aborted); brcmf_set_mpc(ndev, 1); } - if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { WL_ERR("Scan complete while device not scanning\n"); return -EPERM; } @@ -685,8 +1036,8 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, params->action = cpu_to_le16(action); params->sync_id = cpu_to_le16(0x1234); - err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan", - params, params_size); + err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size, + cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN); if (err) { if (err == -EBUSY) WL_INFO("system busy : escan canceled\n"); @@ -704,16 +1055,16 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) { s32 err; - u32 passive_scan; + __le32 passive_scan; struct brcmf_scan_results *results; WL_SCAN("Enter\n"); cfg->escan_info.ndev = ndev; cfg->escan_info.wiphy = wiphy; cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); + passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, + &passive_scan, sizeof(passive_scan)); if (err) { WL_ERR("error (%d)\n", err); return err; @@ -735,11 +1086,10 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid) { - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); struct cfg80211_ssid *ssids; - struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int; - u32 passive_scan; + struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; + __le32 passive_scan; bool escan_req; bool spec_scan; s32 err; @@ -747,17 +1097,18 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, WL_SCAN("START ESCAN\n"); - if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { - WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); + if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("Scanning already : status (%lu)\n", cfg->status); return -EAGAIN; } - if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { - WL_ERR("Scanning being aborted: status (%lu)\n", - cfg->scan_status); + if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { + WL_ERR("Scanning being aborted : status (%lu)\n", + cfg->status); return -EAGAIN; } - if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { - WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); + if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { + WL_ERR("Connecting : status (%lu)\n", + cfg->status); return -EAGAIN; } @@ -777,10 +1128,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, } cfg->scan_request = request; - set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + set_bit(WL_STATUS_SCANNING, &cfg->status); if (escan_req) { err = brcmf_do_escan(cfg, wiphy, ndev, request); - if (err) + if (!err) + return err; + else goto scan_out; } else { WL_SCAN("ssid \"%s\", ssid_len (%d)\n", @@ -796,16 +1149,16 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, } else WL_SCAN("Broadcast scan\n"); - passive_scan = cfg->active_scan ? 0 : 1; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, - passive_scan); + passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, + &passive_scan, sizeof(passive_scan)); if (err) { WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); goto scan_out; } brcmf_set_mpc(ndev, 0); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, - &sr->ssid_le, sizeof(sr->ssid_le)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le, + sizeof(sr->ssid_le)); if (err) { if (err == -EBUSY) WL_INFO("BUSY: scan for \"%s\" canceled\n", @@ -821,7 +1174,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, return 0; scan_out: - clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + clear_bit(WL_STATUS_SCANNING, &cfg->status); if (timer_pending(&cfg->escan_timeout)) del_timer_sync(&cfg->escan_timeout); cfg->scan_request = NULL; @@ -829,18 +1182,22 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, } static s32 -brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) +brcmf_cfg80211_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) { struct net_device *ndev = request->wdev->netdev; + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(container_of(request->wdev, - struct brcmf_cfg80211_vif, wdev))) + if (!check_sys_up(wiphy)) return -EIO; - err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); + if (cfg->iscan_on) + err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL); + else if (cfg->escan_on) + err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); if (err) WL_ERR("scan error (%d)\n", err); @@ -853,8 +1210,7 @@ static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) { s32 err = 0; - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh", - rts_threshold); + err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold); if (err) WL_ERR("Error (%d)\n", err); @@ -865,8 +1221,7 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) { s32 err = 0; - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh", - frag_threshold); + err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold); if (err) WL_ERR("Error (%d)\n", err); @@ -876,9 +1231,9 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) { s32 err = 0; - u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); + u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); + err = brcmf_exec_dcmd_u32(ndev, cmd, &retry); if (err) { WL_ERR("cmd (%d) , error (%d)\n", cmd, err); return err; @@ -890,11 +1245,10 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct net_device *ndev = cfg_to_ndev(cfg); - struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; if (changed & WIPHY_PARAM_RTS_THRESHOLD && @@ -973,8 +1327,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_info *cfg) if (cfg->link_up) { ndev = cfg_to_ndev(cfg); WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); - err = brcmf_fil_cmd_data_set(netdev_priv(ndev), - BRCMF_C_DISASSOC, NULL, 0); + err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0); if (err) WL_ERR("WLC_DISASSOC failed (%d)\n", err); cfg->link_up = false; @@ -987,8 +1340,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_join_params join_params; size_t join_params_size = 0; s32 err = 0; @@ -996,7 +1348,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, s32 bcnprd; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; if (params->ssid) @@ -1006,7 +1358,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, return -EOPNOTSUPP; } - set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); + set_bit(WL_STATUS_CONNECTING, &cfg->status); if (params->bssid) WL_CONN("BSSID: %pM\n", params->bssid); @@ -1047,7 +1399,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, if (params->privacy) wsec |= WEP_ENABLED; - err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec); + err = brcmf_dev_intvar_set(ndev, "wsec", wsec); if (err) { WL_ERR("wsec failed (%d)\n", err); goto done; @@ -1059,7 +1411,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, else bcnprd = 100; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); + err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd); if (err) { WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); goto done; @@ -1082,7 +1434,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, BRCMF_ASSOC_PARAMS_FIXED_SIZE; memcpy(profile->bssid, params->bssid, ETH_ALEN); } else { - memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); + memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); memset(profile->bssid, 0, ETH_ALEN); } @@ -1101,8 +1453,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, /* set channel for starter */ target_channel = cfg->channel; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, - target_channel); + err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL, + &target_channel); if (err) { WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); goto done; @@ -1113,8 +1465,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, cfg->ibss_starter = false; - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, - &join_params, join_params_size); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, + &join_params, join_params_size); if (err) { WL_ERR("WLC_SET_SSID failed (%d)\n", err); goto done; @@ -1122,7 +1474,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, done: if (err) - clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); + clear_bit(WL_STATUS_CONNECTING, &cfg->status); WL_TRACE("Exit\n"); return err; } @@ -1131,11 +1483,10 @@ static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; brcmf_link_down(cfg); @@ -1148,7 +1499,8 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) static s32 brcmf_set_wpa_version(struct net_device *ndev, struct cfg80211_connect_params *sme) { - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; @@ -1160,7 +1512,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev, else val = WPA_AUTH_DISABLED; WL_CONN("setting wpa_auth to 0x%0x\n", val); - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val); + err = brcmf_dev_intvar_set(ndev, "wpa_auth", val); if (err) { WL_ERR("set wpa_auth failed (%d)\n", err); return err; @@ -1173,7 +1525,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev, static s32 brcmf_set_auth_type(struct net_device *ndev, struct cfg80211_connect_params *sme) { - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; @@ -1199,7 +1552,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev, break; } - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val); + err = brcmf_dev_intvar_set(ndev, "auth", val); if (err) { WL_ERR("set auth failed (%d)\n", err); return err; @@ -1213,7 +1566,8 @@ static s32 brcmf_set_set_cipher(struct net_device *ndev, struct cfg80211_connect_params *sme) { - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; s32 pval = 0; s32 gval = 0; @@ -1263,7 +1617,7 @@ brcmf_set_set_cipher(struct net_device *ndev, } WL_CONN("pval (%d) gval (%d)\n", pval, gval); - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval); + err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval); if (err) { WL_ERR("error (%d)\n", err); return err; @@ -1279,14 +1633,14 @@ brcmf_set_set_cipher(struct net_device *ndev, static s32 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) { - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; if (sme->crypto.n_akm_suites) { - err = brcmf_fil_iovar_int_get(netdev_priv(ndev), - "wpa_auth", &val); + err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val); if (err) { WL_ERR("could not get wpa_auth (%d)\n", err); return err; @@ -1320,8 +1674,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) } WL_CONN("setting wpa_auth to %d\n", val); - err = brcmf_fil_iovar_int_set(netdev_priv(ndev), - "wpa_auth", val); + err = brcmf_dev_intvar_set(ndev, "wpa_auth", val); if (err) { WL_ERR("could not set wpa_auth (%d)\n", err); return err; @@ -1337,11 +1690,13 @@ static s32 brcmf_set_sharedkey(struct net_device *ndev, struct cfg80211_connect_params *sme) { - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; struct brcmf_wsec_key key; s32 val; s32 err = 0; + s32 bssidx; WL_CONN("key len (%d)\n", sme->key_len); @@ -1384,14 +1739,15 @@ brcmf_set_sharedkey(struct net_device *ndev, WL_CONN("key length (%d) key index (%d) algo (%d)\n", key.len, key.index, key.algo); WL_CONN("key \"%s\"\n", key.data); - err = send_key_to_dongle(ndev, &key); + bssidx = brcmf_find_bssidx(cfg, ndev); + err = send_key_to_dongle(cfg, bssidx, ndev, &key); if (err) return err; if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { WL_CONN("set auth_type to shared key\n"); val = WL_AUTH_SHARED_KEY; /* shared key */ - err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val); + err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx); if (err) WL_ERR("set auth failed (%d)\n", err); } @@ -1403,8 +1759,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct ieee80211_channel *chan = sme->channel; struct brcmf_join_params join_params; size_t join_params_size; @@ -1413,7 +1768,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; if (!sme->ssid) { @@ -1421,7 +1776,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, return -EOPNOTSUPP; } - set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); + set_bit(WL_STATUS_CONNECTING, &cfg->status); if (chan) { cfg->channel = @@ -1472,7 +1827,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len); join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); - memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); + memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) WL_CONN("ssid \"%s\", len (%d)\n", @@ -1480,14 +1835,14 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, brcmf_ch_to_chanspec(cfg->channel, &join_params, &join_params_size); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, - &join_params, join_params_size); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, + &join_params, join_params_size); if (err) WL_ERR("WLC_SET_SSID failed (%d)\n", err); done: if (err) - clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); + clear_bit(WL_STATUS_CONNECTING, &cfg->status); WL_TRACE("Exit\n"); return err; } @@ -1497,21 +1852,20 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_scb_val_le scbval; s32 err = 0; WL_TRACE("Enter. Reason code = %d\n", reason_code); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; - clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); + clear_bit(WL_STATUS_CONNECTED, &cfg->status); memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); scbval.val = cpu_to_le32(reason_code); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC, - &scbval, sizeof(scbval)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval, + sizeof(struct brcmf_scb_val_le)); if (err) WL_ERR("error (%d)\n", err); @@ -1522,20 +1876,19 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, } static s32 -brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, +brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 mbm) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct net_device *ndev = cfg_to_ndev(cfg); - struct brcmf_if *ifp = netdev_priv(ndev); u16 txpwrmw; s32 err = 0; s32 disable = 0; s32 dbm = MBM_TO_DBM(mbm); WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; switch (type) { @@ -1552,7 +1905,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, } /* Make sure radio is off or on as far as software is concerned */ disable = WL_RADIO_SW_DISABLE << 16; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable); if (err) WL_ERR("WLC_SET_RADIO error (%d)\n", err); @@ -1560,8 +1913,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, txpwrmw = 0xffff; else txpwrmw = (u16) dbm; - err = brcmf_fil_iovar_int_set(ifp, "qtxpower", - (s32)brcmf_mw_to_qdbm(txpwrmw)); + err = brcmf_dev_intvar_set(ndev, "qtxpower", + (s32) (brcmf_mw_to_qdbm(txpwrmw))); if (err) WL_ERR("qtxpower error (%d)\n", err); cfg->conf->tx_power = dbm; @@ -1571,21 +1924,19 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, return err; } -static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, - s32 *dbm) +static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + struct net_device *ndev = cfg_to_ndev(cfg); s32 txpwrdbm; u8 result; s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; - err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm); + err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); if (err) { WL_ERR("error (%d)\n", err); goto done; @@ -1603,17 +1954,19 @@ static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, bool unicast, bool multicast) { - struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); u32 index; u32 wsec; s32 err = 0; + s32 bssidx; WL_TRACE("Enter\n"); WL_CONN("key index (%d)\n", key_idx); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; - err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + bssidx = brcmf_find_bssidx(cfg, ndev); + err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); if (err) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); goto done; @@ -1622,8 +1975,8 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, if (wsec & WEP_ENABLED) { /* Just select a new current key */ index = key_idx; - err = brcmf_fil_cmd_int_set(ifp, - BRCMF_C_SET_KEY_PRIMARY, index); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY, + &index); if (err) WL_ERR("error (%d)\n", err); } @@ -1636,8 +1989,11 @@ static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, const u8 *mac_addr, struct key_params *params) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_wsec_key key; + struct brcmf_wsec_key_le key_le; s32 err = 0; + s32 bssidx; memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -1646,10 +2002,11 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, if (!is_multicast_ether_addr(mac_addr)) memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); key.len = (u32) params->key_len; + bssidx = brcmf_find_bssidx(cfg, ndev); /* check for key index change */ if (key.len == 0) { /* key delete */ - err = send_key_to_dongle(ndev, &key); + err = send_key_to_dongle(cfg, bssidx, ndev, &key); if (err) WL_ERR("key delete error (%d)\n", err); } else { @@ -1704,7 +2061,13 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, WL_ERR("Invalid cipher (0x%x)\n", params->cipher); return -EINVAL; } - err = send_key_to_dongle(ndev, &key); + convert_key_from_CPU(&key, &key_le); + + brcmf_netdev_wait_pend8021x(ndev); + err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, + sizeof(key_le), + cfg->extra_buf, + WL_EXTRA_BUF_MAX, bssidx); if (err) WL_ERR("wsec_key error (%d)\n", err); } @@ -1717,16 +2080,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct key_params *params) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_wsec_key key; s32 val; s32 wsec; s32 err = 0; u8 keybuf[8]; + s32 bssidx; WL_TRACE("Enter\n"); WL_CONN("key index (%d)\n", key_idx); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; if (mac_addr) { @@ -1784,17 +2147,18 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, goto done; } - err = send_key_to_dongle(ndev, &key); + bssidx = brcmf_find_bssidx(cfg, ndev); + err = send_key_to_dongle(cfg, bssidx, ndev, &key); if (err) goto done; - err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); if (err) { WL_ERR("get wsec error (%d)\n", err); goto done; } wsec |= val; - err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx); if (err) { WL_ERR("set wsec error (%d)\n", err); goto done; @@ -1809,20 +2173,15 @@ static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, bool pairwise, const u8 *mac_addr) { - struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_wsec_key key; s32 err = 0; + s32 bssidx; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; - if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { - /* we ignore this key index in this case */ - WL_ERR("invalid key index (%d)\n", key_idx); - return -EINVAL; - } - memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -1832,7 +2191,17 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, WL_CONN("key index (%d)\n", key_idx); /* Set the new key/index */ - err = send_key_to_dongle(ndev, &key); + bssidx = brcmf_find_bssidx(cfg, ndev); + err = send_key_to_dongle(cfg, bssidx, ndev, &key); + if (err) { + if (err == -EINVAL) { + if (key.index >= DOT11_MAX_DEFAULT_KEYS) + /* we ignore this key index in this case */ + WL_ERR("invalid key index (%d)\n", key_idx); + } + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + } WL_TRACE("Exit\n"); return err; @@ -1844,20 +2213,22 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, void (*callback) (void *cookie, struct key_params * params)) { struct key_params params; - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_security *sec; s32 wsec; s32 err = 0; + s32 bssidx; WL_TRACE("Enter\n"); WL_CONN("key index (%d)\n", key_idx); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; memset(¶ms, 0, sizeof(params)); - err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + bssidx = brcmf_find_bssidx(cfg, ndev); + err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); if (err) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); /* Ignore this error, may happen during DISASSOC */ @@ -1909,33 +2280,33 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, u8 *mac, struct station_info *sinfo) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_scb_val_le scb_val; int rssi; s32 rate; s32 err = 0; u8 *bssid = profile->bssid; - struct brcmf_sta_info_le sta_info_le; + struct brcmf_sta_info_le *sta_info_le; WL_TRACE("Enter, MAC %pM\n", mac); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; if (cfg->conf->mode == WL_MODE_AP) { - memcpy(&sta_info_le, mac, ETH_ALEN); - err = brcmf_fil_iovar_data_get(ifp, "sta_info", - &sta_info_le, - sizeof(sta_info_le)); + err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN, + cfg->dcmd_buf, + WL_DCMD_LEN_MAX); if (err < 0) { WL_ERR("GET STA INFO failed, %d\n", err); goto done; } + sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf; + sinfo->filled = STATION_INFO_INACTIVE_TIME; - sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; - if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { + sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000; + if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) { sinfo->filled |= STATION_INFO_CONNECTED_TIME; - sinfo->connected_time = le32_to_cpu(sta_info_le.in); + sinfo->connected_time = le32_to_cpu(sta_info_le->in); } WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", sinfo->inactive_time, sinfo->connected_time); @@ -1947,7 +2318,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, goto done; } /* Report the current tx rate */ - err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate); if (err) { WL_ERR("Could not get rate (%d)\n", err); goto done; @@ -1957,11 +2328,10 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, WL_CONN("Rate %d Mbps\n", rate / 2); } - if (test_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state)) { + if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) { memset(&scb_val, 0, sizeof(scb_val)); - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, - &scb_val, sizeof(scb_val)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, + sizeof(scb_val)); if (err) { WL_ERR("Could not get rssi (%d)\n", err); goto done; @@ -1986,7 +2356,6 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, s32 pm; s32 err = 0; struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); WL_TRACE("Enter\n"); @@ -1998,7 +2367,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, * FW later while initializing the dongle */ cfg->pwr_save = enabled; - if (!check_vif_up(ifp->vif)) { + if (!test_bit(WL_STATUS_READY, &cfg->status)) { WL_INFO("Device is not ready, storing the value in cfg_info struct\n"); goto done; @@ -2007,7 +2376,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, pm = enabled ? PM_FAST : PM_OFF; WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm); if (err) { if (err == -ENODEV) WL_ERR("net_device is not ready yet\n"); @@ -2024,7 +2393,6 @@ 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; @@ -2034,13 +2402,13 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) 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)); + err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le, + sizeof(rateset_le)); if (err) { WL_ERR("could not get current rateset (%d)\n", err); goto done; @@ -2067,8 +2435,8 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, * 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); + err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate); + err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate); if (err_bg && err_a) { WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); err = err_bg | err_a; @@ -2154,14 +2522,13 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) int i; bss_list = cfg->bss_list; - if (bss_list->count != 0 && - bss_list->version != BRCMF_BSS_INFO_VERSION) { + if (bss_list->version != BRCMF_BSS_INFO_VERSION) { WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version); return -EOPNOTSUPP; } WL_SCAN("scanned AP count (%d)\n", bss_list->count); - for (i = 0; i < bss_list->count; i++) { + for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { bi = next_bss_le(bss_list, bi); err = brcmf_inform_single_bss(cfg, bi); if (err) @@ -2198,8 +2565,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); - err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO, - buf, WL_BSS_INFO_MAX); + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); if (err) { WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err); goto CleanUp; @@ -2308,12 +2674,12 @@ brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, return false; } -static struct brcmf_vs_tlv * +struct brcmf_vs_tlv * brcmf_find_wpaie(u8 *parse, u32 len) { struct brcmf_tlv *ie; - while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) { + while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) { if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len, WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE)) return (struct brcmf_vs_tlv *)ie; @@ -2323,9 +2689,7 @@ brcmf_find_wpaie(u8 *parse, u32 len) static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) { - struct net_device *ndev = cfg_to_ndev(cfg); - struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); - struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_bss_info_le *bi; struct brcmf_ssid *ssid; struct brcmf_tlv *tim; @@ -2342,8 +2706,8 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) ssid = &profile->ssid; *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, - cfg->extra_buf, WL_EXTRA_BUF_MAX); + err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO, + cfg->extra_buf, WL_EXTRA_BUF_MAX); if (err) { WL_ERR("Could not get bss info %d\n", err); goto update_bss_info_out; @@ -2368,7 +2732,8 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) * so we speficially query dtim information to dongle. */ u32 var; - err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var); + err = brcmf_dev_intvar_get(cfg_to_ndev(cfg), + "dtim_assoc", &var); if (err) { WL_ERR("wl dtim_assoc failed (%d)\n", err); goto update_bss_info_out; @@ -2376,6 +2741,9 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) dtim_period = (u8)var; } + profile->beacon_interval = beacon_interval; + profile->dtim_period = dtim_period; + update_bss_info_out: WL_TRACE("Exit"); return err; @@ -2383,25 +2751,243 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) { + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); struct escan_info *escan = &cfg->escan_info; + struct brcmf_ssid ssid; - set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); - if (cfg->scan_request) { + set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); + if (cfg->iscan_on) { + iscan->state = WL_ISCAN_STATE_IDLE; + + if (iscan->timer_on) { + del_timer_sync(&iscan->timer); + iscan->timer_on = 0; + } + + cancel_work_sync(&iscan->work); + + /* Abort iscan running in FW */ + memset(&ssid, 0, sizeof(ssid)); + brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); + + if (cfg->scan_request) { + /* Indidate scan abort to cfg80211 layer */ + WL_INFO("Terminating scan in progress\n"); + cfg80211_scan_done(cfg->scan_request, true); + cfg->scan_request = NULL; + } + } + if (cfg->escan_on && cfg->scan_request) { escan->escan_state = WL_ESCAN_STATE_IDLE; brcmf_notify_escan_complete(cfg, escan->ndev, true, true); } - clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); - clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); + clear_bit(WL_STATUS_SCANNING, &cfg->status); + clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); } -static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) +static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, + bool aborted) { - struct brcmf_cfg80211_info *cfg = - container_of(work, struct brcmf_cfg80211_info, - escan_timeout_work); + struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); + struct net_device *ndev = cfg_to_ndev(cfg); - brcmf_notify_escan_complete(cfg, - cfg->escan_info.ndev, true, true); + if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("Scan complete while device not scanning\n"); + return; + } + if (cfg->scan_request) { + WL_SCAN("ISCAN Completed scan: %s\n", + aborted ? "Aborted" : "Done"); + cfg80211_scan_done(cfg->scan_request, aborted); + brcmf_set_mpc(ndev, 1); + cfg->scan_request = NULL; + } + cfg->iscan_kickstart = false; +} + +static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) +{ + if (iscan->state != WL_ISCAN_STATE_IDLE) { + WL_SCAN("wake up iscan\n"); + schedule_work(&iscan->work); + return 0; + } + + return -EIO; +} + +static s32 +brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, + struct brcmf_scan_results **bss_list) +{ + struct brcmf_iscan_results list; + struct brcmf_scan_results *results; + struct brcmf_scan_results_le *results_le; + struct brcmf_iscan_results *list_buf; + s32 err = 0; + + memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); + list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; + results = &list_buf->results; + results_le = &list_buf->results_le; + results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE; + results->version = 0; + results->count = 0; + + memset(&list, 0, sizeof(list)); + list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX); + err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list, + BRCMF_ISCAN_RESULTS_FIXED_SIZE, + iscan->scan_buf, WL_ISCAN_BUF_MAX); + if (err) { + WL_ERR("error (%d)\n", err); + return err; + } + results->buflen = le32_to_cpu(results_le->buflen); + results->version = le32_to_cpu(results_le->version); + results->count = le32_to_cpu(results_le->count); + WL_SCAN("results->count = %d\n", results_le->count); + WL_SCAN("results->buflen = %d\n", results_le->buflen); + *status = le32_to_cpu(list_buf->status_le); + WL_SCAN("status = %d\n", *status); + *bss_list = results; + + return err; +} + +static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + iscan->state = WL_ISCAN_STATE_IDLE; + brcmf_inform_bss(cfg); + brcmf_notify_iscan_complete(iscan, false); + + return err; +} + +static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + /* Reschedule the timer */ + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + + return err; +} + +static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + brcmf_inform_bss(cfg); + brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); + /* Reschedule the timer */ + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + + return err; +} + +static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + iscan->state = WL_ISCAN_STATE_IDLE; + brcmf_notify_iscan_complete(iscan, true); + + return err; +} + +static void brcmf_cfg80211_iscan_handler(struct work_struct *work) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = + container_of(work, struct brcmf_cfg80211_iscan_ctrl, + work); + struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); + struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; + u32 status = BRCMF_SCAN_RESULTS_PARTIAL; + + if (iscan->timer_on) { + del_timer_sync(&iscan->timer); + iscan->timer_on = 0; + } + + if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) { + status = BRCMF_SCAN_RESULTS_ABORTED; + WL_ERR("Abort iscan\n"); + } + + el->handler[status](cfg); +} + +static void brcmf_iscan_timer(unsigned long data) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = + (struct brcmf_cfg80211_iscan_ctrl *)data; + + if (iscan) { + iscan->timer_on = 0; + WL_SCAN("timer expired\n"); + brcmf_wakeup_iscan(iscan); + } +} + +static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + + if (cfg->iscan_on) { + iscan->state = WL_ISCAN_STATE_IDLE; + INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); + } + + return 0; +} + +static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) +{ + memset(el, 0, sizeof(*el)); + el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done; + el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress; + el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending; + el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted; + el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; +} + +static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + int err = 0; + + if (cfg->iscan_on) { + iscan->ndev = cfg_to_ndev(cfg); + brcmf_init_iscan_eloop(&iscan->el); + iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; + init_timer(&iscan->timer); + iscan->timer.data = (unsigned long) iscan; + iscan->timer.function = brcmf_iscan_timer; + err = brcmf_invoke_iscan(cfg); + if (!err) + iscan->data = cfg; + } + + return err; +} + +static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) +{ + struct brcmf_cfg80211_info *cfg = + container_of(work, struct brcmf_cfg80211_info, + escan_timeout_work); + + brcmf_notify_escan_complete(cfg, + cfg->escan_info.ndev, true, true); } static void brcmf_escan_timeout(unsigned long data) @@ -2411,7 +2997,8 @@ static void brcmf_escan_timeout(unsigned long data) if (cfg->scan_request) { WL_ERR("timer expired\n"); - schedule_work(&cfg->escan_timeout_work); + if (cfg->escan_on) + schedule_work(&cfg->escan_timeout_work); } } @@ -2448,11 +3035,10 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, } static s32 -brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, +brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; s32 status; s32 err = 0; struct brcmf_escan_result_le *escan_result_le; @@ -2463,11 +3049,13 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, u32 i; bool aborted; - status = e->status; + status = be32_to_cpu(e->status); - if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { - WL_ERR("scan not ready ndev %p drv_status %x\n", ndev, - !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); + if (!ndev || !cfg->escan_on || + !test_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", + ndev, cfg->escan_on, + !test_bit(WL_STATUS_SCANNING, &cfg->status)); return -EPERM; } @@ -2544,15 +3132,18 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) { - brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT, - brcmf_cfg80211_escan_handler); - cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - /* Init scan_timeout timer */ - init_timer(&cfg->escan_timeout); - cfg->escan_timeout.data = (unsigned long) cfg; - cfg->escan_timeout.function = brcmf_escan_timeout; - INIT_WORK(&cfg->escan_timeout_work, - brcmf_cfg80211_escan_timeout_worker); + + if (cfg->escan_on) { + cfg->el.handler[BRCMF_E_ESCAN_RESULT] = + brcmf_cfg80211_escan_handler; + cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; + /* Init scan_timeout timer */ + init_timer(&cfg->escan_timeout); + cfg->escan_timeout.data = (unsigned long) cfg; + cfg->escan_timeout.function = brcmf_escan_timeout; + INIT_WORK(&cfg->escan_timeout_work, + brcmf_cfg80211_escan_timeout_worker); + } } static __always_inline void brcmf_delay(u32 ms) @@ -2567,8 +3158,19 @@ static __always_inline void brcmf_delay(u32 ms) static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + + /* + * Check for WL_STATUS_READY before any function call which + * could result is bus access. Don't block the resume for + * any driver error conditions + */ WL_TRACE("Enter\n"); + if (test_bit(WL_STATUS_READY, &cfg->status)) + brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); + + WL_TRACE("Exit\n"); return 0; } @@ -2577,52 +3179,84 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct net_device *ndev = cfg_to_ndev(cfg); - struct brcmf_cfg80211_vif *vif; WL_TRACE("Enter\n"); /* - * if the primary net_device is not READY there is nothing - * we can do but pray resume goes smoothly. + * Check for WL_STATUS_READY before any function call which + * could result is bus access. Don't block the suspend for + * any driver error conditions */ - vif = ((struct brcmf_if *)netdev_priv(ndev))->vif; - if (!check_vif_up(vif)) - goto exit; - list_for_each_entry(vif, &cfg->vif_list, list) { - if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) - continue; + /* + * While going to suspend if associated with AP disassociate + * from AP to save power while system is in suspended state + */ + if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || + test_bit(WL_STATUS_CONNECTING, &cfg->status)) && + test_bit(WL_STATUS_READY, &cfg->status)) { + WL_INFO("Disassociating from AP" + " while entering suspend state\n"); + brcmf_link_down(cfg); + /* - * While going to suspend if associated with AP disassociate - * from AP to save power while system is in suspended state + * Make sure WPA_Supplicant receives all the event + * generated due to DISASSOC call to the fw to keep + * the state fw and WPA_Supplicant state consistent */ - if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) || - test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { - WL_INFO("Disassociating from AP before suspend\n"); - brcmf_link_down(cfg); - - /* Make sure WPA_Supplicant receives all the event - * generated due to DISASSOC call to the fw to keep - * the state fw and WPA_Supplicant state consistent - */ - brcmf_delay(500); - } + brcmf_delay(500); } - /* end any scanning */ - if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) + if (test_bit(WL_STATUS_READY, &cfg->status)) brcmf_abort_scanning(cfg); + else + clear_bit(WL_STATUS_SCANNING, &cfg->status); /* Turn off watchdog timer */ - brcmf_set_mpc(ndev, 1); + if (test_bit(WL_STATUS_READY, &cfg->status)) + brcmf_set_mpc(ndev, 1); -exit: WL_TRACE("Exit\n"); - /* clear any scanning activity */ - cfg->scan_status = 0; + return 0; } +static __used s32 +brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len) +{ + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + u32 buflen; + + buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf, + WL_DCMD_LEN_MAX); + BUG_ON(!buflen); + + return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf, + buflen); +} + +static s32 +brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf, + s32 buf_len) +{ + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + u32 len; + s32 err = 0; + + len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf, + WL_DCMD_LEN_MAX); + BUG_ON(!len); + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf, + WL_DCMD_LEN_MAX); + if (err) { + WL_ERR("error (%d)\n", err); + return err; + } + memcpy(buf, cfg->dcmd_buf, buf_len); + + return err; +} + static __used s32 brcmf_update_pmklist(struct net_device *ndev, struct brcmf_cfg80211_pmk_list *pmk_list, s32 err) @@ -2641,8 +3275,8 @@ brcmf_update_pmklist(struct net_device *ndev, } if (!err) - brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info", - (char *)pmk_list, sizeof(*pmk_list)); + brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list, + sizeof(*pmk_list)); return err; } @@ -2652,14 +3286,13 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); struct pmkid_list *pmkids = &cfg->pmk_list->pmkids; s32 err = 0; int i; int pmkid_len; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; pmkid_len = le32_to_cpu(pmkids->npmkid); @@ -2692,13 +3325,12 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); struct pmkid_list pmkid; s32 err = 0; int i, pmkid_len; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); @@ -2743,11 +3375,10 @@ static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; WL_TRACE("Enter\n"); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list)); @@ -2767,11 +3398,10 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) * cfg80211_scan_request one out of the received PNO event. */ static s32 -brcmf_notify_sched_scan_results(struct brcmf_if *ifp, +brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; struct brcmf_pno_net_info_le *netinfo, *netinfo_start; struct cfg80211_scan_request *request = NULL; struct cfg80211_ssid *ssid = NULL; @@ -2786,7 +3416,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, WL_SCAN("Enter\n"); - if (e->event_code == BRCMF_E_PFN_NET_LOST) { + if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) { WL_SCAN("PFN NET LOST event. Do Nothing\n"); return 0; } @@ -2848,15 +3478,15 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, if (request->n_ssids) request->ssids = &ssid[0]; - if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { /* Abort any on-going scan */ brcmf_abort_scanning(cfg); } - set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + set_bit(WL_STATUS_SCANNING, &cfg->status); err = brcmf_do_escan(cfg, wiphy, ndev, request); if (err) { - clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + clear_bit(WL_STATUS_SCANNING, &cfg->status); goto out_err; } cfg->sched_escan = true; @@ -2879,16 +3509,18 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, return err; } +#ifndef CONFIG_BRCMISCAN static int brcmf_dev_pno_clean(struct net_device *ndev) { + char iovbuf[128]; int ret; /* Disable pfn */ - ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0); + ret = brcmf_dev_intvar_set(ndev, "pfn", 0); if (ret == 0) { /* clear pfn */ - ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear", - NULL, 0); + ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0, + iovbuf, sizeof(iovbuf)); } if (ret < 0) WL_ERR("failed code %d\n", ret); @@ -2899,6 +3531,7 @@ static int brcmf_dev_pno_clean(struct net_device *ndev) static int brcmf_dev_pno_config(struct net_device *ndev) { struct brcmf_pno_param_le pfn_param; + char iovbuf[128]; memset(&pfn_param, 0, sizeof(pfn_param)); pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); @@ -2911,8 +3544,9 @@ static int brcmf_dev_pno_config(struct net_device *ndev) /* set up pno scan fr */ pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); - return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set", - &pfn_param, sizeof(pfn_param)); + return brcmf_dev_iovar_setbuf(ndev, "pfn_set", + &pfn_param, sizeof(pfn_param), + iovbuf, sizeof(iovbuf)); } static int @@ -2920,7 +3554,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_sched_scan_request *request) { - struct brcmf_if *ifp = netdev_priv(ndev); + char iovbuf[128]; struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); struct brcmf_pno_net_param_le pfn; int i; @@ -2928,14 +3562,14 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n", request->n_match_sets, request->n_ssids); - if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { - WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); + if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("Scanning already : status (%lu)\n", cfg->status); return -EAGAIN; } if (!request || !request->n_ssids || !request->n_match_sets) { WL_ERR("Invalid sched scan req!! n_ssids:%d\n", - request ? request->n_ssids : 0); + request->n_ssids); return -EINVAL; } @@ -2986,14 +3620,15 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); pfn.ssid.SSID_len = cpu_to_le32(ssid_len); memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len); - ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, - sizeof(pfn)); + ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add", + &pfn, sizeof(pfn), + iovbuf, sizeof(iovbuf)); WL_SCAN(">>> PNO filter %s for ssid (%s)\n", ret == 0 ? "set" : "failed", ssid->ssid); } /* Enable the PNO */ - if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) { + if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) { WL_ERR("PNO enable failed!! ret=%d\n", ret); return -EINVAL; } @@ -3015,25 +3650,18 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, brcmf_notify_escan_complete(cfg, ndev, true, true); return 0; } +#endif /* CONFIG_BRCMISCAN */ #ifdef CONFIG_NL80211_TESTMODE static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct net_device *ndev = cfg_to_ndev(cfg); + struct net_device *ndev = cfg->wdev->netdev; struct brcmf_dcmd *dcmd = data; struct sk_buff *reply; int ret; - WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set, - dcmd->buf, dcmd->len); - - if (dcmd->set) - ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd, - dcmd->buf, dcmd->len); - else - ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd, - dcmd->buf, dcmd->len); + ret = brcmf_netlink_dcmd(ndev, dcmd); if (ret == 0) { reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd)); nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd); @@ -3045,23 +3673,23 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx) { - struct brcmf_if *ifp = netdev_priv(ndev); s32 err; /* set auth */ - err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0); + err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx); if (err < 0) { WL_ERR("auth error %d\n", err); return err; } /* set wsec */ - err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx); if (err < 0) { WL_ERR("wsec error %d\n", err); return err; } /* set upper-layer auth */ - err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", + WPA_AUTH_NONE, bssidx); if (err < 0) { WL_ERR("wpa_auth error %d\n", err); return err; @@ -3080,9 +3708,8 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie) static s32 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, - bool is_rsn_ie) + bool is_rsn_ie, s32 bssidx) { - struct brcmf_if *ifp = netdev_priv(ndev); u32 auth = 0; /* d11 open authentication */ u16 count; s32 err = 0; @@ -3223,8 +3850,8 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, wme_bss_disable = 0; } /* set wme_bss_disable to sync RSN Capabilities */ - err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", - wme_bss_disable); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable", + wme_bss_disable, bssidx); if (err < 0) { WL_ERR("wme_bss_disable error %d\n", err); goto exit; @@ -3234,19 +3861,19 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, wsec = (pval | gval | SES_OW_ENABLED); /* set auth */ - err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth); + err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx); if (err < 0) { WL_ERR("auth error %d\n", err); goto exit; } /* set wsec */ - err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx); if (err < 0) { WL_ERR("wsec error %d\n", err); goto exit; } /* set upper-layer auth */ - err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); + err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx); if (err < 0) { WL_ERR("wpa_auth error %d\n", err); goto exit; @@ -3257,7 +3884,7 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, } static s32 -brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, +brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, struct parsed_vndr_ies *vndr_ies) { s32 err = 0; @@ -3336,18 +3963,17 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) return ie_len + VNDR_IE_HDR_SIZE; } -static -s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, - const u8 *vndr_ie_buf, u32 vndr_ie_len) +s32 +brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, s32 bssidx, s32 pktflag, + u8 *vndr_ie_buf, u32 vndr_ie_len) { - struct brcmf_if *ifp; - struct vif_saved_ie *saved_ie; s32 err = 0; u8 *iovar_ie_buf; u8 *curr_ie_buf; u8 *mgmt_ie_buf = NULL; - int mgmt_ie_buf_len; - u32 *mgmt_ie_len; + u32 mgmt_ie_buf_len = 0; + u32 *mgmt_ie_len = 0; u32 del_add_ie_buf_len = 0; u32 total_ie_buf_len = 0; u32 parsed_ie_buf_len = 0; @@ -3356,35 +3982,33 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, struct parsed_vndr_ie_info *vndrie_info; s32 i; u8 *ptr; - int remained_buf_len; + u32 remained_buf_len; - if (!vif) - return -ENODEV; - ifp = vif->ifp; - saved_ie = &vif->saved_ie; - - WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag); + WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (!iovar_ie_buf) return -ENOMEM; curr_ie_buf = iovar_ie_buf; - if (ifp->vif->mode == WL_MODE_AP) { + if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) || + test_bit(WL_STATUS_AP_CREATED, &cfg->status)) { switch (pktflag) { case VNDR_IE_PRBRSP_FLAG: - mgmt_ie_buf = saved_ie->probe_res_ie; - mgmt_ie_len = &saved_ie->probe_res_ie_len; - mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie); + mgmt_ie_buf = cfg->ap_info->probe_res_ie; + mgmt_ie_len = &cfg->ap_info->probe_res_ie_len; + mgmt_ie_buf_len = + sizeof(cfg->ap_info->probe_res_ie); break; case VNDR_IE_BEACON_FLAG: - mgmt_ie_buf = saved_ie->beacon_ie; - mgmt_ie_len = &saved_ie->beacon_ie_len; - mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie); + mgmt_ie_buf = cfg->ap_info->beacon_ie; + mgmt_ie_len = &cfg->ap_info->beacon_ie_len; + mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie); break; default: err = -EPERM; WL_ERR("not suitable type\n"); goto exit; } + bssidx = 0; } else { err = -EPERM; WL_ERR("not suitable type\n"); @@ -3480,8 +4104,11 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, } } if (total_ie_buf_len) { - err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf, - total_ie_buf_len); + err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie", + iovar_ie_buf, + total_ie_buf_len, + cfg->extra_buf, + WL_EXTRA_BUF_MAX, bssidx); if (err) WL_ERR("vndr ie set error : %d\n", err); } @@ -3496,23 +4123,24 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ap_settings *settings) { s32 ie_offset; - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_tlv *ssid_ie; struct brcmf_ssid_le ssid_le; + s32 ioctl_value; s32 err = -EPERM; struct brcmf_tlv *rsn_ie; struct brcmf_vs_tlv *wpa_ie; struct brcmf_join_params join_params; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); s32 bssidx = 0; WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", settings->channel_type, settings->beacon_interval, settings->dtim_period); - WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", + WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", settings->ssid, settings->ssid_len, settings->auth_type, settings->inactivity_timeout); - if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) { + if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) { WL_ERR("Not in AP creation mode\n"); return -EPERM; } @@ -3536,17 +4164,20 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, } brcmf_set_mpc(ndev, 0); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + ioctl_value = 1; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value); if (err < 0) { WL_ERR("BRCMF_C_DOWN error %d\n", err); goto exit; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1); + ioctl_value = 1; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value); if (err < 0) { WL_ERR("SET INFRA error %d\n", err); goto exit; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1); + ioctl_value = 1; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value); if (err < 0) { WL_ERR("setting AP mode failed %d\n", err); goto exit; @@ -3560,61 +4191,80 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, settings->beacon.tail_len); + kfree(cfg->ap_info->rsn_ie); + cfg->ap_info->rsn_ie = NULL; + kfree(cfg->ap_info->wpa_ie); + cfg->ap_info->wpa_ie = NULL; + if ((wpa_ie != NULL || rsn_ie != NULL)) { WL_TRACE("WPA(2) IE is found\n"); if (wpa_ie != NULL) { /* WPA IE */ - err = brcmf_configure_wpaie(ndev, wpa_ie, false); + err = brcmf_configure_wpaie(ndev, wpa_ie, false, + bssidx); if (err < 0) goto exit; + cfg->ap_info->wpa_ie = kmemdup(wpa_ie, + wpa_ie->len + + TLV_HDR_LEN, + GFP_KERNEL); } else { /* RSN IE */ err = brcmf_configure_wpaie(ndev, - (struct brcmf_vs_tlv *)rsn_ie, true); + (struct brcmf_vs_tlv *)rsn_ie, true, bssidx); if (err < 0) goto exit; + cfg->ap_info->rsn_ie = kmemdup(rsn_ie, + rsn_ie->len + + TLV_HDR_LEN, + GFP_KERNEL); } + cfg->ap_info->security_mode = true; } else { WL_TRACE("No WPA(2) IEs found\n"); brcmf_configure_opensecurity(ndev, bssidx); + cfg->ap_info->security_mode = false; } /* Set Beacon IEs to FW */ - err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), - VNDR_IE_BEACON_FLAG, - settings->beacon.tail, - settings->beacon.tail_len); + err = brcmf_set_management_ie(cfg, ndev, bssidx, + VNDR_IE_BEACON_FLAG, + (u8 *)settings->beacon.tail, + settings->beacon.tail_len); if (err) WL_ERR("Set Beacon IE Failed\n"); else WL_TRACE("Applied Vndr IEs for Beacon\n"); /* Set Probe Response IEs to FW */ - err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), - VNDR_IE_PRBRSP_FLAG, - settings->beacon.proberesp_ies, - settings->beacon.proberesp_ies_len); + err = brcmf_set_management_ie(cfg, ndev, bssidx, + VNDR_IE_PRBRSP_FLAG, + (u8 *)settings->beacon.proberesp_ies, + settings->beacon.proberesp_ies_len); if (err) WL_ERR("Set Probe Resp IE Failed\n"); else WL_TRACE("Applied Vndr IEs for Probe Resp\n"); if (settings->beacon_interval) { - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, - settings->beacon_interval); + ioctl_value = settings->beacon_interval; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD, + &ioctl_value); if (err < 0) { WL_ERR("Beacon Interval Set Error, %d\n", err); goto exit; } } if (settings->dtim_period) { - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD, - settings->dtim_period); + ioctl_value = settings->dtim_period; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD, + &ioctl_value); if (err < 0) { WL_ERR("DTIM Interval Set Error, %d\n", err); goto exit; } } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + ioctl_value = 1; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value); if (err < 0) { WL_ERR("BRCMF_C_UP error (%d)\n", err); goto exit; @@ -3624,14 +4274,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, /* join parameters starts with ssid */ memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le)); /* create softap */ - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, - &join_params, sizeof(join_params)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params, + sizeof(join_params)); if (err < 0) { WL_ERR("SET SSID error (%d)\n", err); goto exit; } - clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); - set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); + clear_bit(WL_STATUS_AP_CREATING, &cfg->status); + set_bit(WL_STATUS_AP_CREATED, &cfg->status); exit: if (err) @@ -3641,8 +4291,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) { - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + s32 ioctl_value; s32 err = -EPERM; WL_TRACE("Enter\n"); @@ -3651,20 +4301,21 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) /* Due to most likely deauths outstanding we sleep */ /* first to make sure they get processed by fw. */ msleep(400); - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), - BRCMF_C_SET_AP, 0); + ioctl_value = 0; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value); if (err < 0) { WL_ERR("setting AP mode failed %d\n", err); goto exit; } - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0); + ioctl_value = 0; + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value); if (err < 0) { WL_ERR("BRCMF_C_UP error %d\n", err); goto exit; } brcmf_set_mpc(ndev, 1); - clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); - clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); + clear_bit(WL_STATUS_AP_CREATING, &cfg->status); + clear_bit(WL_STATUS_AP_CREATED, &cfg->status); } exit: return err; @@ -3675,7 +4326,6 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, u8 *mac) { struct brcmf_scb_val_le scbval; - struct brcmf_if *ifp = netdev_priv(ndev); s32 err; if (!mac) @@ -3683,13 +4333,13 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, WL_TRACE("Enter %pM\n", mac); - if (!check_vif_up(ifp->vif)) + if (!check_sys_up(wiphy)) return -EIO; memcpy(&scbval.ea, mac, ETH_ALEN); scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scbval)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, + &scbval, sizeof(scbval)); if (err) WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err); @@ -3723,8 +4373,11 @@ static struct cfg80211_ops wl_cfg80211_ops = { .start_ap = brcmf_cfg80211_start_ap, .stop_ap = brcmf_cfg80211_stop_ap, .del_station = brcmf_cfg80211_del_station, +#ifndef CONFIG_BRCMISCAN + /* scheduled scan need e-scan, which is mutual exclusive with i-scan */ .sched_scan_start = brcmf_cfg80211_sched_scan_start, .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, +#endif #ifdef CONFIG_NL80211_TESTMODE .testmode_cmd = brcmf_cfg80211_testmode #endif @@ -3748,111 +4401,88 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) static void brcmf_wiphy_pno_params(struct wiphy *wiphy) { +#ifndef CONFIG_BRCMFISCAN /* scheduled scan settings */ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; +#endif } -static struct wiphy *brcmf_setup_wiphy(struct device *phydev) +static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev) { - struct wiphy *wiphy; + struct wireless_dev *wdev; s32 err = 0; - wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); - if (!wiphy) { - WL_ERR("Could not allocate wiphy device\n"); + wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); + if (!wdev) return ERR_PTR(-ENOMEM); - } - set_wiphy_dev(wiphy, phydev); - wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; - wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set + + wdev->wiphy = wiphy_new(&wl_cfg80211_ops, + sizeof(struct brcmf_cfg80211_info)); + if (!wdev->wiphy) { + WL_ERR("Could not allocate wiphy device\n"); + err = -ENOMEM; + goto wiphy_new_out; + } + set_wiphy_dev(wdev->wiphy, ndev); + wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; + wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set * it as 11a by default. * This will be updated with * 11n phy tables in * "ifconfig up" * if phy has 11n capability */ - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->cipher_suites = __wl_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); - wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power + wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wdev->wiphy->cipher_suites = __wl_cipher_suites; + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); + wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power * save mode * by default */ - brcmf_wiphy_pno_params(wiphy); - err = wiphy_register(wiphy); + brcmf_wiphy_pno_params(wdev->wiphy); + err = wiphy_register(wdev->wiphy); if (err < 0) { WL_ERR("Could not register wiphy device (%d)\n", err); - wiphy_free(wiphy); - return ERR_PTR(err); + goto wiphy_register_out; } - return wiphy; -} - -static -struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, - struct net_device *netdev, - s32 mode, bool pm_block) -{ - struct brcmf_cfg80211_vif *vif; - - if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) - return ERR_PTR(-ENOSPC); + return wdev; - vif = kzalloc(sizeof(*vif), GFP_KERNEL); - if (!vif) - return ERR_PTR(-ENOMEM); +wiphy_register_out: + wiphy_free(wdev->wiphy); - vif->wdev.wiphy = cfg->wiphy; - vif->wdev.netdev = netdev; - vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode); +wiphy_new_out: + kfree(wdev); - if (netdev) { - vif->ifp = netdev_priv(netdev); - netdev->ieee80211_ptr = &vif->wdev; - SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy)); - } - - vif->mode = mode; - vif->pm_block = pm_block; - vif->roam_off = -1; - - brcmf_init_prof(&vif->profile); - - list_add_tail(&vif->list, &cfg->vif_list); - cfg->vif_cnt++; - return vif; + return ERR_PTR(err); } -static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) +static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_info *cfg; - struct wiphy *wiphy; - - wiphy = vif->wdev.wiphy; - cfg = wiphy_priv(wiphy); - list_del(&vif->list); - cfg->vif_cnt--; + struct wireless_dev *wdev = cfg->wdev; - kfree(vif); - if (!cfg->vif_cnt) { - wiphy_unregister(wiphy); - wiphy_free(wiphy); + if (!wdev) { + WL_ERR("wdev is invalid\n"); + return; } + wiphy_unregister(wdev->wiphy); + wiphy_free(wdev->wiphy); + kfree(wdev); + cfg->wdev = NULL; } static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { WL_CONN("Processing set ssid\n"); @@ -3866,8 +4496,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u16 flags = e->flags; + u32 event = be32_to_cpu(e->event_type); + u16 flags = be16_to_cpu(e->flags); if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { WL_CONN("Processing link down\n"); @@ -3879,12 +4509,13 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { WL_CONN("Processing Link %s & no network found\n", - e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down"); + be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? + "up" : "down"); return true; } @@ -3910,7 +4541,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg) static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + struct net_device *ndev = cfg_to_ndev(cfg); struct brcmf_cfg80211_assoc_ielen_le *assoc_info; struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); u32 req_len; @@ -3919,8 +4550,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) brcmf_clear_assoc_ies(cfg); - err = brcmf_fil_iovar_data_get(ifp, "assoc_info", - cfg->extra_buf, WL_ASSOC_INFO_MAX); + err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf, + WL_ASSOC_INFO_MAX); if (err) { WL_ERR("could not get assoc info (%d)\n", err); return err; @@ -3930,9 +4561,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) req_len = le32_to_cpu(assoc_info->req_len); resp_len = le32_to_cpu(assoc_info->resp_len); if (req_len) { - err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies", - cfg->extra_buf, - WL_ASSOC_INFO_MAX); + err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", + cfg->extra_buf, + WL_ASSOC_INFO_MAX); if (err) { WL_ERR("could not get assoc req (%d)\n", err); return err; @@ -3946,9 +4577,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) conn_info->req_ie = NULL; } if (resp_len) { - err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies", - cfg->extra_buf, - WL_ASSOC_INFO_MAX); + err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", + cfg->extra_buf, + WL_ASSOC_INFO_MAX); if (err) { WL_ERR("could not get assoc resp (%d)\n", err); return err; @@ -3972,17 +4603,15 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, const struct brcmf_event_msg *e) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); struct wiphy *wiphy = cfg_to_wiphy(cfg); - struct ieee80211_channel *notify_channel = NULL; + struct brcmf_channel_info_le channel_le; + struct ieee80211_channel *notify_channel; struct ieee80211_supported_band *band; - struct brcmf_bss_info_le *bi; u32 freq; s32 err = 0; u32 target_channel; - u8 *buf; WL_TRACE("Enter\n"); @@ -3990,23 +4619,11 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, memcpy(profile->bssid, e->addr, ETH_ALEN); brcmf_update_bss_info(cfg); - buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); - if (buf == NULL) { - err = -ENOMEM; - goto done; - } - - /* data sent to dongle has to be little endian */ - *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, - buf, WL_BSS_INFO_MAX); - - if (err) - goto done; + brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, + sizeof(channel_le)); - bi = (struct brcmf_bss_info_le *)(buf + 4); - target_channel = bi->ctl_ch ? bi->ctl_ch : - CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); + target_channel = le32_to_cpu(channel_le.target_channel); + WL_CONN("Roamed to channel %d\n", target_channel); if (target_channel <= CH_MAX_2G_CHANNEL) band = wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -4016,14 +4633,12 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, freq = ieee80211_channel_to_frequency(target_channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); -done: - kfree(buf); cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); WL_CONN("Report roaming result\n"); - set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); + set_bit(WL_STATUS_CONNECTED, &cfg->status); WL_TRACE("Exit\n"); return err; } @@ -4033,15 +4648,13 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, const struct brcmf_event_msg *e, bool completed) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); s32 err = 0; WL_TRACE("Enter\n"); - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING, - &ifp->vif->sme_state)) { + if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) { if (completed) { brcmf_get_assoc_ies(cfg); memcpy(profile->bssid, e->addr, ETH_ALEN); @@ -4057,8 +4670,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); if (completed) - set_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state); + set_bit(WL_STATUS_CONNECTED, &cfg->status); WL_CONN("Report connect result - connection %s\n", completed ? "succeeded" : "failed"); } @@ -4072,9 +4684,9 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e, void *data) { s32 err = 0; - u32 event = e->event_code; - u32 reason = e->reason; - u32 len = e->datalen; + u32 event = be32_to_cpu(e->event_type); + u32 reason = be32_to_cpu(e->reason); + u32 len = be32_to_cpu(e->datalen); static int generation; struct station_info sinfo; @@ -4106,12 +4718,11 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, } static s32 -brcmf_notify_connect_status(struct brcmf_if *ifp, +brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; - struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct brcmf_cfg80211_profile *profile = cfg->profile; s32 err = 0; if (cfg->conf->mode == WL_MODE_AP) { @@ -4122,34 +4733,30 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, memcpy(profile->bssid, e->addr, ETH_ALEN); wl_inform_ibss(cfg, ndev, e->addr); cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); - clear_bit(BRCMF_VIF_STATUS_CONNECTING, - &ifp->vif->sme_state); - set_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state); + clear_bit(WL_STATUS_CONNECTING, &cfg->status); + set_bit(WL_STATUS_CONNECTED, &cfg->status); } else brcmf_bss_connect_done(cfg, ndev, e, true); } else if (brcmf_is_linkdown(cfg, e)) { WL_CONN("Linkdown\n"); if (brcmf_is_ibssmode(cfg)) { - clear_bit(BRCMF_VIF_STATUS_CONNECTING, - &ifp->vif->sme_state); - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state)) + clear_bit(WL_STATUS_CONNECTING, &cfg->status); + if (test_and_clear_bit(WL_STATUS_CONNECTED, + &cfg->status)) brcmf_link_down(cfg); } else { brcmf_bss_connect_done(cfg, ndev, e, false); - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, - &ifp->vif->sme_state)) { + if (test_and_clear_bit(WL_STATUS_CONNECTED, + &cfg->status)) { cfg80211_disconnected(ndev, 0, NULL, 0, - GFP_KERNEL); + GFP_KERNEL); brcmf_link_down(cfg); } } - brcmf_init_prof(ndev_to_prof(ndev)); + brcmf_init_prof(cfg->profile); } else if (brcmf_is_nonetwork(cfg, e)) { if (brcmf_is_ibssmode(cfg)) - clear_bit(BRCMF_VIF_STATUS_CONNECTING, - &ifp->vif->sme_state); + clear_bit(WL_STATUS_CONNECTING, &cfg->status); else brcmf_bss_connect_done(cfg, ndev, e, false); } @@ -4158,29 +4765,30 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, } static s32 -brcmf_notify_roaming_status(struct brcmf_if *ifp, +brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err = 0; - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { - if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) - brcmf_bss_roaming_done(cfg, ifp->ndev, e); + if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) + brcmf_bss_roaming_done(cfg, ndev, e); else - brcmf_bss_connect_done(cfg, ifp->ndev, e, true); + brcmf_bss_connect_done(cfg, ndev, e, true); } return err; } static s32 -brcmf_notify_mic_status(struct brcmf_if *ifp, +brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - u16 flags = e->flags; + u16 flags = be16_to_cpu(e->flags); enum nl80211_key_type key_type; if (flags & BRCMF_EVENT_MSG_GROUP) @@ -4188,12 +4796,82 @@ brcmf_notify_mic_status(struct brcmf_if *ifp, else key_type = NL80211_KEYTYPE_PAIRWISE; - cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1, + cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL); return 0; } +static s32 +brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) +{ + struct brcmf_channel_info_le channel_inform_le; + struct brcmf_scan_results_le *bss_list_le; + u32 len = WL_SCAN_BUF_MAX; + s32 err = 0; + bool scan_abort = false; + u32 scan_channel; + + WL_TRACE("Enter\n"); + + if (cfg->iscan_on && cfg->iscan_kickstart) { + WL_TRACE("Exit\n"); + return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); + } + + if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { + WL_ERR("Scan complete while device not scanning\n"); + scan_abort = true; + err = -EINVAL; + goto scan_done_out; + } + + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le, + sizeof(channel_inform_le)); + if (err) { + WL_ERR("scan busy (%d)\n", err); + scan_abort = true; + goto scan_done_out; + } + scan_channel = le32_to_cpu(channel_inform_le.scan_channel); + if (scan_channel) + WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); + cfg->bss_list = cfg->scan_results; + bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list; + + memset(cfg->scan_results, 0, len); + bss_list_le->buflen = cpu_to_le32(len); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS, + cfg->scan_results, len); + if (err) { + WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); + err = -EINVAL; + scan_abort = true; + goto scan_done_out; + } + cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); + cfg->scan_results->version = le32_to_cpu(bss_list_le->version); + cfg->scan_results->count = le32_to_cpu(bss_list_le->count); + + err = brcmf_inform_bss(cfg); + if (err) + scan_abort = true; + +scan_done_out: + if (cfg->scan_request) { + WL_SCAN("calling cfg80211_scan_done\n"); + cfg80211_scan_done(cfg->scan_request, scan_abort); + brcmf_set_mpc(ndev, 1); + cfg->scan_request = NULL; + } + + WL_TRACE("Exit\n"); + + return err; +} + static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) { conf->mode = (u32)-1; @@ -4204,53 +4882,82 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) conf->tx_power = -1; } -static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) -{ - brcmf_fweh_register(cfg->pub, BRCMF_E_LINK, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM, - brcmf_notify_roaming_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR, - brcmf_notify_mic_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, - brcmf_notify_sched_scan_results); +static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) +{ + memset(el, 0, sizeof(*el)); + el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; + el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; + el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; + el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; + el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; } static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) { + kfree(cfg->scan_results); + cfg->scan_results = NULL; + kfree(cfg->bss_info); + cfg->bss_info = NULL; kfree(cfg->conf); cfg->conf = NULL; + kfree(cfg->profile); + cfg->profile = NULL; + kfree(cfg->scan_req_int); + cfg->scan_req_int = NULL; kfree(cfg->escan_ioctl_buf); cfg->escan_ioctl_buf = NULL; + kfree(cfg->dcmd_buf); + cfg->dcmd_buf = NULL; kfree(cfg->extra_buf); cfg->extra_buf = NULL; + kfree(cfg->iscan); + cfg->iscan = NULL; kfree(cfg->pmk_list); cfg->pmk_list = NULL; + if (cfg->ap_info) { + kfree(cfg->ap_info->wpa_ie); + kfree(cfg->ap_info->rsn_ie); + kfree(cfg->ap_info); + cfg->ap_info = NULL; + } } static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) { + cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); + if (!cfg->scan_results) + goto init_priv_mem_out; cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); if (!cfg->conf) goto init_priv_mem_out; + cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL); + if (!cfg->profile) + goto init_priv_mem_out; + cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (!cfg->bss_info) + goto init_priv_mem_out; + cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int), + GFP_KERNEL); + if (!cfg->scan_req_int) + goto init_priv_mem_out; cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); if (!cfg->escan_ioctl_buf) goto init_priv_mem_out; + cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); + if (!cfg->dcmd_buf) + goto init_priv_mem_out; cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (!cfg->extra_buf) goto init_priv_mem_out; + cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL); + if (!cfg->iscan) + goto init_priv_mem_out; cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); if (!cfg->pmk_list) goto init_priv_mem_out; @@ -4263,24 +4970,152 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) return -ENOMEM; } +/* +* retrieve first queued event from head +*/ + +static struct brcmf_cfg80211_event_q *brcmf_deq_event( + struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_event_q *e = NULL; + + spin_lock_irq(&cfg->evt_q_lock); + if (!list_empty(&cfg->evt_q_list)) { + e = list_first_entry(&cfg->evt_q_list, + struct brcmf_cfg80211_event_q, evt_q_list); + list_del(&e->evt_q_list); + } + spin_unlock_irq(&cfg->evt_q_lock); + + return e; +} + +/* +* push event to tail of the queue +* +* remark: this function may not sleep as it is called in atomic context. +*/ + +static s32 +brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event, + const struct brcmf_event_msg *msg, void *data) +{ + struct brcmf_cfg80211_event_q *e; + s32 err = 0; + ulong flags; + u32 data_len; + u32 total_len; + + total_len = sizeof(struct brcmf_cfg80211_event_q); + if (data) + data_len = be32_to_cpu(msg->datalen); + else + data_len = 0; + total_len += data_len; + e = kzalloc(total_len, GFP_ATOMIC); + if (!e) + return -ENOMEM; + + e->etype = event; + memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); + if (data) + memcpy(&e->edata, data, data_len); + + spin_lock_irqsave(&cfg->evt_q_lock, flags); + list_add_tail(&e->evt_q_list, &cfg->evt_q_list); + spin_unlock_irqrestore(&cfg->evt_q_lock, flags); + + return err; +} + +static void brcmf_put_event(struct brcmf_cfg80211_event_q *e) +{ + kfree(e); +} + +static void brcmf_cfg80211_event_handler(struct work_struct *work) +{ + struct brcmf_cfg80211_info *cfg = + container_of(work, struct brcmf_cfg80211_info, + event_work); + struct brcmf_cfg80211_event_q *e; + + e = brcmf_deq_event(cfg); + if (unlikely(!e)) { + WL_ERR("event queue empty...\n"); + return; + } + + do { + WL_INFO("event type (%d)\n", e->etype); + if (cfg->el.handler[e->etype]) + cfg->el.handler[e->etype](cfg, + cfg_to_ndev(cfg), + &e->emsg, e->edata); + else + WL_INFO("Unknown Event (%d): ignoring\n", e->etype); + brcmf_put_event(e); + } while ((e = brcmf_deq_event(cfg))); + +} + +static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg) +{ + spin_lock_init(&cfg->evt_q_lock); + INIT_LIST_HEAD(&cfg->evt_q_list); +} + +static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_event_q *e; + + spin_lock_irq(&cfg->evt_q_lock); + while (!list_empty(&cfg->evt_q_list)) { + e = list_first_entry(&cfg->evt_q_list, + struct brcmf_cfg80211_event_q, evt_q_list); + list_del(&e->evt_q_list); + kfree(e); + } + spin_unlock_irq(&cfg->evt_q_lock); +} + static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) { s32 err = 0; cfg->scan_request = NULL; cfg->pwr_save = true; +#ifdef CONFIG_BRCMISCAN + cfg->iscan_on = true; /* iscan on & off switch. + we enable iscan per default */ + cfg->escan_on = false; /* escan on & off switch. + we disable escan per default */ +#else + cfg->iscan_on = false; /* iscan on & off switch. + we disable iscan per default */ + cfg->escan_on = true; /* escan on & off switch. + we enable escan per default */ +#endif cfg->roam_on = true; /* roam on & off switch. we enable roam per default */ + + cfg->iscan_kickstart = false; cfg->active_scan = true; /* we do active scan for specific scan per default */ cfg->dongle_up = false; /* dongle is not up yet */ + brcmf_init_eq(cfg); err = brcmf_init_priv_mem(cfg); if (err) return err; - brcmf_register_event_handlers(cfg); + INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler); + brcmf_init_eloop_handler(&cfg->el); mutex_init(&cfg->usr_sync); + err = brcmf_init_iscan(cfg); + if (err) + return err; brcmf_init_escan(cfg); brcmf_init_conf(cfg->conf); + brcmf_init_prof(cfg->profile); brcmf_link_down(cfg); return err; @@ -4288,20 +5123,20 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) { + cancel_work_sync(&cfg->event_work); cfg->dongle_up = false; /* dongle down */ + brcmf_flush_eq(cfg); brcmf_link_down(cfg); brcmf_abort_scanning(cfg); brcmf_deinit_priv_mem(cfg); } -struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr) +struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev, + struct device *busdev, + struct brcmf_pub *drvr) { - struct net_device *ndev = drvr->iflist[0]->ndev; - struct device *busdev = drvr->dev; + struct wireless_dev *wdev; struct brcmf_cfg80211_info *cfg; - struct wiphy *wiphy; - struct brcmf_cfg80211_vif *vif; - struct brcmf_if *ifp; s32 err = 0; if (!ndev) { @@ -4309,61 +5144,157 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr) return NULL; } - ifp = netdev_priv(ndev); - wiphy = brcmf_setup_wiphy(busdev); - if (IS_ERR(wiphy)) - return NULL; - - cfg = wiphy_priv(wiphy); - cfg->wiphy = wiphy; - cfg->pub = drvr; - INIT_LIST_HEAD(&cfg->vif_list); - - vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false); - if (IS_ERR(vif)) { - wiphy_free(wiphy); + wdev = brcmf_alloc_wdev(busdev); + if (IS_ERR(wdev)) { return NULL; } + wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); + cfg = wdev_to_cfg(wdev); + cfg->wdev = wdev; + cfg->pub = drvr; + ndev->ieee80211_ptr = wdev; + SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); + wdev->netdev = ndev; err = wl_init_priv(cfg); if (err) { WL_ERR("Failed to init iwm_priv (%d)\n", err); goto cfg80211_attach_out; } - ifp->vif = vif; return cfg; cfg80211_attach_out: - brcmf_free_vif(vif); + brcmf_free_wdev(cfg); return NULL; } void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_vif *vif; - struct brcmf_cfg80211_vif *tmp; - wl_deinit_priv(cfg); - list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { - brcmf_free_vif(vif); + brcmf_free_wdev(cfg); +} + +void +brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) +{ + u32 event_type = be32_to_cpu(e->event_type); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + + if (!brcmf_enq_event(cfg, event_type, e, data)) + schedule_work(&cfg->event_work); +} + +static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) +{ + s32 infra = 0; + s32 err = 0; + + switch (iftype) { + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_WDS: + WL_ERR("type (%d) : currently we do not support this mode\n", + iftype); + err = -EINVAL; + return err; + case NL80211_IFTYPE_ADHOC: + infra = 0; + break; + case NL80211_IFTYPE_STATION: + infra = 1; + break; + case NL80211_IFTYPE_AP: + infra = 1; + break; + default: + err = -EINVAL; + WL_ERR("invalid type (%d)\n", iftype); + return err; + } + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); + if (err) { + WL_ERR("WLC_SET_INFRA error (%d)\n", err); + return err; + } + + return 0; +} + +static s32 brcmf_dongle_eventmsg(struct net_device *ndev) +{ + /* Room for "event_msgs" + '\0' + bitvec */ + s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + s32 err = 0; + + WL_TRACE("Enter\n"); + + /* Setup event_msgs */ + brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf)); + if (err) { + WL_ERR("Get event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; + } + memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); + + setbit(eventmask, BRCMF_E_SET_SSID); + setbit(eventmask, BRCMF_E_ROAM); + setbit(eventmask, BRCMF_E_PRUNE); + setbit(eventmask, BRCMF_E_AUTH); + setbit(eventmask, BRCMF_E_REASSOC); + setbit(eventmask, BRCMF_E_REASSOC_IND); + setbit(eventmask, BRCMF_E_DEAUTH_IND); + setbit(eventmask, BRCMF_E_DISASSOC_IND); + setbit(eventmask, BRCMF_E_DISASSOC); + setbit(eventmask, BRCMF_E_JOIN); + setbit(eventmask, BRCMF_E_ASSOC_IND); + setbit(eventmask, BRCMF_E_PSK_SUP); + setbit(eventmask, BRCMF_E_LINK); + setbit(eventmask, BRCMF_E_NDIS_LINK); + setbit(eventmask, BRCMF_E_MIC_ERROR); + setbit(eventmask, BRCMF_E_PMKID_CACHE); + setbit(eventmask, BRCMF_E_TXFAIL); + setbit(eventmask, BRCMF_E_JOIN_START); + setbit(eventmask, BRCMF_E_SCAN_COMPLETE); + setbit(eventmask, BRCMF_E_ESCAN_RESULT); + setbit(eventmask, BRCMF_E_PFN_NET_FOUND); + + brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); + if (err) { + WL_ERR("Set event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; } + +dongle_eventmsg_out: + WL_TRACE("Exit\n"); + return err; } static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) { - struct brcmf_if *ifp = netdev_priv(ndev); + s8 iovbuf[32]; s32 err = 0; __le32 roamtrigger[2]; __le32 roam_delta[2]; + __le32 bcn_to_le; + __le32 roamvar_le; /* * Setup timeout if Beacons are lost and roam is * off to report link down */ if (roamvar) { - err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); + bcn_to_le = cpu_to_le32(bcn_timeout); + brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le, + sizeof(bcn_to_le), iovbuf, sizeof(iovbuf)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); if (err) { WL_ERR("bcn_timeout error (%d)\n", err); goto dongle_rom_out; @@ -4375,7 +5306,10 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) * to take care of roaming */ WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On"); - err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar); + roamvar_le = cpu_to_le32(roamvar); + brcmf_c_mkiovar("roam_off", (char *)&roamvar_le, + sizeof(roamvar_le), iovbuf, sizeof(iovbuf)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); if (err) { WL_ERR("roam_off error (%d)\n", err); goto dongle_rom_out; @@ -4383,8 +5317,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL); roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER, - (void *)roamtrigger, sizeof(roamtrigger)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER, + (void *)roamtrigger, sizeof(roamtrigger)); if (err) { WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err); goto dongle_rom_out; @@ -4392,8 +5326,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA); roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA, - (void *)roam_delta, sizeof(roam_delta)); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA, + (void *)roam_delta, sizeof(roam_delta)); if (err) { WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err); goto dongle_rom_out; @@ -4407,11 +5341,13 @@ static s32 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; + __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time); + __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time); + __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, - scan_assoc_time); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME, + &scan_assoc_tm_le, sizeof(scan_assoc_tm_le)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan assoc time is not supported\n"); @@ -4419,8 +5355,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, WL_ERR("Scan assoc time error (%d)\n", err); goto dongle_scantime_out; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, - scan_unassoc_time); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME, + &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan unassoc time is not supported\n"); @@ -4429,8 +5365,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, goto dongle_scantime_out; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME, - scan_passive_time); + err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME, + &scan_passive_tm_le, sizeof(scan_passive_tm_le)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan passive time is not supported\n"); @@ -4445,14 +5381,13 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct wiphy *wiphy; s32 phy_list; s8 phy; s32 err = 0; - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, - &phy_list, sizeof(phy_list)); + err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST, + &phy_list, sizeof(phy_list)); if (err) { WL_ERR("error (%d)\n", err); return err; @@ -4489,9 +5424,12 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); + err = brcmf_dongle_eventmsg(ndev); + if (err) + goto default_conf_out; + power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; - err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, - power_mode); + err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode); if (err) goto default_conf_out; WL_INFO("power save set to %s\n", @@ -4501,8 +5439,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) WL_BEACON_TIMEOUT); if (err) goto default_conf_out; - err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype, - NULL, NULL); + err = brcmf_dongle_mode(ndev, wdev->iftype); if (err && err != -EINPROGRESS) goto default_conf_out; err = brcmf_dongle_probecap(cfg); @@ -4519,26 +5456,66 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) } -static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) +static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg) { - set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); - if (ifp->idx) - return 0; + char buf[10+IFNAMSIZ]; + struct dentry *fd; + s32 err = 0; + + sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name); + cfg->debugfsdir = debugfs_create_dir(buf, + cfg_to_wiphy(cfg)->debugfsdir); - return brcmf_config_dongle(ifp->drvr->config); + fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir, + (u16 *)&cfg->profile->beacon_interval); + if (!fd) { + err = -ENOMEM; + goto err_out; + } + + fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir, + (u8 *)&cfg->profile->dtim_period); + if (!fd) { + err = -ENOMEM; + goto err_out; + } + +err_out: + return err; } -static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) +static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + debugfs_remove_recursive(cfg->debugfsdir); + cfg->debugfsdir = NULL; +} + +static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) +{ + s32 err = 0; + set_bit(WL_STATUS_READY, &cfg->status); + + brcmf_debugfs_add_netdev_params(cfg); + + err = brcmf_config_dongle(cfg); + if (err) + return err; + + brcmf_invoke_iscan(cfg); + + return err; +} + +static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) +{ /* * While going down, if associated with AP disassociate * from AP to save power */ - if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) || - test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) && - check_vif_up(ifp->vif)) { + if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || + test_bit(WL_STATUS_CONNECTING, &cfg->status)) && + test_bit(WL_STATUS_READY, &cfg->status)) { WL_INFO("Disassociating from AP"); brcmf_link_down(cfg); @@ -4550,32 +5527,30 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) } brcmf_abort_scanning(cfg); - clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); + clear_bit(WL_STATUS_READY, &cfg->status); + + brcmf_debugfs_remove_netdev(cfg); return 0; } -s32 brcmf_cfg80211_up(struct net_device *ndev) +s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err = 0; mutex_lock(&cfg->usr_sync); - err = __brcmf_cfg80211_up(ifp); + err = __brcmf_cfg80211_up(cfg); mutex_unlock(&cfg->usr_sync); return err; } -s32 brcmf_cfg80211_down(struct net_device *ndev) +s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err = 0; mutex_lock(&cfg->usr_sync); - err = __brcmf_cfg80211_down(ifp); + err = __brcmf_cfg80211_down(cfg); mutex_unlock(&cfg->usr_sync); return err; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index e2ef8519ea84..71ced174748a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -84,12 +84,31 @@ do { \ #define WL_CONN(fmt, args...) #endif /* (defined DEBUG) */ -#define WL_NUM_SCAN_MAX 10 -#define WL_NUM_PMKIDS_MAX MAXPMKID +#define WL_NUM_SCAN_MAX 1 +#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used + * for 2.6.33 kernel + * or later + */ +#define WL_SCAN_BUF_MAX (1024 * 8) #define WL_TLV_INFO_MAX 1024 #define WL_BSS_INFO_MAX 2048 -#define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */ -#define WL_EXTRA_BUF_MAX 2048 +#define WL_ASSOC_INFO_MAX 512 /* + * needs to grab assoc info from dongle to + * report it to cfg80211 through "connect" + * event + */ +#define WL_DCMD_LEN_MAX 1024 +#define WL_EXTRA_BUF_MAX 2048 +#define WL_ISCAN_BUF_MAX 2048 /* + * the buf length can be BRCMF_DCMD_MAXLEN + * to reduce iteration + */ +#define WL_ISCAN_TIMER_INTERVAL_MS 3000 +#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1) +#define WL_AP_MAX 256 /* virtually unlimitted as long + * as kernel memory allows + */ + #define WL_ROAM_TRIGGER_LEVEL -75 #define WL_ROAM_DELTA 20 #define WL_BEACON_TIMEOUT 3 @@ -108,15 +127,15 @@ do { \ #define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ #define IE_MAX_LEN 512 -/** - * enum brcmf_scan_status - dongle scan status - * - * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle. - * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle. - */ -enum brcmf_scan_status { - BRCMF_SCAN_STATUS_BUSY, - BRCMF_SCAN_STATUS_ABORT, +/* dongle status */ +enum wl_status { + WL_STATUS_READY, + WL_STATUS_SCANNING, + WL_STATUS_SCAN_ABORTING, + WL_STATUS_CONNECTING, + WL_STATUS_CONNECTED, + WL_STATUS_AP_CREATING, + WL_STATUS_AP_CREATED }; /* wi-fi mode */ @@ -126,6 +145,25 @@ enum wl_mode { WL_MODE_AP }; +/* dongle profile list */ +enum wl_prof_list { + WL_PROF_MODE, + WL_PROF_SSID, + WL_PROF_SEC, + WL_PROF_IBSS, + WL_PROF_BAND, + WL_PROF_BSSID, + WL_PROF_ACT, + WL_PROF_BEACONINT, + WL_PROF_DTIMPERIOD +}; + +/* dongle iscan state */ +enum wl_iscan_state { + WL_ISCAN_STATE_IDLE, + WL_ISCAN_STATE_SCANING +}; + /* dongle configuration */ struct brcmf_cfg80211_conf { u32 mode; /* adhoc , infrastructure or ap */ @@ -137,6 +175,17 @@ struct brcmf_cfg80211_conf { struct ieee80211_channel channel; }; +/* forward declaration */ +struct brcmf_cfg80211_info; + +/* cfg80211 main event loop */ +struct brcmf_cfg80211_event_loop { + s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, + const struct brcmf_event_msg *e, + void *data); +}; + /* basic structure of scan request */ struct brcmf_cfg80211_scan_req { struct brcmf_ssid_le ssid_le; @@ -148,6 +197,14 @@ struct brcmf_cfg80211_ie { u8 buf[WL_TLV_INFO_MAX]; }; +/* event queue for cfg80211 main event */ +struct brcmf_cfg80211_event_q { + struct list_head evt_q_list; + u32 etype; + struct brcmf_event_msg emsg; + s8 edata[1]; +}; + /* security information with currently associated ap */ struct brcmf_cfg80211_security { u32 wpa_versions; @@ -157,73 +214,45 @@ struct brcmf_cfg80211_security { u32 wpa_auth; }; -/** - * struct brcmf_cfg80211_profile - profile information. - * - * @ssid: ssid of associated/associating ap. - * @bssid: bssid of joined/joining ibss. - * @sec: security information. - */ +/* ibss information for currently joined ibss network */ +struct brcmf_cfg80211_ibss { + u8 beacon_interval; /* in millisecond */ + u8 atim; /* in millisecond */ + s8 join_only; + u8 band; + u8 channel; +}; + +/* dongle profile */ struct brcmf_cfg80211_profile { + u32 mode; struct brcmf_ssid ssid; u8 bssid[ETH_ALEN]; + u16 beacon_interval; + u8 dtim_period; struct brcmf_cfg80211_security sec; + struct brcmf_cfg80211_ibss ibss; + s32 band; }; -/** - * enum brcmf_vif_status - bit indices for vif status. - * - * @BRCMF_VIF_STATUS_READY: ready for operation. - * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress. - * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully. - * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation. - * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started. - */ -enum brcmf_vif_status { - BRCMF_VIF_STATUS_READY, - BRCMF_VIF_STATUS_CONNECTING, - BRCMF_VIF_STATUS_CONNECTED, - BRCMF_VIF_STATUS_AP_CREATING, - BRCMF_VIF_STATUS_AP_CREATED -}; - -/** - * struct vif_saved_ie - holds saved IEs for a virtual interface. - * - * @probe_res_ie: IE info for probe response. - * @beacon_ie: IE info for beacon frame. - * @probe_res_ie_len: IE info length for probe response. - * @beacon_ie_len: IE info length for beacon frame. - */ -struct vif_saved_ie { - u8 probe_res_ie[IE_MAX_LEN]; - u8 beacon_ie[IE_MAX_LEN]; - u32 probe_res_ie_len; - u32 beacon_ie_len; +/* dongle iscan event loop */ +struct brcmf_cfg80211_iscan_eloop { + s32 (*handler[WL_SCAN_ERSULTS_LAST]) + (struct brcmf_cfg80211_info *cfg); }; -/** - * struct brcmf_cfg80211_vif - virtual interface specific information. - * - * @ifp: lower layer interface pointer - * @wdev: wireless device. - * @profile: profile information. - * @mode: operating mode. - * @roam_off: roaming state. - * @sme_state: SME state using enum brcmf_vif_status bits. - * @pm_block: power-management blocked. - * @list: linked list. - */ -struct brcmf_cfg80211_vif { - struct brcmf_if *ifp; - struct wireless_dev wdev; - struct brcmf_cfg80211_profile profile; - s32 mode; - s32 roam_off; - unsigned long sme_state; - bool pm_block; - struct vif_saved_ie saved_ie; - struct list_head list; +/* dongle iscan controller */ +struct brcmf_cfg80211_iscan_ctrl { + struct net_device *ndev; + struct timer_list timer; + u32 timer_ms; + u32 timer_on; + s32 state; + struct work_struct work; + struct brcmf_cfg80211_iscan_eloop el; + void *data; + s8 dcmd_buf[BRCMF_DCMD_SMLEN]; + s8 scan_buf[WL_ISCAN_BUF_MAX]; }; /* association inform */ @@ -259,6 +288,17 @@ struct escan_info { struct net_device *ndev; }; +/* Structure to hold WPS, WPA IEs for a AP */ +struct ap_info { + u8 probe_res_ie[IE_MAX_LEN]; + u8 beacon_ie[IE_MAX_LEN]; + u32 probe_res_ie_len; + u32 beacon_ie_len; + u8 *wpa_ie; + u8 *rsn_ie; + bool security_mode; +}; + /** * struct brcmf_pno_param_le - PNO scan configuration parameters * @@ -343,19 +383,28 @@ struct brcmf_pno_scanresults_le { /** * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface * - * @wiphy: wiphy object for cfg80211 interface. + * @wdev: representing wl cfg80211 device. * @conf: dongle configuration. * @scan_request: cfg80211 scan request object. + * @el: main event loop. + * @evt_q_list: used for event queue. + * @evt_q_lock: for event queue synchronization. * @usr_sync: mainly for dongle up/down synchronization. * @bss_list: bss_list holding scanned ap information. + * @scan_results: results of the last scan. * @scan_req_int: internal scan request object. * @bss_info: bss information for cfg80211 layer. * @ie: information element object for internal purpose. + * @profile: holding dongle profile. + * @iscan: iscan controller information. * @conn_info: association info. * @pmk_list: wpa2 pmk list. - * @scan_status: scan activity on the dongle. + * @event_work: event handler work struct. + * @status: current dongle status. * @pub: common driver information. * @channel: current channel. + * @iscan_on: iscan on/off switch. + * @iscan_kickstart: indicate iscan already started. * @active_scan: current scan mode. * @sched_escan: e-scan for scheduled scan support running. * @ibss_starter: indicates this sta is ibss starter. @@ -367,27 +416,37 @@ struct brcmf_pno_scanresults_le { * @dcmd_buf: dcmd buffer. * @extra_buf: mainly to grab assoc information. * @debugfsdir: debugfs folder for this device. + * @escan_on: escan on/off switch. * @escan_info: escan information. * @escan_timeout: Timer for catch scan timeout. * @escan_timeout_work: scan timeout worker. * @escan_ioctl_buf: dongle command buffer for escan commands. - * @vif_list: linked list of vif instances. - * @vif_cnt: number of vif instances. + * @ap_info: host ap information. + * @ci: used to link this structure to netdev private data. */ struct brcmf_cfg80211_info { - struct wiphy *wiphy; + struct wireless_dev *wdev; struct brcmf_cfg80211_conf *conf; struct cfg80211_scan_request *scan_request; + struct brcmf_cfg80211_event_loop el; + struct list_head evt_q_list; + spinlock_t evt_q_lock; struct mutex usr_sync; struct brcmf_scan_results *bss_list; - struct brcmf_cfg80211_scan_req scan_req_int; + struct brcmf_scan_results *scan_results; + struct brcmf_cfg80211_scan_req *scan_req_int; struct wl_cfg80211_bss_info *bss_info; struct brcmf_cfg80211_ie ie; + struct brcmf_cfg80211_profile *profile; + struct brcmf_cfg80211_iscan_ctrl *iscan; struct brcmf_cfg80211_connect_info conn_info; struct brcmf_cfg80211_pmk_list *pmk_list; - unsigned long scan_status; + struct work_struct event_work; + unsigned long status; struct brcmf_pub *pub; u32 channel; + bool iscan_on; + bool iscan_kickstart; bool active_scan; bool sched_escan; bool ibss_starter; @@ -399,17 +458,17 @@ struct brcmf_cfg80211_info { u8 *dcmd_buf; u8 *extra_buf; struct dentry *debugfsdir; + bool escan_on; struct escan_info escan_info; struct timer_list escan_timeout; struct work_struct escan_timeout_work; u8 *escan_ioctl_buf; - struct list_head vif_list; - u8 vif_cnt; + struct ap_info *ap_info; }; -static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) +static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w) { - return cfg->wiphy; + return w->wdev->wiphy; } static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) @@ -422,12 +481,9 @@ static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); } -static inline -struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) +static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_vif *vif; - vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list); - return vif->wdev.netdev; + return cfg->wdev->netdev; } static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) @@ -435,17 +491,8 @@ static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) return wdev_to_cfg(ndev->ieee80211_ptr); } -static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd) -{ - struct brcmf_if *ifp = netdev_priv(nd); - return &ifp->vif->profile; -} - -static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev) -{ - struct brcmf_if *ifp = netdev_priv(ndev); - return ifp->vif; -} +#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) +#define cfg_to_iscan(w) (w->iscan) static inline struct brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) @@ -453,9 +500,15 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) return &cfg->conn_info; } -struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); +struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev, + struct device *busdev, + struct brcmf_pub *drvr); void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); -s32 brcmf_cfg80211_up(struct net_device *ndev); -s32 brcmf_cfg80211_down(struct net_device *ndev); + +/* event handler from dongle */ +void brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data); +s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg); +s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg); #endif /* _wl_cfg80211_h_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile index d3d4151c3eda..e227c4c68ef9 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile @@ -40,8 +40,7 @@ BRCMSMAC_OFILES := \ phy/phytbl_n.o \ phy/phy_qmath.o \ dma.o \ - brcms_trace_events.o \ - debug.o + brcms_trace_events.o MODULEPFX := brcmsmac diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index de96290f5ccd..b89f1272b93f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -692,7 +692,7 @@ void ai_pci_up(struct si_pub *sih) sii = container_of(sih, struct si_info, pub); if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) - bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true); + bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true); } /* Unconfigure and/or apply various WARs when going down */ @@ -703,7 +703,7 @@ void ai_pci_down(struct si_pub *sih) sii = container_of(sih, struct si_info, pub); if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) - bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false); + bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false); } /* Enable BT-COEX & Ex-PA for 4313 */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 1de94f30564f..be5bcfb9153b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -21,8 +21,6 @@ #include "antsel.h" #include "main.h" #include "ampdu.h" -#include "debug.h" -#include "brcms_trace_events.h" /* max number of mpdus in an ampdu */ #define AMPDU_MAX_MPDU 32 @@ -42,6 +40,8 @@ #define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit at reg rate */ #define AMPDU_DEF_RR_RETRY_LIMIT 2 +/* default weight of ampdu in txfifo */ +#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default ffpld reserved bytes */ #define AMPDU_DEF_FFPLD_RSVD 2048 /* # of inis to be freed on detach */ @@ -114,6 +114,7 @@ struct brcms_fifo_info { * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec * max_pdu: max pdus allowed in ampdu * dur: max duration of an ampdu (in msec) + * txpkt_weight: weight of ampdu in txfifo; reduces rate lag * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes * ffpld_rsvd: number of bytes to reserve for preload * max_txlen: max size of ampdu per mcs, bw and sgi @@ -135,6 +136,7 @@ struct ampdu_info { u8 mpdu_density; s8 max_pdu; u8 dur; + u8 txpkt_weight; u8 rx_factor; u32 ffpld_rsvd; u32 max_txlen[MCS_TABLE_SIZE][2][2]; @@ -181,19 +183,18 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu) static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) { struct brcms_c_info *wlc = ampdu->wlc; - struct bcma_device *core = wlc->hw->d11core; wlc->pub->_ampdu = false; if (on) { if (!(wlc->pub->_n_enab & SUPPORT_11N)) { - brcms_err(core, "wl%d: driver not nmode enabled\n", - wlc->pub->unit); + wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " + "nmode enabled\n", wlc->pub->unit); return -ENOTSUPP; } if (!brcms_c_ampdu_cap(ampdu)) { - brcms_err(core, "wl%d: device not ampdu capable\n", - wlc->pub->unit); + wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " + "ampdu capable\n", wlc->pub->unit); return -ENOTSUPP; } wlc->pub->_ampdu = on; @@ -246,6 +247,7 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; ampdu->max_pdu = AUTO; ampdu->dur = AMPDU_MAX_DUR; + ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; /* @@ -372,8 +374,7 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) offsetof(struct macstat, txfunfl[fid])); new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); if (new_txunfl == 0) { - brcms_dbg_ht(wlc->hw->d11core, - "TX status FRAG set but no tx underflows\n"); + BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); return -1; } fifo->prev_txfunfl = cur_txunfl; @@ -395,8 +396,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); + BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); /* compute the current ratio of tx unfl per ampdu. @@ -449,10 +450,9 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - brcms_dbg_ht(wlc->hw->d11core, - "DMA estimated transfer rate %d; " - "pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size); + BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " + "pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); } else { /* decrease ampdu size */ @@ -486,7 +486,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, scb_ampdu = &scb->scb_ampdu; if (!ampdu->ini_enable[tid]) { - brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n", + wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", __func__, tid); return; } @@ -498,324 +498,378 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; } -void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc) +int +brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, + struct sk_buff **pdu, int prec) { - session->wlc = wlc; - skb_queue_head_init(&session->skb_list); - session->max_ampdu_len = 0; /* determined from first MPDU */ - session->max_ampdu_frames = 0; /* determined from first MPDU */ - session->ampdu_len = 0; - session->dma_len = 0; -} + struct brcms_c_info *wlc; + struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; + u8 tid, ndelim; + int err = 0; + u8 preamble_type = BRCMS_GF_PREAMBLE; + u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; + u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; + u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; -/* - * Preps the given packet for AMPDU based on the session data. If the - * frame cannot be accomodated in the current session, -ENOSPC is - * returned. - */ -int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p) -{ - struct brcms_c_info *wlc = session->wlc; - struct ampdu_info *ampdu = wlc->ampdu; - struct scb *scb = &wlc->pri_scb; - struct scb_ampdu *scb_ampdu = &scb->scb_ampdu; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); - struct ieee80211_tx_rate *txrate = tx_info->status.rates; - struct d11txh *txh = (struct d11txh *)p->data; - unsigned ampdu_frames; - u8 ndelim, tid; + bool rr = true, fbr = false; + uint i, count = 0, fifo, seg_cnt = 0; + u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; + u32 ampdu_len, max_ampdu_bytes = 0; + struct d11txh *txh = NULL; u8 *plcp; - uint len; - u16 mcl; + struct ieee80211_hdr *h; + struct scb *scb; + struct scb_ampdu *scb_ampdu; + struct scb_ampdu_tid_ini *ini; + u8 mcs = 0; + bool use_rts = false, use_cts = false; + u32 rspec = 0, rspec_fallback = 0; + u32 rts_rspec = 0, rts_rspec_fallback = 0; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; + struct ieee80211_rts *rts; + u8 rr_retry_limit; + struct brcms_fifo_info *f; bool fbr_iscck; - bool rr; - - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - plcp = (u8 *)(txh + 1); - fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); - len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : - BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN; + struct ieee80211_tx_info *tx_info; + u16 qlen; + struct wiphy *wiphy; - ampdu_frames = skb_queue_len(&session->skb_list); - if (ampdu_frames != 0) { - struct sk_buff *first; + wlc = ampdu->wlc; + wiphy = wlc->wiphy; + p = *pdu; - if (ampdu_frames + 1 > session->max_ampdu_frames || - session->ampdu_len + len > session->max_ampdu_len) - return -ENOSPC; + tid = (u8) (p->priority); - /* - * We aren't really out of space if the new frame is of - * a different priority, but we want the same behaviour - * so return -ENOSPC anyway. - * - * XXX: The old AMPDU code did this, but is it really - * necessary? - */ - first = skb_peek(&session->skb_list); - if (p->priority != first->priority) - return -ENOSPC; - } + f = ampdu->fifo_tb + prio2fifo[tid]; - /* - * Now that we're sure this frame can be accomodated, update the - * session information. - */ - session->ampdu_len += len; - session->dma_len += p->len; + scb = &wlc->pri_scb; + scb_ampdu = &scb->scb_ampdu; + ini = &scb_ampdu->ini[tid]; - tid = (u8)p->priority; + /* Let pressure continue to build ... */ + qlen = pktq_plen(&qi->q, prec); + if (ini->tx_in_transit > 0 && + qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) + /* Collect multiple MPDU's to be sent in the next AMPDU */ + return -EBUSY; - /* Handle retry limits */ - if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) { - txrate[0].count++; - rr = true; - } else { - txrate[1].count++; - rr = false; - } + /* at this point we intend to transmit an AMPDU */ + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + ampdu_len = 0; + dma_len = 0; + while (p) { + struct ieee80211_tx_rate *txrate; - if (ampdu_frames == 0) { - u8 plcp0, plcp3, is40, sgi, mcs; - uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; - struct brcms_fifo_info *f = &du->fifo_tb[fifo]; + tx_info = IEEE80211_SKB_CB(p); + txrate = tx_info->status.rates; - if (rr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = brcms_c_prep_pdu(wlc, p, &fifo); } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; + wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); + *pdu = NULL; + err = 0; + break; + } + + if (err) { + if (err == -EBUSY) { + wiphy_err(wiphy, "wl%d: sendampdu: " + "prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); + *pdu = p; + break; + } + /* error in the packet; reject it */ + wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " + "rejected; seq 0x%x\n", wlc->pub->unit, seq); + *pdu = NULL; + break; } - /* Limit AMPDU size based on MCS */ - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = plcp3_issgi(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes, - ampdu->max_txlen[mcs][is40][sgi]); + /* pkt is good to be aggregated */ + txh = (struct d11txh *) p->data; + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; + index = TX_SEQ_TO_INDEX(seq); - session->max_ampdu_frames = scb_ampdu->max_pdu; - if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { - session->max_ampdu_frames = - min_t(u16, f->mcs2ampdu_table[mcs], - session->max_ampdu_frames); + /* check mcl fields and test whether it can be agg'd */ + mcl = le16_to_cpu(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); + txh->PreloadSize = 0; /* always default to 0 */ + + /* Handle retry limits */ + if (txrate[0].count <= rr_retry_limit) { + txrate[0].count++; + rr = true; + fbr = false; + } else { + fbr = true; + rr = false; + txrate[1].count++; } - } - /* - * Treat all frames as "middle" frames of AMPDU here. First and - * last frames must be fixed up after all MPDUs have been prepped. - */ - mcl = le16_to_cpu(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); - mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); - txh->MacTxControlLow = cpu_to_le16(mcl); - txh->PreloadSize = 0; /* always default to 0 */ + /* extract the length info */ + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - skb_queue_tail(&session->skb_list, p); + /* retrieve null delimiter count */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + seg_cnt += 1; - return 0; -} + BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); -void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) -{ - struct brcms_c_info *wlc = session->wlc; - struct ampdu_info *ampdu = wlc->ampdu; - struct sk_buff *first, *last; - struct d11txh *txh; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *txrate; - u8 ndelim; - u8 *plcp; - uint len; - uint fifo; - struct brcms_fifo_info *f; - u16 mcl; - bool fbr; - bool fbr_iscck; - struct ieee80211_rts *rts; - bool use_rts = false, use_cts = false; - u16 dma_len = session->dma_len; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - u32 rspec = 0, rspec_fallback = 0; - u32 rts_rspec = 0, rts_rspec_fallback = 0; - u8 plcp0, plcp3, is40, sgi, mcs; - u16 mch; - u8 preamble_type = BRCMS_GF_PREAMBLE; - u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; - u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; - u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; + /* + * aggregateable mpdu. For ucode/hw agg, + * test whether need to break or change the epoch + */ + if (count == 0) { + mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); + /* refill the bits since might be a retx mpdu */ + mcl |= TXC_STARTMSDU; + rts = (struct ieee80211_rts *)&txh->rts_frame; + + if (ieee80211_is_rts(rts->frame_control)) { + mcl |= TXC_SENDRTS; + use_rts = true; + } + if (ieee80211_is_cts(rts->frame_control)) { + mcl |= TXC_SENDCTS; + use_cts = true; + } + } else { + mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); + mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); + } - if (skb_queue_empty(&session->skb_list)) - return; + len = roundup(len, 4); + ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - first = skb_peek(&session->skb_list); - last = skb_peek_tail(&session->skb_list); - - /* Need to fix up last MPDU first to adjust AMPDU length */ - txh = (struct d11txh *)last->data; - fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; - f = &du->fifo_tb[fifo]; - - mcl = le16_to_cpu(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); - txh->MacTxControlLow = cpu_to_le16(mcl); - - /* remove the null delimiter after last mpdu */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; - session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; - - /* remove the pad len from last mpdu */ - fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); - len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : - BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - session->ampdu_len -= roundup(len, 4) - len; - - /* Now fix up the first MPDU */ - tx_info = IEEE80211_SKB_CB(first); - txrate = tx_info->status.rates; - txh = (struct d11txh *)first->data; - plcp = (u8 *)(txh + 1); - rts = (struct ieee80211_rts *)&txh->rts_frame; - - mcl = le16_to_cpu(txh->MacTxControlLow); - /* If only one MPDU leave it marked as last */ - if (first != last) { - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); - } - mcl |= TXC_STARTMSDU; - if (ieee80211_is_rts(rts->frame_control)) { - mcl |= TXC_SENDRTS; - use_rts = true; - } - if (ieee80211_is_cts(rts->frame_control)) { - mcl |= TXC_SENDCTS; - use_cts = true; - } - txh->MacTxControlLow = cpu_to_le16(mcl); + dma_len += (u16) p->len; - fbr = txrate[1].count > 0; - if (!fbr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; - } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; - } - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = plcp3_issgi(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - - if (is40) { - if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi))) - mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP; - else - mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - } + BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" + " seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); - /* rebuild the rspec and rspec_fallback */ - rspec = RSPEC_MIMORATE; - rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; - if (plcp[0] & MIMO_PLCP_40MHZ) - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + txh->MacTxControlLow = cpu_to_le16(mcl); - fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); - if (fbr_iscck) { - rspec_fallback = - cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0])); - } else { - rspec_fallback = RSPEC_MIMORATE; - rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; - if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) - rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT; - } + /* this packet is added */ + pkt[count++] = p; - if (use_rts || use_cts) { - rts_rspec = - brcms_c_rspec_to_rts_rspec(wlc, rspec, - false, mimo_ctlchbw); - rts_rspec_fallback = - brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback, - false, mimo_ctlchbw); - } + /* patch the first MPDU */ + if (count == 1) { + u8 plcp0, plcp3, is40, sgi; - BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len); - /* mark plcp to indicate ampdu */ - BRCMS_SET_MIMO_PLCP_AMPDU(plcp); + if (rr) { + plcp0 = plcp[0]; + plcp3 = plcp[3]; + } else { + plcp0 = txh->FragPLCPFallback[0]; + plcp3 = txh->FragPLCPFallback[3]; - /* reset the mixed mode header durations */ - if (txh->MModeLen) { - u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec, - session->ampdu_len); - txh->MModeLen = cpu_to_le16(mmodelen); - preamble_type = BRCMS_MM_PREAMBLE; - } - if (txh->MModeFbrLen) { - u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback, - session->ampdu_len); - txh->MModeFbrLen = cpu_to_le16(mmfbrlen); - fbr_preamble_type = BRCMS_MM_PREAMBLE; - } + } + is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; + sgi = plcp3_issgi(plcp3) ? 1 : 0; + mcs = plcp0 & ~MIMO_PLCP_40MHZ; + max_ampdu_bytes = + min(scb_ampdu->max_rx_ampdu_bytes, + ampdu->max_txlen[mcs][is40][sgi]); + + if (is40) + mimo_ctlchbw = + CHSPEC_SB_UPPER(wlc_phy_chanspec_get( + wlc->band->pi)) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + /* rebuild the rspec and rspec_fallback */ + rspec = RSPEC_MIMORATE; + rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; + if (plcp[0] & MIMO_PLCP_40MHZ) + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + + if (fbr_iscck) /* CCK */ + rspec_fallback = cck_rspec(cck_phy2mac_rate + (txh->FragPLCPFallback[0])); + else { /* MIMO */ + rspec_fallback = RSPEC_MIMORATE; + rspec_fallback |= + txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; + if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) + rspec_fallback |= + (PHY_TXC1_BW_40MHZ << + RSPEC_BW_SHIFT); + } - /* set the preload length */ - if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { - dma_len = min(dma_len, f->ampdu_pld_size); - txh->PreloadSize = cpu_to_le16(dma_len); - } else { - txh->PreloadSize = 0; - } + if (use_rts || use_cts) { + rts_rspec = + brcms_c_rspec_to_rts_rspec(wlc, + rspec, false, mimo_ctlchbw); + rts_rspec_fallback = + brcms_c_rspec_to_rts_rspec(wlc, + rspec_fallback, false, mimo_ctlchbw); + } + } + + /* if (first mpdu for host agg) */ + /* test whether to add more */ + if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) && + (count == f->mcs2ampdu_table[mcs])) { + BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" + " ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); + break; + } + + if (count == scb_ampdu->max_pdu) + break; + + /* + * check to see if the next pkt is + * a candidate for aggregation + */ + p = pktq_ppeek(&qi->q, prec); + if (p) { + tx_info = IEEE80211_SKB_CB(p); + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + ((u8) (p->priority) == tid)) { + plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; + plen = max(scb_ampdu->min_len, plen); - mch = le16_to_cpu(txh->MacTxControlHigh); + if ((plen + ampdu_len) > max_ampdu_bytes) { + p = NULL; + continue; + } - /* update RTS dur fields */ - if (use_rts || use_cts) { - u16 durid; - if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == - TXC_PREAMBLE_RTS_MAIN_SHORT) - rts_preamble_type = BRCMS_SHORT_PREAMBLE; + /* + * check if there are enough + * descriptors available + */ + if (*wlc->core->txavail[fifo] <= seg_cnt + 1) { + wiphy_err(wiphy, "%s: No fifo space " + "!!\n", __func__); + p = NULL; + continue; + } + /* next packet fit for aggregation so dequeue */ + p = brcmu_pktq_pdeq(&qi->q, prec); + } else { + p = NULL; + } + } + } /* end while(p) */ - if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == - TXC_PREAMBLE_RTS_FB_SHORT) - rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; + ini->tx_in_transit += count; - durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, - rspec, rts_preamble_type, - preamble_type, - session->ampdu_len, true); - rts->duration = cpu_to_le16(durid); - durid = brcms_c_compute_rtscts_dur(wlc, use_cts, - rts_rspec_fallback, - rspec_fallback, - rts_fbr_preamble_type, - fbr_preamble_type, - session->ampdu_len, true); - txh->RTSDurFallback = cpu_to_le16(durid); - /* set TxFesTimeNormal */ - txh->TxFesTimeNormal = rts->duration; - /* set fallback rate version of TxFesTimeNormal */ - txh->TxFesTimeFallback = txh->RTSDurFallback; - } + if (count) { + /* patch up the last txh */ + txh = (struct d11txh *) pkt[count - 1]->data; + mcl = le16_to_cpu(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); + txh->MacTxControlLow = cpu_to_le16(mcl); + + /* remove the null delimiter after last mpdu */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; + ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; + + /* remove the pad len from last mpdu */ + fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + ampdu_len -= roundup(len, 4) - len; + + /* patch up the first txh & plcp */ + txh = (struct d11txh *) pkt[0]->data; + plcp = (u8 *) (txh + 1); - /* set flag and plcp for fallback rate */ - if (fbr) { - mch |= TXC_AMPDU_FBR; - txh->MacTxControlHigh = cpu_to_le16(mch); + BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); + /* mark plcp to indicate ampdu */ BRCMS_SET_MIMO_PLCP_AMPDU(plcp); - BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); - } - brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n", - wlc->pub->unit, skb_queue_len(&session->skb_list), - session->ampdu_len); + /* reset the mixed mode header durations */ + if (txh->MModeLen) { + u16 mmodelen = + brcms_c_calc_lsig_len(wlc, rspec, ampdu_len); + txh->MModeLen = cpu_to_le16(mmodelen); + preamble_type = BRCMS_MM_PREAMBLE; + } + if (txh->MModeFbrLen) { + u16 mmfbrlen = + brcms_c_calc_lsig_len(wlc, rspec_fallback, + ampdu_len); + txh->MModeFbrLen = cpu_to_le16(mmfbrlen); + fbr_preamble_type = BRCMS_MM_PREAMBLE; + } + + /* set the preload length */ + if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { + dma_len = min(dma_len, f->ampdu_pld_size); + txh->PreloadSize = cpu_to_le16(dma_len); + } else + txh->PreloadSize = 0; + + mch = le16_to_cpu(txh->MacTxControlHigh); + + /* update RTS dur fields */ + if (use_rts || use_cts) { + u16 durid; + rts = (struct ieee80211_rts *)&txh->rts_frame; + if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == + TXC_PREAMBLE_RTS_MAIN_SHORT) + rts_preamble_type = BRCMS_SHORT_PREAMBLE; + + if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == + TXC_PREAMBLE_RTS_FB_SHORT) + rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; + + durid = + brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, + rspec, rts_preamble_type, + preamble_type, ampdu_len, + true); + rts->duration = cpu_to_le16(durid); + durid = brcms_c_compute_rtscts_dur(wlc, use_cts, + rts_rspec_fallback, + rspec_fallback, + rts_fbr_preamble_type, + fbr_preamble_type, + ampdu_len, true); + txh->RTSDurFallback = cpu_to_le16(durid); + /* set TxFesTimeNormal */ + txh->TxFesTimeNormal = rts->duration; + /* set fallback rate version of TxFesTimeNormal */ + txh->TxFesTimeFallback = txh->RTSDurFallback; + } + + /* set flag and plcp for fallback rate */ + if (fbr) { + mch |= TXC_AMPDU_FBR; + txh->MacTxControlHigh = cpu_to_le16(mch); + BRCMS_SET_MIMO_PLCP_AMPDU(plcp); + BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); + } + + BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); + + /* inform rate_sel if it this is a rate probe pkt */ + frameid = le16_to_cpu(txh->TxFrameID); + if (frameid & TXFID_RATE_PROBE_MASK) + wiphy_err(wiphy, "%s: XXX what to do with " + "TXFID_RATE_PROBE_MASK!?\n", __func__); + + for (i = 0; i < count; i++) + brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), + ampdu->txpkt_weight); + + } + /* endif (count) */ + return err; } static void @@ -855,6 +909,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u8 antselid = 0; u8 retry_limit, rr_retry_limit; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); + struct wiphy *wiphy = wlc->wiphy; #ifdef DEBUG u8 hole[AMPDU_MAX_MPDU]; @@ -900,14 +955,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - brcms_err(wlc->hw->d11core, + wiphy_err(wiphy, "%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL( wlc->default_bss->chanspec)); } else { if (supr_status != TX_STATUS_SUPR_FRAG) - brcms_err(wlc->hw->d11core, - "%s: supr_status 0x%x\n", + wiphy_err(wiphy, "%s: supr_status 0x%x\n", __func__, supr_status); } /* no need to retry for badch; will fail again */ @@ -923,14 +977,20 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, * if there were underflows, but pre-loading * is not active, notify rate adaptation. */ - if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0) + if (brcms_c_ffpld_check_txfunfl(wlc, + prio2fifo[tid]) > 0) tx_error = true; } } else if (txs->phyerr) { update_rate = false; - brcms_err(wlc->hw->d11core, - "%s: ampdu tx phy error (0x%x)\n", + wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", __func__, txs->phyerr); + + if (brcm_msg_level & LOG_ERROR_VAL) { + brcmu_prpkt("txpkt (AMPDU)", p); + brcms_c_print_txdesc((struct d11txh *) p->data); + } + brcms_c_print_txstatus(txs); } } @@ -943,8 +1003,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); - if (tot_mpdu == 0) { mcs = plcp[0] & MIMO_PLCP_MCS_MASK; mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); @@ -954,10 +1012,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ack_recd = false; if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - brcms_dbg_ht(wlc->hw->d11core, - "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", - tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + BCMMSG(wiphy, + "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", + tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { @@ -988,16 +1046,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* either retransmit or send bar if ack not recd */ if (!ack_recd) { 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 - * ring here since we're reinserting a frame - * that was just pulled out. + * Use high prededence for retransmit to + * give some punch */ - WARN_ONCE(ret, "queue %d out of txds\n", queue); + brcms_c_txq_enq(wlc, scb, p, + BRCMS_PRIO_TO_HI_PREC(tid)); } else { /* Retry timeout */ ini->tx_in_transit--; @@ -1008,9 +1064,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, IEEE80211_TX_STAT_AMPDU_NO_BACK; skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); - brcms_dbg_ht(wlc->hw->d11core, - "BA Timeout, seq %d, in_transit %d\n", - seq, ini->tx_in_transit); + BCMMSG(wiphy, + "BA Timeout, seq %d, in_transit %d\n", + seq, ini->tx_in_transit); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } @@ -1024,9 +1080,12 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); } + brcms_c_send_q(wlc); /* update rate state */ antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); + + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } void @@ -1074,8 +1133,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, while (p) { tx_info = IEEE80211_SKB_CB(p); txh = (struct d11txh *) p->data; - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, - sizeof(*txh)); mcl = le16_to_cpu(txh->MacTxControlLow); brcmu_pkt_buf_free_skb(p); /* break out if last packet of ampdu */ @@ -1085,6 +1142,7 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); } + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } } @@ -1123,6 +1181,23 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) } } +/* + * callback function that helps flushing ampdu packets from a priority queue + */ +static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); + struct cb_del_ampdu_pars *ampdu_pars = + (struct cb_del_ampdu_pars *)arg_a; + bool rc; + + rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; + rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL || + tx_info->rate_driver_data[0] == ampdu_pars->sta); + rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); + return rc; +} + /* * callback function that helps invalidating ampdu packets in a DMA queue */ @@ -1143,5 +1218,15 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, u16 tid) { + struct brcms_txq_info *qi = wlc->pkt_queue; + struct pktq *pq = &qi->q; + int prec; + struct cb_del_ampdu_pars ampdu_pars; + + ampdu_pars.sta = sta; + ampdu_pars.tid = tid; + for (prec = 0; prec < pq->num_prec; prec++) + brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + (void *)&du_pars); brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 73d01e586109..421f4ba7c63c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h @@ -17,34 +17,11 @@ #ifndef _BRCM_AMPDU_H_ #define _BRCM_AMPDU_H_ -/* - * Data structure representing an in-progress session for accumulating - * frames for AMPDU. - * - * wlc: pointer to common driver data - * skb_list: queue of skb's for AMPDU - * max_ampdu_len: maximum length for this AMPDU - * max_ampdu_frames: maximum number of frames for this AMPDU - * ampdu_len: total number of bytes accumulated for this AMPDU - * dma_len: DMA length of this AMPDU - */ -struct brcms_ampdu_session { - struct brcms_c_info *wlc; - struct sk_buff_head skb_list; - unsigned max_ampdu_len; - u16 max_ampdu_frames; - u16 ampdu_len; - u16 dma_len; -}; - -extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc); -extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p); -extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); - extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); +extern int brcms_c_sendampdu(struct ampdu_info *ampdu, + struct brcms_txq_info *qi, + struct sk_buff **aggp, int prec); extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, struct tx_status *txs); extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c index 54c616919590..55e12c327911 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c @@ -21,7 +21,6 @@ #include "main.h" #include "phy_shim.h" #include "antsel.h" -#include "debug.h" #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ @@ -138,8 +137,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) asi->antsel_avail = false; } else { asi->antsel_avail = false; - brcms_err(wlc->hw->d11core, - "antsel_attach: 2o3 " + wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " "board cfg invalid\n"); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h index 871781e6a713..27dd73eef56d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h @@ -14,29 +14,22 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmsmac + #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) #define __TRACE_BRCMSMAC_H -#include -#include #include #include "mac80211_if.h" -#ifndef CONFIG_BRCM_TRACING +#ifndef CONFIG_BRCMDBG #undef TRACE_EVENT #define TRACE_EVENT(name, proto, ...) \ static inline void trace_ ## name(proto) {} -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(...) -#undef DEFINE_EVENT -#define DEFINE_EVENT(evt_class, name, proto, ...) \ -static inline void trace_ ## name(proto) {} #endif -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac - /* * We define a tracepoint, its arguments, its printk format and its * 'fast binary record' layout. @@ -85,165 +78,9 @@ TRACE_EVENT(brcms_dpc, ) ); -TRACE_EVENT(brcms_macintstatus, - TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, - u32 mask), - TP_ARGS(dev, in_isr, macintstatus, mask), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(int, in_isr) - __field(u32, macintstatus) - __field(u32, mask) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->in_isr = in_isr; - __entry->macintstatus = macintstatus; - __entry->mask = mask; - ), - TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), - __entry->in_isr, __entry->macintstatus, __entry->mask) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_tx - -TRACE_EVENT(brcms_txdesc, - TP_PROTO(const struct device *dev, - void *txh, size_t txh_len), - TP_ARGS(dev, txh, txh_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __dynamic_array(u8, txh, txh_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - memcpy(__get_dynamic_array(txh), txh, txh_len); - ), - TP_printk("[%s] txdesc", __get_str(dev)) -); - -TRACE_EVENT(brcms_txstatus, - TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, - u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, - u16 ackphyrxsh), - TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, - ackphyrxsh), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(u16, framelen) - __field(u16, frameid) - __field(u16, status) - __field(u16, lasttxtime) - __field(u16, sequence) - __field(u16, phyerr) - __field(u16, ackphyrxsh) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->framelen = framelen; - __entry->frameid = frameid; - __entry->status = status; - __entry->lasttxtime = lasttxtime; - __entry->sequence = sequence; - __entry->phyerr = phyerr; - __entry->ackphyrxsh = ackphyrxsh; - ), - TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " - "Seq %#04x PHYTxStatus %#04x RxAck %#04x", - __get_str(dev), __entry->frameid, __entry->status, - __entry->lasttxtime, __entry->sequence, __entry->phyerr, - __entry->ackphyrxsh) -); - -TRACE_EVENT(brcms_ampdu_session, - TP_PROTO(const struct device *dev, unsigned max_ampdu_len, - u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, - u16 dma_len), - TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, - dma_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(unsigned, max_ampdu_len) - __field(u16, max_ampdu_frames) - __field(u16, ampdu_len) - __field(u16, ampdu_frames) - __field(u16, dma_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->max_ampdu_len = max_ampdu_len; - __entry->max_ampdu_frames = max_ampdu_frames; - __entry->ampdu_len = ampdu_len; - __entry->ampdu_frames = ampdu_frames; - __entry->dma_len = dma_len; - ), - TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", - __get_str(dev), __entry->max_ampdu_len, - __entry->max_ampdu_frames, __entry->ampdu_len, - __entry->ampdu_frames, __entry->dma_len) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_msg - -#define MAX_MSG_LEN 100 - -DECLARE_EVENT_CLASS(brcms_msg_event, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf), - TP_STRUCT__entry( - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s", __get_str(msg)) -); - -DEFINE_EVENT(brcms_msg_event, brcms_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_warn, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_crit, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -TRACE_EVENT(brcms_dbg, - TP_PROTO(u32 level, const char *func, struct va_format *vaf), - TP_ARGS(level, func, vaf), - TP_STRUCT__entry( - __field(u32, level) - __string(func, func) - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - __entry->level = level; - __assign_str(func, func); - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s: %s", __get_str(func), __get_str(msg)) -); - #endif /* __TRACE_BRCMSMAC_H */ -#ifdef CONFIG_BRCM_TRACING +#ifdef CONFIG_BRCMDBG #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . @@ -252,4 +89,4 @@ TRACE_EVENT(brcms_dbg, #include -#endif /* CONFIG_BRCM_TRACING */ +#endif /* CONFIG_BRCMDBG */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c index a90b72202ec5..64a48f06d68b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -26,7 +26,6 @@ #include "stf.h" #include "channel.h" #include "mac80211_if.h" -#include "debug.h" /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) @@ -337,6 +336,8 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) const char *ccode = sprom->alpha2; int ccode_len = sizeof(sprom->alpha2); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); if (wlc_cm == NULL) return NULL; @@ -614,8 +615,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) /* check the chanspec */ if (brcms_c_chspec_malformed(chspec)) { - brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n", - wlc->pub->unit, chspec); + wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); return false; } @@ -737,8 +738,7 @@ static int brcms_reg_notifier(struct wiphy *wiphy, mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); } else { mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - brcms_err(wlc->hw->d11core, - "wl%d: %s: no valid channel for \"%s\"\n", + wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", wlc->pub->unit, __func__, request->alpha2); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c deleted file mode 100644 index 6ba4136c7cf6..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include "types.h" -#include "debug.h" -#include "brcms_trace_events.h" - -#define __brcms_fn(fn) \ -void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ -{ \ - struct va_format vaf = { \ - .fmt = fmt, \ - }; \ - va_list args; \ - \ - va_start(args, fmt); \ - vaf.va = &args; \ - dev_ ##fn(dev, "%pV", &vaf); \ - trace_brcms_ ##fn(&vaf); \ - va_end(args); \ -} - -__brcms_fn(info) -__brcms_fn(warn) -__brcms_fn(err) -__brcms_fn(crit) - -#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) -void __brcms_dbg(struct device *dev, u32 level, const char *func, - const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; -#ifdef CONFIG_BRCMDBG - if ((brcm_msg_level & level) && net_ratelimit()) - dev_err(dev, "%s %pV", func, &vaf); -#endif - trace_brcms_dbg(level, func, &vaf); - va_end(args); -} -#endif diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h deleted file mode 100644 index c0d2cf7d9be1..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _BRCMS_DEBUG_H_ -#define _BRCMS_DEBUG_H_ - -#include -#include -#include -#include -#include "main.h" -#include "mac80211_if.h" - -void __brcms_info(struct device *dev, const char *fmt, ...); -void __brcms_warn(struct device *dev, const char *fmt, ...); -void __brcms_err(struct device *dev, const char *fmt, ...); -void __brcms_crit(struct device *dev, const char *fmt, ...); - -#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) -void __brcms_dbg(struct device *dev, u32 level, const char *func, - const char *fmt, ...); -#else -static inline void __brcms_dbg(struct device *dev, u32 level, - const char *func, const char *fmt, ...) -{ -} -#endif - -/* - * Debug macros cannot be used when wlc is uninitialized. Generally - * this means any code that could run before brcms_c_attach() has - * returned successfully probably shouldn't use the following macros. - */ - -#define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a) -#define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a) -#define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a) -#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a) -#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a) - -#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a) -#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a) -#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a) -#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a) -#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a) -#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) -#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) - -#endif /* _BRCMS_DEBUG_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 511e45775c33..5e53305bd9a9 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -14,22 +14,17 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -#include -#include #include #include #include "types.h" -#include "main.h" #include "dma.h" #include "soc.h" -#include "scb.h" -#include "ampdu.h" -#include "debug.h" -#include "brcms_trace_events.h" /* * dma register field offset calculation @@ -181,6 +176,28 @@ #define BCMEXTRAHDROOM 172 +/* debug/trace */ +#ifdef DEBUG +#define DMA_ERROR(fmt, ...) \ +do { \ + if (*di->msg_level & 1) \ + pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ +} while (0) +#define DMA_TRACE(fmt, ...) \ +do { \ + if (*di->msg_level & 2) \ + pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ +} while (0) +#else +#define DMA_ERROR(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) +#define DMA_TRACE(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) +#endif /* DEBUG */ + +#define DMA_NONE(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) + #define MAXNAMEL 8 /* 8 char names */ /* macros to convert between byte offsets and indexes */ @@ -207,14 +224,12 @@ struct dma64desc { /* dma engine software state */ struct dma_info { struct dma_pub dma; /* exported structure */ + uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ struct bcma_device *core; struct device *dmadev; - /* session information for AMPDU */ - struct brcms_ampdu_session ampdu_session; - bool dma64; /* this dma engine is operating in 64-bit mode */ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ @@ -283,6 +298,12 @@ struct dma_info { bool aligndesc_4k; }; +/* + * default dma message level (if input msg_level + * pointer is null in dma_attach()) + */ +static uint dma_msg_level; + /* Check for odd number of 1's */ static u32 parity32(__le32 data) { @@ -332,7 +353,7 @@ static uint prevtxd(struct dma_info *di, uint i) static uint nextrxd(struct dma_info *di, uint i) { - return rxd(di, i + 1); + return txd(di, i + 1); } static uint ntxdactive(struct dma_info *di, uint h, uint t) @@ -350,7 +371,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) uint dmactrlflags; if (di == NULL) { - brcms_dbg_dma(di->core, "NULL dma handle\n"); + DMA_ERROR("NULL dma handle\n"); return 0; } @@ -402,15 +423,13 @@ static bool _dma_isaddrext(struct dma_info *di) /* not all tx or rx channel are available */ if (di->d64txregbase != 0) { if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) - brcms_dbg_dma(di->core, - "%s: DMA64 tx doesn't have AE set\n", - di->name); + DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", + di->name); return true; } else if (di->d64rxregbase != 0) { if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) - brcms_dbg_dma(di->core, - "%s: DMA64 rx doesn't have AE set\n", - di->name); + DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", + di->name); return true; } @@ -511,9 +530,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->txdpaorig); if (va == NULL) { - brcms_dbg_dma(di->core, - "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", - di->name); + DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", + di->name); return false; } align = (1 << align_bits); @@ -526,9 +544,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig); if (va == NULL) { - brcms_dbg_dma(di->core, - "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", - di->name); + DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", + di->name); return false; } align = (1 << align_bits); @@ -547,13 +564,12 @@ static bool _dma_alloc(struct dma_info *di, uint direction) return dma64_alloc(di, direction); } -struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, +struct dma_pub *dma_attach(char *name, struct si_pub *sih, + struct bcma_device *core, uint txregbase, uint rxregbase, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, - uint nrxpost, uint rxoffset) + uint nrxpost, uint rxoffset, uint *msg_level) { - struct si_pub *sih = wlc->hw->sih; - struct bcma_device *core = wlc->hw->d11core; struct dma_info *di; u8 rev = core->id.rev; uint size; @@ -564,6 +580,9 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, if (di == NULL) return NULL; + di->msg_level = msg_level ? msg_level : &dma_msg_level; + + di->dma64 = ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); @@ -579,11 +598,11 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, */ _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); - brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d " - "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " - "txregbase %u rxregbase %u\n", name, "DMA64", - di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, - rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); + DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d " + "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " + "txregbase %u rxregbase %u\n", name, "DMA64", + di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, + rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); /* make a private copy of our callers name */ strncpy(di->name, name, MAXNAMEL); @@ -645,8 +664,8 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, di->dmadesc_align = 4; /* 16 byte alignment */ } - brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n", - di->aligndesc_4k, di->dmadesc_align); + DMA_NONE("DMA descriptor align_needed %d, align %d\n", + di->aligndesc_4k, di->dmadesc_align); /* allocate tx packet pointer vector */ if (ntxd) { @@ -684,27 +703,21 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, if ((di->ddoffsetlow != 0) && !di->addrext) { if (di->txdpa > SI_PCI_DMA_SZ) { - brcms_dbg_dma(di->core, - "%s: txdpa 0x%x: addrext not supported\n", - di->name, (u32)di->txdpa); + DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", + di->name, (u32)di->txdpa); goto fail; } if (di->rxdpa > SI_PCI_DMA_SZ) { - brcms_dbg_dma(di->core, - "%s: rxdpa 0x%x: addrext not supported\n", - di->name, (u32)di->rxdpa); + DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", + di->name, (u32)di->rxdpa); goto fail; } } - /* Initialize AMPDU session */ - brcms_c_ampdu_reset_session(&di->ampdu_session, wlc); - - brcms_dbg_dma(di->core, - "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", - di->ddoffsetlow, di->ddoffsethigh, - di->dataoffsetlow, di->dataoffsethigh, - di->addrext); + DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", + di->ddoffsetlow, di->ddoffsethigh, + di->dataoffsetlow, di->dataoffsethigh, + di->addrext); return (struct dma_pub *) di; @@ -750,7 +763,7 @@ void dma_detach(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); /* free dma descriptor rings */ if (di->txd64) @@ -826,7 +839,7 @@ static void _dma_rxenable(struct dma_info *di) uint dmactrlflags = di->dma.dmactrlflags; u32 control; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); control = D64_RC_RE | (bcma_read32(di->core, DMA64RXREGOFFS(di, control)) & @@ -846,7 +859,7 @@ void dma_rxinit(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->nrxd == 0) return; @@ -941,7 +954,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) return 0; len = le16_to_cpu(*(__le16 *) (p->data)); - brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len); + DMA_TRACE("%s: dma_rx len %d\n", di->name, len); dma_spin_for_len(len, p); /* set actual length */ @@ -968,15 +981,14 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc); - brcms_dbg_dma(di->core, - "rxin %d rxout %d, hw_curr %d\n", - di->rxin, di->rxout, cur); + DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", + di->rxin, di->rxout, cur); } #endif /* DEBUG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { - brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n", - di->name, len); + DMA_ERROR("%s: bad frame length (%d)\n", + di->name, len); skb_queue_walk_safe(&dma_frames, p, next) { skb_unlink(p, &dma_frames); brcmu_pkt_buf_free_skb(p); @@ -993,7 +1005,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) static bool dma64_rxidle(struct dma_info *di) { - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->nrxd == 0) return true; @@ -1004,17 +1016,6 @@ static bool dma64_rxidle(struct dma_info *di) D64_RS0_CD_MASK)); } -static bool dma64_txidle(struct dma_info *di) -{ - if (di->ntxd == 0) - return true; - - return ((bcma_read32(di->core, - DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) == - (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) & - D64_XS0_CD_MASK)); -} - /* * post receive buffers * return false is refill failed completely and ring is empty this will stall @@ -1046,7 +1047,7 @@ bool dma_rxfill(struct dma_pub *pub) n = di->nrxpost - nrxdactive(di, rxin, rxout); - brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n); + DMA_TRACE("%s: post %d\n", di->name, n); if (di->rxbufsize > BCMEXTRAHDROOM) extra_offset = di->rxextrahdrroom; @@ -1059,11 +1060,9 @@ bool dma_rxfill(struct dma_pub *pub) p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { - brcms_dbg_dma(di->core, "%s: out of rxbufs\n", - di->name); + DMA_ERROR("%s: out of rxbufs\n", di->name); if (i == 0 && dma64_rxidle(di)) { - brcms_dbg_dma(di->core, "%s: ring is empty !\n", - di->name); + DMA_ERROR("%s: ring is empty !\n", di->name); ring_empty = true; } di->dma.rxnobuf++; @@ -1108,7 +1107,7 @@ void dma_rxreclaim(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); while ((p = _dma_getnextrxp(di, true))) brcmu_pkt_buf_free_skb(p); @@ -1139,7 +1138,7 @@ void dma_txinit(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; u32 control = D64_XC_XE; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1171,7 +1170,7 @@ void dma_txsuspend(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1183,7 +1182,7 @@ void dma_txresume(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1206,11 +1205,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - brcms_dbg_dma(di->core, "%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE("%s: %s\n", + di->name, + range == DMA_RANGE_ALL ? "all" : + range == DMA_RANGE_TRANSMITTED ? "transmitted" : + "transferred"); if (di->txin == di->txout) return; @@ -1265,18 +1264,24 @@ bool dma_rxreset(struct dma_pub *pub) return status == D64_RS0_RS_DISABLED; } -static void dma_txenq(struct dma_info *di, struct sk_buff *p) +/* + * !! tx entry routine + * WARNING: call must check the return value for error. + * the error(toss frames) could be fatal and cause many subsequent hard + * to debug problems + */ +int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) { + struct dma_info *di = (struct dma_info *)pub; unsigned char *data; uint len; u16 txout; u32 flags = 0; dma_addr_t pa; - txout = di->txout; + DMA_TRACE("%s:\n", di->name); - if (WARN_ON(nexttxd(di, txout) == di->txin)) - return; + txout = di->txout; /* * obtain and initialize transmit descriptor entry. @@ -1284,6 +1289,14 @@ static void dma_txenq(struct dma_info *di, struct sk_buff *p) data = p->data; len = p->len; + /* no use to transmit a zero length packet */ + if (len == 0) + return 0; + + /* return nonzero if out of tx descriptors */ + if (nexttxd(di, txout) == di->txin) + goto outoftxd; + /* get physical address of buffer start */ pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); @@ -1305,147 +1318,23 @@ static void dma_txenq(struct dma_info *di, struct sk_buff *p) /* bump the tx descriptor index */ di->txout = txout; -} - -static void ampdu_finalize(struct dma_info *di) -{ - struct brcms_ampdu_session *session = &di->ampdu_session; - struct sk_buff *p; - - trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev, - session->max_ampdu_len, - session->max_ampdu_frames, - session->ampdu_len, - skb_queue_len(&session->skb_list), - session->dma_len); - - if (WARN_ON(skb_queue_empty(&session->skb_list))) - return; - - brcms_c_ampdu_finalize(session); - - while (!skb_queue_empty(&session->skb_list)) { - p = skb_dequeue(&session->skb_list); - dma_txenq(di, p); - } - - bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), - di->xmtptrbase + I2B(di->txout, struct dma64desc)); - brcms_c_ampdu_reset_session(session, session->wlc); -} - -static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p) -{ - struct brcms_ampdu_session *session = &di->ampdu_session; - int ret; - - ret = brcms_c_ampdu_add_frame(session, p); - if (ret == -ENOSPC) { - /* - * AMPDU cannot accomodate this frame. Close out the in- - * progress AMPDU session and start a new one. - */ - ampdu_finalize(di); - ret = brcms_c_ampdu_add_frame(session, p); - } - - WARN_ON(ret); -} - -/* Update count of available tx descriptors based on current DMA state */ -static void dma_update_txavail(struct dma_info *di) -{ - /* - * Available space is number of descriptors less the number of - * active descriptors and the number of queued AMPDU frames. - */ - di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - - skb_queue_len(&di->ampdu_session.skb_list) - 1; -} - -/* - * !! tx entry routine - * WARNING: call must check the return value for error. - * the error(toss frames) could be fatal and cause many subsequent hard - * to debug problems - */ -int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, - struct sk_buff *p) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - struct ieee80211_tx_info *tx_info; - bool is_ampdu; - - /* no use to transmit a zero length packet */ - if (p->len == 0) - return 0; - - /* return nonzero if out of tx descriptors */ - if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin) - goto outoftxd; - - tx_info = IEEE80211_SKB_CB(p); - is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU; - if (is_ampdu) - prep_ampdu_frame(di, p); - else - dma_txenq(di, p); - - /* tx flow control */ - dma_update_txavail(di); /* kick the chip */ - if (is_ampdu) { - /* - * Start sending data if we've got a full AMPDU, there's - * no more space in the DMA ring, or the ring isn't - * currently transmitting. - */ - if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames || - di->dma.txavail == 0 || dma64_txidle(di)) - ampdu_finalize(di); - } else { + if (commit) bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), - di->xmtptrbase + I2B(di->txout, struct dma64desc)); - } + di->xmtptrbase + I2B(txout, struct dma64desc)); + + /* tx flow control */ + di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; return 0; outoftxd: - brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name); + DMA_ERROR("%s: out of txds !!!\n", di->name); brcmu_pkt_buf_free_skb(p); di->dma.txavail = 0; di->dma.txnobuf++; - return -ENOSPC; -} - -void dma_txflush(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - - if (!skb_queue_empty(&session->skb_list)) - ampdu_finalize(di); -} - -int dma_txpending(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - return ntxdactive(di, di->txin, di->txout); -} - -/* - * If we have an active AMPDU session and are not transmitting, - * this function will force tx to start. - */ -void dma_kick_tx(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - - if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) - ampdu_finalize(di); + return -1; } /* @@ -1465,11 +1354,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) u16 active_desc; struct sk_buff *txp; - brcms_dbg_dma(di->core, "%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE("%s: %s\n", + di->name, + range == DMA_RANGE_ALL ? "all" : + range == DMA_RANGE_TRANSMITTED ? "transmitted" : + "transferred"); if (di->ntxd == 0) return NULL; @@ -1523,13 +1412,13 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) di->txin = i; /* tx flow control */ - dma_update_txavail(di); + di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; return txp; bogus: - brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n", - start, end, di->txout); + DMA_NONE("bogus curr: start %d end %d txout %d\n", + start, end, di->txout); return NULL; } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h index ff5b80b09046..cc269ee5c499 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h @@ -74,11 +74,12 @@ struct dma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, +extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, + struct bcma_device *d11core, uint txregbase, uint rxregbase, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, - uint nrxpost, uint rxoffset); + uint nrxpost, uint rxoffset, uint *msg_level); void dma_rxinit(struct dma_pub *pub); int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); @@ -86,11 +87,7 @@ bool dma_rxfill(struct dma_pub *pub); bool dma_rxreset(struct dma_pub *pub); bool dma_txreset(struct dma_pub *pub); void dma_txinit(struct dma_pub *pub); -int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, - struct sk_buff *p0); -void dma_txflush(struct dma_pub *pub); -int dma_txpending(struct dma_pub *pub); -void dma_kick_tx(struct dma_pub *pub); +int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); void dma_txsuspend(struct dma_pub *pub); bool dma_txsuspended(struct dma_pub *pub); void dma_txresume(struct dma_pub *pub); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 1710ccba8bac..a744ea5a9559 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -33,7 +33,6 @@ #include "ucode_loader.h" #include "mac80211_if.h" #include "main.h" -#include "debug.h" #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ @@ -99,14 +98,10 @@ static struct bcma_device_id brcms_coreid_table[] = { }; MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); -#if defined(CONFIG_BRCMDBG) -/* - * Module parameter for setting the debug message level. Available - * flags are specified by the BRCM_DL_* macros in - * drivers/net/wireless/brcm80211/include/defs.h. - */ -module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); -#endif +#ifdef DEBUG +static int msglevel = 0xdeadbeef; +module_param(msglevel, int, 0); +#endif /* DEBUG */ static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), @@ -281,7 +276,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, spin_lock_bh(&wl->lock); if (!wl->pub->up) { - brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n"); + wiphy_err(wl->wiphy, "ops->tx called while down\n"); kfree_skb(skb); goto done; } @@ -318,8 +313,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) spin_unlock_bh(&wl->lock); if (err != 0) - brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", - __func__, err); + wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, + err); return err; } @@ -337,7 +332,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) status = brcms_c_chipmatch(wl->wlc->hw->d11core); spin_unlock_bh(&wl->lock); if (!status) { - brcms_err(wl->wlc->hw->d11core, + wiphy_err(wl->wiphy, "wl: brcms_ops_stop: chipmatch failed\n"); return; } @@ -355,9 +350,8 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) /* Just STA for now */ if (vif->type != NL80211_IFTYPE_STATION) { - brcms_err(wl->wlc->hw->d11core, - "%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type); + wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" + " STA for now\n", __func__, vif->type); return -EOPNOTSUPP; } @@ -376,9 +370,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) { struct ieee80211_conf *conf = &hw->conf; struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; int err = 0; int new_int; + struct wiphy *wiphy = hw->wiphy; spin_lock_bh(&wl->lock); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { @@ -386,26 +380,25 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) conf->listen_interval); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) - brcms_dbg_info(core, "%s: change monitor mode: %s\n", - __func__, conf->flags & IEEE80211_CONF_MONITOR ? - "true" : "false"); + wiphy_dbg(wiphy, "%s: change monitor mode: %s\n", + __func__, conf->flags & IEEE80211_CONF_MONITOR ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_PS) - brcms_err(core, "%s: change power-save mode: %s (implement)\n", + wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", __func__, conf->flags & IEEE80211_CONF_PS ? "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { err = brcms_c_set_tx_power(wl->wlc, conf->power_level); if (err < 0) { - brcms_err(core, "%s: Error setting power_level\n", + wiphy_err(wiphy, "%s: Error setting power_level\n", __func__); goto config_out; } new_int = brcms_c_get_tx_power(wl->wlc); if (new_int != conf->power_level) - brcms_err(core, - "%s: Power level req != actual, %d %d\n", - __func__, conf->power_level, + wiphy_err(wiphy, "%s: Power level req != actual, %d %d" + "\n", __func__, conf->power_level, new_int); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { @@ -432,13 +425,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u32 changed) { struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; + struct wiphy *wiphy = hw->wiphy; if (changed & BSS_CHANGED_ASSOC) { /* association status changed (associated/disassociated) * also implies a change in the AID. */ - brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME, + wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, info->assoc ? "" : "dis"); spin_lock_bh(&wl->lock); brcms_c_associate_upd(wl->wlc, info->assoc); @@ -498,7 +491,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, error = brcms_c_set_rateset(wl->wlc, &rs); spin_unlock_bh(&wl->lock); if (error) - brcms_err(core, "changing basic rates failed: %d\n", + wiphy_err(wiphy, "changing basic rates failed: %d\n", error); } if (changed & BSS_CHANGED_BEACON_INT) { @@ -515,30 +508,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON) /* Beacon data changed, retrieve new beacon (beaconing modes) */ - brcms_err(core, "%s: beacon changed\n", __func__); + wiphy_err(wiphy, "%s: beacon changed\n", __func__); if (changed & BSS_CHANGED_BEACON_ENABLED) { /* Beaconing should be enabled/disabled (beaconing modes) */ - brcms_err(core, "%s: Beacon enabled: %s\n", __func__, + wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, info->enable_beacon ? "true" : "false"); } if (changed & BSS_CHANGED_CQM) { /* Connection quality monitor config changed */ - brcms_err(core, "%s: cqm change: threshold %d, hys %d " + wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " " (implement)\n", __func__, info->cqm_rssi_thold, info->cqm_rssi_hyst); } if (changed & BSS_CHANGED_IBSS) { /* IBSS join status changed */ - brcms_err(core, "%s: IBSS joined: %s (implement)\n", - __func__, info->ibss_joined ? "true" : "false"); + wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, + info->ibss_joined ? "true" : "false"); } if (changed & BSS_CHANGED_ARP_FILTER) { /* Hardware ARP filter address list or state changed */ - brcms_err(core, "%s: arp filtering: enabled %s, count %d" + wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" " (implement)\n", __func__, info->arp_filter_enabled ? "true" : "false", info->arp_addr_cnt); } @@ -548,8 +541,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, * QoS for this association was enabled/disabled. * Note that it is only ever disabled for station mode. */ - brcms_err(core, "%s: qos enabled: %s (implement)\n", - __func__, info->qos ? "true" : "false"); + wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, + info->qos ? "true" : "false"); } return; } @@ -560,25 +553,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; + struct wiphy *wiphy = hw->wiphy; changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; if (changed_flags & FIF_PROMISC_IN_BSS) - brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n"); + wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n"); if (changed_flags & FIF_ALLMULTI) - brcms_dbg_info(core, "FIF_ALLMULTI\n"); + wiphy_dbg(wiphy, "FIF_ALLMULTI\n"); if (changed_flags & FIF_FCSFAIL) - brcms_dbg_info(core, "FIF_FCSFAIL\n"); + wiphy_dbg(wiphy, "FIF_FCSFAIL\n"); if (changed_flags & FIF_CONTROL) - brcms_dbg_info(core, "FIF_CONTROL\n"); + wiphy_dbg(wiphy, "FIF_CONTROL\n"); if (changed_flags & FIF_OTHER_BSS) - brcms_dbg_info(core, "FIF_OTHER_BSS\n"); + wiphy_dbg(wiphy, "FIF_OTHER_BSS\n"); if (changed_flags & FIF_PSPOLL) - brcms_dbg_info(core, "FIF_PSPOLL\n"); + wiphy_dbg(wiphy, "FIF_PSPOLL\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) - brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n"); + wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n"); spin_lock_bh(&wl->lock); brcms_c_mac_promisc(wl->wlc, *total_flags); @@ -660,8 +653,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, status = brcms_c_aggregatable(wl->wlc, tid); spin_unlock_bh(&wl->lock); if (!status) { - brcms_err(wl->wlc->hw->d11core, - "START: tid %d is not agg\'able\n", tid); + wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", + tid); return -EINVAL; } ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -688,8 +681,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, /* Power save wakeup */ break; default: - brcms_err(wl->wlc->hw->d11core, - "%s: Invalid command, ignoring\n", __func__); + wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", + __func__); } return 0; @@ -1151,13 +1144,14 @@ static int brcms_suspend(struct bcma_device *pdev) wl->pub->hw_up = false; spin_unlock_bh(&wl->lock); - brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n"); + pr_debug("brcms_suspend ok\n"); return 0; } static int brcms_resume(struct bcma_device *pdev) { + pr_debug("brcms_resume ok\n"); return 0; } @@ -1190,6 +1184,10 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init); static int __init brcms_module_init(void) { +#ifdef DEBUG + if (msglevel != 0xdeadbeef) + brcm_msg_level = msglevel; +#endif if (!schedule_work(&brcms_driver_work)) return -EBUSY; @@ -1218,7 +1216,7 @@ module_exit(brcms_module_exit); void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, bool state, int prio) { - brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__); + wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); } /* @@ -1226,8 +1224,7 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, */ void brcms_init(struct brcms_info *wl) { - brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n", - wl->pub->unit); + BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); brcms_reset(wl); brcms_c_init(wl->wlc, wl->mute_tx); } @@ -1237,7 +1234,7 @@ void brcms_init(struct brcms_info *wl) */ uint brcms_reset(struct brcms_info *wl) { - brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit); + BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); brcms_c_reset(wl->wlc); /* dpc will not be rescheduled */ @@ -1251,7 +1248,7 @@ uint brcms_reset(struct brcms_info *wl) void brcms_fatal_error(struct brcms_info *wl) { - brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n", + wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", wl->wlc->pub->unit); brcms_reset(wl); ieee80211_restart_hw(wl->pub->ieee_hw); @@ -1399,9 +1396,8 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) #ifdef DEBUG if (t->set) - brcms_dbg_info(t->wl->wlc->hw->d11core, - "%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic); + wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); #endif t->ms = ms; t->periodic = (bool) periodic; @@ -1490,8 +1486,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) } } } - brcms_err(wl->wlc->hw->d11core, - "ERROR: ucode buf tag:%d can not be found!\n", idx); + wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", + idx); *pbuf = NULL; fail: return -ENODATA; @@ -1514,7 +1510,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) pdata = wl->fw.fw_bin[i]->data + le32_to_cpu(hdr->offset); if (le32_to_cpu(hdr->len) != 4) { - brcms_err(wl->wlc->hw->d11core, + wiphy_err(wl->wiphy, "ERROR: fw hdr len\n"); return -ENOMSG; } @@ -1523,8 +1519,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) } } } - brcms_err(wl->wlc->hw->d11core, - "ERROR: ucode tag:%d can not be found!\n", idx); + wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); return -ENOMSG; } @@ -1565,8 +1560,8 @@ int brcms_check_firmwares(struct brcms_info *wl) sizeof(struct firmware_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n", - __func__, fw->size); + wiphy_err(wl->wiphy, "%s: out of bounds fw file size " + "%zu\n", __func__, fw->size); rc = -EBADF; } else { /* check if ucode section overruns firmware image */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index c21cee3ab250..75086b37c817 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -34,9 +34,12 @@ #include "ucode_loader.h" #include "main.h" #include "soc.h" -#include "dma.h" -#include "debug.h" -#include "brcms_trace_events.h" + +/* + * Indication for txflowcontrol that all priority bits in + * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. + */ +#define ALLPRIO -1 /* watchdog timer, in unit of ms */ #define TIMER_INTERVAL_WATCHDOG 1000 @@ -123,6 +126,21 @@ #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ +/* precedences numbers for wlc queues. These are twice as may levels as + * 802.1D priorities. + * Odd numbers are used for HI priority traffic at same precedence levels + * These constants are used ONLY by wlc_prio2prec_map. Do not use them + * elsewhere. + */ +#define _BRCMS_PREC_NONE 0 /* None = - */ +#define _BRCMS_PREC_BK 2 /* BK - Background */ +#define _BRCMS_PREC_BE 4 /* BE - Best-effort */ +#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ +#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ +#define _BRCMS_PREC_VI 10 /* Vi - Video */ +#define _BRCMS_PREC_VO 12 /* Vo - Voice */ +#define _BRCMS_PREC_NC 14 /* NC - Network Control */ + /* synthpu_dly times in us */ #define SYNTHPU_DLY_APHY_US 3700 #define SYNTHPU_DLY_BPHY_US 1050 @@ -219,17 +237,17 @@ #define MAX_DMA_SEGS 4 -/* # of entries in Tx FIFO */ -#define NTXD 64 +/* Max # of entries in Tx FIFO based on 4kb page size */ +#define NTXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ #define NRXD 256 -/* Amount of headroom to leave in Tx FIFO */ -#define TX_HEADROOM 4 - /* try to keep this # rbufs posted to the chip */ #define NRXBUFPOST 32 +/* data msg txq hiwat mark */ +#define BRCMS_DATAHIWAT 50 + /* max # frames to process in brcms_c_recv() */ #define RXBND 8 /* max # tx status to process in wlc_txstatus() */ @@ -265,8 +283,24 @@ struct edcf_acparam { u16 TXOP; } __packed; +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + /* debug/trace */ -uint brcm_msg_level; +uint brcm_msg_level = +#if defined(DEBUG) + LOG_ERROR_VAL; +#else + 0; +#endif /* DEBUG */ /* TX FIFO number to WME/802.1E Access Category */ static const u8 wme_fifo2ac[] = { @@ -286,6 +320,18 @@ static const u8 wme_ac2fifo[] = { TX_AC_BK_FIFO }; +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _BRCMS_PREC_BE, /* 0 BE - Best-effort */ + _BRCMS_PREC_BK, /* 1 BK - Background */ + _BRCMS_PREC_NONE, /* 2 None = - */ + _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ + _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ + _BRCMS_PREC_VI, /* 5 Vi - Video */ + _BRCMS_PREC_VO, /* 6 Vo - Voice */ + _BRCMS_PREC_NC, /* 7 NC - Network Control */ +}; + static const u16 xmtfifo_sz[][NFIFO] = { /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ {20, 192, 192, 21, 17, 5}, @@ -325,36 +371,6 @@ static const char fifo_names[6][0]; static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif -/* Mapping of ieee80211 AC numbers to tx fifos */ -static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = { - [IEEE80211_AC_VO] = TX_AC_VO_FIFO, - [IEEE80211_AC_VI] = TX_AC_VI_FIFO, - [IEEE80211_AC_BE] = TX_AC_BE_FIFO, - [IEEE80211_AC_BK] = TX_AC_BK_FIFO, -}; - -/* Mapping of tx fifos to ieee80211 AC numbers */ -static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = { - [TX_AC_BK_FIFO] = IEEE80211_AC_BK, - [TX_AC_BE_FIFO] = IEEE80211_AC_BE, - [TX_AC_VI_FIFO] = IEEE80211_AC_VI, - [TX_AC_VO_FIFO] = IEEE80211_AC_VO, -}; - -static u8 brcms_ac_to_fifo(u8 ac) -{ - if (ac >= ARRAY_SIZE(ac_to_fifo_mapping)) - return TX_AC_BE_FIFO; - return ac_to_fifo_mapping[ac]; -} - -static u8 brcms_fifo_to_ac(u8 fifo) -{ - if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping)) - return IEEE80211_AC_BE; - return fifo_to_ac_mapping[fifo]; -} - /* Find basic rate for a given rate */ static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) { @@ -399,15 +415,10 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc) } /* sum the individual fifo tx pending packet counts */ -static int brcms_txpktpendtot(struct brcms_c_info *wlc) +static s16 brcms_txpktpendtot(struct brcms_c_info *wlc) { - int i; - int pending = 0; - - for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) - if (wlc->hw->di[i]) - pending += dma_txpending(wlc->hw->di[i]); - return pending; + return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] + + wlc->core->txpktpend[2] + wlc->core->txpktpend[3]; } static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) @@ -615,11 +626,14 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, uint rate = rspec2rate(ratespec); if (rate == 0) { - brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n", + wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); rate = BRCM_RATE_1M; } + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); @@ -682,7 +696,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, u16 size; u32 value; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { size = le16_to_cpu(inits[i].size); @@ -711,6 +725,7 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) { + struct wiphy *wiphy = wlc_hw->wlc->wiphy; struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; /* init microcode host flags */ @@ -721,9 +736,8 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) if (BRCMS_ISNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else { if (D11REV_IS(wlc_hw->corerev, 24)) { @@ -731,14 +745,12 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) brcms_c_write_inits(wlc_hw, ucode->d11lcn0bsinitvals24); else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in core rev %d\n", - __func__, wlc_hw->unit, - wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in" + " core rev %d\n", __func__, + wlc_hw->unit, wlc_hw->corerev); } else { - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -753,7 +765,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v) static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) { - brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); wlc_hw->phyclk = clk; @@ -778,8 +790,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) /* low-level band switch utility routine */ static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) { - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, - bandunit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + bandunit); wlc_hw->band = wlc_hw->bandstate[bandunit]; @@ -807,7 +819,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) u32 macintmask; u32 macctrl; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); macctrl = bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)); WARN_ON((macctrl & MCTL_EN_MAC) != 0); @@ -829,10 +841,9 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) static bool brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) { - struct sk_buff *p = NULL; - uint queue = NFIFO; - struct dma_pub *dma = NULL; - struct d11txh *txh = NULL; + struct sk_buff *p; + uint queue; + struct d11txh *txh; struct scb *scb = NULL; bool free_pdu; int tx_rts, tx_frame_count, tx_rts_count; @@ -843,11 +854,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *txrate; int i; - bool fatal = true; - - trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen, - txs->frameid, txs->status, txs->lasttxtime, - txs->sequence, txs->phyerr, txs->ackphyrxsh); /* discard intermediate indications for ucode with one legitimate case: * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, @@ -856,36 +862,34 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { - brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n"); - fatal = false; - goto out; + BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); + return false; } queue = txs->frameid & TXFID_QUEUE_MASK; if (queue >= NFIFO) { - brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue); - goto out; + p = NULL; + goto fatal; } - dma = wlc->hw->di[queue]; - p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); - if (p == NULL) { - brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n"); - goto out; - } + if (p == NULL) + goto fatal; txh = (struct d11txh *) (p->data); mcl = le16_to_cpu(txh->MacTxControlLow); - if (txs->phyerr) - brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); - - if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { - brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); - goto out; + if (txs->phyerr) { + if (brcm_msg_level & LOG_ERROR_VAL) { + wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + brcms_c_print_txdesc(txh); + } + brcms_c_print_txstatus(txs); } + + if (txs->frameid != le16_to_cpu(txh->TxFrameID)) + goto fatal; tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); @@ -894,24 +898,14 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); - fatal = false; - goto out; + return false; } - /* - * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU - * frames; this traces them for the rest. - */ - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); - supr_status = txs->status & TX_STATUS_SUPR_MASK; - if (supr_status == TX_STATUS_SUPR_BADCH) { - unsigned xfts = le16_to_cpu(txh->XtraFrameTypes); - brcms_dbg_tx(wlc->hw->d11core, - "Pkt tx suppressed, dest chan %u, current %d\n", - (xfts >> XFTS_CHANNEL_SHIFT) & 0xff, - CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - } + if (supr_status == TX_STATUS_SUPR_BADCH) + BCMMSG(wlc->wiphy, + "%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; tx_frame_count = @@ -922,7 +916,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) lastframe = !ieee80211_has_morefrags(h->frame_control); if (!lastframe) { - brcms_err(wlc->hw->d11core, "Not last frame!\n"); + wiphy_err(wlc->wiphy, "Not last frame!\n"); } else { /* * Set information to be consumed by Minstrel ht. @@ -988,37 +982,26 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) totlen = p->len; free_pdu = true; + brcms_c_txfifo_complete(wlc, queue, 1); + if (lastframe) { /* remove PLCP & Broadcom tx descriptor header */ skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } else { - brcms_err(wlc->hw->d11core, - "%s: Not last frame => not calling tx_status\n", - __func__); + wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " + "tx_status\n", __func__); } - fatal = false; + return false; - out: - if (fatal) { - if (txh) - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, - sizeof(*txh)); - if (p) - brcmu_pkt_buf_free_skb(p); - } + fatal: + if (p) + brcmu_pkt_buf_free_skb(p); - if (dma && queue < NFIFO) { - u16 ac_queue = brcms_fifo_to_ac(queue); - if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO && - ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue)) - ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue); - dma_kick_tx(dma); - } + return true; - return fatal; } /* process tx completion events in BMAC @@ -1028,6 +1011,7 @@ static bool brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) { bool morepending = false; + struct brcms_c_info *wlc = wlc_hw->wlc; struct bcma_device *core; struct tx_status txstatus, *txs; u32 s1, s2; @@ -1038,6 +1022,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) */ uint max_tx_num = bound ? TXSBND : -1; + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + txs = &txstatus; core = wlc_hw->d11core; *fatal = false; @@ -1046,8 +1032,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) && (s1 & TXS_V)) { if (s1 == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); return morepending; } s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); @@ -1072,6 +1058,9 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) if (n >= max_tx_num) morepending = true; + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); + return morepending; } @@ -1123,6 +1112,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) u16 pio_mhf2 = 0; struct brcms_hardware *wlc_hw = wlc->hw; uint unit = wlc_hw->unit; + struct wiphy *wiphy = wlc->wiphy; /* name and offsets for dma_attach */ snprintf(name, sizeof(name), "wl%d", unit); @@ -1135,12 +1125,12 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * TX: TX_AC_BK_FIFO (TX AC Background data packets) * RX: RX_FIFO (RX data packets) */ - wlc_hw->di[0] = dma_attach(name, wlc, + wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, (wme ? dmareg(DMA_TX, 0) : 0), dmareg(DMA_RX, 0), (wme ? NTXD : 0), NRXD, RXBUFSZ, -1, NRXBUFPOST, - BRCMS_HWRXOFF); + BRCMS_HWRXOFF, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[0]); /* @@ -1149,9 +1139,10 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * (legacy) TX_DATA_FIFO (TX data packets) * RX: UNUSED */ - wlc_hw->di[1] = dma_attach(name, wlc, + wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 1), 0, - NTXD, 0, 0, -1, 0, 0); + NTXD, 0, 0, -1, 0, 0, + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[1]); /* @@ -1159,26 +1150,26 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * TX: TX_AC_VI_FIFO (TX AC Video data packets) * RX: UNUSED */ - wlc_hw->di[2] = dma_attach(name, wlc, + wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 2), 0, - NTXD, 0, 0, -1, 0, 0); + NTXD, 0, 0, -1, 0, 0, + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[2]); /* * FIFO 3 * TX: TX_AC_VO_FIFO (TX AC Voice data packets) * (legacy) TX_CTL_FIFO (TX control & mgmt packets) */ - wlc_hw->di[3] = dma_attach(name, wlc, + wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 3), 0, NTXD, 0, 0, -1, - 0, 0); + 0, 0, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[3]); /* Cleaner to leave this as if with AP defined */ if (dma_attach_err) { - brcms_err(wlc_hw->d11core, - "wl%d: wlc_attach: dma_attach failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" + "\n", unit); return false; } @@ -1512,7 +1503,8 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, u16 mac_m; u16 mac_h; - brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", + wlc_hw->unit); mac_l = addr[0] | (addr[1] << 8); mac_m = addr[2] | (addr[3] << 8); @@ -1535,7 +1527,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, __le32 word_le; __be32 word_be; bool be_bit; - brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); bcma_write32(core, D11REGOFFS(tplatewrptr), offset); @@ -1708,8 +1700,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) { struct brcms_hardware *wlc_hw = wlc->hw; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); brcms_c_ucode_bsinit(wlc_hw); @@ -1744,6 +1736,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) /* Perform a soft reset of the PHY PLL */ void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, 0); udelay(1); @@ -1788,7 +1782,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) u32 phy_bw_clkbits; bool phy_in_reset = false; - brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); if (pih == NULL) return; @@ -1922,7 +1916,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ /* power both the pll and external oscillator on/off */ static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) { - brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); /* * dont power down if plldown is false or @@ -2011,7 +2005,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) if (flags == BRCMS_USE_COREFLAGS) flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; @@ -2022,13 +2016,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) if (bcma_core_is_enabled(wlc_hw->d11core)) { for (i = 0; i < NFIFO; i++) if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) - brcms_err(wlc_hw->d11core, "wl%d: %s: " + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " "dma_txreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, i); if ((wlc_hw->di[RX_FIFO]) && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) - brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset" + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" "[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_FIFO); } @@ -2241,7 +2235,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw, uint i; uint count; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); count = (nbytes / sizeof(u32)); @@ -2269,8 +2263,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) ucode->bcm43xx_16_mimosz); wlc_hw->ucode_loaded = true; } else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (BRCMS_ISLCNPHY(wlc_hw->band)) { @@ -2278,8 +2272,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) ucode->bcm43xx_24_lcnsz); wlc_hw->ucode_loaded = true; } else { - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } } @@ -2316,6 +2310,7 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) uint unit; uint intstatus, idx; struct bcma_device *core = wlc_hw->d11core; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; unit = wlc_hw->unit; @@ -2328,39 +2323,39 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) if (!intstatus) continue; - brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n", - unit, idx, intstatus); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", + unit, idx, intstatus); if (intstatus & I_RO) { - brcms_err(core, "wl%d: fifo %d: receive fifo " + wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " "overflow\n", unit, idx); fatal = true; } if (intstatus & I_PC) { - brcms_err(core, "wl%d: fifo %d: descriptor error\n", - unit, idx); + wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", + unit, idx); fatal = true; } if (intstatus & I_PD) { - brcms_err(core, "wl%d: fifo %d: data error\n", unit, + wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, idx); fatal = true; } if (intstatus & I_DE) { - brcms_err(core, "wl%d: fifo %d: descriptor protocol " + wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " "error\n", unit, idx); fatal = true; } if (intstatus & I_RU) - brcms_err(core, "wl%d: fifo %d: receive descriptor " + wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " "underflow\n", idx, unit); if (intstatus & I_XU) { - brcms_err(core, "wl%d: fifo %d: transmit fifo " + wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " "underflow\n", idx, unit); fatal = true; } @@ -2521,13 +2516,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) { struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; - u32 macintstatus, mask; + u32 macintstatus; /* macintstatus includes a DMA interrupt summary bit */ macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); - mask = in_isr ? wlc->macintmask : wlc->defmacintmask; - trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask); + BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, + macintstatus); /* detect cardbus removed, in power down(suspend) and in reset */ if (brcms_deviceremoved(wlc)) @@ -2540,7 +2535,7 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) return 0; /* defer unsolicited interrupts */ - macintstatus &= mask; + macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); /* if not for us */ if (macintstatus == 0) @@ -2610,8 +2605,8 @@ bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) macintstatus = wlc_intstatus(wlc, true); if (macintstatus == 0xffffffff) - brcms_err(wlc_hw->d11core, - "DEVICEREMOVED detected in the ISR code path\n"); + wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" + " path\n"); /* it is not for us */ if (macintstatus == 0) @@ -2631,9 +2626,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; u32 mc, mi; + struct wiphy *wiphy = wlc->wiphy; - brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); /* * Track overlapping suspend requests @@ -2648,7 +2644,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mc = bcma_read32(core, D11REGOFFS(maccontrol)); if (mc == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2659,7 +2655,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mi = bcma_read32(core, D11REGOFFS(macintstatus)); if (mi == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2672,10 +2668,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) BRCMS_MAX_MAC_SUSPEND); if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { - brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" + wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" " and MI_MACSSPNDD is still not on.\n", wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); - brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " + wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " "psm_brc 0x%04x\n", wlc_hw->unit, bcma_read32(core, D11REGOFFS(psmdebug)), bcma_read32(core, D11REGOFFS(phydebug)), @@ -2684,7 +2680,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mc = bcma_read32(core, D11REGOFFS(maccontrol)); if (mc == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2700,8 +2696,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc) struct bcma_device *core = wlc_hw->d11core; u32 mc, mi; - brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc->band->bandunit); /* * Track overlapping suspend requests @@ -2744,6 +2740,8 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) u32 w, val; struct wiphy *wiphy = wlc_hw->wlc->wiphy; + BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); + /* Validate dchip register access */ bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); @@ -2804,7 +2802,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) struct bcma_device *core = wlc_hw->d11core; u32 tmp; - brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); tmp = 0; @@ -2820,8 +2818,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) - brcms_err(core, "%s: turn on PHY PLL failed\n", - __func__); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" + " PLL failed\n", __func__); } else { bcma_set32(core, D11REGOFFS(clk_ctl_st), tmp | CCS_ERSRC_REQ_D11PLL | @@ -2837,8 +2835,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) - brcms_err(core, "%s: turn on PHY PLL failed\n", - __func__); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " + "PHY PLL failed\n", __func__); } } else { /* @@ -2856,7 +2854,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw) { bool dev_gone; - brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); dev_gone = brcms_deviceremoved(wlc_hw->wlc); @@ -2886,14 +2884,12 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc) uint i; /* free any posted tx packets */ - for (i = 0; i < NFIFO; i++) { + for (i = 0; i < NFIFO; i++) if (wlc_hw->di[i]) { dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); - if (i < TX_BCMC_FIFO) - ieee80211_wake_queue(wlc->pub->ieee_hw, - brcms_fifo_to_ac(i)); + wlc->core->txpktpend[i] = 0; + BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); } - } /* free any posted rx packets */ dma_rxreclaim(wlc_hw->di[RX_FIFO]); @@ -3113,7 +3109,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) - brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", + wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", wlc->pub->unit, delta); /* check for tx fifo underflows */ @@ -3122,9 +3118,8 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) (u16) (wlc->core->macstat_snapshot->txfunfl[i] - txfunfl[i]); if (delta) - brcms_err(wlc->hw->d11core, - "wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); + wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" + "\n", wlc->pub->unit, delta, i); } #endif /* DEBUG */ @@ -3137,6 +3132,8 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) static void brcms_b_reset(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + /* reset the core */ if (!brcms_deviceremoved(wlc_hw->wlc)) brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); @@ -3147,7 +3144,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw) void brcms_c_reset(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* slurp up hw mac counters before core reset */ brcms_c_statsupd(wlc); @@ -3192,9 +3189,10 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) bool fifosz_fixup = false; int err = 0; u16 buf[NFIFO]; + struct wiphy *wiphy = wlc->wiphy; struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; - brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset PSM */ brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); @@ -3214,7 +3212,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0), 1000 * 1000); if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) - brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-" + wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" "suspend!\n", wlc_hw->unit); brcms_c_gpio_init(wlc); @@ -3225,18 +3223,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) if (BRCMS_ISNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); else - brcms_err(core, "%s: wl%d: unsupported phy in corerev" + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (BRCMS_ISLCNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); else - brcms_err(core, "%s: wl%d: unsupported phy in corerev" + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else { - brcms_err(core, "%s: wl%d: unsupported corerev %d\n", + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } @@ -3278,7 +3276,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) err = -1; } if (err != 0) - brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d" + wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" " driver size %d index %d\n", buf[i], wlc_hw->xmtfifo_sz[i], i); @@ -3361,6 +3359,8 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { bool fastclk; struct brcms_c_info *wlc = wlc_hw->wlc; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) @@ -3453,7 +3453,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, rate = (rateset->rates[i] & BRCMS_RATE_MASK); if (rate > BRCM_MAXRATE) { - brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: " + wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " "invalid rate 0x%X in rate set\n", rateset->rates[i]); continue; @@ -3529,6 +3529,7 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, uint parkband; uint i, band_order[2]; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* * We might have been bandlocked during down and the chip * power-cycled (hibernate). Figure out the right band to park on @@ -3709,8 +3710,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc) /* band-specific init */ static void brcms_c_bsinit(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n", - wlc->pub->unit, wlc->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); /* write ucode ACK/CTS rate table */ brcms_c_set_ratetable(wlc); @@ -3733,8 +3734,7 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : M_TX_IDLE_BUSY_RATIO_X_16_CCK; if (duty_cycle > 100 || duty_cycle < 0) { - brcms_err(wlc->hw->d11core, - "wl%d: duty cycle value off limit\n", + wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", wlc->pub->unit); return -EINVAL; } @@ -3752,6 +3752,40 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, return 0; } +/* + * Initialize the base precedence map for dequeueing + * from txq based on WME settings + */ +static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) +{ + wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); + + wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO; +} + +static void +brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, bool on, int prio) +{ + /* transmit flowcontrol is not yet implemented */ +} + +static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc) +{ + struct brcms_txq_info *qi; + + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + if (qi->stopped) { + brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + qi->stopped = 0; + } + } +} + /* push sw hps and wake state through hardware */ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) { @@ -3761,8 +3795,7 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) hps = brcms_c_ps_allowed(wlc); - brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit, - hps); + BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); v2 = MCTL_WAKE; @@ -3848,8 +3881,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, { uint bandunit; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit, - chanspec); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); wlc_hw->chanspec = chanspec; @@ -3910,7 +3942,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) u16 old_chanspec = wlc->chanspec; if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; } @@ -3921,8 +3953,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { switchband = true; if (wlc->bandlocked) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: chspec %d band is locked!\n", + wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " + "band is locked!\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; @@ -3986,10 +4018,6 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, */ void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) { - /* - * Cannot use brcms_dbg_* here because this function is called - * before wlc is sufficiently initialized. - */ BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); switch (idx) { @@ -4062,8 +4090,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, /* Only apply params if the core is out of reset and has clocks */ if (!wlc->clk) { - brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, + __func__); return; } @@ -4081,7 +4109,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad " + wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " "aifs %d\n", wlc->pub->unit, acp_shm.aifs); } else { acp_shm.cwmin = params->cw_min; @@ -4196,8 +4224,8 @@ static void brcms_c_radio_timer(void *arg) struct brcms_c_info *wlc = (struct brcms_c_info *) arg; if (brcms_deviceremoved(wlc)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); brcms_down(wlc->wl); return; } @@ -4210,6 +4238,8 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) { struct brcms_hardware *wlc_hw = wlc->hw; + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return; @@ -4228,14 +4258,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) /* common watchdog code */ static void brcms_c_watchdog(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); if (!wlc->pub->up) return; if (brcms_deviceremoved(wlc)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); brcms_down(wlc->wl); return; } @@ -4407,13 +4437,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, struct ssb_sprom *sprom = &core->bus->sprom; if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) - brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, - pcidev->vendor, - pcidev->device); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, + pcidev->vendor, + pcidev->device); else - brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, - core->bus->boardinfo.vendor, - core->bus->boardinfo.type); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, + core->bus->boardinfo.vendor, + core->bus->boardinfo.type); wme = true; @@ -4685,9 +4715,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, goto fail; } - brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n", - wlc_hw->deviceid, wlc_hw->_nbands, - ai_get_boardtype(wlc_hw->sih)); + BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", + wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); return err; @@ -4807,6 +4836,56 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc) bi->flags |= BRCMS_BSS_HT; } +static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) +{ + struct brcms_txq_info *qi, *p; + + qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC); + if (qi != NULL) { + /* + * Have enough room for control packets along with HI watermark + * Also, add room to txq for total psq packets if all the SCBs + * leave PS mode. The watermark for flowcontrol to OS packets + * will remain the same + */ + brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT, + 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } + } + return qi; +} + +static void brcms_c_txq_free(struct brcms_c_info *wlc, + struct brcms_txq_info *qi) +{ + struct brcms_txq_info *p; + + if (qi == NULL) + return; + + /* remove the queue from the linked list */ + p = wlc->tx_queues; + if (p == qi) + wlc->tx_queues = p->next; + else { + while (p != NULL && p->next != qi) + p = p->next; + if (p != NULL) + p->next = p->next->next; + } + + kfree(qi); +} + static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) { uint i; @@ -4912,6 +4991,8 @@ uint brcms_c_detach(struct brcms_c_info *wlc) if (wlc == NULL) return 0; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + callbacks += brcms_b_detach(wlc); /* delete software timers */ @@ -4924,6 +5005,10 @@ uint brcms_c_detach(struct brcms_c_info *wlc) brcms_c_detach_module(wlc); + + while (wlc->tx_queues != NULL) + brcms_c_txq_free(wlc, wlc->tx_queues); + brcms_c_detach_mfree(wlc); return callbacks; } @@ -4941,7 +5026,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) if (wlc_hw->wlc->pub->hw_up) return; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, @@ -4978,7 +5063,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) { - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, @@ -4992,7 +5077,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) * Configure pci/pcmcia here instead of in brcms_c_attach() * to allow mfg hotswap: down, hotswap (chip power cycle), up. */ - bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, + bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core, true); /* @@ -5017,6 +5102,8 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + wlc_hw->up = true; wlc_phy_hw_state_upd(wlc_hw->band->pi, true); @@ -5048,7 +5135,7 @@ int brcms_c_up(struct brcms_c_info *wlc) { struct ieee80211_channel *ch; - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* HW is turned off so don't try to access it */ if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) @@ -5089,8 +5176,8 @@ int brcms_c_up(struct brcms_c_info *wlc) WL_RADIO_HW_DISABLE); if (bsscfg->enable && bsscfg->BSS) - brcms_err(wlc->hw->d11core, - "wl%d: up: rfdisable -> " + wiphy_err(wlc->wiphy, "wl%d: up" + ": rfdisable -> " "bsscfg_disable()\n", wlc->pub->unit); } @@ -5150,6 +5237,8 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) bool dev_gone; uint callbacks = 0; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return callbacks; @@ -5176,6 +5265,8 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw) uint callbacks = 0; bool dev_gone; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return callbacks; @@ -5223,14 +5314,14 @@ uint brcms_c_down(struct brcms_c_info *wlc) uint callbacks = 0; int i; bool dev_gone = false; + struct brcms_txq_info *qi; - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* check if we are already in the going down path */ if (wlc->going_down) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" + "\n", wlc->pub->unit, __func__); return 0; } if (!wlc->pub->up) @@ -5262,6 +5353,13 @@ uint brcms_c_down(struct brcms_c_info *wlc) wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); + /* clear txq flow control */ + brcms_c_txflowcontrol_reset(wlc); + + /* flush tx queues */ + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) + brcmu_pktq_flush(&qi->q, true, NULL, NULL); + callbacks += brcms_b_down_finish(wlc->hw); /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ @@ -5343,7 +5441,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) default: /* Error */ - brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n", + wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", wlc->pub->unit, __func__, gmode); return -ENOTSUPP; } @@ -5647,6 +5745,45 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } +void brcms_c_print_txstatus(struct tx_status *txs) +{ + pr_debug("\ntxpkt (MPDU) Complete\n"); + + pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); + + pr_debug("[15:12] %d frame attempts\n", + (txs->status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + pr_debug(" [11:8] %d rts attempts\n", + (txs->status & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + pr_debug(" [7] %d PM mode indicated\n", + txs->status & TX_STATUS_PMINDCTD ? 1 : 0); + pr_debug(" [6] %d intermediate status\n", + txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); + pr_debug(" [5] %d AMPDU\n", + txs->status & TX_STATUS_AMPDU ? 1 : 0); + pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", + (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, + (const char *[]) { + "None", + "PMQ Entry", + "Flush request", + "Previous frag failure", + "Channel mismatch", + "Lifetime Expiry", + "Underflow" + } [(txs->status & TX_STATUS_SUPR_MASK) >> + TX_STATUS_SUPR_SHIFT]); + pr_debug(" [1] %d acked\n", + txs->status & TX_STATUS_ACK_RCV ? 1 : 0); + + pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", + txs->lasttxtime, txs->sequence, txs->phyerr, + (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, + (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); +} + static bool brcms_c_chipmatch_pci(struct bcma_device *core) { struct pci_dev *pcidev = core->bus->host_pci; @@ -5695,6 +5832,184 @@ bool brcms_c_chipmatch(struct bcma_device *core) } } +#if defined(DEBUG) +void brcms_c_print_txdesc(struct d11txh *txh) +{ + u16 mtcl = le16_to_cpu(txh->MacTxControlLow); + u16 mtch = le16_to_cpu(txh->MacTxControlHigh); + u16 mfc = le16_to_cpu(txh->MacFrameControl); + u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); + u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); + u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = le16_to_cpu(txh->MainRates); + u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); + u8 *iv = txh->IV; + u8 *ra = txh->TxFrameRA; + u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); + u8 *rtspfb = txh->RTSPLCPFallback; + u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); + u8 *fragpfb = txh->FragPLCPFallback; + u16 fragdfb = le16_to_cpu(txh->FragDurFallback); + u16 mmodelen = le16_to_cpu(txh->MModeLen); + u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); + u16 tfid = le16_to_cpu(txh->TxFrameID); + u16 txs = le16_to_cpu(txh->TxStatus); + u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); + u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); + u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); + u16 mmbyte = le16_to_cpu(txh->MinMBytes); + + u8 *rtsph = txh->RTSPhyHeader; + struct ieee80211_rts rts = txh->rts_frame; + + /* add plcp header along with txh descriptor */ + brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, + "Raw TxDesc + plcp header:\n"); + + pr_debug("TxCtlLow: %04x ", mtcl); + pr_debug("TxCtlHigh: %04x ", mtch); + pr_debug("FC: %04x ", mfc); + pr_debug("FES Time: %04x\n", tfest); + pr_debug("PhyCtl: %04x%s ", ptcw, + (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); + pr_debug("PhyCtl_1: %04x ", ptcw_1); + pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + pr_debug("MainRates: %04x ", mainrates); + pr_debug("XtraFrameTypes: %04x ", xtraft); + pr_debug("\n"); + + print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); + print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, + ra, sizeof(txh->TxFrameRA)); + + pr_debug("Fb FES Time: %04x ", tfestfb); + print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, + rtspfb, sizeof(txh->RTSPLCPFallback)); + pr_debug("RTS DUR: %04x ", rtsdfb); + print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, + fragpfb, sizeof(txh->FragPLCPFallback)); + pr_debug("DUR: %04x", fragdfb); + pr_debug("\n"); + + pr_debug("MModeLen: %04x ", mmodelen); + pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); + + pr_debug("FrameID: %04x\n", tfid); + pr_debug("TxStatus: %04x\n", txs); + + pr_debug("MaxNumMpdu: %04x\n", mnmpdu); + pr_debug("MaxAggbyte: %04x\n", mabyte); + pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); + pr_debug("MinByte: %04x\n", mmbyte); + + print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, + rtsph, sizeof(txh->RTSPhyHeader)); + print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, + (u8 *)&rts, sizeof(txh->rts_frame)); + pr_debug("\n"); +} +#endif /* defined(DEBUG) */ + +#if defined(DEBUG) +static int +brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, + int len) +{ + int i; + char *p = buf; + char hexstr[16]; + int slen = 0, nlen = 0; + u32 bit; + const char *name; + + if (len < 2 || !buf) + return 0; + + buf[0] = '\0'; + + for (i = 0; flags != 0; i++) { + bit = bd[i].bit; + name = bd[i].name; + if (bit == 0 && flags != 0) { + /* print any unnamed bits */ + snprintf(hexstr, 16, "0x%X", flags); + name = hexstr; + flags = 0; /* exit loop */ + } else if ((flags & bit) == 0) + continue; + flags &= ~bit; + nlen = strlen(name); + slen += nlen; + /* count btwn flag space */ + if (flags != 0) + slen += 1; + /* need NULL char as well */ + if (len <= slen) + break; + /* copy NULL char but don't count it */ + strncpy(p, name, nlen + 1); + p += nlen; + /* copy btwn flag space and NULL char */ + if (flags != 0) + p += snprintf(p, 2, " "); + len -= slen; + } + + /* indicate the str was too short */ + if (flags != 0) { + if (len < 2) + p -= 2 - len; /* overwrite last char */ + p += snprintf(p, 2, ">"); + } + + return (int)(p - buf); +} +#endif /* defined(DEBUG) */ + +#if defined(DEBUG) +void brcms_c_print_rxh(struct d11rxhdr *rxh) +{ + u16 len = rxh->RxFrameSize; + u16 phystatus_0 = rxh->PhyRxStatus_0; + u16 phystatus_1 = rxh->PhyRxStatus_1; + u16 phystatus_2 = rxh->PhyRxStatus_2; + u16 phystatus_3 = rxh->PhyRxStatus_3; + u16 macstatus1 = rxh->RxStatus1; + u16 macstatus2 = rxh->RxStatus2; + char flagstr[64]; + char lenbuf[20]; + static const struct brcms_c_bit_desc macstat_flags[] = { + {RXS_FCSERR, "FCSErr"}, + {RXS_RESPFRAMETX, "Reply"}, + {RXS_PBPRES, "PADDING"}, + {RXS_DECATMPT, "DeCr"}, + {RXS_DECERR, "DeCrErr"}, + {RXS_BCNSENT, "Bcn"}, + {0, NULL} + }; + + brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); + + brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); + + snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); + + pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, + (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); + pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", + phystatus_0, phystatus_1, phystatus_2, phystatus_3); + pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); + pr_debug("RXMACaggtype: %x\n", + (macstatus2 & RXS_AGGTYPE_MASK)); + pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); +} +#endif /* defined(DEBUG) */ + u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { u16 table_ptr; @@ -5718,6 +6033,86 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); } +static bool +brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) + eprec = prec; + else if (pktq_full(q)) { + p = brcmu_pktq_peek_tail(q, &eprec); + if (eprec > prec) { + wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" + "\n", __func__, eprec, prec); + return false; + } + } + + /* Evict if needed */ + if (eprec >= 0) { + bool discard_oldest; + + discard_oldest = ac_bitmap_tst(0, eprec); + + /* Refuse newer packet unless configured to discard oldest */ + if (eprec == prec && !discard_oldest) { + wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d" + "\n", __func__, prec); + return false; + } + + /* Evict packet according to discard policy */ + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : + brcmu_pktq_pdeq_tail(q, eprec); + brcmu_pkt_buf_free_skb(p); + } + + /* Enqueue */ + if (head) + p = brcmu_pktq_penq_head(q, prec, pkt); + else + p = brcmu_pktq_penq(q, prec, pkt); + + return true; +} + +/* + * Attempts to queue a packet onto a multiple-precedence queue, + * if necessary evicting a lower precedence packet from the queue. + * + * 'prec' is the precedence number that has already been mapped + * from the packet priority. + * + * Returns true if packet consumed (queued), false if not. + */ +static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec) +{ + return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); +} + +void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec) +{ + struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ + struct pktq *q = &qi->q; + int prio; + + prio = sdu->priority; + + if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { + /* + * we might hit this condtion in case + * packet flooding from mac80211 stack + */ + brcmu_pkt_buf_free_skb(sdu); + } +} + /* * bcmc_fid_generate: * Generate frame ID for a BCMC packet. The frag field is not used @@ -5745,6 +6140,8 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, { uint dur = 0; + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); /* * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that * is less than or equal to the rate of the immediately previous @@ -5762,6 +6159,8 @@ static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { + BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); return brcms_c_calc_ack_time(wlc, rspec, preamble_type); } @@ -5769,6 +6168,8 @@ static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " + "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); /* * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that * is less than or equal to the rate of the immediately previous @@ -5822,6 +6223,9 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, uint nsyms, mac_len, Ndps, kNdps; uint rate = rspec2rate(ratespec); + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); @@ -5888,7 +6292,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, return true; error: if (verbose) - brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x " + wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " "not in hw_rateset\n", wlc->pub->unit, rspec); return false; @@ -5898,7 +6302,6 @@ static u32 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, u32 int_val) { - struct bcma_device *core = wlc->hw->d11core; u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; u8 rate = int_val & NRATE_RATE_MASK; u32 rspec; @@ -5915,7 +6318,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { /* mcs only allowed when nmode */ if (stf > PHY_TXC1_MODE_SDM) { - brcms_err(core, "wl%d: %s: Invalid stf\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -5926,8 +6329,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if (!CHSPEC_IS40(wlc->home_chanspec) || ((stf != PHY_TXC1_MODE_SISO) && (stf != PHY_TXC1_MODE_CDD))) { - brcms_err(core, "wl%d: %s: Invalid mcs 32\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " + "32\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } @@ -5935,9 +6338,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { /* mcs > 7 must use stf SDM */ if (stf != PHY_TXC1_MODE_SDM) { - brcms_dbg_mac80211(core, "wl%d: enabling " - "SDM mode for mcs %d\n", - wlc->pub->unit, rate); + BCMMSG(wlc->wiphy, "wl%d: enabling " + "SDM mode for mcs %d\n", + wlc->pub->unit, rate); stf = PHY_TXC1_MODE_SDM; } } else { @@ -5948,15 +6351,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if ((stf > PHY_TXC1_MODE_STBC) || (!BRCMS_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { - brcms_err(core, "wl%d: %s: Invalid STBC\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" + "\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } } } else if (is_ofdm_rate(rate)) { if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - brcms_err(core, "wl%d: %s: Invalid OFDM\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -5964,20 +6367,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, } else if (is_cck_rate(rate)) { if ((cur_band->bandtype != BRCM_BAND_2G) || (stf != PHY_TXC1_MODE_SISO)) { - brcms_err(core, "wl%d: %s: Invalid CCK\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } } else { - brcms_err(core, "wl%d: %s: Unknown rate type\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } /* make sure multiple antennae are available for non-siso rates */ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - brcms_err(core, "wl%d: %s: SISO antenna but !SISO " + wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " "request\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -6046,7 +6449,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, break; default: - brcms_err(wlc->hw->d11core, + wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d\n", rate_500); rate_500 = BRCM_RATE_1M; @@ -6179,7 +6582,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) bw = rspec_get_bw(rspec); /* 10Mhz is not supported yet */ if (bw < PHY_TXC1_BW_20MHZ) { - brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is " + wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " "not supported yet, set to 20L\n", bw); bw = PHY_TXC1_BW_20MHZ; } @@ -6206,7 +6609,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) /* get the phyctl byte from rate phycfg table */ phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); if (phycfg == -1) { - brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong " + wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " "legacy OFDM/CCK rate\n"); phycfg = 0; } @@ -6286,9 +6689,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { /* non-AP STA should never use BCMC queue */ if (queue == TX_BCMC_FIFO) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: ASSERT queue == TX_BCMC!\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " + "TX_BCMC!\n", wlc->pub->unit, __func__); frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ @@ -6458,8 +6860,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) && (!is_mcs_rate(rspec[k]))) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: IEEE80211_TX_" + wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" "RC_MCS != is_mcs_rate(rspec)\n", wlc->pub->unit, __func__); } @@ -6853,16 +7254,14 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, wlc->fragthresh[queue] = (u16) newfragthresh; } else { - brcms_err(wlc->hw->d11core, - "wl%d: %s txop invalid " + wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " "for rate %d\n", wlc->pub->unit, fifo_names[queue], rspec2rate(rspec[0])); } if (dur > wlc->edcf_txop[ac]) - brcms_err(wlc->hw->d11core, - "wl%d: %s: %s txop " + wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " "exceeded phylen %d/%d dur %d/%d\n", wlc->pub->unit, __func__, fifo_names[queue], @@ -6874,33 +7273,79 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, return 0; } -static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) +void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) { - struct dma_pub *dma; - int fifo, ret = -ENOSPC; - struct d11txh *txh; - u16 frameid = INVALIDFID; + u8 prio; + uint fifo; + struct scb *scb = &wlc->pri_scb; + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb)); - dma = wlc->hw->di[fifo]; - txh = (struct d11txh *)(skb->data); + /* + * 802.11 standard requires management traffic + * to go at highest priority + */ + prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : + MAXPRIO; + fifo = prio2fifo[prio]; + if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) + return; + brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); + brcms_c_send_q(wlc); +} - if (dma->txavail == 0) { - /* - * We sometimes get a frame from mac80211 after stopping - * the queues. This only ever seems to be a single frame - * and is seems likely to be a race. TX_HEADROOM should - * ensure that we have enough space to handle these stray - * packets, so warn if there isn't. If we're out of space - * in the tx ring and the tx queue isn't stopped then - * we've really got a bug; warn loudly if that happens. - */ - brcms_warn(wlc->hw->d11core, - "Received frame for tx with no space in DMA ring\n"); - WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw, - skb_get_queue_mapping(skb))); - return -ENOSPC; +void brcms_c_send_q(struct brcms_c_info *wlc) +{ + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; + int prec; + u16 prec_map; + int err = 0, i, count; + uint fifo; + struct brcms_txq_info *qi = wlc->pkt_queue; + struct pktq *q = &qi->q; + struct ieee80211_tx_info *tx_info; + + prec_map = wlc->tx_prec_map; + + /* Send all the enq'd pkts that we can. + * Dequeue packets with precedence with empty HW fifo only + */ + while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) { + tx_info = IEEE80211_SKB_CB(pkt[0]); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec); + } else { + count = 1; + err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); + if (!err) { + for (i = 0; i < count; i++) + brcms_c_txfifo(wlc, fifo, pkt[i], true, + 1); + } + } + + if (err == -EBUSY) { + brcmu_pktq_penq_head(q, prec, pkt[0]); + /* + * If send failed due to any other reason than a + * change in HW FIFO condition, quit. Otherwise, + * read the new prec_map! + */ + if (prec_map == wlc->tx_prec_map) + break; + prec_map = wlc->tx_prec_map; + } } +} + +void +brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend) +{ + u16 frameid = INVALIDFID; + struct d11txh *txh; + + txh = (struct d11txh *) (p->data); /* When a BC/MC frame is being committed to the BCMC fifo * via DMA (NOT PIO), update ucode or BSS info as appropriate. @@ -6908,6 +7353,16 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) if (fifo == TX_BCMC_FIFO) frameid = le16_to_cpu(txh->TxFrameID); + /* + * Bump up pending count for if not using rpc. If rpc is + * used, this will be handled in brcms_b_txfifo() + */ + if (commit) { + wlc->core->txpktpend[fifo] += txpktpend; + BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n", + txpktpend, wlc->core->txpktpend[fifo]); + } + /* Commit BCMC sequence number in the SHM frame ID location */ if (frameid != INVALIDFID) { /* @@ -6917,52 +7372,8 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); } - ret = brcms_c_txfifo(wlc, fifo, skb); - /* - * The only reason for brcms_c_txfifo to fail is because - * there weren't any DMA descriptors, but we've already - * checked for that. So if it does fail yell loudly. - */ - WARN_ON_ONCE(ret); - - return ret; -} - -void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw) -{ - uint fifo; - struct scb *scb = &wlc->pri_scb; - - fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); - if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) - return; - if (brcms_c_tx(wlc, sdu)) - dev_kfree_skb_any(sdu); -} - -int -brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p) -{ - struct dma_pub *dma = wlc->hw->di[fifo]; - int ret; - u16 queue; - - ret = dma_txfast(wlc, dma, p); - if (ret < 0) + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); - - /* - * Stop queue if DMA ring is full. Reserve some free descriptors, - * as we sometimes receive a frame from mac80211 after the queues - * are stopped. - */ - queue = skb_get_queue_mapping(p); - if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO && - !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue)) - ieee80211_stop_queue(wlc->pub->ieee_hw, queue); - - return ret; } u32 @@ -7012,6 +7423,19 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, return rts_rspec; } +void +brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) +{ + wlc->core->txpktpend[fifo] -= txpktpend; + BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, + wlc->core->txpktpend[fifo]); + + /* There is more room; mark precedences related to this FIFO sendable */ + wlc->tx_prec_map |= wlc->fifo2prec_map[fifo]; + + /* figure out which bsscfg is being worked on... */ +} + /* Update beacon listen interval in shared memory */ static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) { @@ -7147,8 +7571,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, rx_status->rate_idx = 11; break; default: - brcms_err(wlc->hw->d11core, - "%s: Unknown rate\n", __func__); + wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); } /* @@ -7167,7 +7590,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, } else if (is_ofdm_rate(rspec)) { rx_status->flag |= RX_FLAG_SHORTPRE; } else { - brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n", + wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", __func__); } } @@ -7177,12 +7600,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, if (rxh->RxStatus1 & RXS_DECERR) { rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n", + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); } if (rxh->RxStatus1 & RXS_FCSERR) { rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n", + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); } } @@ -7226,6 +7649,9 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, { uint nsyms, len = 0, kNdps; + BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n", + wlc->pub->unit, rspec2rate(ratespec), mac_len); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = (mcs_2_txstreams(mcs) + 1) + @@ -7457,6 +7883,35 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); } +/* prepares pdu for transmission. returns BCM error codes */ +int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) +{ + uint fifo; + struct d11txh *txh; + struct ieee80211_hdr *h; + struct scb *scb; + + txh = (struct d11txh *) (pdu->data); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + + /* get the pkt queue info. This was put at brcms_c_sendctl or + * brcms_c_send for PDU */ + fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; + + scb = NULL; + + *fifop = fifo; + + /* return if insufficient dma resources */ + if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) { + /* Mark precedences related to this FIFO, unsendable */ + /* A fifo is full. Clear precedences related to that FIFO */ + wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]); + return -EBUSY; + } + return 0; +} + int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks) { @@ -7522,15 +7977,13 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { int timeout = 20; - int i; - /* Kick DMA to send any pending AMPDU */ - for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) - if (wlc->hw->di[i]) - dma_txflush(wlc->hw->di[i]); + /* flush packet queue when requested */ + if (drop) + brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); /* wait for queue and DMA fifos to run dry */ - while (brcms_txpktpendtot(wlc) > 0) { + while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { brcms_msleep(wlc->wl, 1); if (--timeout == 0) @@ -7579,6 +8032,8 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) uint len; bool is_amsdu; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + /* frame starts with rxhdr */ rxh = (struct d11rxhdr *) (p->data); @@ -7588,9 +8043,8 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { - brcms_err(wlc->hw->d11core, - "wl%d: recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); + wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " + "len %d\n", wlc->pub->unit, p->len); goto toss; } skb_pull(p, 2); @@ -7635,6 +8089,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) uint n = 0; uint bound_limit = bound ? RXBND : -1; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); skb_queue_head_init(&recv_frames); /* gather received frames */ @@ -7685,9 +8140,10 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) u32 macintstatus; struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; + struct wiphy *wiphy = wlc->wiphy; if (brcms_deviceremoved(wlc)) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return false; @@ -7697,8 +8153,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) macintstatus = wlc->macintstatus; wlc->macintstatus = 0; - brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); + BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ @@ -7708,7 +8164,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) wlc->macintstatus |= MI_TFS; if (fatal) { - brcms_err(core, "MI_TFS: fatal\n"); + wiphy_err(wiphy, "MI_TFS: fatal\n"); goto fatal; } } @@ -7718,7 +8174,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) /* ATIM window end */ if (macintstatus & MI_ATIMWINEND) { - brcms_dbg_info(core, "end of ATIM window\n"); + BCMMSG(wlc->wiphy, "end of ATIM window\n"); bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); wlc->qvalid = 0; } @@ -7736,7 +8192,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) wlc_phy_noise_sample_intr(wlc_hw->band->pi); if (macintstatus & MI_GP0) { - brcms_err(core, "wl%d: PSM microcode watchdog fired at %d " + wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", @@ -7750,11 +8206,15 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) bcma_write32(core, D11REGOFFS(gptimer), 0); if (macintstatus & MI_RFDISABLE) { - brcms_dbg_info(core, "wl%d: BMAC Detected a change on the" - " RF Disable Input\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" + " RF Disable Input\n", wlc_hw->unit); brcms_rfkill_set_hw_state(wlc->wl); } + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); + /* it isn't done and needs to be resched if macintstatus is non-zero */ return wlc->macintstatus != 0; @@ -7769,7 +8229,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; u16 chanspec; - brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); chanspec = ch20mhz_chspec(ch->hw_value); @@ -7826,6 +8286,9 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); brcms_c_edcf_setparams(wlc, false); + /* Init precedence maps for empty FIFOs */ + brcms_c_tx_prec_map_init(wlc); + /* read the ucode version if we have not yet done so */ if (wlc->ucode_rev == 0) { wlc->ucode_rev = @@ -7840,6 +8303,9 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) if (mute_tx) brcms_b_mute(wlc->hw, true); + /* clear tx flow control */ + brcms_c_txflowcontrol_reset(wlc); + /* enable the RF Disable Delay timer */ bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); @@ -7998,6 +8464,15 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, * Complete the wlc default state initializations.. */ + /* allocate our initial queue */ + wlc->pkt_queue = brcms_c_txq_alloc(wlc); + if (wlc->pkt_queue == NULL) { + wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", + unit, __func__); + err = 100; + goto fail; + } + wlc->bsscfg->wlc = wlc; wlc->mimoft = FT_HT; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h index fb447747c2c6..8debc74c54e1 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -101,6 +101,9 @@ #define DATA_BLOCK_TX_SUPR (1 << 4) +/* 802.1D Priority to TX FIFO number for wme */ +extern const u8 prio2fifo[]; + /* Ucode MCTL_WAKE override bits */ #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 @@ -239,6 +242,7 @@ struct brcms_core { /* fifo */ uint *txavail[NFIFO]; /* # tx descriptors available */ + s16 txpktpend[NFIFO]; /* tx admission control */ struct macstat *macstat_snapshot; /* mac hw prev read values */ }; @@ -378,6 +382,19 @@ struct brcms_hardware { */ }; +/* TX Queue information + * + * Each flow of traffic out of the device has a TX Queue with independent + * flow control. Several interfaces may be associated with a single TX Queue + * if they belong to the same flow of traffic from the device. For multi-channel + * operation there are independent TX Queues for each channel. + */ +struct brcms_txq_info { + struct brcms_txq_info *next; + struct pktq q; + uint stopped; /* tx flow control bits */ +}; + /* * Principal common driver data structure. * @@ -418,8 +435,11 @@ struct brcms_hardware { * WDlast: last time wlc_watchdog() was called. * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. * wme_retries: per-AC retry limits. + * tx_prec_map: Precedence map based on HW FIFO space. + * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. * bsscfg: set of BSS configurations, idx 0 is default and always valid. * cfg: the primary bsscfg (can be AP or STA). + * tx_queues: common TX Queue list. * modulecb: * mimoft: SIGN or 11N. * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. @@ -449,6 +469,7 @@ struct brcms_hardware { * tempsense_lasttime; * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. + * pkt_queue: txq for transmit packets. * wiphy: * pri_scb: primary Station Control Block */ @@ -512,9 +533,14 @@ struct brcms_c_info { u16 edcf_txop[IEEE80211_NUM_ACS]; u16 wme_retries[IEEE80211_NUM_ACS]; + u16 tx_prec_map; + u16 fifo2prec_map[NFIFO]; struct brcms_bss_cfg *bsscfg; + /* tx queue */ + struct brcms_txq_info *tx_queues; + struct modulecb *modulecb; u8 mimoft; @@ -559,6 +585,7 @@ struct brcms_c_info { u16 tx_duty_cycle_ofdm; u16 tx_duty_cycle_cck; + struct brcms_txq_info *pkt_queue; struct wiphy *wiphy; struct scb pri_scb; }; @@ -610,13 +637,30 @@ struct brcms_bss_cfg { struct brcms_bss_info *current_bss; }; -extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, - struct sk_buff *p); +extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, + struct sk_buff *p, + bool commit, s8 txpktpend); +extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, + s8 txpktpend); +extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec); +extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks); +#if defined(DEBUG) +extern void brcms_c_print_txdesc(struct d11txh *txh); +#else +static inline void brcms_c_print_txdesc(struct d11txh *txh) +{ +} +#endif + extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); +extern void brcms_c_send_q(struct brcms_c_info *wlc); +extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, + uint *fifo); extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len); extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 0148dec104f0..5855f4fd16dc 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -200,6 +200,43 @@ enum wlc_par_id { /* WL11N Support */ #define AMPDU_AGG_HOST 1 +/* pri is priority encoded in the packet. This maps the Packet priority to + * enqueue precedence as defined in wlc_prec_map + */ +extern const u8 wlc_prio2prec_map[]; +#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] + +#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */ + +/* Mask to describe all precedence levels */ +#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) + +/* + * This maps priority to one precedence higher - Used by PS-Poll response + * packets to simulate enqueue-at-head operation, but still maintain the + * order on the queue + */ +#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ + BRCMS_PREC_COUNT - 1) + +/* Define a bitmap of precedences comprised by each AC */ +#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE))) +#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) +#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI))) +#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC))) + /* network protection config */ #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c index dd9162722495..ed1d1aa71d2d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c @@ -23,7 +23,6 @@ #include "channel.h" #include "main.h" #include "stf.h" -#include "debug.h" #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 @@ -161,8 +160,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, u8 core_mask) { - brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n", - wlc->pub->unit, Nsts, core_mask); + BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", + wlc->pub->unit, Nsts, core_mask); if (hweight8(core_mask) > wlc->stf->txstreams) core_mask = 0; @@ -195,8 +194,7 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val) int i; u8 core_mask = 0; - brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit, - val); + BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); wlc->stf->spatial_policy = (s8) val; for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h index ae1f3ad40d45..e11ae83111e4 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h @@ -246,7 +246,7 @@ #define BCMMSG(dev, fmt, args...) \ do { \ - if (brcm_msg_level & BRCM_DL_INFO) \ + if (brcm_msg_level & LOG_TRACE_VAL) \ wiphy_err(dev, "%s: " fmt, __func__, ##args); \ } while (0) @@ -281,6 +281,7 @@ struct ieee80211_tx_queue_params; struct brcms_info; struct brcms_c_info; struct brcms_hardware; +struct brcms_txq_info; struct brcms_band; struct dma_pub; struct si_pub; diff --git a/trunk/drivers/net/wireless/brcm80211/include/defs.h b/trunk/drivers/net/wireless/brcm80211/include/defs.h index fb7cbcf81179..f0d8c04a9c8c 100644 --- a/trunk/drivers/net/wireless/brcm80211/include/defs.h +++ b/trunk/drivers/net/wireless/brcm80211/include/defs.h @@ -78,14 +78,9 @@ #define PM_OFF 0 #define PM_MAX 1 -/* Debug levels */ -#define BRCM_DL_INFO 0x00000001 -#define BRCM_DL_MAC80211 0x00000002 -#define BRCM_DL_RX 0x00000004 -#define BRCM_DL_TX 0x00000008 -#define BRCM_DL_INT 0x00000010 -#define BRCM_DL_DMA 0x00000020 -#define BRCM_DL_HT 0x00000040 +/* Message levels */ +#define LOG_ERROR_VAL 0x00000001 +#define LOG_TRACE_VAL 0x00000002 #define PM_OFF 0 #define PM_MAX 1 diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c index d39e3e24077b..df7050abe717 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -415,7 +415,7 @@ static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb, ssid = pos + 2; ssid_len = pos[1]; break; - case WLAN_EID_VENDOR_SPECIFIC: + case WLAN_EID_GENERIC: if (pos[1] >= 4 && pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 && pos[5] == 1) { diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index 46938bc9886d..29b8fa1adefd 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1788,7 +1788,10 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) } /* Initialize the geo */ - libipw_set_geo(priv->ieee, &ipw_geos[0]); + if (libipw_set_geo(priv->ieee, &ipw_geos[0])) { + printk(KERN_WARNING DRV_NAME "Could not set geo\n"); + return 0; + } priv->ieee->freq_band = LIBIPW_24GHZ_BAND; lock = LOCK_NONE; diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 482f505f3f35..935120fc8c93 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -10472,7 +10472,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, } else len = src->len; - dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC); + dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC); if (!dst) continue; @@ -11269,31 +11269,10 @@ static const struct libipw_geo ipw_geos[] = { } }; -static void ipw_set_geo(struct ipw_priv *priv) -{ - int j; - - for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { - if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], - ipw_geos[j].name, 3)) - break; - } - - if (j == ARRAY_SIZE(ipw_geos)) { - IPW_WARNING("SKU [%c%c%c] not recognized.\n", - priv->eeprom[EEPROM_COUNTRY_CODE + 0], - priv->eeprom[EEPROM_COUNTRY_CODE + 1], - priv->eeprom[EEPROM_COUNTRY_CODE + 2]); - j = 0; - } - - libipw_set_geo(priv->ieee, &ipw_geos[j]); -} - #define MAX_HW_RESTARTS 5 static int ipw_up(struct ipw_priv *priv) { - int rc, i; + int rc, i, j; /* Age scan list entries found before suspend */ if (priv->suspend_time) { @@ -11331,7 +11310,22 @@ static int ipw_up(struct ipw_priv *priv) memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); - ipw_set_geo(priv); + for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { + if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], + ipw_geos[j].name, 3)) + break; + } + if (j == ARRAY_SIZE(ipw_geos)) { + IPW_WARNING("SKU [%c%c%c] not recognized.\n", + priv->eeprom[EEPROM_COUNTRY_CODE + 0], + priv->eeprom[EEPROM_COUNTRY_CODE + 1], + priv->eeprom[EEPROM_COUNTRY_CODE + 2]); + j = 0; + } + if (libipw_set_geo(priv->ieee, &ipw_geos[j])) { + IPW_WARNING("Could not set geography."); + return 0; + } if (priv->status & STATUS_RF_KILL_SW) { IPW_WARNING("Radio disabled by module parameter.\n"); diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw.h b/trunk/drivers/net/wireless/ipw2x00/libipw.h index 6eede52ad8c0..0b22fb421735 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw.h +++ b/trunk/drivers/net/wireless/ipw2x00/libipw.h @@ -978,7 +978,7 @@ extern void libipw_network_reset(struct libipw_network *network); /* libipw_geo.c */ extern const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee); -extern void libipw_set_geo(struct libipw_device *ieee, +extern int libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo); extern int libipw_is_valid_channel(struct libipw_device *ieee, diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c b/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c index 218f2a32de21..c9fe3c99cb00 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c @@ -132,7 +132,7 @@ u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) return 0; } -void libipw_set_geo(struct libipw_device *ieee, +int libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo) { memcpy(ieee->geo.name, geo->name, 3); @@ -143,6 +143,7 @@ void libipw_set_geo(struct libipw_device *ieee, sizeof(struct libipw_channel)); memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * sizeof(struct libipw_channel)); + return 0; } const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c b/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c index 95a1ca1e895c..02e057923236 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -1108,7 +1108,7 @@ static const char *get_info_element_string(u16 id) MFIE_STRING(ERP_INFO); MFIE_STRING(RSN); MFIE_STRING(EXT_SUPP_RATES); - MFIE_STRING(VENDOR_SPECIFIC); + MFIE_STRING(GENERIC); MFIE_STRING(QOS_PARAMETER); default: return "UNKNOWN"; @@ -1248,8 +1248,8 @@ static int libipw_parse_info_param(struct libipw_info_element LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n"); break; - case WLAN_EID_VENDOR_SPECIFIC: - LIBIPW_DEBUG_MGMT("WLAN_EID_VENDOR_SPECIFIC: %d bytes\n", + case WLAN_EID_GENERIC: + LIBIPW_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n", info_element->len); if (!libipw_parse_qos_info_param_IE(info_element, network)) diff --git a/trunk/drivers/net/wireless/iwlegacy/common.h b/trunk/drivers/net/wireless/iwlegacy/common.h index e254cba4557a..b4bb813362bd 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.h +++ b/trunk/drivers/net/wireless/iwlegacy/common.h @@ -2919,8 +2919,9 @@ do { \ #define IL_DBG(level, fmt, args...) \ do { \ if (il_get_debug_level(il) & level) \ - dev_err(&il->hw->wiphy->dev, "%c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __func__ , ##args); \ + dev_printk(KERN_ERR, &il->hw->wiphy->dev, \ + "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ + __func__ , ## args); \ } while (0) #define il_print_hex_dump(il, level, p, len) \ diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c b/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c index da5862064195..349c205d5f62 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -518,7 +518,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, * See iwlagn_mac_channel_switch. */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl6000_channel_switch_cmd *cmd; + struct iwl6000_channel_switch_cmd cmd; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; @@ -527,25 +527,18 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, - .len = { sizeof(*cmd), }, + .len = { sizeof(cmd), }, .flags = CMD_SYNC, - .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + .data = { &cmd, }, }; - int err; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - hcmd.data[0] = cmd; - cmd->band = priv->band == IEEE80211_BAND_2GHZ; + cmd.band = priv->band == IEEE80211_BAND_2GHZ; ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", ctx->active.channel, ch); - cmd->channel = cpu_to_le16(ch); - cmd->rxon_flags = ctx->staging.flags; - cmd->rxon_filter_flags = ctx->staging.filter_flags; + cmd.channel = cpu_to_le16(ch); + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -561,25 +554,23 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, switch_count = 0; } if (switch_count <= 1) - cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time); + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); else { switch_time_in_usec = vif->bss_conf.beacon_int * switch_count * TIME_UNIT; ucode_switch_time = iwl_usecs_to_beacons(priv, switch_time_in_usec, beacon_interval); - cmd->switch_time = iwl_add_beacon_time(priv, - priv->ucode_beacon_time, - ucode_switch_time, - beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); } IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", - cmd->switch_time); - cmd->expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; + cmd.switch_time); + cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; - err = iwl_dvm_send_cmd(priv, &hcmd); - kfree(cmd); - return err; + return iwl_dvm_send_cmd(priv, &hcmd); } struct iwl_lib_ops iwl6000_lib = { diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index bf189f115413..cb443d54f9b9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -519,7 +519,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwlagn_tx_skb(priv, control->sta, skb)) - ieee80211_free_txskb(hw, skb); + dev_kfree_skb_any(skb); } static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, @@ -1352,20 +1352,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, vif_priv->ctx = ctx; ctx->vif = vif; - /* - * In SNIFFER device type, the firmware reports the FCS to - * the host, rather than snipping it off. Unfortunately, - * mac80211 doesn't (yet) provide a per-packet flag for - * this, so that we have to set the hardware flag based - * on the interfaces added. As the monitor interface can - * only be present by itself, and will be removed before - * other interfaces are added, this is safe. - */ - if (vif->type == NL80211_IFTYPE_MONITOR) - priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; - else - priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; - err = iwl_setup_interface(priv, ctx); if (!err || reset) goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index 37bb4575ad8d..03cbfa765f87 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2107,7 +2107,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); - ieee80211_free_txskb(priv->hw, skb); + dev_kfree_skb_any(skb); } static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index 323079769567..11a93eddc84f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -318,14 +318,6 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) dma_map_page(trans->dev, page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - rxb->page = NULL; - spin_lock_irqsave(&rxq->lock, flags); - list_add(&rxb->list, &rxq->rx_used); - spin_unlock_irqrestore(&rxq->lock, flags); - __free_pages(page, trans_pcie->rx_page_order); - return; - } /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -497,19 +489,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - /* - * free the page(s) as well to not break - * the invariant that the items on the used - * list have no page(s) - */ - __free_pages(rxb->page, trans_pcie->rx_page_order); - rxb->page = NULL; - list_add_tail(&rxb->list, &rxq->rx_used); - } else { - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; } else list_add_tail(&rxb->list, &rxq->rx_used); 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 f21bf661931d..a1b9d07b9d01 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -700,11 +700,13 @@ static void iwl_apm_config(struct iwl_trans *trans) PCI_CFG_LINK_CTRL_VAL_L1_EN) { /* L1-ASPM enabled; disable(!) L0S */ iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Enabled; Disabling L0S\n"); + dev_printk(KERN_INFO, trans->dev, + "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Disabled; Enabling L0S\n"); + dev_printk(KERN_INFO, trans->dev, + "L1 Disabled; Enabling L0S\n"); } trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } @@ -2124,7 +2126,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans = kzalloc(sizeof(struct iwl_trans) + sizeof(struct iwl_trans_pcie), GFP_KERNEL); - if (WARN_ON(!trans)) + if (!trans) return NULL; trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -2157,20 +2159,22 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, DMA_BIT_MASK(32)); /* both attempts failed: */ if (err) { - dev_err(&pdev->dev, "No suitable DMA available\n"); + dev_printk(KERN_ERR, &pdev->dev, + "No suitable DMA available.\n"); goto out_pci_disable_device; } } err = pci_request_regions(pdev, DRV_NAME); if (err) { - dev_err(&pdev->dev, "pci_request_regions failed\n"); + dev_printk(KERN_ERR, &pdev->dev, + "pci_request_regions failed\n"); goto out_pci_disable_device; } trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); if (!trans_pcie->hw_base) { - dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); + dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed\n"); err = -ENODEV; goto out_pci_release_regions; } @@ -2181,7 +2185,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, err = pci_enable_msi(pdev); if (err) - dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)\n", err); trans->dev = &pdev->dev; trans_pcie->irq = pdev->irq; diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 739309e70d8b..4cb234349fbf 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -588,38 +588,17 @@ static int if_sdio_prog_real(struct if_sdio_card *card, size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); - if (ret) - goto release; - - req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, - &ret); - if (ret) - goto release; - - req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, - &ret) << 8; - if (ret) - goto release; + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; - /* - * For SD8688 wait until the length is not 0, 1 or 2 - * before downloading the first FW block, - * since BOOT code writes the register to indicate the - * helper/FW download winner, - * the value could be 1 or 2 (Func1 or Func2). - */ - if ((size != fw->size) || (req_size > 2)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); + if (ret) + goto release; + req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; + if (ret) + goto release; /* lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); */ diff --git a/trunk/drivers/net/wireless/libertas/mesh.c b/trunk/drivers/net/wireless/libertas/mesh.c index 3e81264db81e..97807751ebcf 100644 --- a/trunk/drivers/net/wireless/libertas/mesh.c +++ b/trunk/drivers/net/wireless/libertas/mesh.c @@ -101,7 +101,7 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, switch (action) { case CMD_ACT_MESH_CONFIG_START: - ie->id = WLAN_EID_VENDOR_SPECIFIC; + ie->id = WLAN_EID_GENERIC; ie->val.oui[0] = 0x00; ie->val.oui[1] = 0x50; ie->val.oui[2] = 0x43; diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index a8ec7086ad09..429ca3215fdb 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -44,9 +44,9 @@ static int radios = 2; module_param(radios, int, 0444); MODULE_PARM_DESC(radios, "Number of simulated radios"); -static int channels = 1; -module_param(channels, int, 0444); -MODULE_PARM_DESC(channels, "Number of concurrent channels"); +static bool fake_hw_scan; +module_param(fake_hw_scan, bool, 0444); +MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler"); /** * enum hwsim_regtest - the type of regulatory tests we offer @@ -166,9 +166,7 @@ struct hwsim_vif_priv { static inline void hwsim_check_magic(struct ieee80211_vif *vif) { struct hwsim_vif_priv *vp = (void *)vif->drv_priv; - WARN(vp->magic != HWSIM_VIF_MAGIC, - "Invalid VIF (%p) magic %#x, %pM, %d/%d\n", - vif, vp->magic, vif->addr, vif->type, vif->p2p); + WARN_ON(vp->magic != HWSIM_VIF_MAGIC); } static inline void hwsim_set_magic(struct ieee80211_vif *vif) @@ -187,7 +185,7 @@ struct hwsim_sta_priv { u32 magic; }; -#define HWSIM_STA_MAGIC 0x6d537749 +#define HWSIM_STA_MAGIC 0x6d537748 static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta) { @@ -207,30 +205,6 @@ static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta) sp->magic = 0; } -struct hwsim_chanctx_priv { - u32 magic; -}; - -#define HWSIM_CHANCTX_MAGIC 0x6d53774a - -static inline void hwsim_check_chanctx_magic(struct ieee80211_chanctx_conf *c) -{ - struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; - WARN_ON(cp->magic != HWSIM_CHANCTX_MAGIC); -} - -static inline void hwsim_set_chanctx_magic(struct ieee80211_chanctx_conf *c) -{ - struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; - cp->magic = HWSIM_CHANCTX_MAGIC; -} - -static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c) -{ - struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; - cp->magic = 0; -} - static struct class *hwsim_class; static struct net_device *hwsim_mon; /* global monitor netdev */ @@ -325,13 +299,6 @@ struct mac80211_hwsim_data { struct mac_address addresses[2]; - struct ieee80211_channel *tmp_chan; - struct delayed_work roc_done; - struct delayed_work hw_scan; - struct cfg80211_scan_request *hw_scan_request; - struct ieee80211_vif *hw_scan_vif; - int scan_chan_idx; - struct ieee80211_channel *channel; unsigned long beacon_int; /* in jiffies unit */ unsigned int rx_filter; @@ -429,8 +396,7 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, } static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, - struct sk_buff *tx_skb, - struct ieee80211_channel *chan) + struct sk_buff *tx_skb) { struct mac80211_hwsim_data *data = hw->priv; struct sk_buff *skb; @@ -457,7 +423,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); hdr->rt_flags = 0; hdr->rt_rate = txrate->bitrate / 5; - hdr->rt_channel = cpu_to_le16(chan->center_freq); + hdr->rt_channel = cpu_to_le16(data->channel->center_freq); flags = IEEE80211_CHAN_2GHZ; if (txrate->flags & IEEE80211_RATE_ERP_G) flags |= IEEE80211_CHAN_OFDM; @@ -475,9 +441,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, } -static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan, - const u8 *addr) +static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr) { + struct mac80211_hwsim_data *data = hw->priv; struct sk_buff *skb; struct hwsim_radiotap_hdr *hdr; u16 flags; @@ -498,7 +464,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan, (1 << IEEE80211_RADIOTAP_CHANNEL)); hdr->rt_flags = 0; hdr->rt_rate = 0; - hdr->rt_channel = cpu_to_le16(chan->center_freq); + hdr->rt_channel = cpu_to_le16(data->channel->center_freq); flags = IEEE80211_CHAN_2GHZ; hdr->rt_chbitmask = cpu_to_le16(flags); @@ -571,7 +537,6 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, md.ret = false; md.addr = addr; ieee80211_iterate_active_interfaces_atomic(data->hw, - IEEE80211_IFACE_ITER_NORMAL, mac80211_hwsim_addr_iter, &md); @@ -591,6 +556,12 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, int i; struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; + if (data->idle) { + wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); + dev_kfree_skb(my_skb); + return; + } + if (data->ps != PS_DISABLED) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); /* If the queue contains MAX_QUEUE skb's drop some */ @@ -658,38 +629,8 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); } -static bool hwsim_chans_compat(struct ieee80211_channel *c1, - struct ieee80211_channel *c2) -{ - if (!c1 || !c2) - return false; - - return c1->center_freq == c2->center_freq; -} - -struct tx_iter_data { - struct ieee80211_channel *channel; - bool receive; -}; - -static void mac80211_hwsim_tx_iter(void *_data, u8 *addr, - struct ieee80211_vif *vif) -{ - struct tx_iter_data *data = _data; - - if (!vif->chanctx_conf) - return; - - if (!hwsim_chans_compat(data->channel, - rcu_dereference(vif->chanctx_conf)->channel)) - return; - - data->receive = true; -} - static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ieee80211_channel *chan) + struct sk_buff *skb) { struct mac80211_hwsim_data *data = hw->priv, *data2; bool ack = false; @@ -698,10 +639,15 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, struct ieee80211_rx_status rx_status; struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); + if (data->idle) { + wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); + return false; + } + memset(&rx_status, 0, sizeof(rx_status)); rx_status.flag |= RX_FLAG_MACTIME_MPDU; - rx_status.freq = chan->center_freq; - rx_status.band = chan->band; + rx_status.freq = data->channel->center_freq; + rx_status.band = data->channel->band; rx_status.rate_idx = info->control.rates[0].idx; if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) rx_status.flag |= RX_FLAG_HT; @@ -727,30 +673,16 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, list_for_each_entry(data2, &hwsim_radios, list) { struct sk_buff *nskb; struct ieee80211_mgmt *mgmt; - struct tx_iter_data tx_iter_data = { - .receive = false, - .channel = chan, - }; if (data == data2) continue; - if (!data2->started || (data2->idle && !data2->tmp_chan) || - !hwsim_ps_rx_ok(data2, skb)) - continue; - - if (!(data->group & data2->group)) + if (data2->idle || !data2->started || + !hwsim_ps_rx_ok(data2, skb) || !data2->channel || + data->channel->center_freq != data2->channel->center_freq || + !(data->group & data2->group)) continue; - if (!hwsim_chans_compat(chan, data2->tmp_chan) && - !hwsim_chans_compat(chan, data2->channel)) { - ieee80211_iterate_active_interfaces_atomic( - data2->hw, IEEE80211_IFACE_ITER_NORMAL, - mac80211_hwsim_tx_iter, &tx_iter_data); - if (!tx_iter_data.receive) - continue; - } - nskb = skb_copy(skb, GFP_ATOMIC); if (nskb == NULL) continue; @@ -781,51 +713,18 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { - struct mac80211_hwsim_data *data = hw->priv; - struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *channel; bool ack; + struct ieee80211_tx_info *txi; u32 _portid; - if (WARN_ON(skb->len < 10)) { - /* Should not happen; just a sanity check for addr1 use */ - dev_kfree_skb(skb); - return; - } - - if (channels == 1) { - channel = data->channel; - } else if (txi->hw_queue == 4) { - channel = data->tmp_chan; - } else { - chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf); - if (chanctx_conf) - channel = chanctx_conf->channel; - else - channel = NULL; - } - - if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) { - dev_kfree_skb(skb); - return; - } + mac80211_hwsim_monitor_rx(hw, skb); - if (data->idle && !data->tmp_chan) { - wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); + if (skb->len < 10) { + /* Should not happen; just a sanity check for addr1 use */ dev_kfree_skb(skb); return; } - if (txi->control.vif) - hwsim_check_magic(txi->control.vif); - if (control->sta) - hwsim_check_sta_magic(control->sta); - - txi->rate_driver_data[0] = channel; - - mac80211_hwsim_monitor_rx(hw, skb, channel); - /* wmediumd mode check */ _portid = ACCESS_ONCE(wmediumd_portid); @@ -833,13 +732,15 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); /* NO wmediumd detected, perfect medium simulation */ - ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel); + ack = mac80211_hwsim_tx_frame_no_nl(hw, skb); if (ack && skb->len >= 16) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - mac80211_hwsim_monitor_ack(channel, hdr->addr2); + mac80211_hwsim_monitor_ack(hw, hdr->addr2); } + txi = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(txi); /* frame was transmitted at most favorable rate at first attempt */ @@ -877,13 +778,6 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, __func__, ieee80211_vif_type_p2p(vif), vif->addr); hwsim_set_magic(vif); - - vif->cab_queue = 0; - vif->hw_queue[IEEE80211_AC_VO] = 0; - vif->hw_queue[IEEE80211_AC_VI] = 1; - vif->hw_queue[IEEE80211_AC_BE] = 2; - vif->hw_queue[IEEE80211_AC_BK] = 3; - return 0; } @@ -913,26 +807,14 @@ static void mac80211_hwsim_remove_interface( hwsim_clear_magic(vif); } -static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ieee80211_channel *chan) -{ - u32 _pid = ACCESS_ONCE(wmediumd_portid); - - mac80211_hwsim_monitor_rx(hw, skb, chan); - - if (_pid) - return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); - - mac80211_hwsim_tx_frame_no_nl(hw, skb, chan); - dev_kfree_skb(skb); -} static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, struct ieee80211_vif *vif) { struct ieee80211_hw *hw = arg; struct sk_buff *skb; + struct ieee80211_tx_info *info; + u32 _portid; hwsim_check_magic(vif); @@ -944,9 +826,18 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, skb = ieee80211_beacon_get(hw, vif); if (skb == NULL) return; + info = IEEE80211_SKB_CB(skb); + + mac80211_hwsim_monitor_rx(hw, skb); + + /* wmediumd mode check */ + _portid = ACCESS_ONCE(wmediumd_portid); + + if (_portid) + return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); - mac80211_hwsim_tx_frame(hw, skb, - rcu_dereference(vif->chanctx_conf)->channel); + mac80211_hwsim_tx_frame_no_nl(hw, skb); + dev_kfree_skb(skb); } @@ -959,8 +850,7 @@ static void mac80211_hwsim_beacon(unsigned long arg) return; ieee80211_iterate_active_interfaces_atomic( - hw, IEEE80211_IFACE_ITER_NORMAL, - mac80211_hwsim_beacon_tx, hw); + hw, mac80211_hwsim_beacon_tx, hw); data->beacon_timer.expires = jiffies + data->beacon_int; add_timer(&data->beacon_timer); @@ -987,7 +877,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) wiphy_debug(hw->wiphy, "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", __func__, - conf->channel ? conf->channel->center_freq : 0, + conf->channel->center_freq, hwsim_chantypes[conf->channel_type], !!(conf->flags & IEEE80211_CONF_IDLE), !!(conf->flags & IEEE80211_CONF_PS), @@ -996,9 +886,6 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); data->channel = conf->channel; - - WARN_ON(data->channel && channels > 1); - data->power_level = conf->power_level; if (!data->started || !data->beacon_int) del_timer(&data->beacon_timer); @@ -1085,9 +972,6 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", (unsigned long long) info->basic_rates); } - - if (changed & BSS_CHANGED_TXPOWER) - wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower); } static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, @@ -1282,102 +1166,45 @@ static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) /* Not implemented, queues only on kernel side */ } -static void hw_scan_work(struct work_struct *work) -{ - struct mac80211_hwsim_data *hwsim = - container_of(work, struct mac80211_hwsim_data, hw_scan.work); - struct cfg80211_scan_request *req = hwsim->hw_scan_request; - int dwell, i; +struct hw_scan_done { + struct delayed_work w; + struct ieee80211_hw *hw; +}; - mutex_lock(&hwsim->mutex); - if (hwsim->scan_chan_idx >= req->n_channels) { - wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n"); - ieee80211_scan_completed(hwsim->hw, false); - hwsim->hw_scan_request = NULL; - hwsim->hw_scan_vif = NULL; - hwsim->tmp_chan = NULL; - mutex_unlock(&hwsim->mutex); - return; - } +static void hw_scan_done(struct work_struct *work) +{ + struct hw_scan_done *hsd = + container_of(work, struct hw_scan_done, w.work); - wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n", - req->channels[hwsim->scan_chan_idx]->center_freq); - - hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; - if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || - !req->n_ssids) { - dwell = 120; - } else { - dwell = 30; - /* send probes */ - for (i = 0; i < req->n_ssids; i++) { - struct sk_buff *probe; - - probe = ieee80211_probereq_get(hwsim->hw, - hwsim->hw_scan_vif, - req->ssids[i].ssid, - req->ssids[i].ssid_len, - req->ie, req->ie_len); - if (!probe) - continue; - local_bh_disable(); - mac80211_hwsim_tx_frame(hwsim->hw, probe, - hwsim->tmp_chan); - local_bh_enable(); - } - } - ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, - msecs_to_jiffies(dwell)); - hwsim->scan_chan_idx++; - mutex_unlock(&hwsim->mutex); + ieee80211_scan_completed(hsd->hw, false); + kfree(hsd); } static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { - struct mac80211_hwsim_data *hwsim = hw->priv; + struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); int i; - mutex_lock(&hwsim->mutex); - if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { - mutex_unlock(&hwsim->mutex); - return -EBUSY; - } - hwsim->hw_scan_request = req; - hwsim->hw_scan_vif = vif; - hwsim->scan_chan_idx = 0; - mutex_unlock(&hwsim->mutex); + if (!hsd) + return -ENOMEM; + + hsd->hw = hw; + INIT_DELAYED_WORK(&hsd->w, hw_scan_done); - wiphy_debug(hw->wiphy, "hwsim hw_scan request\n"); + printk(KERN_DEBUG "hwsim hw_scan request\n"); for (i = 0; i < req->n_channels; i++) printk(KERN_DEBUG "hwsim hw_scan freq %d\n", req->channels[i]->center_freq); print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET, 16, 1, req->ie, req->ie_len, 1); - ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0); + ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); return 0; } -static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct mac80211_hwsim_data *hwsim = hw->priv; - - wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n"); - - cancel_delayed_work_sync(&hwsim->hw_scan); - - mutex_lock(&hwsim->mutex); - ieee80211_scan_completed(hwsim->hw, true); - hwsim->tmp_chan = NULL; - hwsim->hw_scan_request = NULL; - hwsim->hw_scan_vif = NULL; - mutex_unlock(&hwsim->mutex); -} - static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *hwsim = hw->priv; @@ -1408,105 +1235,6 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) mutex_unlock(&hwsim->mutex); } -static void hw_roc_done(struct work_struct *work) -{ - struct mac80211_hwsim_data *hwsim = - container_of(work, struct mac80211_hwsim_data, roc_done.work); - - mutex_lock(&hwsim->mutex); - ieee80211_remain_on_channel_expired(hwsim->hw); - hwsim->tmp_chan = NULL; - mutex_unlock(&hwsim->mutex); - - wiphy_debug(hwsim->hw->wiphy, "hwsim ROC expired\n"); -} - -static int mac80211_hwsim_roc(struct ieee80211_hw *hw, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - int duration) -{ - struct mac80211_hwsim_data *hwsim = hw->priv; - - mutex_lock(&hwsim->mutex); - if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { - mutex_unlock(&hwsim->mutex); - return -EBUSY; - } - - hwsim->tmp_chan = chan; - mutex_unlock(&hwsim->mutex); - - wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n", - chan->center_freq, duration); - - ieee80211_ready_on_channel(hw); - - ieee80211_queue_delayed_work(hw, &hwsim->roc_done, - msecs_to_jiffies(duration)); - return 0; -} - -static int mac80211_hwsim_croc(struct ieee80211_hw *hw) -{ - struct mac80211_hwsim_data *hwsim = hw->priv; - - cancel_delayed_work_sync(&hwsim->roc_done); - - mutex_lock(&hwsim->mutex); - hwsim->tmp_chan = NULL; - mutex_unlock(&hwsim->mutex); - - wiphy_debug(hw->wiphy, "hwsim ROC canceled\n"); - - return 0; -} - -static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) -{ - hwsim_set_chanctx_magic(ctx); - wiphy_debug(hw->wiphy, "add channel context %d MHz/%d\n", - ctx->channel->center_freq, ctx->channel_type); - return 0; -} - -static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx) -{ - wiphy_debug(hw->wiphy, "remove channel context %d MHz/%d\n", - ctx->channel->center_freq, ctx->channel_type); - hwsim_check_chanctx_magic(ctx); - hwsim_clear_chanctx_magic(ctx); -} - -static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx, - u32 changed) -{ - hwsim_check_chanctx_magic(ctx); - wiphy_debug(hw->wiphy, "change channel context %#x (%d MHz/%d)\n", - changed, ctx->channel->center_freq, ctx->channel_type); -} - -static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_chanctx_conf *ctx) -{ - hwsim_check_magic(vif); - hwsim_check_chanctx_magic(ctx); - - return 0; -} - -static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_chanctx_conf *ctx) -{ - hwsim_check_magic(vif); - hwsim_check_chanctx_magic(ctx); -} - static struct ieee80211_ops mac80211_hwsim_ops = { .tx = mac80211_hwsim_tx, @@ -1587,6 +1315,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_pspoll *pspoll; + u32 _portid; if (!vp->assoc) return; @@ -1606,18 +1335,25 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); memcpy(pspoll->ta, mac, ETH_ALEN); - rcu_read_lock(); - mac80211_hwsim_tx_frame(data->hw, skb, - rcu_dereference(vif->chanctx_conf)->channel); - rcu_read_unlock(); + /* wmediumd mode check */ + _portid = ACCESS_ONCE(wmediumd_portid); + + if (_portid) + return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid); + + if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) + printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__); + dev_kfree_skb(skb); } + static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, struct ieee80211_vif *vif, int ps) { struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_hdr *hdr; + u32 _portid; if (!vp->assoc) return; @@ -1638,10 +1374,15 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN); - rcu_read_lock(); - mac80211_hwsim_tx_frame(data->hw, skb, - rcu_dereference(vif->chanctx_conf)->channel); - rcu_read_unlock(); + /* wmediumd mode check */ + _portid = ACCESS_ONCE(wmediumd_portid); + + if (_portid) + return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid); + + if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) + printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); + dev_kfree_skb(skb); } @@ -1682,17 +1423,14 @@ static int hwsim_fops_ps_write(void *dat, u64 val) if (val == PS_MANUAL_POLL) { ieee80211_iterate_active_interfaces(data->hw, - IEEE80211_IFACE_ITER_NORMAL, hwsim_send_ps_poll, data); data->ps_poll_pending = true; } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { ieee80211_iterate_active_interfaces(data->hw, - IEEE80211_IFACE_ITER_NORMAL, hwsim_send_nullfunc_ps, data); } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { ieee80211_iterate_active_interfaces(data->hw, - IEEE80211_IFACE_ITER_NORMAL, hwsim_send_nullfunc_no_ps, data); } @@ -1813,8 +1551,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, (hwsim_flags & HWSIM_TX_STAT_ACK)) { if (skb->len >= 16) { hdr = (struct ieee80211_hdr *) skb->data; - mac80211_hwsim_monitor_ack(txi->rate_driver_data[0], - hdr->addr2); + mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); } txi->flags |= IEEE80211_TX_STAT_ACK; } @@ -1829,7 +1566,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, struct genl_info *info) { - struct mac80211_hwsim_data *data2; + struct mac80211_hwsim_data *data2; struct ieee80211_rx_status rx_status; struct mac_address *dst; int frame_data_len; @@ -1837,9 +1574,9 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, struct sk_buff *skb = NULL; if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || - !info->attrs[HWSIM_ATTR_FRAME] || - !info->attrs[HWSIM_ATTR_RX_RATE] || - !info->attrs[HWSIM_ATTR_SIGNAL]) + !info->attrs[HWSIM_ATTR_FRAME] || + !info->attrs[HWSIM_ATTR_RX_RATE] || + !info->attrs[HWSIM_ATTR_SIGNAL]) goto out; dst = (struct mac_address *)nla_data( @@ -1867,7 +1604,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, /* check if radio is configured properly */ - if (data2->idle || !data2->started) + if (data2->idle || !data2->started || !data2->channel) goto out; /*A frame is received from user space*/ @@ -1951,11 +1688,6 @@ static struct notifier_block hwsim_netlink_notifier = { static int hwsim_init_netlink(void) { int rc; - - /* userspace test API hasn't been adjusted for multi-channel */ - if (channels > 1) - return 0; - printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); rc = genl_register_family_with_ops(&hwsim_genl_family, @@ -1978,10 +1710,6 @@ static void hwsim_exit_netlink(void) { int ret; - /* userspace test API hasn't been adjusted for multi-channel */ - if (channels > 1) - return; - printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); /* unregister the notifier */ netlink_unregister_notifier(&hwsim_netlink_notifier); @@ -2004,7 +1732,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = { { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, }; -static struct ieee80211_iface_combination hwsim_if_comb = { +static const struct ieee80211_iface_combination hwsim_if_comb = { .limits = hwsim_if_limits, .n_limits = ARRAY_SIZE(hwsim_if_limits), .max_interfaces = 2048, @@ -2022,30 +1750,10 @@ static int __init init_mac80211_hwsim(void) if (radios < 1 || radios > 100) return -EINVAL; - if (channels < 1) - return -EINVAL; - - if (channels > 1) { - hwsim_if_comb.num_different_channels = channels; + if (fake_hw_scan) { mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; - mac80211_hwsim_ops.cancel_hw_scan = - mac80211_hwsim_cancel_hw_scan; mac80211_hwsim_ops.sw_scan_start = NULL; mac80211_hwsim_ops.sw_scan_complete = NULL; - mac80211_hwsim_ops.remain_on_channel = - mac80211_hwsim_roc; - mac80211_hwsim_ops.cancel_remain_on_channel = - mac80211_hwsim_croc; - mac80211_hwsim_ops.add_chanctx = - mac80211_hwsim_add_chanctx; - mac80211_hwsim_ops.remove_chanctx = - mac80211_hwsim_remove_chanctx; - mac80211_hwsim_ops.change_chanctx = - mac80211_hwsim_change_chanctx; - mac80211_hwsim_ops.assign_vif_chanctx = - mac80211_hwsim_assign_vif_chanctx; - mac80211_hwsim_ops.unassign_vif_chanctx = - mac80211_hwsim_unassign_vif_chanctx; } spin_lock_init(&hwsim_radio_lock); @@ -2095,18 +1803,13 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->iface_combinations = &hwsim_if_comb; hw->wiphy->n_iface_combinations = 1; - if (channels > 1) { + if (fake_hw_scan) { hw->wiphy->max_scan_ssids = 255; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; - hw->wiphy->max_remain_on_channel_duration = 1000; } - INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); - INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work); - hw->channel_change_time = 1; - hw->queues = 5; - hw->offchannel_tx_hw_queue = 4; + hw->queues = 4; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -2121,8 +1824,7 @@ static int __init init_mac80211_hwsim(void) IEEE80211_HW_SUPPORTS_STATIC_SMPS | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_AMPDU_AGGREGATION | - IEEE80211_HW_WANT_MONITOR_VIF | - IEEE80211_HW_QUEUE_CONTROL; + IEEE80211_HW_WANT_MONITOR_VIF; hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; diff --git a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c index 68d52cfc1ebd..395f1bfd4102 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c @@ -197,7 +197,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ra_list_flags); mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); - mwifiex_write_data_complete(adapter, skb_src, 0, 0); + mwifiex_write_data_complete(adapter, skb_src, 0); spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -256,7 +256,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb_aggr, 1, -1); + mwifiex_write_data_complete(adapter, skb_aggr, -1); return -1; } if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && @@ -282,13 +282,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, 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); + mwifiex_write_data_complete(adapter, skb_aggr, ret); return 0; case -EINPROGRESS: adapter->data_sent = false; break; case 0: - mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); + mwifiex_write_data_complete(adapter, skb_aggr, ret); break; default: break; diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c index 4a97acd170f7..9402b93b9a36 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -58,7 +58,8 @@ mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); else - mwifiex_process_rx_packet(priv, rx_tmp_ptr); + mwifiex_process_rx_packet(priv->adapter, + rx_tmp_ptr); } } @@ -105,7 +106,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); else - mwifiex_process_rx_packet(priv, rx_tmp_ptr); + mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } spin_lock_irqsave(&priv->rx_pkt_lock, flags); @@ -441,7 +442,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) mwifiex_handle_uap_rx_forward(priv, payload); else - mwifiex_process_rx_packet(priv, payload); + mwifiex_process_rx_packet(priv->adapter, + payload); } return 0; } diff --git a/trunk/drivers/net/wireless/mwifiex/Kconfig b/trunk/drivers/net/wireless/mwifiex/Kconfig index b2e27723f801..8e384fae3e68 100644 --- a/trunk/drivers/net/wireless/mwifiex/Kconfig +++ b/trunk/drivers/net/wireless/mwifiex/Kconfig @@ -1,6 +1,7 @@ config MWIFIEX tristate "Marvell WiFi-Ex Driver" depends on CFG80211 + select LIB80211 ---help--- This adds support for wireless adapters based on Marvell 802.11n chipsets. diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 41be319665eb..0679458a1bac 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -324,7 +324,6 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, */ static int mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm) { @@ -472,13 +471,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) flag = 1; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_power; + max_pwr = ch->max_reg_power; no_of_parsed_chan = 1; continue; } if (ch->hw_value == next_chan + 1 && - ch->max_power == max_pwr) { + ch->max_reg_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -489,7 +488,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) no_of_triplet++; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_power; + max_pwr = ch->max_reg_power; no_of_parsed_chan = 1; } } @@ -1820,17 +1819,13 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); - if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && - atomic_read(&priv->wmm.tx_pkts_queued) >= + if (atomic_read(&priv->wmm.tx_pkts_queued) >= MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) { dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n"); return -EBUSY; } - if (priv->user_scan_cfg) { - dev_err(priv->adapter->dev, "cmd: Scan already in process..\n"); - return -EBUSY; - } + priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); @@ -1839,8 +1834,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, return -ENOMEM; } - priv->scan_request = request; - priv->user_scan_cfg->num_ssids = request->n_ssids; priv->user_scan_cfg->ssid_list = request->ssids; @@ -1877,9 +1870,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); if (ret) { dev_err(priv->adapter->dev, "scan failed: %d\n", ret); - priv->scan_request = NULL; - kfree(priv->user_scan_cfg); - priv->user_scan_cfg = NULL; return ret; } @@ -2081,8 +2071,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, return ERR_PTR(-EINVAL); } - dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, - ether_setup, IEEE80211_NUM_ACS, 1); + dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, + ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; @@ -2123,6 +2113,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, } sema_init(&priv->async_sem, 1); + priv->scan_pending_on_block = false; dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); @@ -2144,7 +2135,8 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) mwifiex_dev_debugfs_remove(priv); #endif - mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -2258,9 +2250,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; - wiphy->features |= NL80211_FEATURE_HT_IBSS | - NL80211_FEATURE_INACTIVITY_TIMER | - NL80211_FEATURE_LOW_PRIORITY_SCAN; + wiphy->features = NL80211_FEATURE_HT_IBSS | + NL80211_FEATURE_INACTIVITY_TIMER; /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index 5f438e6c2155..8d465107f52b 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -890,6 +890,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -ETIMEDOUT; + if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -914,44 +917,30 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "last_cmd_index = %d\n", adapter->dbg.last_cmd_index); - dev_err(adapter->dev, "last_cmd_id: %*ph\n", - (int)sizeof(adapter->dbg.last_cmd_id), - adapter->dbg.last_cmd_id); - dev_err(adapter->dev, "last_cmd_act: %*ph\n", - (int)sizeof(adapter->dbg.last_cmd_act), - adapter->dbg.last_cmd_act); + print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_id, DBG_CMD_NUM); + print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_act, DBG_CMD_NUM); dev_err(adapter->dev, "last_cmd_resp_index = %d\n", adapter->dbg.last_cmd_resp_index); - dev_err(adapter->dev, "last_cmd_resp_id: %*ph\n", - (int)sizeof(adapter->dbg.last_cmd_resp_id), - adapter->dbg.last_cmd_resp_id); + print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_cmd_resp_id, + DBG_CMD_NUM); dev_err(adapter->dev, "last_event_index = %d\n", adapter->dbg.last_event_index); - dev_err(adapter->dev, "last_event: %*ph\n", - (int)sizeof(adapter->dbg.last_event), - adapter->dbg.last_event); + print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, + adapter->dbg.last_event, DBG_CMD_NUM); dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", adapter->data_sent, adapter->cmd_sent); dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); - - if (cmd_node->wait_q_enabled) { - adapter->cmd_wait_q.status = -ETIMEDOUT; - wake_up_interruptible(&adapter->cmd_wait_q.wait); - mwifiex_cancel_pending_ioctl(adapter); - /* reset cmd_sent flag to unblock new commands */ - adapter->cmd_sent = false; - } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); - - if (adapter->if_ops.card_reset) - adapter->if_ops.card_reset(adapter); } /* diff --git a/trunk/drivers/net/wireless/mwifiex/debugfs.c b/trunk/drivers/net/wireless/mwifiex/debugfs.c index 46e34aa65d1c..a870b5885c09 100644 --- a/trunk/drivers/net/wireless/mwifiex/debugfs.c +++ b/trunk/drivers/net/wireless/mwifiex/debugfs.c @@ -178,7 +178,6 @@ mwifiex_info_read(struct file *file, char __user *ubuf, (struct mwifiex_private *) file->private_data; struct net_device *netdev = priv->netdev; struct netdev_hw_addr *ha; - struct netdev_queue *txq; unsigned long page = get_zeroed_page(GFP_KERNEL); char *p = (char *) page, fmt[64]; struct mwifiex_bss_info info; @@ -230,13 +229,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf, p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); - p += sprintf(p, "tx queue"); - for (i = 0; i < netdev->num_tx_queues; i++) { - txq = netdev_get_tx_queue(netdev, i); - p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ? - "stopped" : "started"); - } - p += sprintf(p, "\n"); + p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) + ? "stopped" : "started")); ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, (unsigned long) p - page); diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index 39f03ce5a5b1..b5d37a8caa09 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -84,19 +84,18 @@ static void scan_delay_timer_fn(unsigned long data) spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); if (priv->user_scan_cfg) { - if (priv->scan_request) { - dev_dbg(priv->adapter->dev, - "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } else { - dev_dbg(priv->adapter->dev, - "info: scan already aborted\n"); - } - + dev_dbg(priv->adapter->dev, + "info: %s: scan aborted\n", __func__); + cfg80211_scan_done(priv->scan_request, 1); + priv->scan_request = NULL; kfree(priv->user_scan_cfg); priv->user_scan_cfg = NULL; } + + if (priv->scan_pending_on_block) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } goto done; } @@ -388,17 +387,9 @@ void mwifiex_wake_up_net_dev_queue(struct net_device *netdev, struct mwifiex_adapter *adapter) { unsigned long dev_queue_flags; - unsigned int i; spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); - - for (i = 0; i < netdev->num_tx_queues; i++) { - struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); - - if (netif_tx_queue_stopped(txq)) - netif_tx_wake_queue(txq); - } - + netif_tx_wake_all_queues(netdev); spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); } @@ -409,17 +400,9 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev, struct mwifiex_adapter *adapter) { unsigned long dev_queue_flags; - unsigned int i; spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); - - for (i = 0; i < netdev->num_tx_queues; i++) { - struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); - - if (!netif_tx_queue_stopped(txq)) - netif_tx_stop_queue(txq); - } - + netif_tx_stop_all_queues(netdev); spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); } diff --git a/trunk/drivers/net/wireless/mwifiex/join.c b/trunk/drivers/net/wireless/mwifiex/join.c index 88664ae667ba..7b0858af8f5d 100644 --- a/trunk/drivers/net/wireless/mwifiex/join.c +++ b/trunk/drivers/net/wireless/mwifiex/join.c @@ -721,7 +721,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->scan_block = true; @@ -1237,7 +1238,8 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); mwifiex_save_curr_bcn(priv); diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index 9c802ede9c3b..eb22dd248d54 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -282,7 +282,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) mwifiex_shutdown_drv(adapter); return ret; } -EXPORT_SYMBOL_GPL(mwifiex_main_process); /* * This function frees the adapter structure. @@ -412,6 +411,49 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) return ret; } +/* + * This function fills a driver buffer. + * + * The function associates a given SKB with the provided driver buffer + * and also updates some of the SKB parameters, including IP header, + * priority and timestamp. + */ +static void +mwifiex_fill_buffer(struct sk_buff *skb) +{ + struct ethhdr *eth; + struct iphdr *iph; + struct timeval tv; + u8 tid = 0; + + eth = (struct ethhdr *) skb->data; + switch (eth->h_proto) { + case __constant_htons(ETH_P_IP): + iph = ip_hdr(skb); + tid = IPTOS_PREC(iph->tos); + pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", + eth->h_proto, tid, skb->priority); + break; + case __constant_htons(ETH_P_ARP): + pr_debug("data: ARP packet: %04x\n", eth->h_proto); + default: + break; + } +/* Offset for TOS field in the IP header */ +#define IPTOS_OFFSET 5 + tid = (tid >> IPTOS_OFFSET); + skb->priority = tid; + /* Record the current time the packet was queued; used to + determine the amount of time the packet was queued in + the driver before it was sent to the firmware. + The delay is then sent along with the packet to the + firmware for aggregate delay calculation for stats and + MSDU lifetime expiry. + */ + do_gettimeofday(&tv); + skb->tstamp = timeval_to_ktime(tv); +} + /* * CFG802.11 network device handler for open. * @@ -430,14 +472,6 @@ mwifiex_open(struct net_device *dev) static int mwifiex_close(struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - - if (priv->scan_request) { - dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n"); - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } - return 0; } @@ -446,23 +480,17 @@ mwifiex_close(struct net_device *dev) */ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) { - struct netdev_queue *txq; - int index = mwifiex_1d_to_wmm_queue[skb->priority]; - - if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) { - txq = netdev_get_tx_queue(priv->netdev, index); - if (!netif_tx_queue_stopped(txq)) { - netif_tx_stop_queue(txq); - dev_dbg(priv->adapter->dev, "stop queue: %d\n", index); - } - } - - atomic_inc(&priv->adapter->tx_pending); mwifiex_wmm_add_buf_txqueue(priv, skb); + atomic_inc(&priv->adapter->tx_pending); if (priv->adapter->scan_delay_cnt) atomic_set(&priv->adapter->is_tx_received, true); + if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { + mwifiex_set_trans_start(priv->netdev); + mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); + } + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); return 0; @@ -477,7 +505,6 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; - struct timeval tv; dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", jiffies, priv->bss_type, priv->bss_num); @@ -515,16 +542,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_info = MWIFIEX_SKB_TXCB(skb); tx_info->bss_num = priv->bss_num; tx_info->bss_type = priv->bss_type; - - /* Record the current time the packet was queued; used to - * determine the amount of time the packet was queued in - * the driver before it was sent to the firmware. - * The delay is then sent along with the packet to the - * firmware for aggregate delay calculation for stats and - * MSDU lifetime expiry. - */ - do_gettimeofday(&tv); - skb->tstamp = timeval_to_ktime(tv); + mwifiex_fill_buffer(skb); mwifiex_queue_tx_pkt(priv, skb); @@ -604,13 +622,6 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) return &priv->stats; } -static u16 -mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) -{ - skb->priority = cfg80211_classify8021d(skb); - return mwifiex_1d_to_wmm_queue[skb->priority]; -} - /* Network device handlers */ static const struct net_device_ops mwifiex_netdev_ops = { .ndo_open = mwifiex_open, @@ -620,7 +631,6 @@ static const struct net_device_ops mwifiex_netdev_ops = { .ndo_tx_timeout = mwifiex_tx_timeout, .ndo_get_stats = mwifiex_get_stats, .ndo_set_rx_mode = mwifiex_set_multicast_list, - .ndo_select_queue = mwifiex_netdev_select_wmm_queue, }; /* @@ -820,7 +830,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; if (priv && priv->netdev) { - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, + adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index db57dd430e92..c2d0ab146af5 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -115,6 +115,8 @@ enum { #define MWIFIEX_TYPE_DATA 0 #define MWIFIEX_TYPE_EVENT 3 +#define DBG_CMD_NUM 5 + #define MAX_BITMAP_RATES_SIZE 10 #define MAX_CHANNEL_BAND_BG 14 @@ -440,7 +442,6 @@ struct mwifiex_private { u8 wmm_enabled; u8 wmm_qosinfo; struct mwifiex_wmm_desc wmm; - atomic_t wmm_tx_pending[IEEE80211_NUM_ACS]; struct list_head sta_list; /* spin lock for associated station list */ spinlock_t sta_list_spinlock; @@ -483,6 +484,7 @@ struct mwifiex_private { u8 nick_name[16]; u16 current_key_index; struct semaphore async_sem; + u8 scan_pending_on_block; u8 report_scan_result; struct cfg80211_scan_request *scan_request; struct mwifiex_user_scan_cfg *user_scan_cfg; @@ -601,7 +603,6 @@ struct mwifiex_if_ops { int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); - void (*card_reset) (struct mwifiex_adapter *); }; struct mwifiex_adapter { @@ -749,9 +750,9 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter); int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); -int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb); +int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); -int mwifiex_process_mgmt_packet(struct mwifiex_private *priv, +int mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb); int mwifiex_process_event(struct mwifiex_adapter *adapter); @@ -790,7 +791,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, struct mwifiex_tx_param *tx_param); int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, - struct sk_buff *skb, int aggr, int status); + struct sk_buff *skb, int status); void mwifiex_clean_txrx(struct mwifiex_private *priv); u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); @@ -808,7 +809,7 @@ void mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated); int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -int mwifiex_process_rx_packet(struct mwifiex_private *priv, +int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb); int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, u16 cmd_action, u32 cmd_oid, @@ -818,9 +819,9 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, void *data_buf, void *cmd_buf); int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, struct host_cmd_ds_command *resp); -int mwifiex_process_sta_rx_packet(struct mwifiex_private *, +int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, struct sk_buff *skb); -int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, +int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb); int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, struct sk_buff *skb); diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c index 9189a32b7844..00b658d3b6ec 100644 --- a/trunk/drivers/net/wireless/mwifiex/scan.c +++ b/trunk/drivers/net/wireless/mwifiex/scan.c @@ -153,7 +153,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == - WLAN_EID_VENDOR_SPECIFIC))) { + WLAN_EID_WPA))) { iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; oui = &mwifiex_wpa_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); @@ -202,7 +202,7 @@ mwifiex_is_bss_no_sec(struct mwifiex_private *priv, if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != - WLAN_EID_VENDOR_SPECIFIC)) && + WLAN_EID_WPA)) && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && @@ -237,8 +237,7 @@ mwifiex_is_bss_wpa(struct mwifiex_private *priv, { if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && - ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)) + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == WLAN_EID_WPA)) /* * Privacy bit may NOT be set in some APs like * LinkSys WRT54G && bss_desc->privacy @@ -310,8 +309,7 @@ mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && !priv->sec_info.encryption_mode && bss_desc->privacy) { @@ -331,8 +329,7 @@ mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || - ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && priv->sec_info.encryption_mode && bss_desc->privacy) { @@ -941,11 +938,6 @@ mwifiex_config_scan(struct mwifiex_private *priv, chan_idx)->chan_scan_mode_bitmap &= ~MWIFIEX_PASSIVE_SCAN; - if (*filtered_scan) - (scan_chan_list + - chan_idx)->chan_scan_mode_bitmap - |= MWIFIEX_DISABLE_CHAN_FILT; - if (user_scan_in->chan_list[chan_idx].scan_time) { scan_dur = (u16) user_scan_in-> chan_list[chan_idx].scan_time; @@ -1767,39 +1759,26 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, } if (priv->report_scan_result) priv->report_scan_result = false; + if (priv->scan_pending_on_block) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } if (priv->user_scan_cfg) { - if (priv->scan_request) { - dev_dbg(priv->adapter->dev, - "info: notifying scan done\n"); - cfg80211_scan_done(priv->scan_request, 0); - priv->scan_request = NULL; - } else { - dev_dbg(priv->adapter->dev, - "info: scan already aborted\n"); - } - + dev_dbg(priv->adapter->dev, + "info: %s: sending scan results\n", __func__); + cfg80211_scan_done(priv->scan_request, 0); + priv->scan_request = NULL; kfree(priv->user_scan_cfg); priv->user_scan_cfg = NULL; } } else { - if (priv->user_scan_cfg && !priv->scan_request) { - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); - adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT; - mod_timer(&priv->scan_delay_timer, jiffies); - dev_dbg(priv->adapter->dev, - "info: %s: triggerring scan abort\n", __func__); - } else if (!mwifiex_wmm_lists_empty(adapter) && - (priv->scan_request && (priv->scan_request->flags & - NL80211_SCAN_FLAG_LOW_PRIORITY))) { + if (!mwifiex_wmm_lists_empty(adapter)) { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); adapter->scan_delay_cnt = 1; mod_timer(&priv->scan_delay_timer, jiffies + msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); - dev_dbg(priv->adapter->dev, - "info: %s: deferring scan\n", __func__); } else { /* Get scan command from scan_pending_q and put to cmd_pending_q */ @@ -1864,18 +1843,21 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, struct cfg80211_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; - int ret; + int ret = 0; struct mwifiex_user_scan_cfg *scan_cfg; + if (!req_ssid) + return -1; + if (adapter->scan_processing) { - dev_err(adapter->dev, "cmd: Scan already in process...\n"); - return -EBUSY; + dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); + return ret; } if (priv->scan_block) { - dev_err(adapter->dev, + dev_dbg(adapter->dev, "cmd: Scan is blocked during association...\n"); - return -EBUSY; + return ret; } scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); @@ -1912,6 +1894,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv, __func__); return -1; } + priv->scan_pending_on_block = true; priv->adapter->scan_wait_q_woken = false; @@ -1925,7 +1908,10 @@ int mwifiex_request_scan(struct mwifiex_private *priv, if (!ret) ret = mwifiex_wait_queue_complete(priv->adapter); - up(&priv->async_sem); + if (ret == -1) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index 5a1c1d0e5599..fc8a9bfa1248 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -161,6 +161,7 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; + int hs_actived = 0; int i; int ret = 0; @@ -187,14 +188,12 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - if (!mwifiex_enable_hs(adapter)) { - dev_err(adapter->dev, "cmd: failed to suspend\n"); - return -EFAULT; + hs_actived = mwifiex_enable_hs(adapter); + if (hs_actived) { + pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } - dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - /* Indicate device suspended */ adapter->is_suspended = true; @@ -906,8 +905,8 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) /* * SDIO interrupt handler. * - * This function reads the interrupt status from firmware and handles - * the interrupt in current thread (ksdioirqd) right away. + * This function reads the interrupt status from firmware and assigns + * the main process in workqueue which will handle the interrupt. */ static void mwifiex_sdio_interrupt(struct sdio_func *func) @@ -930,7 +929,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) adapter->ps_state = PS_STATE_AWAKE; mwifiex_interrupt_status(adapter); - mwifiex_main_process(adapter); + queue_work(adapter->workqueue, &adapter->main_work); } /* @@ -1749,37 +1748,6 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) port, card->mp_data_port_mask); } -static struct mmc_host *reset_host; -static void sdio_card_reset_worker(struct work_struct *work) -{ - /* The actual reset operation must be run outside of driver thread. - * This is because mmc_remove_host() will cause the device to be - * instantly destroyed, and the driver then needs to end its thread, - * leading to a deadlock. - * - * We run it in a totally independent workqueue. - */ - - pr_err("Resetting card...\n"); - mmc_remove_host(reset_host); - /* 20ms delay is based on experiment with sdhci controller */ - mdelay(20); - mmc_add_host(reset_host); -} -static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); - -/* This function resets the card */ -static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) -{ - struct sdio_mmc_card *card = adapter->card; - - if (work_pending(&card_reset_work)) - return; - - reset_host = card->func->card->host; - schedule_work(&card_reset_work); -} - static struct mwifiex_if_ops sdio_ops = { .init_if = mwifiex_init_sdio, .cleanup_if = mwifiex_cleanup_sdio, @@ -1798,7 +1766,6 @@ static struct mwifiex_if_ops sdio_ops = { .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, .event_complete = mwifiex_sdio_event_complete, - .card_reset = mwifiex_sdio_card_reset, }; /* @@ -1836,7 +1803,6 @@ mwifiex_sdio_cleanup_module(void) /* Set the flag as user is removing this module. */ user_rmmod = 1; - cancel_work_sync(&card_reset_work); sdio_unregister_driver(&mwifiex_sdio); } diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.h b/trunk/drivers/net/wireless/mwifiex/sdio.h index 8cc5468654b4..21033738ef0c 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.h +++ b/trunk/drivers/net/wireless/mwifiex/sdio.h @@ -25,7 +25,6 @@ #include #include #include -#include #include "main.h" diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c index 65c12eb3e5e7..09e6a267f566 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -85,6 +85,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); if (priv->report_scan_result) priv->report_scan_result = false; + if (priv->scan_pending_on_block) { + priv->scan_pending_on_block = false; + up(&priv->async_sem); + } break; case HostCmd_CMD_MAC_CONTROL: diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 5b0d71969ba7..8132119e1a21 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -124,7 +124,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) } memset(priv->cfg_bssid, 0, ETH_ALEN); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } @@ -196,7 +197,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) dev_dbg(adapter->dev, "event: LINK_SENSED\n"); if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); break; case EVENT_DEAUTHENTICATED: @@ -304,7 +306,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); priv->adhoc_is_link_sensed = false; mwifiex_clean_txrx(priv); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); break; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index c8b50c70a03d..0c9f70b2cbe6 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -276,7 +276,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, dev_dbg(adapter->dev, "info: SSID found in scan list ... " "associating...\n"); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -317,7 +318,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, ret = mwifiex_check_network_compatibility(priv, bss_desc); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -711,7 +713,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", priv->wpa_ie_len, priv->wpa_ie[0]); - if (priv->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) { + if (priv->wpa_ie[0] == WLAN_EID_WPA) { priv->sec_info.wpa_enabled = true; } else if (priv->wpa_ie[0] == WLAN_EID_RSN) { priv->sec_info.wpa2_enabled = true; @@ -1251,7 +1253,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, } pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; /* Test to see if it is a WPA IE, if not, then it is a gen IE */ - if (((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && + if (((pvendor_ie->element_id == WLAN_EID_WPA) && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || (pvendor_ie->element_id == WLAN_EID_RSN)) { diff --git a/trunk/drivers/net/wireless/mwifiex/sta_rx.c b/trunk/drivers/net/wireless/mwifiex/sta_rx.c index b5c109504393..07d32b73783e 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_rx.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_rx.c @@ -38,10 +38,14 @@ * * The completion callback is called after processing in complete. */ -int mwifiex_process_rx_packet(struct mwifiex_private *priv, +int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { int ret; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -94,9 +98,9 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, priv->rxpd_htinfo = local_rx_pd->ht_info; - ret = mwifiex_recv_packet(priv, skb); + ret = mwifiex_recv_packet(adapter, skb); if (ret == -1) - dev_err(priv->adapter->dev, "recv packet failed\n"); + dev_err(adapter->dev, "recv packet failed\n"); return ret; } @@ -113,15 +117,21 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv, * * The completion callback is called after processing in complete. */ -int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, +int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; struct rxpd *local_rx_pd; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type, rx_pkt_offset, rx_pkt_length, seq_num; + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); + + if (!priv) + return -1; local_rx_pd = (struct rxpd *) (skb->data); rx_pkt_type = le16_to_cpu(local_rx_pd->rx_pkt_type); @@ -159,13 +169,13 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, while (!skb_queue_empty(&list)) { rx_skb = __skb_dequeue(&list); - ret = mwifiex_recv_packet(priv, rx_skb); + ret = mwifiex_recv_packet(adapter, rx_skb); if (ret == -1) dev_err(adapter->dev, "Rx of A-MSDU failed"); } return 0; } else if (rx_pkt_type == PKT_TYPE_MGMT) { - ret = mwifiex_process_mgmt_packet(priv, skb); + ret = mwifiex_process_mgmt_packet(adapter, skb); if (ret) dev_err(adapter->dev, "Rx of mgmt packet failed"); dev_kfree_skb_any(skb); @@ -178,7 +188,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, */ if (!IS_11N_ENABLED(priv) || memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) { - mwifiex_process_rx_packet(priv, skb); + mwifiex_process_rx_packet(adapter, skb); return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/txrx.c b/trunk/drivers/net/wireless/mwifiex/txrx.c index 8c80024c30ff..2af263992e83 100644 --- a/trunk/drivers/net/wireless/mwifiex/txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/txrx.c @@ -48,19 +48,13 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - if (!priv) { - dev_err(adapter->dev, "data: priv not found. Drop RX packet\n"); - dev_kfree_skb_any(skb); - return -1; - } - rx_info->bss_num = priv->bss_num; rx_info->bss_type = priv->bss_type; if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) - return mwifiex_process_uap_rx_packet(priv, skb); + return mwifiex_process_uap_rx_packet(adapter, skb); - return mwifiex_process_sta_rx_packet(priv, skb); + return mwifiex_process_sta_rx_packet(adapter, skb); } EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); @@ -121,13 +115,13 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, 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); + mwifiex_write_data_complete(adapter, skb, ret); break; case -EINPROGRESS: adapter->data_sent = false; break; case 0: - mwifiex_write_data_complete(adapter, skb, 0, ret); + mwifiex_write_data_complete(adapter, skb, ret); break; default: break; @@ -144,12 +138,11 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, * wakes up stalled traffic queue if required, and then frees the buffer. */ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, - struct sk_buff *skb, int aggr, int status) + struct sk_buff *skb, int status) { - struct mwifiex_private *priv; + struct mwifiex_private *priv, *tpriv; struct mwifiex_txinfo *tx_info; - struct netdev_queue *txq; - int index; + int i; if (!skb) return 0; @@ -173,20 +166,15 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) atomic_dec_return(&adapter->pending_bridged_pkts); - - if (aggr) - /* For skb_aggr, do not wake up tx queue */ + if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) goto done; - atomic_dec(&adapter->tx_pending); + for (i = 0; i < adapter->priv_num; i++) { + tpriv = adapter->priv[i]; - index = mwifiex_1d_to_wmm_queue[skb->priority]; - if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) { - txq = netdev_get_tx_queue(priv->netdev, index); - if (netif_tx_queue_stopped(txq)) { - netif_tx_wake_queue(txq); - dev_dbg(adapter->dev, "wake queue: %d\n", index); - } + if (tpriv->media_connected && + netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); } done: dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c index 8dd72240f162..d95a2d558fcf 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c @@ -188,19 +188,10 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); const u8 *var_pos = params->beacon.head + var_offset; int len = params->beacon.head_len - var_offset; - u8 rate_len = 0; rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); - if (rate_ie) { - memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len); - rate_len = rate_ie->len; - } - - rate_ie = (void *)cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, - params->beacon.tail, - params->beacon.tail_len); if (rate_ie) - memcpy(bss_cfg->rates + rate_len, rate_ie + 1, rate_ie->len); + memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len); return; } diff --git a/trunk/drivers/net/wireless/mwifiex/uap_event.c b/trunk/drivers/net/wireless/mwifiex/uap_event.c index 21c640d3b579..a33fa394e349 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_event.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_event.c @@ -235,18 +235,11 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; - if (netif_carrier_ok(priv->netdev)) - netif_carrier_off(priv->netdev); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); - mwifiex_clean_txrx(priv); mwifiex_del_all_sta_list(priv); break; case EVENT_UAP_BSS_ACTIVE: priv->media_connected = true; - if (!netif_carrier_ok(priv->netdev)) - netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); break; case EVENT_UAP_BSS_START: dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_txrx.c b/trunk/drivers/net/wireless/mwifiex/uap_txrx.c index a018e42d117e..0966ac24b3b4 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_txrx.c @@ -146,7 +146,7 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, } /* Forward unicat/Inter-BSS packets to kernel. */ - return mwifiex_process_rx_packet(priv, skb); + return mwifiex_process_rx_packet(adapter, skb); } /* @@ -159,17 +159,24 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, * * The completion callback is called after processing is complete. */ -int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, +int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { - struct mwifiex_adapter *adapter = priv->adapter; int ret; struct uap_rxpd *uap_rx_pd; + struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); struct rx_packet_hdr *rx_pkt_hdr; u16 rx_pkt_type; u8 ta[ETH_ALEN], pkt_type; struct mwifiex_sta_node *node; + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); + + if (!priv) + return -1; + uap_rx_pd = (struct uap_rxpd *)(skb->data); rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); @@ -203,7 +210,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, while (!skb_queue_empty(&list)) { rx_skb = __skb_dequeue(&list); - ret = mwifiex_recv_packet(priv, rx_skb); + ret = mwifiex_recv_packet(adapter, rx_skb); if (ret) dev_err(adapter->dev, "AP:Rx A-MSDU failed"); @@ -211,7 +218,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, return 0; } else if (rx_pkt_type == PKT_TYPE_MGMT) { - ret = mwifiex_process_mgmt_packet(priv, skb); + ret = mwifiex_process_mgmt_packet(adapter, skb); if (ret) dev_err(adapter->dev, "Rx of mgmt packet failed"); dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index bbe1f3518e4b..22a5916564b8 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -238,7 +238,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb) } else { dev_dbg(adapter->dev, "%s: DATA\n", __func__); atomic_dec(&card->tx_data_urb_pending); - mwifiex_write_data_complete(adapter, context->skb, 0, + mwifiex_write_data_complete(adapter, context->skb, urb->status ? -1 : 0); } diff --git a/trunk/drivers/net/wireless/mwifiex/util.c b/trunk/drivers/net/wireless/mwifiex/util.c index 0982375ba3b1..ae88f80cf86b 100644 --- a/trunk/drivers/net/wireless/mwifiex/util.c +++ b/trunk/drivers/net/wireless/mwifiex/util.c @@ -146,16 +146,20 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, * to the kernel. */ int -mwifiex_process_mgmt_packet(struct mwifiex_private *priv, +mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct rxpd *rx_pd; + struct mwifiex_private *priv; u16 pkt_len; if (!skb) return -1; rx_pd = (struct rxpd *)skb->data; + priv = mwifiex_get_priv_by_id(adapter, rx_pd->bss_num, rx_pd->bss_type); + if (!priv) + return -1; skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); skb_pull(skb, sizeof(pkt_len)); @@ -186,11 +190,20 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, * the function creates a blank SKB, fills it with the data from the * received buffer and then sends this new SKB to the kernel. */ -int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) +int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) { + struct mwifiex_rxinfo *rx_info; + struct mwifiex_private *priv; + if (!skb) return -1; + rx_info = MWIFIEX_SKB_RXCB(skb); + priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); + if (!priv) + return -1; + skb->dev = priv->netdev; skb->protocol = eth_type_trans(skb, priv->netdev); skb->ip_summed = CHECKSUM_NONE; @@ -212,7 +225,7 @@ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) * fragments. Currently we fail the Filesndl-ht.scr script * for UDP, hence this fix */ - if ((priv->adapter->iface_type == MWIFIEX_USB) && + if ((adapter->iface_type == MWIFIEX_USB) && (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 818f871ae987..600d8194610e 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -483,7 +483,7 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv, struct sk_buff *skb, *tmp; skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); } /* @@ -650,7 +650,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -680,7 +680,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (!ra_list) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1090,7 +1090,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1195,7 +1195,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1209,7 +1209,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, 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); + mwifiex_write_data_complete(adapter, skb, ret); break; case -EINPROGRESS: adapter->data_sent = false; diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.h b/trunk/drivers/net/wireless/mwifiex/wmm.h index b92f39d8963b..ec839952d2e7 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.h +++ b/trunk/drivers/net/wireless/mwifiex/wmm.h @@ -31,8 +31,6 @@ enum ieee_types_wmm_ecw_bitmasks { MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), }; -static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; - /* * This function retrieves the TID of the given RA list. */ diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index 0cdae6632735..5099e5375cb3 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -1851,7 +1851,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, bool start_ba_session = false; bool mgmtframe = false; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - bool eapol_frame = false; wh = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(wh->frame_control)) @@ -1859,9 +1858,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, else qos = 0; - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) - eapol_frame = true; - if (ieee80211_is_mgmt(wh->frame_control)) mgmtframe = true; @@ -1920,8 +1916,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, txpriority = index; - if (priv->ap_fw && sta && sta->ht_cap.ht_supported && !eapol_frame && - ieee80211_is_data_qos(wh->frame_control)) { + if (priv->ap_fw && sta && sta->ht_cap.ht_supported + && skb->protocol != cpu_to_be16(ETH_P_PAE) + && ieee80211_is_data_qos(wh->frame_control)) { tid = qos & 0xf; mwl8k_tx_count_packet(sta, tid); spin_lock(&priv->stream_lock); @@ -2008,8 +2005,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, spin_unlock(&priv->stream_lock); } spin_unlock_bh(&priv->tx_lock); - pci_unmap_single(priv->pdev, dma, skb->len, - PCI_DMA_TODEVICE); dev_kfree_skb(skb); return; } @@ -2030,11 +2025,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, else tx->peer_id = 0; - if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame) + if (priv->ap_fw) tx->timestamp = cpu_to_le32(ioread32(priv->regs + MWL8K_HW_TIMER_REGISTER)); - else - tx->timestamp = 0; wmb(); tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); @@ -3686,8 +3679,7 @@ struct mwl8k_cmd_bastream { } __packed; static int -mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, - struct ieee80211_vif *vif) +mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) { struct mwl8k_cmd_bastream *cmd; int rc; @@ -3710,7 +3702,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); - rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + rc = mwl8k_post_cmd(hw, &cmd->header); kfree(cmd); @@ -3719,7 +3711,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, static int mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, - u8 buf_size, struct ieee80211_vif *vif) + u8 buf_size) { struct mwl8k_cmd_bastream *cmd; int rc; @@ -3753,7 +3745,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | BASTREAM_FLAG_DIRECTION_UPSTREAM); - rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + rc = mwl8k_post_cmd(hw, &cmd->header); wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", stream->sta->addr, stream->tid); @@ -5093,7 +5085,6 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mwl8k_priv *priv = hw->priv; struct mwl8k_ampdu_stream *stream; u8 *addr = sta->addr; - struct mwl8k_sta *sta_info = MWL8K_STA(sta); if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) return -ENOTSUPP; @@ -5136,16 +5127,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* Release the lock before we do the time consuming stuff */ spin_unlock(&priv->stream_lock); for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { - - /* Check if link is still valid */ - if (!sta_info->is_ampdu_allowed) { - spin_lock(&priv->stream_lock); - mwl8k_remove_stream(hw, stream); - spin_unlock(&priv->stream_lock); - return -EBUSY; - } - - rc = mwl8k_check_ba(hw, stream, vif); + rc = mwl8k_check_ba(hw, stream); /* If HW restart is in progress mwl8k_post_cmd will * return -EBUSY. Avoid retrying mwl8k_check_ba in @@ -5185,7 +5167,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, BUG_ON(stream == NULL); BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); spin_unlock(&priv->stream_lock); - rc = mwl8k_create_ba(hw, stream, buf_size, vif); + rc = mwl8k_create_ba(hw, stream, buf_size); spin_lock(&priv->stream_lock); if (!rc) stream->state = AMPDU_STREAM_ACTIVE; @@ -5635,18 +5617,6 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) return rc; } -static const struct ieee80211_iface_limit ap_if_limits[] = { - { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, -}; - -static const struct ieee80211_iface_combination ap_if_comb = { - .limits = ap_if_limits, - .n_limits = ARRAY_SIZE(ap_if_limits), - .max_interfaces = 8, - .num_different_channels = 1, -}; - - static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) { struct ieee80211_hw *hw = priv->hw; @@ -5726,13 +5696,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) goto err_free_cookie; hw->wiphy->interface_modes = 0; - - if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { + if (priv->ap_macids_supported || priv->device_info->fw_image_ap) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); - hw->wiphy->iface_combinations = &ap_if_comb; - hw->wiphy->n_iface_combinations = 1; - } - if (priv->sta_macids_supported || priv->device_info->fw_image_sta) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); diff --git a/trunk/drivers/net/wireless/orinoco/main.h b/trunk/drivers/net/wireless/orinoco/main.h index 5a8fec26136e..4dadf9880a97 100644 --- a/trunk/drivers/net/wireless/orinoco/main.h +++ b/trunk/drivers/net/wireless/orinoco/main.h @@ -39,7 +39,7 @@ static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len) { u8 *p = data; while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) { - if ((p[0] == WLAN_EID_VENDOR_SPECIFIC) && + if ((p[0] == WLAN_EID_GENERIC) && (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0)) return p; p += p[1] + 2; diff --git a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c b/trunk/drivers/net/wireless/orinoco/orinoco_usb.c index 01624dcaf73e..7f53cea2f205 100644 --- a/trunk/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/trunk/drivers/net/wireless/orinoco/orinoco_usb.c @@ -865,7 +865,7 @@ static int ezusb_firmware_download(struct ezusb_priv *upriv, static int ezusb_access_ltv(struct ezusb_priv *upriv, struct request_context *ctx, u16 length, const void *data, u16 frame_type, - void *ans_buff, unsigned ans_size, u16 *ans_length) + void *ans_buff, int ans_size, u16 *ans_length) { int req_size; int retval = 0; @@ -933,7 +933,7 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, } if (ctx->in_rid) { struct ezusb_packet *ans = ctx->buf; - unsigned exp_len; + int exp_len; if (ans->hermes_len != 0) exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12; @@ -949,7 +949,8 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, } if (ans_buff) - memcpy(ans_buff, ans->data, min(exp_len, ans_size)); + memcpy(ans_buff, ans->data, + min_t(int, exp_len, ans_size)); if (ans_length) *ans_length = le16_to_cpu(ans->hermes_len); } @@ -994,7 +995,7 @@ static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid, struct ezusb_priv *upriv = hw->priv; struct request_context *ctx; - if (bufsize % 2) + if ((bufsize < 0) || (bufsize % 2)) return -EINVAL; ctx = ezusb_alloc_ctx(upriv, rid, rid); diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index 5390af36c064..bd1f0cb56085 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -490,12 +490,9 @@ static int rndis_scan(struct wiphy *wiphy, static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); static int rndis_set_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); -static int rndis_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, - int *dbm); +static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); @@ -1906,7 +1903,6 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed) } static int rndis_set_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm) { @@ -1934,9 +1930,7 @@ static int rndis_set_tx_power(struct wiphy *wiphy, return -ENOTSUPP; } -static int rndis_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, - int *dbm) +static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 6b2e1e431dd2..a12e84f892be 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1988,7 +1988,6 @@ static struct usb_driver rt2500usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index c0441a715c96..01dc8891070c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* @@ -2520,37 +2520,20 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, return comp_value; } -static int rt2800_get_txpower_reg_delta(struct rt2x00_dev *rt2x00dev, - int power_level, int max_power) -{ - int delta; - - if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) - return 0; - - /* - * XXX: We don't know the maximum transmit power of our hardware since - * the EEPROM doesn't expose it. We only know that we are calibrated - * to 100% tx power. - * - * Hence, we assume the regulatory limit that cfg80211 calulated for - * the current channel is our maximum and if we are requested to lower - * the value we just reduce our tx power accordingly. - */ - delta = power_level - max_power; - return min(delta, 0); -} - static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, enum ieee80211_band band, int power_level, u8 txpower, int delta) { + u32 reg; u16 eeprom; u8 criterion; u8 eirp_txpower; u8 eirp_txpower_criterion; u8 reg_limit; + if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) + return txpower; + if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { /* * Check if eirp txpower exceed txpower_limit. @@ -2559,13 +2542,11 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, * .11b data rate need add additional 4dbm * when calculating eirp txpower. */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1, - &eeprom); - criterion = rt2x00_get_field16(eeprom, - EEPROM_TXPOWER_BYRATE_RATE0); + rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); + criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); - rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, - &eeprom); + rt2x00_eeprom_read(rt2x00dev, + EEPROM_EIRP_MAX_TX_POWER, &eeprom); if (band == IEEE80211_BAND_2GHZ) eirp_txpower_criterion = rt2x00_get_field16(eeprom, @@ -2582,71 +2563,36 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, } else reg_limit = 0; - txpower = max(0, txpower + delta - reg_limit); - return min_t(u8, txpower, 0xc); + return txpower + delta - reg_limit; } -/* - * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and - * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values, - * 4 bits for each rate (tune from 0 to 15 dBm). BBP_R1 controls transmit power - * for all rates, but allow to set only 4 discrete values: -12, -6, 0 and 6 dBm. - * Reference per rate transmit power values are located in the EEPROM at - * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to - * current conditions (i.e. band, bandwidth, temperature, user settings). - */ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, - struct ieee80211_channel *chan, + enum ieee80211_band band, int power_level) { - u8 txpower, r1; + u8 txpower; u16 eeprom; - u32 reg, offset; - int i, is_rate_b, delta, power_ctrl; - enum ieee80211_band band = chan->band; + int i, is_rate_b; + u32 reg; + u8 r1; + u32 offset; + int delta; /* - * Calculate HT40 compensation. For 40MHz we need to add or subtract - * value read from EEPROM (different for 2GHz and for 5GHz). + * Calculate HT40 compensation delta */ delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); /* - * Calculate temperature compensation. Depends on measurement of current - * TSSI (Transmitter Signal Strength Indication) we know TX power (due - * to temperature or maybe other factors) is smaller or bigger than - * expected. We adjust it, based on TSSI reference and boundaries values - * provided in EEPROM. + * calculate temperature compensation delta */ delta += rt2800_get_gain_calibration_delta(rt2x00dev); /* - * Decrease power according to user settings, on devices with unknown - * maximum tx power. For other devices we take user power_level into - * consideration on rt2800_compensate_txpower(). - */ - delta += rt2800_get_txpower_reg_delta(rt2x00dev, power_level, - chan->max_power); - - /* - * BBP_R1 controls TX power for all rates, it allow to set the following - * gains -12, -6, 0, +6 dBm by setting values 2, 1, 0, 3 respectively. - * - * TODO: we do not use +6 dBm option to do not increase power beyond - * regulatory limit, however this could be utilized for devices with - * CAPABILITY_POWER_LIMIT. + * set to normal bbp tx power control mode: +/- 0dBm */ rt2800_bbp_read(rt2x00dev, 1, &r1); - if (delta <= -12) { - power_ctrl = 2; - delta += 12; - } else if (delta <= -6) { - power_ctrl = 1; - delta += 6; - } else { - power_ctrl = 0; - } - rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); + rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); rt2800_bbp_write(rt2x00dev, 1, r1); offset = TX_PWR_CFG_0; @@ -2764,7 +2710,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) { - rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel, + rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band, rt2x00dev->tx_power); } EXPORT_SYMBOL_GPL(rt2800_gain_calibration); @@ -2899,11 +2845,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { rt2800_config_channel(rt2x00dev, libconf->conf, &libconf->rf, &libconf->channel); - rt2800_config_txpower(rt2x00dev, libconf->conf->channel, + rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, libconf->conf->power_level); } if (flags & IEEE80211_CONF_CHANGE_POWER) - rt2800_config_txpower(rt2x00dev, libconf->conf->channel, + rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, libconf->conf->power_level); if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) rt2800_config_retry_limit(rt2x00dev, libconf); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 023081286e0c..c9e9370eb789 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1096,7 +1096,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x177f, 0x0153) }, { USB_DEVICE(0x177f, 0x0302) }, { USB_DEVICE(0x177f, 0x0313) }, - { USB_DEVICE(0x177f, 0x0323) }, /* U-Media */ { USB_DEVICE(0x157e, 0x300e) }, { USB_DEVICE(0x157e, 0x3013) }, @@ -1283,7 +1282,6 @@ static struct usb_driver rt2800usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 67d167993d45..69097d1faeb6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -157,7 +157,6 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) * requested configurations. */ ieee80211_iterate_active_interfaces(rt2x00dev->hw, - IEEE80211_IFACE_ITER_RESUME_ALL, rt2x00lib_intf_scheduled_iter, rt2x00dev); } @@ -226,9 +225,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) return; /* send buffered bc/mc frames out for every bssid */ - ieee80211_iterate_active_interfaces_atomic( - rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - rt2x00lib_bc_buffer_iter, rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_bc_buffer_iter, + rt2x00dev); /* * Devices with pre tbtt interrupt don't need to update the beacon * here as they will fetch the next beacon directly prior to @@ -238,9 +237,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) return; /* fetch next beacon */ - ieee80211_iterate_active_interfaces_atomic( - rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - rt2x00lib_beaconupdate_iter, rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); @@ -250,9 +249,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) return; /* fetch next beacon */ - ieee80211_iterate_active_interfaces_atomic( - rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - rt2x00lib_beaconupdate_iter, rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index ed7a1bb3f245..98a9e48f8e4a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -424,9 +424,9 @@ int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return 0; - ieee80211_iterate_active_interfaces_atomic( - rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, - rt2x00mac_set_tim_iter, rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00mac_set_tim_iter, + rt2x00dev); /* queue work to upodate the beacon template */ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 24eec66e9fd2..e5eb43b3eee7 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -2535,7 +2535,6 @@ static struct usb_driver rt73usb_driver = { .disconnect = rt2x00usb_disconnect, .suspend = rt2x00usb_suspend, .resume = rt2x00usb_resume, - .reset_resume = rt2x00usb_resume, .disable_hub_initiated_lpm = 1, }; diff --git a/trunk/drivers/net/wireless/rtlwifi/Kconfig b/trunk/drivers/net/wireless/rtlwifi/Kconfig index 21b1bbb93a7e..6b28e92d1d21 100644 --- a/trunk/drivers/net/wireless/rtlwifi/Kconfig +++ b/trunk/drivers/net/wireless/rtlwifi/Kconfig @@ -32,17 +32,6 @@ config RTL8192DE If you choose to build it as a module, it will be called rtl8192de -config RTL8723AE - tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" - depends on MAC80211 && PCI && EXPERIMENTAL - select FW_LOADER - select RTLWIFI - ---help--- - This is the driver for Realtek RTL8723AE 802.11n PCIe - wireless network adapters. - - If you choose to build it as a module, it will be called rtl8723ae - config RTL8192CU tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" depends on MAC80211 && USB diff --git a/trunk/drivers/net/wireless/rtlwifi/Makefile b/trunk/drivers/net/wireless/rtlwifi/Makefile index 3b1cbac741e3..97935c565bab 100644 --- a/trunk/drivers/net/wireless/rtlwifi/Makefile +++ b/trunk/drivers/net/wireless/rtlwifi/Makefile @@ -7,8 +7,7 @@ rtlwifi-objs := \ efuse.o \ ps.o \ rc.o \ - regd.o \ - stats.o + regd.o rtl8192c_common-objs += \ @@ -25,6 +24,5 @@ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ obj-$(CONFIG_RTL8192SE) += rtl8192se/ obj-$(CONFIG_RTL8192DE) += rtl8192de/ -obj-$(CONFIG_RTL8723AE) += rtl8723ae/ ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index 4494d130b37c..59381fe8ed06 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -826,30 +826,6 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, } EXPORT_SYMBOL(rtlwifi_rate_mapping); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - __le16 fc = rtl_get_fc(skb); - - if (rtlpriv->dm.supp_phymode_switch && - mac->link_state < MAC80211_LINKED && - (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) { - if (rtlpriv->cfg->ops->check_switch_to_dmdp) - rtlpriv->cfg->ops->check_switch_to_dmdp(hw); - } - if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); - rtl_ips_nic_on(hw); - - mac->link_state = MAC80211_LINKING; - /* Dual mac */ - rtlpriv->phy.need_iqk = true; - } - - return true; -} - void rtl_get_tcb_desc(struct ieee80211_hw *hw, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, diff --git a/trunk/drivers/net/wireless/rtlwifi/base.h b/trunk/drivers/net/wireless/rtlwifi/base.h index 5a8c80e259f7..f35af0fdaaf0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.h +++ b/trunk/drivers/net/wireless/rtlwifi/base.h @@ -142,6 +142,4 @@ u8 rtl_tid_to_ac(u8 tid); extern struct attribute_group rtl_attribute_group; int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, u8 desc_rate, bool first_ampdu); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); - #endif diff --git a/trunk/drivers/net/wireless/rtlwifi/cam.c b/trunk/drivers/net/wireless/rtlwifi/cam.c index 0e510f73041a..5b4b4d4eaf9e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/cam.c +++ b/trunk/drivers/net/wireless/rtlwifi/cam.c @@ -52,8 +52,11 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u32 target_content = 0; u8 entry_i; - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %6phC\n", - key_cont_128); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + "key_cont_128:\n %x:%x:%x:%x:%x:%x\n", + key_cont_128[0], key_cont_128[1], + key_cont_128[2], key_cont_128[3], + key_cont_128[4], key_cont_128[5]); for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { target_command = entry_i + CAM_CONTENT_COUNT * entry_no; @@ -337,7 +340,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) if (((bitmap & BIT(0)) == BIT(0)) && (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { /* Remove from HW Security CAM */ - eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); + memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "del CAM entry %d\n", i); diff --git a/trunk/drivers/net/wireless/rtlwifi/core.c b/trunk/drivers/net/wireless/rtlwifi/core.c index be33aa14c8af..a7c0e52869ba 100644 --- a/trunk/drivers/net/wireless/rtlwifi/core.c +++ b/trunk/drivers/net/wireless/rtlwifi/core.c @@ -962,6 +962,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, int err = 0; u8 mac_addr[ETH_ALEN]; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 zero_addr[ETH_ALEN] = { 0 }; if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, @@ -1056,7 +1057,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(rtlpriv->sec.key_buf[key_idx], key->key, key->keylen); rtlpriv->sec.key_len[key_idx] = key->keylen; - eth_zero_addr(mac_addr); + memcpy(mac_addr, zero_addr, ETH_ALEN); } else if (group_key) { /* group key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set group key\n"); @@ -1107,7 +1108,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); rtlpriv->sec.key_len[key_idx] = 0; - eth_zero_addr(mac_addr); + memcpy(mac_addr, zero_addr, ETH_ALEN); /* *mac80211 will delete entrys one by one, *so don't use rtl_cam_reset_all_entry diff --git a/trunk/drivers/net/wireless/rtlwifi/debug.h b/trunk/drivers/net/wireless/rtlwifi/debug.h index fd3269f47685..07493d2957f2 100644 --- a/trunk/drivers/net/wireless/rtlwifi/debug.h +++ b/trunk/drivers/net/wireless/rtlwifi/debug.h @@ -106,8 +106,6 @@ #define COMP_REGD BIT(27) #define COMP_CHAN BIT(28) #define COMP_USB BIT(29) -#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */ -#define COMP_BT_COEXIST BIT(30) /*-------------------------------------------------------------- Define the rt_print components diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index f38e30a947bc..abc306b502ac 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1309,7 +1309,6 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_sta_info *sta_entry = NULL; u8 tid = rtl_get_tid(skb); - __le16 fc = rtl_get_fc(skb); if (!sta) return false; @@ -1317,12 +1316,6 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, if (!rtlpriv->rtlhal.earlymode_enable) return false; - if (ieee80211_is_nullfunc(fc)) - return false; - if (ieee80211_is_qos_nullfunc(fc)) - return false; - if (ieee80211_is_pspoll(fc)) - return false; if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) return false; if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) @@ -1364,8 +1357,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, u8 own; u8 temp_one = 1; - if (ieee80211_is_mgmt(fc)) - rtl_tx_mgmt_proc(hw, skb); + if (ieee80211_is_auth(fc)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_ips_nic_on(hw); + } if (rtlpriv->psc.sw_ps_enabled) { if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && @@ -1633,7 +1628,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, "8192 PCI-E is found - vid/did=%x/%x\n", venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; - return false; + break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "8192SE is found - vid/did=%x/%x\n", @@ -1648,11 +1643,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, break; } - } else if (deviceid == RTL_PCI_8723AE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8723AE PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.h b/trunk/drivers/net/wireless/rtlwifi/pci.h index f71b12aa8cb4..241448fc9ed5 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.h +++ b/trunk/drivers/net/wireless/rtlwifi/pci.h @@ -79,7 +79,6 @@ #define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ #define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ #define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ -#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */ #define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ #define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ #define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ @@ -153,7 +152,6 @@ struct rtl8192_rx_ring { struct rtl_pci { struct pci_dev *pdev; - bool irq_enabled; bool driver_is_goingto_unload; bool up_first_time; diff --git a/trunk/drivers/net/wireless/rtlwifi/rc.c b/trunk/drivers/net/wireless/rtlwifi/rc.c index c1e065f136ba..d5cbf01da8ac 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rc.c +++ b/trunk/drivers/net/wireless/rtlwifi/rc.c @@ -55,8 +55,7 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, * 1M we will not use FW rate but user rate. */ if (rtlmac->opmode == NL80211_IFTYPE_AP || - rtlmac->opmode == NL80211_IFTYPE_ADHOC || - rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) { + rtlmac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) { sta_entry = (struct rtl_sta_info *) sta->drv_priv; wireless_mode = sta_entry->wireless_mode; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 1cdf5a271c9f..1ca4e25c143b 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -43,8 +43,8 @@ #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ ((RTLPRIV(_priv))->mac80211.opmode == \ NL80211_IFTYPE_ADHOC) ? \ - ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \ - ((RTLPRIV(_priv))->dm.undec_sm_pwdb) + ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ + ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { 0x7f8001fe, @@ -167,18 +167,18 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw) dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; dm_digtable->cur_igvalue = 0x20; dm_digtable->pre_igvalue = 0x0; - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - dm_digtable->presta_cstate = DIG_STA_DISCONNECT; - dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; + dm_digtable->presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; dm_digtable->rx_gain_range_max = DM_DIG_MAX; dm_digtable->rx_gain_range_min = DM_DIG_MIN; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; } @@ -189,21 +189,22 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; long rssi_val_min = 0; - if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && - (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + if ((dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable->cursta_connectstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) rssi_val_min = - (rtlpriv->dm.entry_min_undec_sm_pwdb > - rtlpriv->dm.undec_sm_pwdb) ? - rtlpriv->dm.undec_sm_pwdb : - rtlpriv->dm.entry_min_undec_sm_pwdb; + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; else - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT || + dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable->curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; } return (u8) rssi_val_min; @@ -285,33 +286,37 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *digtable = &rtlpriv->dm_digtable; + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { - if ((digtable->back_val - 2) < digtable->back_range_min) - digtable->back_val = digtable->back_range_min; + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) { + if ((dm_digtable->backoff_val - 2) < + dm_digtable->backoff_val_range_min) + dm_digtable->backoff_val = + dm_digtable->backoff_val_range_min; else - digtable->back_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { - if ((digtable->back_val + 2) > digtable->back_range_max) - digtable->back_val = digtable->back_range_max; + dm_digtable->backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) { + if ((dm_digtable->backoff_val + 2) > + dm_digtable->backoff_val_range_max) + dm_digtable->backoff_val = + dm_digtable->backoff_val_range_max; else - digtable->back_val += 2; + dm_digtable->backoff_val += 2; } - if ((digtable->rssi_val_min + 10 - digtable->back_val) > - digtable->rx_gain_range_max) - digtable->cur_igvalue = digtable->rx_gain_range_max; - else if ((digtable->rssi_val_min + 10 - - digtable->back_val) < digtable->rx_gain_range_min) - digtable->cur_igvalue = digtable->rx_gain_range_min; + if ((dm_digtable->rssi_val_min + 10 - dm_digtable->backoff_val) > + dm_digtable->rx_gain_range_max) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_max; + else if ((dm_digtable->rssi_val_min + 10 - + dm_digtable->backoff_val) < dm_digtable->rx_gain_range_min) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_min; else - digtable->cur_igvalue = digtable->rssi_val_min + 10 - - digtable->back_val; + dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 - + dm_digtable->backoff_val; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "rssi_val_min = %x back_val %x\n", - digtable->rssi_val_min, digtable->back_val); + "rssi_val_min = %x backoff_val %x\n", + dm_digtable->rssi_val_min, dm_digtable->backoff_val); rtl92c_dm_write_dig(hw); } @@ -322,14 +327,14 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct dig_t *dm_digtable = &rtlpriv->dm_digtable; struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; bool multi_sta = false; if (mac->opmode == NL80211_IFTYPE_ADHOC) multi_sta = true; if (!multi_sta || - dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { initialized = false; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; return; @@ -340,7 +345,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) rtl92c_dm_write_dig(hw); } - if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { + if (dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) { if ((rssi_strength < dm_digtable->rssi_lowthresh) && (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { @@ -362,8 +367,8 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "curmultista_cstate = %x dig_ext_port_stage %x\n", - dm_digtable->curmultista_cstate, + "curmultista_connectstate = %x dig_ext_port_stage %x\n", + dm_digtable->curmultista_connectstate, dm_digtable->dig_ext_port_stage); } @@ -373,14 +378,15 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "presta_cstate = %x, cursta_cstate = %x\n", - dm_digtable->presta_cstate, dm_digtable->cursta_cstate); + "presta_connectstate = %x, cursta_connectstate = %x\n", + dm_digtable->presta_connectstate, + dm_digtable->cursta_connectstate); - if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->presta_connectstate == dm_digtable->cursta_connectstate + || dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT + || dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { - if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + if (dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); rtl92c_dm_ctrl_initgain_by_rssi(hw); @@ -388,7 +394,7 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) } else { dm_digtable->rssi_val_min = 0; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; dm_digtable->cur_igvalue = 0x20; dm_digtable->pre_igvalue = 0; rtl92c_dm_write_dig(hw); @@ -401,7 +407,7 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { @@ -478,15 +484,15 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) return; if (mac->link_state >= MAC80211_LINKED) - dm_digtable->cursta_cstate = DIG_STA_CONNECT; + dm_digtable->cursta_connectstate = DIG_STA_CONNECT; else - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; + dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; rtl92c_dm_initial_gain_sta(hw); rtl92c_dm_initial_gain_multi_sta(hw); rtl92c_dm_cck_packet_detection_thresh(hw); - dm_digtable->presta_cstate = dm_digtable->cursta_cstate; + dm_digtable->presta_connectstate = dm_digtable->cursta_connectstate; } @@ -520,9 +526,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, - dm_digtable->back_val); + dm_digtable->backoff_val); dm_digtable->cur_igvalue += 2; if (dm_digtable->cur_igvalue > 0x3f) @@ -549,18 +555,20 @@ static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) return; if (tmpentry_max_pwdb != 0) { - rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; } else { - rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; } if (tmpentry_min_pwdb != 0xff) { - rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; } else { - rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; } - h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); h2c_parameter[0] = 0; rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); @@ -1152,7 +1160,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rate_adaptive *p_ra = &(rtlpriv->ra); - u32 low_rssi_thresh, high_rssi_thresh; + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; struct ieee80211_sta *sta = NULL; if (is_hal_stop(rtlhal)) { @@ -1171,33 +1179,35 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) mac->opmode == NL80211_IFTYPE_STATION) { switch (p_ra->pre_ratr_state) { case DM_RATR_STA_HIGH: - high_rssi_thresh = 50; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; break; case DM_RATR_STA_MIDDLE: - high_rssi_thresh = 55; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; break; case DM_RATR_STA_LOW: - high_rssi_thresh = 50; - low_rssi_thresh = 25; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; break; default: - high_rssi_thresh = 50; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; break; } - if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) p_ra->ratr_state = DM_RATR_STA_HIGH; - else if (rtlpriv->dm.undec_sm_pwdb > (long)low_rssi_thresh) + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) p_ra->ratr_state = DM_RATR_STA_MIDDLE; else p_ra->ratr_state = DM_RATR_STA_LOW; if (p_ra->pre_ratr_state != p_ra->ratr_state) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", - rtlpriv->dm.undec_sm_pwdb); + rtlpriv->dm.undecorated_smoothed_pwdb); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI_LEVEL = %d\n", p_ra->ratr_state); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, @@ -1305,7 +1315,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { dm_pstable->rssi_val_min = 0; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); } @@ -1313,19 +1323,20 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) if (mac->link_state == MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "AP Client PWDB = 0x%lx\n", dm_pstable->rssi_val_min); } else { - dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + dm_pstable->rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", dm_pstable->rssi_val_min); } } else { dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", @@ -1357,7 +1368,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -1368,7 +1379,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -1380,35 +1391,41 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); @@ -1456,46 +1473,48 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; u8 curr_bt_rssi_state = 0x00; if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { - undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); + undecorated_smoothed_pwdb = + GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); } else { - if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0) - undec_sm_pwdb = 100; + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) + undecorated_smoothed_pwdb = 100; else - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; } /* Check RSSI to determine HighPower/NormalPower state for * BT coexistence. */ - if (undec_sm_pwdb >= 67) + if (undecorated_smoothed_pwdb >= 67) curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); - else if (undec_sm_pwdb < 62) + else if (undecorated_smoothed_pwdb < 62) curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; /* Check RSSI to determine AMPDU setting for BT coexistence. */ - if (undec_sm_pwdb >= 40) + if (undecorated_smoothed_pwdb >= 40) curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); - else if (undec_sm_pwdb <= 32) + else if (undecorated_smoothed_pwdb <= 32) curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; /* Marked RSSI state. It will be used to determine BT coexistence * setting later. */ - if (undec_sm_pwdb < 35) + if (undecorated_smoothed_pwdb < 35) curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; else curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); /* Set Tx Power according to BT status. */ - if (undec_sm_pwdb >= 30) + if (undecorated_smoothed_pwdb >= 30) curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; - else if (undec_sm_pwdb < 25) + else if (undecorated_smoothed_pwdb < 25) curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); /* Check BT state related to BT_Idle in B/G mode. */ - if (undec_sm_pwdb < 15) + if (undecorated_smoothed_pwdb < 15) curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; else curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 1d5d3604e3e0..cdcad7d9f15e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -34,6 +34,9 @@ #include "dm_common.h" #include "phy_common.h" +/* Define macro to shorten lines */ +#define MCS_TXPWR mcs_txpwrlevel_origoffset + u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -135,13 +138,13 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSIREADBACKDATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); @@ -287,11 +290,11 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", rtlphy->pwrgroup_cnt, index, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]); if (index == 13) rtlphy->pwrgroup_cnt++; @@ -371,10 +374,14 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; @@ -386,33 +393,47 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVEB_HSPI_READBACK; } EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); @@ -703,26 +724,6 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) } EXPORT_SYMBOL(rtl92c_phy_sw_chnl); -static void _rtl92c_phy_sw_rf_setting(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - if (channel == 6 && rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - 0x00255); - else{ - u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, - RF_RX_G1, RFREG_OFFSET_MASK); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - backupRF0x1A); - } - } -} - static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, @@ -836,7 +837,6 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, currentcmd->para1, RFREG_OFFSET_MASK, rtlphy->rfreg_chnlval[rfpath]); - _rtl92c_phy_sw_rf_setting(hw, channel); } break; default: diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 3cfa1bb0f476..2925094b2d91 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -116,9 +116,6 @@ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) #define CHIP_VER_B BIT(4) -#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) -#define CHIP_BONDING_92C_1T2R 0x1 -#define RF_TYPE_1T2R BIT(1) #define CHIP_92C_BITMASK BIT(0) #define CHIP_UNKNOWN BIT(7) #define CHIP_92C_1T2R 0x03 diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 74f9c083b80d..27b3af880d96 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -41,7 +41,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -52,7 +52,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -64,35 +64,41 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index d1f34f6ffbdf..86d73b32d995 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -896,6 +896,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + static bool iqk_initialized; /* initialized to false */ bool rtstatus = true; bool is92c; int err; @@ -920,28 +921,9 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtlhal->last_hmeboxnum = 0; rtl92c_phy_mac_config(hw); - /* because last function modify RCR, so we update - * rcr var here, or TP will unstable for receive_config - * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx - * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ - rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); - rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); rtl92c_phy_bb_config(hw); rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; rtl92c_phy_rf_config(hw); - if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && - !IS_92C_SERIAL(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); - } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); - rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); - rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); - rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); - } rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, RF_CHNLBW, RFREG_OFFSET_MASK); rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, @@ -963,11 +945,11 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) if (ppsc->rfpwr_state == ERFON) { rtl92c_phy_set_rfpath_switch(hw, 1); - if (rtlphy->iqk_initialized) { + if (iqk_initialized) { rtl92c_phy_iq_calibrate(hw, true); } else { rtl92c_phy_iq_calibrate(hw, false); - rtlphy->iqk_initialized = true; + iqk_initialized = true; } rtl92c_dm_check_txpower_tracking(hw); @@ -1022,13 +1004,6 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | CHIP_VENDOR_UMC)); } - if (IS_92C_SERIAL(version)) { - value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); - version = (enum version_8192c)(version | - ((CHIP_BONDING_IDENTIFIER(value32) - == CHIP_BONDING_92C_1T2R) ? - RF_TYPE_1T2R : 0)); - } } switch (version) { @@ -1044,30 +1019,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) case VERSION_A_CHIP_88C: versionid = "A_CHIP_88C"; break; - case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: - versionid = "A_CUT_92C_1T2R"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: - versionid = "A_CUT_92C"; - break; - case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: - versionid = "A_CUT_88C"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: - versionid = "B_CUT_92C_1T2R"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: - versionid = "B_CUT_92C"; - break; - case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: - versionid = "B_CUT_88C"; - break; default: versionid = "Unknown. Bug?"; break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Chip Version ID: %s\n", versionid); switch (version & 0x3) { @@ -1240,7 +1197,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); u8 u1b_tmp; u32 u4b_tmp; @@ -1269,8 +1225,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); - if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); if (rtlpcipriv->bt_coexist.bt_coexistence) { u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); u4b_tmp |= 0x03824800; @@ -1299,9 +1254,6 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw) rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); _rtl92ce_poweroff_adapter(hw); - - /* after power off we should do iqk again */ - rtlpriv->phy.iqk_initialized = false; } void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, @@ -1403,9 +1355,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; else tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = ((tempval & 0xf0) >> 4); } @@ -1429,7 +1381,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { @@ -1444,14 +1396,14 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, if ((rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) > 0) { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path] [index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path] + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] [index]; } else { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; @@ -1960,16 +1912,16 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, ratr_bitmap &= 0x0f0ff0ff; break; } - sta_entry->ratr_index = ratr_index; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", ratr_bitmap); *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "Rate_index:%x, ratr_val:%x, %5phC\n", - ratr_index, ratr_bitmap, rate_mask); + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); if (macid != 0) @@ -2224,7 +2176,7 @@ static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) rtlpcipriv->bt_coexist.bt_ant_isolation = - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol; + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; else rtlpcipriv->bt_coexist.bt_ant_isolation = rtlpcipriv->bt_coexist.reg_bt_iso; @@ -2255,22 +2207,23 @@ void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, bool auto_load_fail, u8 *hwinfo) { struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 val; + u8 value; if (!auto_load_fail) { rtlpcipriv->bt_coexist.eeprom_bt_coexist = ((hwinfo[RF_OPTION1] & 0xe0) >> 5); - val = hwinfo[RF_OPTION4]; - rtlpcipriv->bt_coexist.eeprom_bt_type = ((val & 0xe) >> 1); - rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (val & 0x1); - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = ((val & 0x10) >> 4); + value = hwinfo[RF_OPTION4]; + rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1); + rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = + ((value & 0x10) >> 4); rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = - ((val & 0x20) >> 5); + ((value & 0x20) >> 5); } else { rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = 0; + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0; rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 73262ca3864b..88deae67cc14 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -82,8 +82,6 @@ bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) if (is92c) rtl_write_byte(rtlpriv, 0x14, 0x71); - else - rtl_write_byte(rtlpriv, 0x04CA, 0x0A); return rtstatus; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index a9c406f33d0a..54c7614958a8 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -97,12 +97,15 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -206,7 +209,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, case 0: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup][index + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -236,7 +240,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, chnlgroup++; } - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -271,7 +276,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); @@ -311,7 +317,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 60451eea4d82..ea2e1bd847c8 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -162,10 +162,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) /* request fw */ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && - !IS_92C_SERIAL(rtlhal->version)) + !IS_92C_SERIAL(rtlhal->version)) { rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; - else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) + } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n"); + } rtlpriv->max_fw_size = 0x4000; pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index d7e1f0a7e48f..390d6d4fcaa0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -127,11 +127,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; - struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); s8 rx_pwr_all = 0, rx_pwr[4]; u8 evm, pwdb_all, rf_rx_num = 0; u8 i, max_spatial_stream; u32 rssi, total_rssi = 0; + bool in_powersavemode = false; bool is_cck_rate; is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); @@ -140,14 +140,14 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, pstats->is_cck = is_cck_rate; pstats->packet_beacon = packet_beacon; pstats->is_cck = is_cck_rate; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck_rate) { u8 report, cck_highpwr; cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; - if (ppsc->rfpwr_state == ERFON) + if (!in_powersavemode) cck_highpwr = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BIT(9)); @@ -211,8 +211,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = @@ -251,7 +251,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8) (evm & 0xff); - pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); } } } @@ -361,31 +362,36 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (mac->opmode == NL80211_IFTYPE_ADHOC) { return; } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb += 1; + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92ce_update_rxsignalstatistics(hw, pstats); } } @@ -432,14 +438,15 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, for (n_spatialstream = 0; n_spatialstream < 2; n_spatialstream++) { if (pstats-> - rx_mimo_sig_qual[n_spatialstream] != -1) { + rx_mimo_signalquality[n_spatialstream] != + -1) { if (rtlpriv->stats. rx_evm_percentage[n_spatialstream] == 0) { rtlpriv->stats. rx_evm_percentage [n_spatialstream] = - pstats->rx_mimo_sig_qual + pstats->rx_mimo_signalquality [n_spatialstream]; } @@ -449,7 +456,8 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, stats.rx_evm_percentage [n_spatialstream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual + (pstats-> + rx_mimo_signalquality [n_spatialstream] * 1)) / (RX_SMOOTH_FACTOR); } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index 16a0b9e59acf..6fd39eaf361e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -39,7 +39,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -50,7 +50,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -62,35 +62,41 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index b1ccff474c79..4bbb711a36c5 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -152,9 +152,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; else tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = ((tempval & 0xf0) >> 4); } for (rf_path = 0; rf_path < 2; rf_path++) @@ -177,7 +177,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { index = _rtl92c_get_chnl_group((u8) i); @@ -189,13 +189,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, if ((rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) > 0) { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path] [index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path] + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] [index]; } else { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; @@ -2169,8 +2169,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "Rate_index:%x, ratr_val:%x, %5phC\n", - ratr_index, ratr_bitmap, rate_mask); + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 32ff959a0251..7e91c76582ec 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -46,7 +46,7 @@ #define LINK_Q ui_link_quality #define RX_EVM rx_evm_percentage -#define RX_SIGQ rx_mimo_sig_qual +#define RX_SIGQ rx_mimo_signalquality void rtl92c_read_chip_version(struct ieee80211_hw *hw) @@ -982,27 +982,32 @@ static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb = 0; + long undecorated_smoothed_pwdb = 0; if (mac->opmode == NL80211_IFTYPE_ADHOC) { return; } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb += 1; + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92c_update_rxsignalstatistics(hw, pstats); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 953f1a0f8532..506b9a078ed1 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -115,11 +115,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (ppowerlevel[idx1] << 24); } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][7] << 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][15] << 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -211,7 +215,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, switch (rtlefuse->eeprom_regulatory) { case 0: chnlgroup = 0; - writeVal = rtlphy->mcs_offset + writeVal = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, @@ -234,7 +238,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, else chnlgroup += 4; } - writeVal = rtlphy->mcs_offset[chnlgroup][index + + writeVal = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -266,7 +271,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [channel - 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); if (rtlphy->current_chan_bw == @@ -300,7 +306,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index b7e6607e6b6d..9970c2b1b199 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -297,7 +297,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ - {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index fd8df233ff22..ed868c396c25 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -35,7 +35,7 @@ #include "dm.h" #include "fw.h" -#define UNDEC_SM_PWDB entry_min_undec_sm_pwdb +#define UNDEC_SM_PWDB entry_min_undecoratedsmoothed_pwdb static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { 0x7f8001fe, /* 0, +6.0dB */ @@ -164,18 +164,18 @@ static void rtl92d_dm_diginit(struct ieee80211_hw *hw) de_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; de_digtable->cur_igvalue = 0x20; de_digtable->pre_igvalue = 0x0; - de_digtable->cursta_cstate = DIG_STA_DISCONNECT; - de_digtable->presta_cstate = DIG_STA_DISCONNECT; - de_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; + de_digtable->presta_connectstate = DIG_STA_DISCONNECT; + de_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; de_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; de_digtable->rx_gain_range_max = DM_DIG_FA_UPPER; de_digtable->rx_gain_range_min = DM_DIG_FA_LOWER; - de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - de_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - de_digtable->back_range_min = DM_DIG_BACKOFF_MIN; + de_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; + de_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + de_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; de_digtable->pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; de_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; de_digtable->large_fa_hit = 0; @@ -273,34 +273,35 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) /* Determine the minimum RSSI */ if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { - de_digtable->min_undec_pwdb_for_dm = 0; + de_digtable->min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { - de_digtable->min_undec_pwdb_for_dm = + de_digtable->min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "AP Client PWDB = 0x%lx\n", rtlpriv->dm.UNDEC_SM_PWDB); } else { - de_digtable->min_undec_pwdb_for_dm = - rtlpriv->dm.undec_sm_pwdb; + de_digtable->min_undecorated_pwdb_for_dm = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "STA Default Port PWDB = 0x%x\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } } else { - de_digtable->min_undec_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; + de_digtable->min_undecorated_pwdb_for_dm = + rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "AP Ext Port or disconnect PWDB = 0x%x\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -309,16 +310,16 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) struct dig_t *de_digtable = &rtlpriv->dm_digtable; unsigned long flag = 0; - if (de_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (de_digtable->cursta_connectstate == DIG_STA_CONNECT) { if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { - if (de_digtable->min_undec_pwdb_for_dm <= 25) + if (de_digtable->min_undecorated_pwdb_for_dm <= 25) de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else de_digtable->cur_cck_pd_state = CCK_PD_STAGE_HIGHRSSI; } else { - if (de_digtable->min_undec_pwdb_for_dm <= 20) + if (de_digtable->min_undecorated_pwdb_for_dm <= 20) de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else @@ -341,7 +342,7 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", - de_digtable->cursta_cstate == DIG_STA_CONNECT ? + de_digtable->cursta_connectstate == DIG_STA_CONNECT ? "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? @@ -357,9 +358,9 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) struct dig_t *de_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", de_digtable->cur_igvalue, de_digtable->pre_igvalue, - de_digtable->back_val); + de_digtable->backoff_val); if (de_digtable->dig_enable_flag == false) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); de_digtable->pre_igvalue = 0x17; @@ -381,13 +382,13 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && (rtlpriv->mac80211.vendor == PEER_CISCO)) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); - if (de_digtable->last_min_undec_pwdb_for_dm >= 50 - && de_digtable->min_undec_pwdb_for_dm < 50) { + if (de_digtable->last_min_undecorated_pwdb_for_dm >= 50 + && de_digtable->min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode Off\n"); - } else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 && - de_digtable->min_undec_pwdb_for_dm > 55) { + } else if (de_digtable->last_min_undecorated_pwdb_for_dm <= 55 && + de_digtable->min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); @@ -408,8 +409,8 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); - de_digtable->last_min_undec_pwdb_for_dm = - de_digtable->min_undec_pwdb_for_dm; + de_digtable->last_min_undecorated_pwdb_for_dm = + de_digtable->min_undecorated_pwdb_for_dm; } if (!rtlpriv->dm.dm_initialgain_enable) return; @@ -427,9 +428,9 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) - de_digtable->cursta_cstate = DIG_STA_CONNECT; + de_digtable->cursta_connectstate = DIG_STA_CONNECT; else - de_digtable->cursta_cstate = DIG_STA_DISCONNECT; + de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; /* adjust initial gain according to false alarm counter */ if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) @@ -521,7 +522,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if ((!rtlpriv->dm.dynamic_txpower_enable) || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { @@ -538,62 +539,62 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = + undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "IBSS Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = - rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = + undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } if (rtlhal->current_bandtype == BAND_ON_5G) { - if (undec_sm_pwdb >= 0x33) { + if (undecorated_smoothed_pwdb >= 0x33) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < 0x33) - && (undec_sm_pwdb >= 0x2b)) { + } else if ((undecorated_smoothed_pwdb < 0x33) + && (undecorated_smoothed_pwdb >= 0x2b)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < 0x2b) { + } else if (undecorated_smoothed_pwdb < 0x2b) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Normal\n"); } } else { - if (undec_sm_pwdb >= + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else - if ((undec_sm_pwdb < + if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) - && (undec_sm_pwdb >= + && (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < + } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -619,7 +620,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) return; /* Indicate Rx signal strength to FW. */ if (rtlpriv->dm.useramask) { - u32 temp = rtlpriv->dm.undec_sm_pwdb; + u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb; temp <<= 16; temp |= 0x100; @@ -628,7 +629,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); } else { rtl_write_byte(rtlpriv, 0x4fe, - (u8) rtlpriv->dm.undec_sm_pwdb); + (u8) rtlpriv->dm.undecorated_smoothed_pwdb); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 33041bd4da81..db0086062d05 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -298,13 +298,13 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSIREADBACKDATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -478,10 +478,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) /* RF switch Control */ /* TR/Ant switch control */ - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; /* AGC control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; @@ -496,10 +500,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; /* RX AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; /*RX AFE control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; @@ -508,10 +516,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; /* Tx AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTxIQIMBALANCE; /* Tx AFE control 2 */ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE; @@ -520,14 +532,20 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE; /* Tranceiver LSSI Readback SI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; /* Tranceiver LSSI Readback PI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVERB_HSPI_READBACK; } static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, @@ -684,11 +702,12 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", rtlphy->pwrgroup_cnt, index, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][index]); if (index == 13) rtlphy->pwrgroup_cnt++; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 20144e0b4142..3066a7fb0b57 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -106,11 +106,11 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (ppowerlevel[idx1] << 24); } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -227,7 +227,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, switch (rtlefuse->eeprom_regulatory) { case 0: chnlgroup = 0; - writeval = rtlphy->mcs_offset + writeval = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : @@ -247,7 +247,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, chnlgroup++; else chnlgroup += 4; - writeval = rtlphy->mcs_offset + writeval = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : @@ -280,7 +280,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [channel - 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); if (rtlphy->current_chan_bw == @@ -315,7 +316,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index + + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 35bb9da6196a..4686f340b9d6 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -132,8 +132,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, pstats->packet_toself = packet_toself; pstats->packet_beacon = packet_beacon; pstats->is_cck = is_cck_rate; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck_rate) { u8 report, cck_highpwr; @@ -212,8 +212,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, sq = ((64 - sq) * 100) / 44; } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = true; @@ -246,7 +246,7 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8)(evm & 0xff); - pstats->rx_mimo_sig_qual[i] = + pstats->rx_mimo_signalquality[i] = (u8)(evm & 0xff); } } @@ -345,28 +345,33 @@ static void _rtl92de_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_AP) return; else - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb = undec_sm_pwdb + 1; + undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92de_update_rxsignalstatistics(hw, pstats); } } @@ -378,15 +383,15 @@ static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, int stream; for (stream = 0; stream < 2; stream++) { - if (pstats->rx_mimo_sig_qual[stream] != -1) { + if (pstats->rx_mimo_signalquality[stream] != -1) { if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { rtlpriv->stats.rx_evm_percentage[stream] = - pstats->rx_mimo_sig_qual[stream]; + pstats->rx_mimo_signalquality[stream]; } rtlpriv->stats.rx_evm_percentage[stream] = ((rtlpriv->stats.rx_evm_percentage[stream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual[stream] * 1)) / + (pstats->rx_mimo_signalquality[stream] * 1)) / (RX_SMOOTH_FACTOR); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index bf79a52c8a52..465f58157101 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -267,12 +267,13 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) break; } - if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) { + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssi_thresh) { ra->ratr_state = DM_RATR_STA_HIGH; - } else if (rtlpriv->dm.undec_sm_pwdb > + } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)middle_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; - } else if (rtlpriv->dm.undec_sm_pwdb > + } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)low_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; } else { @@ -282,7 +283,8 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) if (ra->pre_ratr_state != ra->ratr_state) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, + rtlpriv->dm.undecorated_smoothed_pwdb, + ra->ratr_state, ra->pre_ratr_state, ra->ratr_state); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, @@ -314,7 +316,7 @@ static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); if (mac->link_state >= MAC80211_LINKED) { - if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) { + if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) { rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; } @@ -422,18 +424,18 @@ static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw) struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); if (falsealm_cnt->cnt_all > digtable->fa_highthresh) { - if ((digtable->back_val - 6) < + if ((digtable->backoff_val - 6) < digtable->backoffval_range_min) - digtable->back_val = digtable->backoffval_range_min; + digtable->backoff_val = digtable->backoffval_range_min; else - digtable->back_val -= 6; + digtable->backoff_val -= 6; } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) { - if ((digtable->back_val + 6) > + if ((digtable->backoff_val + 6) > digtable->backoffval_range_max) - digtable->back_val = + digtable->backoff_val = digtable->backoffval_range_max; else - digtable->back_val += 6; + digtable->backoff_val += 6; } } @@ -445,28 +447,28 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) static u8 initialized, force_write; u8 initial_gain = 0; - if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) || - (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) { - if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) { + if ((digtable->pre_sta_connectstate == digtable->cur_sta_connectstate) || + (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) { + if (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) { if (rtlpriv->psc.rfpwr_state != ERFON) return; if (digtable->backoff_enable_flag) rtl92s_backoff_enable_flag(hw); else - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; - if ((digtable->rssi_val + 10 - digtable->back_val) > + if ((digtable->rssi_val + 10 - digtable->backoff_val) > digtable->rx_gain_range_max) digtable->cur_igvalue = digtable->rx_gain_range_max; - else if ((digtable->rssi_val + 10 - digtable->back_val) + else if ((digtable->rssi_val + 10 - digtable->backoff_val) < digtable->rx_gain_range_min) digtable->cur_igvalue = digtable->rx_gain_range_min; else digtable->cur_igvalue = digtable->rssi_val + 10 - - digtable->back_val; + digtable->backoff_val; if (falsealm_cnt->cnt_all > 10000) digtable->cur_igvalue = @@ -488,7 +490,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; digtable->pre_igvalue = 0; return; @@ -526,14 +528,14 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) - digtable->cur_sta_cstate = DIG_STA_CONNECT; + digtable->cur_sta_connectstate = DIG_STA_CONNECT; else - digtable->cur_sta_cstate = DIG_STA_DISCONNECT; + digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; - digtable->rssi_val = rtlpriv->dm.undec_sm_pwdb; + digtable->rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb; /* Change dig mode to rssi */ - if (digtable->cur_sta_cstate != DIG_STA_DISCONNECT) { + if (digtable->cur_sta_connectstate != DIG_STA_DISCONNECT) { if (digtable->dig_twoport_algorithm == DIG_TWO_PORT_ALGO_FALSE_ALARM) { digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; @@ -544,7 +546,7 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) _rtl92s_dm_false_alarm_counter_statistics(hw); _rtl92s_dm_initial_gain_sta_beforeconnect(hw); - digtable->pre_sta_cstate = digtable->cur_sta_cstate; + digtable->pre_sta_connectstate = digtable->cur_sta_connectstate; } static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) @@ -571,7 +573,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; long txpwr_threshold_lv1, txpwr_threshold_lv2; /* 2T2R TP issue */ @@ -585,7 +587,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -597,22 +599,25 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; @@ -620,12 +625,12 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; - else if (undec_sm_pwdb >= txpwr_threshold_lv2) + else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; - else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) && - (undec_sm_pwdb >= txpwr_threshold_lv1)) + else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) && + (undecorated_smoothed_pwdb >= txpwr_threshold_lv1)) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; - else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3)) + else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3)) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) @@ -660,10 +665,10 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) digtable->dig_state = DM_STA_DIG_MAX; digtable->dig_highpwrstate = DM_STA_DIG_MAX; - digtable->cur_sta_cstate = DIG_STA_DISCONNECT; - digtable->pre_sta_cstate = DIG_STA_DISCONNECT; - digtable->cur_ap_cstate = DIG_AP_DISCONNECT; - digtable->pre_ap_cstate = DIG_AP_DISCONNECT; + digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; + digtable->pre_sta_connectstate = DIG_STA_DISCONNECT; + digtable->cur_ap_connectstate = DIG_AP_DISCONNECT; + digtable->pre_ap_connectstate = DIG_AP_DISCONNECT; digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; @@ -676,7 +681,7 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) /* for dig debug rssi value */ digtable->rssi_val = 50; - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; digtable->rx_gain_range_max = DM_DIG_MAX; digtable->rx_gain_range_min = DM_DIG_MIN; @@ -704,7 +709,7 @@ void rtl92s_dm_init(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtlpriv->dm.undec_sm_pwdb = -1; + rtlpriv->dm.undecorated_smoothed_pwdb = -1; _rtl92s_dm_init_dynamic_txpower(hw); rtl92s_dm_init_edca_turbo(hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 1d72779434ba..4542e6952b97 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1697,7 +1697,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; /* Read OFDM RF A & B Tx power for 2T */ - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i] = hwinfo[EEPROM_TXPOWERBASE + 12 + rf_path * 3 + i]; } @@ -1722,7 +1722,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, - rtlefuse->eprom_chnl_txpwr_ht40_2sdf + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { @@ -1748,7 +1748,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_chnlarea_txpwr_ht40_1s [rf_path][index]; rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = - rtlefuse->eprom_chnl_txpwr_ht40_2sdf + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif [rf_path][index]; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 67404975e00b..b917a2a3caf7 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -139,17 +139,17 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSI_READBACK_DATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; @@ -696,7 +696,7 @@ static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; if (index == 5) rtlphy->pwrgroup_cnt++; } @@ -765,10 +765,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; /* RF switch Control */ - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; /* AGC control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; @@ -783,10 +787,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; /* RX AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; /* RX AFE control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; @@ -795,10 +803,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; /* Tx AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; /* Tx AFE control 2 */ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; @@ -807,14 +819,20 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; /* Tranceiver LSSI Readback */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; /* Tranceiver LSSI Readback PI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVERB_HSPI_READBACK; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 5061f1db3f02..08c2f5625129 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -192,7 +192,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, * defined by Realtek for large power */ chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index] + + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, @@ -222,7 +223,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, chnlgroup++; } - writeval = rtlphy->mcs_offset[chnlgroup][index] + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); @@ -255,7 +257,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, } for (i = 0; i < 4; i++) { - pwrdiff_limit[i] = (u8)((rtlphy->mcs_offset + pwrdiff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index] & (0x7f << (i * 8))) >> (i * 8)); @@ -293,7 +296,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index] + + writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "RTK better performance, writeval = 0x%x\n", writeval); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 1ad51e711a32..e3cf4c02122a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -129,8 +129,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, pstats->packet_matchbssid = packet_match_bssid; pstats->packet_toself = packet_toself; pstats->packet_beacon = packet_beacon; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck) { u8 report, cck_highpwr; @@ -216,8 +216,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = @@ -256,7 +256,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8)(evm & 0xff); - pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); } } } @@ -365,7 +366,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, return; } else { undec_sm_pwdb = - rtlpriv->dm.undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { @@ -385,7 +386,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb; _rtl92se_update_rxsignalstatistics(hw, pstats); } } @@ -397,16 +398,16 @@ static void rtl_92s_process_streams(struct ieee80211_hw *hw, u32 stream; for (stream = 0; stream < 2; stream++) { - if (pstats->rx_mimo_sig_qual[stream] != -1) { + if (pstats->rx_mimo_signalquality[stream] != -1) { if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { rtlpriv->stats.rx_evm_percentage[stream] = - pstats->rx_mimo_sig_qual[stream]; + pstats->rx_mimo_signalquality[stream]; } rtlpriv->stats.rx_evm_percentage[stream] = ((rtlpriv->stats.rx_evm_percentage[stream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual[stream] * + (pstats->rx_mimo_signalquality[stream] * 1)) / (RX_SMOOTH_FACTOR); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile deleted file mode 100644 index 4ed731f09b1f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -obj-m := rtl8723ae.o - - -rtl8723ae-objs := \ - dm.o \ - fw.o \ - hal_btc.o \ - hal_bt_coexist.o\ - hw.o \ - led.o \ - phy.o \ - pwrseq.o \ - pwrseqcmd.o \ - rf.o \ - sw.o \ - table.o \ - trx.o \ - - -obj-$(CONFIG_RTL8723AE) += rtl8723ae.o - -ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h deleted file mode 100644 index 417afeed36af..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - ** - ** Copyright(c) 2009-2012 Realtek Corporation. - ** - ** This program is free software; you can redistribute it and/or modify it - ** under the terms of version 2 of the GNU General Public License as - ** published by the Free Software Foundation. - ** - ** This program is distributed in the hope that it will be useful, but WITHOUT - ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - ** more details. - ** - ** You should have received a copy of the GNU General Public License along with - ** this program; if not, write to the Free Software Foundation, Inc., - ** 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - ** - ** The full GNU General Public License is included in this distribution in the - ** file called LICENSE. - ** - ** Contact Information: - ** wlanfae - ** Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - ** Hsinchu 300, Taiwan. - ** Larry Finger - ** - ***************************************************************************** - */ - -#ifndef __RTL8723E_BTC_H__ -#define __RTL8723E_BTC_H__ - -#include "../wifi.h" -#include "hal_bt_coexist.h" - -struct bt_coexist_c2h_info { - u8 no_parse_c2h; - u8 has_c2h; -}; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h deleted file mode 100644 index 8c110356dff9..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h +++ /dev/null @@ -1,163 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_DEF_H__ -#define __RTL8723E_DEF_H__ - -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 - -#define RX_MPDU_QUEUE 0 - -#define CHIP_8723 BIT(0) -#define NORMAL_CHIP BIT(3) -#define RF_TYPE_1T2R BIT(4) -#define RF_TYPE_2T2R BIT(5) -#define CHIP_VENDOR_UMC BIT(7) -#define B_CUT_VERSION BIT(12) -#define C_CUT_VERSION BIT(13) -#define D_CUT_VERSION ((BIT(12)|BIT(13))) -#define E_CUT_VERSION BIT(14) -#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) - -enum version_8723e { - VERSION_TEST_UMC_CHIP_8723 = 0x0081, - VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, - VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, -}; - -/* MASK */ -#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) -#define CHIP_TYPE_MASK BIT(3) -#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) -#define MANUFACTUER_MASK BIT(7) -#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) -#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) - -/* Get element */ -#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) -#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) -#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) - -#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\ - true : false) -#define IS_8723_SERIES(version) \ - ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false) -#define IS_CHIP_VENDOR_UMC(version) \ - ((GET_CVID_MANUFACTUER(version)) ? true : false) - -#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \ - ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) -#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? \ - ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) -#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) \ - ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \ - true : false) : false) - -enum rf_optype { - RF_OP_BY_SW_3WIRE = 0, - RF_OP_BY_FW, - RF_OP_MAX -}; - -enum rf_power_state { - RF_ON, - RF_OFF, - RF_SLEEP, - RF_SHUT_DOWN, -}; - -enum power_save_mode { - POWER_SAVE_MODE_ACTIVE, - POWER_SAVE_MODE_SAVE, -}; - -enum power_polocy_config { - POWERCFG_MAX_POWER_SAVINGS, - POWERCFG_GLOBAL_POWER_SAVINGS, - POWERCFG_LOCAL_POWER_SAVINGS, - POWERCFG_LENOVO, -}; - -enum interface_select_pci { - INTF_SEL1_MINICARD = 0, - INTF_SEL0_PCIE = 1, - INTF_SEL2_RSV = 2, - INTF_SEL3_RSV = 3, -}; - -enum hal_fw_c2h_cmd_id { - HAL_FW_C2H_CMD_Read_MACREG = 0, - HAL_FW_C2H_CMD_Read_BBREG = 1, - HAL_FW_C2H_CMD_Read_RFREG = 2, - HAL_FW_C2H_CMD_Read_EEPROM = 3, - HAL_FW_C2H_CMD_Read_EFUSE = 4, - HAL_FW_C2H_CMD_Read_CAM = 5, - HAL_FW_C2H_CMD_Get_BasicRate = 6, - HAL_FW_C2H_CMD_Get_DataRate = 7, - HAL_FW_C2H_CMD_Survey = 8, - HAL_FW_C2H_CMD_SurveyDone = 9, - HAL_FW_C2H_CMD_JoinBss = 10, - HAL_FW_C2H_CMD_AddSTA = 11, - HAL_FW_C2H_CMD_DelSTA = 12, - HAL_FW_C2H_CMD_AtimDone = 13, - HAL_FW_C2H_CMD_TX_Report = 14, - HAL_FW_C2H_CMD_CCX_Report = 15, - HAL_FW_C2H_CMD_DTM_Report = 16, - HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, - HAL_FW_C2H_CMD_C2HLBK = 18, - HAL_FW_C2H_CMD_C2HDBG = 19, - HAL_FW_C2H_CMD_C2HFEEDBACK = 20, - HAL_FW_C2H_CMD_MAX -}; - -enum rtl_desc_qsel { - QSLT_BK = 0x2, - QSLT_BE = 0x0, - QSLT_VI = 0x5, - QSLT_VO = 0x7, - QSLT_BEACON = 0x10, - QSLT_HIGH = 0x11, - QSLT_MGNT = 0x12, - QSLT_CMD = 0x13, -}; - -struct phy_sts_cck_8723e_t { - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -struct h2c_cmd_8723e { - u8 element_id; - u32 cmd_len; - u8 *p_cmdbuffer; -}; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c deleted file mode 100644 index 12e2a3cb0701..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c +++ /dev/null @@ -1,920 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#include "../wifi.h" -#include "../base.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "fw.h" -#include "hal_btc.h" - -static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { - 0x7f8001fe, - 0x788001e2, - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1e400079, - 0x1c800072, - 0x1b00006c, - 0x19800066, - 0x18000060, - 0x16c0005b, - 0x15800056, - 0x14400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, -}; - -static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, - {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, - {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, - {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, - {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} -}; - -static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} -}; - -static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - dm_digtable->dig_enable_flag = true; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->cur_igvalue = 0x20; - dm_digtable->pre_igvalue = 0x0; - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - dm_digtable->presta_cstate = DIG_STA_DISCONNECT; - dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; - dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable->rx_gain_range_max = DM_DIG_MAX; - dm_digtable->rx_gain_range_min = DM_DIG_MIN; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; -} - -static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - long rssi_val_min = 0; - - if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && - (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) - rssi_val_min = - (rtlpriv->dm.entry_min_undec_sm_pwdb > - rtlpriv->dm.undec_sm_pwdb) ? - rtlpriv->dm.undec_sm_pwdb : - rtlpriv->dm.entry_min_undec_sm_pwdb; - else - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; - } - - return (u8) rssi_val_min; -} - -static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) -{ - u32 ret_value; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); - falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); - falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); - falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); - falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); - falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; - - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); - falsealm_cnt->cnt_cck_fail = ret_value; - - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); - falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; - falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + - falsealm_cnt->cnt_mcs_fail + - falsealm_cnt->cnt_cck_fail); - - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); -} - -static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - u8 value_igi = dm_digtable->cur_igvalue; - - if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) - value_igi--; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) - value_igi += 0; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) - value_igi++; - else - value_igi += 2; - - value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER); - if (rtlpriv->falsealm_cnt.cnt_all > 10000) - value_igi = 0x32; - - dm_digtable->cur_igvalue = value_igi; - rtl8723ae_dm_write_dig(hw); -} - -static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dgtbl = &rtlpriv->dm_digtable; - - if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) { - if ((dgtbl->back_val - 2) < dgtbl->back_range_min) - dgtbl->back_val = dgtbl->back_range_min; - else - dgtbl->back_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) { - if ((dgtbl->back_val + 2) > dgtbl->back_range_max) - dgtbl->back_val = dgtbl->back_range_max; - else - dgtbl->back_val += 2; - } - - if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) > - dgtbl->rx_gain_range_max) - dgtbl->cur_igvalue = dgtbl->rx_gain_range_max; - else if ((dgtbl->rssi_val_min + 10 - - dgtbl->back_val) < dgtbl->rx_gain_range_min) - dgtbl->cur_igvalue = dgtbl->rx_gain_range_min; - else - dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "rssi_val_min = %x back_val %x\n", - dgtbl->rssi_val_min, dgtbl->back_val); - - rtl8723ae_dm_write_dig(hw); -} - -static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; - bool multi_sta = false; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - multi_sta = true; - - if ((!multi_sta) || - (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { - rtlpriv->initialized = false; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - return; - } else if (!rtlpriv->initialized) { - rtlpriv->initialized = true; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - if ((rssi_strength < dm_digtable->rssi_lowthresh) && - (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { - - if (dm_digtable->dig_ext_port_stage == - DIG_EXT_PORT_STAGE_2) { - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; - } else if (rssi_strength > dm_digtable->rssi_highthresh) { - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; - rtl92c_dm_ctrl_initgain_by_fa(hw); - } - } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "curmultista_cstate = %x dig_ext_port_stage %x\n", - dm_digtable->curmultista_cstate, - dm_digtable->dig_ext_port_stage); -} - -static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "presta_cstate = %x, cursta_cstate = %x\n", - dm_digtable->presta_cstate, - dm_digtable->cursta_cstate); - - if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_CONNECT) { - - if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { - dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); - rtl92c_dm_ctrl_initgain_by_rssi(hw); - } - } else { - dm_digtable->rssi_val_min = 0; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->cur_igvalue = 0x20; - dm_digtable->pre_igvalue = 0; - rtl8723ae_dm_write_dig(hw); - } -} -static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { - dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); - - if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (dm_digtable->rssi_val_min <= 25) - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } else { - if (dm_digtable->rssi_val_min <= 20) - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } - } else { - dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; - } - - if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { - if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) - dm_digtable->cur_cck_fa_state = - CCK_FA_STAGE_High; - else - dm_digtable->cur_cck_fa_state = - CCK_FA_STAGE_Low; - - if (dm_digtable->pre_cck_fa_state != - dm_digtable->cur_cck_fa_state) { - if (dm_digtable->cur_cck_fa_state == - CCK_FA_STAGE_Low) - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0x83); - else - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0xcd); - - dm_digtable->pre_cck_fa_state = - dm_digtable->cur_cck_fa_state; - } - - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - - } else { - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); - - } - dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); - -} - -static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (mac->act_scanning == true) - return; - - if (mac->link_state >= MAC80211_LINKED) - dm_digtable->cursta_cstate = DIG_STA_CONNECT; - else - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - - rtl8723ae_dm_initial_gain_sta(hw); - rtl8723ae_dm_initial_gain_multi_sta(hw); - rtl8723ae_dm_cck_packet_detection_thresh(hw); - - dm_digtable->presta_cstate = dm_digtable->cursta_cstate; - -} - -static void rtl8723ae_dm_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (rtlpriv->dm.dm_initialgain_enable == false) - return; - if (dm_digtable->dig_enable_flag == false) - return; - - rtl8723ae_dm_ctrl_initgain_by_twoport(hw); -} - -static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dynamic_txpower_enable = false; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; -} - -static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; - - if (!rtlpriv->dm.dynamic_txpower_enable) - return; - - if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "Not connected\n"); - - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if (mac->link_state >= MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); - } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); - } - } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); - } - - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_NORMAL\n"); - } - - if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel); - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - } - - rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; -} - -void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, back_val = %d\n", - dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, - dm_digtable->back_val); - - if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { - rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable->cur_igvalue); - rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable->cur_igvalue); - - dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; - } -} - -static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.current_turbo_edca = false; - rtlpriv->dm.is_any_nonbepkts = false; - rtlpriv->dm.is_cur_rdlstate = false; -} - -static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - u64 cur_txok_cnt = 0; - u64 cur_rxok_cnt = 0; - u32 edca_be_ul = 0x5ea42b; - u32 edca_be_dl = 0x5ea42b; - bool bt_change_edca = false; - - if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || - (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { - rtlpriv->dm.current_turbo_edca = false; - mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; - mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; - } - - if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { - edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; - bt_change_edca = true; - } - - if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { - edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; - bt_change_edca = true; - } - - if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.current_turbo_edca = false; - return; - } - - if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { - if (!(edca_be_ul & 0xffff0000)) - edca_be_ul |= 0x005e0000; - - if (!(edca_be_dl & 0xffff0000)) - edca_be_dl |= 0x005e0000; - } - - if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && - (!rtlpriv->dm.disable_framebursting))) { - - cur_txok_cnt = rtlpriv->stats.txbytesunicast - - mac->last_txok_cnt; - cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - - mac->last_rxok_cnt; - - if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.is_cur_rdlstate || - !rtlpriv->dm.current_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_dl); - rtlpriv->dm.is_cur_rdlstate = true; - } - } else { - if (rtlpriv->dm.is_cur_rdlstate || - !rtlpriv->dm.current_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_ul); - rtlpriv->dm.is_cur_rdlstate = false; - } - } - rtlpriv->dm.current_turbo_edca = true; - } else { - if (rtlpriv->dm.current_turbo_edca) { - u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); - rtlpriv->dm.current_turbo_edca = false; - } - } - - rtlpriv->dm.is_any_nonbepkts = false; - mac->last_txok_cnt = rtlpriv->stats.txbytesunicast; - mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast; -} - -static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.txpower_tracking = true; - rtlpriv->dm.txpower_trackinginit = false; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking); -} - -void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - - p_ra->ratr_state = DM_RATR_STA_INIT; - p_ra->pre_ratr_state = DM_RATR_STA_INIT; - - if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.useramask = true; - else - rtlpriv->dm.useramask = false; -} - -static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; - rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; - rtlpriv->dm_pstable.pre_rfstate = RF_MAX; - rtlpriv->dm_pstable.cur_rfstate = RF_MAX; - rtlpriv->dm_pstable.rssi_val_min = 0; -} - -void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct ps_t *dm_pstable = &rtlpriv->dm_pstable; - - if (!rtlpriv->reg_init) { - rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - MASKDWORD) & 0x1CC000) >> 14; - - rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, - MASKDWORD) & BIT(3)) >> 3; - - rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - MASKDWORD) & 0xFF000000) >> 24; - - rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & - 0xF000) >> 12; - - rtlpriv->reg_init = true; - } - - if (!force_in_normal) { - if (dm_pstable->rssi_val_min != 0) { - if (dm_pstable->pre_rfstate == RF_NORMAL) { - if (dm_pstable->rssi_val_min >= 30) - dm_pstable->cur_rfstate = RF_SAVE; - else - dm_pstable->cur_rfstate = RF_NORMAL; - } else { - if (dm_pstable->rssi_val_min <= 25) - dm_pstable->cur_rfstate = RF_NORMAL; - else - dm_pstable->cur_rfstate = RF_SAVE; - } - } else { - dm_pstable->cur_rfstate = RF_MAX; - } - } else { - dm_pstable->cur_rfstate = RF_NORMAL; - } - - if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { - if (dm_pstable->cur_rfstate == RF_SAVE) { - - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - BIT(5), 0x1); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1C0000, 0x2); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - 0xFF000000, 0x63); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0xC000, 0x2); - rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); - } else { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1CC000, rtlpriv->reg_874); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), - rtlpriv->reg_c70); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, - rtlpriv->reg_85c); - rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - BIT(5), 0x0); - } - - dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; - } -} - -static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct ps_t *dm_pstable = &rtlpriv->dm_pstable; - - if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { - dm_pstable->rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "Not connected to any\n"); - } - - if (mac->link_state == MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "AP Client PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } else { - dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "STA Default Port PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } - } else { - dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "AP Ext Port PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } - - rtl8723ae_dm_rf_saving(hw, false); -} - -void rtl8723ae_dm_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtl8723ae_dm_diginit(hw); - rtl8723ae_dm_init_dynamic_txpower(hw); - rtl8723ae_dm_init_edca_turbo(hw); - rtl8723ae_dm_init_rate_adaptive_mask(hw); - rtl8723ae_dm_initialize_txpower_tracking(hw); - rtl8723ae_dm_init_dynamic_bpowersaving(hw); -} - -void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - bool fw_current_inpsmode = false; - bool fw_ps_awake = true; - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&fw_ps_awake)); - - if ((ppsc->rfpwr_state == ERFON) && - ((!fw_current_inpsmode) && fw_ps_awake) && - (!ppsc->rfchange_inprogress)) { - rtl8723ae_dm_pwdmonitor(hw); - rtl8723ae_dm_dig(hw); - rtl8723ae_dm_false_alarm_counter_statistics(hw); - rtl8723ae_dm_dynamic_bpowersaving(hw); - rtl8723ae_dm_dynamic_txpower(hw); - /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ - rtl8723ae_dm_bt_coexist(hw); - rtl8723ae_dm_check_edca_turbo(hw); - } - if (rtlpcipriv->bt_coexist.init_set) - rtl_write_byte(rtlpriv, 0x76e, 0xc); -} - -static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtlpcipriv->bt_coexist.bt_rfreg_origin_1e - = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); - rtlpcipriv->bt_coexist.bt_rfreg_origin_1f - = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); - - rtlpcipriv->bt_coexist.cstate = 0; - rtlpcipriv->bt_coexist.previous_state = 0; - rtlpcipriv->bt_coexist.cstate_h = 0; - rtlpcipriv->bt_coexist.previous_state_h = 0; - rtlpcipriv->bt_coexist.lps_counter = 0; - - /* Enable counter statistics */ - rtl_write_byte(rtlpriv, 0x76e, 0x4); - rtl_write_byte(rtlpriv, 0x778, 0x3); - rtl_write_byte(rtlpriv, 0x40, 0x20); - - rtlpcipriv->bt_coexist.init_set = true; -} - -void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 tmp_byte = 0; - if (!rtlpcipriv->bt_coexist.bt_coexistence) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM]{BT], BT not exist!!\n"); - return; - } - - if (!rtlpcipriv->bt_coexist.init_set) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM][BT], rtl8723ae_dm_bt_coexist()\n"); - - rtl8723ae_dm_init_bt_coexist(hw); - } - - tmp_byte = rtl_read_byte(rtlpriv, 0x40); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM][BT], 0x40 is 0x%x", tmp_byte); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], bt_dm_coexist start"); - rtl8723ae_dm_bt_coexist_8723(hw); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h deleted file mode 100644 index 39d246196247..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_DM_H__ -#define __RTL8723E_DM_H__ - -#define HAL_DM_HIPWR_DISABLE BIT(1) - -#define OFDM_TABLE_SIZE 37 -#define CCK_TABLE_SIZE 33 - -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_FALSEALARM_THRESH_LOW 400 -#define DM_FALSEALARM_THRESH_HIGH 1000 - -#define DM_DIG_MAX 0x3e -#define DM_DIG_MIN 0x1e - -#define DM_DIG_FA_UPPER 0x32 -#define DM_DIG_FA_LOWER 0x20 -#define DM_DIG_FA_TH0 0x20 -#define DM_DIG_FA_TH1 0x100 -#define DM_DIG_FA_TH2 0x200 - -#define DM_DIG_BACKOFF_MAX 12 -#define DM_DIG_BACKOFF_MIN -4 -#define DM_DIG_BACKOFF_DEFAULT 10 - -#define DM_RATR_STA_INIT 0 - -#define TXHIGHPWRLEVEL_NORMAL 0 -#define TXHIGHPWRLEVEL_LEVEL1 1 -#define TXHIGHPWRLEVEL_LEVEL2 2 -#define TXHIGHPWRLEVEL_BT1 3 -#define TXHIGHPWRLEVEL_BT2 4 - -#define DM_TYPE_BYDRIVER 1 - -#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 -#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 - -struct swat_t { - u8 failure_cnt; - u8 try_flag; - u8 stop_trying; - long pre_rssi; - long trying_threshold; - u8 cur_antenna; - u8 pre_antenna; -}; - -enum tag_dynamic_init_gain_operation_type_definition { - DIG_TYPE_THRESH_HIGH = 0, - DIG_TYPE_THRESH_LOW = 1, - DIG_TYPE_BACKOFF = 2, - DIG_TYPE_RX_GAIN_MIN = 3, - DIG_TYPE_RX_GAIN_MAX = 4, - DIG_TYPE_ENABLE = 5, - DIG_TYPE_DISABLE = 6, - DIG_OP_TYPE_MAX -}; - -enum tag_cck_packet_detection_threshold_type_definition { - CCK_PD_STAGE_LowRssi = 0, - CCK_PD_STAGE_HighRssi = 1, - CCK_FA_STAGE_Low = 2, - CCK_FA_STAGE_High = 3, - CCK_PD_STAGE_MAX = 4, -}; - -enum dm_1r_cca_e { - CCA_1R = 0, - CCA_2R = 1, - CCA_MAX = 2, -}; - -enum dm_rf_e { - RF_SAVE = 0, - RF_NORMAL = 1, - RF_MAX = 2, -}; - -enum dm_sw_ant_switch_e { - ANS_ANTENNA_B = 1, - ANS_ANTENNA_A = 2, - ANS_ANTENNA_MAX = 3, -}; - -enum dm_dig_ext_port_alg_e { - DIG_EXT_PORT_STAGE_0 = 0, - DIG_EXT_PORT_STAGE_1 = 1, - DIG_EXT_PORT_STAGE_2 = 2, - DIG_EXT_PORT_STAGE_3 = 3, - DIG_EXT_PORT_STAGE_MAX = 4, -}; - -enum dm_dig_connect_e { - DIG_STA_DISCONNECT = 0, - DIG_STA_CONNECT = 1, - DIG_STA_BEFORE_CONNECT = 2, - DIG_MULTISTA_DISCONNECT = 3, - DIG_MULTISTA_CONNECT = 4, - DIG_CONNECT_MAX -}; - -#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ - ((((struct rtl_priv *)(_priv))->mac80211.opmode == \ - NL80211_IFTYPE_ADHOC) ? \ - (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) \ - : (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb)) - -void rtl8723ae_dm_init(struct ieee80211_hw *hw); -void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw); -void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); -void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw); -void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); -void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); -void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c deleted file mode 100644 index f55b1767ef57..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c +++ /dev/null @@ -1,745 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "reg.h" -#include "def.h" -#include "fw.h" - -static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp; - if (enable) { - tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); - rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); - } else { - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); - - rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); - } -} - -static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blockSize = sizeof(u32); - u8 *bufferPtr = (u8 *) buffer; - u32 *pu4BytePtr = (u32 *) buffer; - u32 i, offset, blockCount, remainSize; - - blockCount = size / blockSize; - remainSize = size % blockSize; - - for (i = 0; i < blockCount; i++) { - offset = i * blockSize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - - if (remainSize) { - offset = blockCount * blockSize; - bufferPtr += offset; - for (i = 0; i < remainSize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferPtr + i)); - } - } -} - -static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl8723ae_fw_block_write(hw, buffer, size); -} - -static void _rtl8723ae_write_fw(struct ieee80211_hw *hw, - enum version_8723e version, u8 *buffer, - u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 *bufferPtr = (u8 *) buffer; - u32 page_nums, remain_size; - u32 page, offset; - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); - - page_nums = size / FW_8192C_PAGE_SIZE; - remain_size = size % FW_8192C_PAGE_SIZE; - - if (page_nums > 6) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Page numbers should not be greater then 6\n"); - } - - for (page = 0; page < page_nums; page++) { - offset = page * FW_8192C_PAGE_SIZE; - _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), - FW_8192C_PAGE_SIZE); - } - - if (remain_size) { - offset = page_nums * FW_8192C_PAGE_SIZE; - page = page_nums; - _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), - remain_size); - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); -} - -static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int err = -EIO; - u32 counter = 0; - u32 value32; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && - (!(value32 & FWDL_ChkSum_rpt))); - - if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32); - goto exit; - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32); - - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - - counter = 0; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (value32 & WINTINI_RDY) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n", - value32); - err = 0; - goto exit; - } - - mdelay(FW_8192C_POLLING_DELAY); - - } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); - - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32); - -exit: - return err; -} - -int rtl8723ae_download_fw(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl8723ae_firmware_header *pfwheader; - u8 *pfwdata; - u32 fwsize; - int err; - enum version_8723e version = rtlhal->version; - - if (!rtlhal->pfirmware) - return 1; - - pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; - fwsize = rtlhal->fwsize; - - if (IS_FW_HEADER_EXIST(pfwheader)) { - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "Firmware Version(%d), Signature(%#x),Size(%d)\n", - pfwheader->version, pfwheader->signature, - (int)sizeof(struct rtl8723ae_firmware_header)); - - pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header); - fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header); - } - - if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) { - rtl8723ae_firmware_selfreset(hw); - rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); - } - _rtl8723ae_enable_fw_download(hw, true); - _rtl8723ae_write_fw(hw, version, pfwdata, fwsize); - _rtl8723ae_enable_fw_download(hw, false); - - err = _rtl8723ae_fw_free_to_go(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is not ready to run!\n"); - } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Firmware is ready to run!\n"); - } - return 0; -} - -static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 val_hmetfr, val_mcutst_1; - bool result = false; - - val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); - val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); - - if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) - result = true; - return result; -} - -static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, - u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 boxnum; - u16 box_reg = 0, box_extreg = 0; - u8 u1tmp; - bool isfw_rd = false; - bool bwrite_sucess = false; - u8 wait_h2c_limmit = 100; - u8 wait_writeh2c_limmit = 100; - u8 boxcontent[4], boxextcontent[2]; - u32 h2c_waitcounter = 0; - unsigned long flag; - u8 idx; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); - - while (true) { - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - if (rtlhal->h2c_setinprogress) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C set in progress! Wait to set..element_id(%d).\n", - element_id); - - while (rtlhal->h2c_setinprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, - flag); - h2c_waitcounter++; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wait 100 us (%d times)...\n", - h2c_waitcounter); - udelay(100); - - if (h2c_waitcounter > 1000) - return; - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, - flag); - } - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - } else { - rtlhal->h2c_setinprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - break; - } - } - - while (!bwrite_sucess) { - wait_writeh2c_limmit--; - if (wait_writeh2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Write H2C fail because no trigger " - "for FW INT!\n"); - break; - } - - boxnum = rtlhal->last_hmeboxnum; - switch (boxnum) { - case 0: - box_reg = REG_HMEBOX_0; - box_extreg = REG_HMEBOX_EXT_0; - break; - case 1: - box_reg = REG_HMEBOX_1; - box_extreg = REG_HMEBOX_EXT_1; - break; - case 2: - box_reg = REG_HMEBOX_2; - box_extreg = REG_HMEBOX_EXT_2; - break; - case 3: - box_reg = REG_HMEBOX_3; - box_extreg = REG_HMEBOX_EXT_3; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - - isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); - while (!isfw_rd) { - - wait_h2c_limmit--; - if (wait_h2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wating too long for FW read clear HMEBox(%d)!\n", - boxnum); - break; - } - - udelay(10); - - isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); - u1tmp = rtl_read_byte(rtlpriv, 0x1BF); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1tmp); - } - - if (!isfw_rd) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum); - break; - } - - memset(boxcontent, 0, sizeof(boxcontent)); - memset(boxextcontent, 0, sizeof(boxextcontent)); - boxcontent[0] = element_id; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id); - - switch (cmd_len) { - case 1: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 1); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 2: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 2); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 3: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 3); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 4: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + 2, 2); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 5: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + 2, 3); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - - bwrite_sucess = true; - - rtlhal->last_hmeboxnum = boxnum + 1; - if (rtlhal->last_hmeboxnum == 4) - rtlhal->last_hmeboxnum = 0; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum); - } - - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - rtlhal->h2c_setinprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); -} - -void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } - - _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer); - return; -} - -void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw) -{ - u8 u1tmp; - u8 delay = 100; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - - while (u1tmp & BIT(2)) { - delay--; - if (delay == 0) - break; - udelay(50); - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - } - if (delay == 0) { - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2))); - } -} - -void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 u1_h2c_set_pwrmode[3] = { 0 }; - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); - - SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); - SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); - SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, - ppsc->reg_max_lps_awakeintvl); - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", - u1_h2c_set_pwrmode, 3); - rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); - -} - -static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl8192_tx_ring *ring; - struct rtl_tx_desc *pdesc; - u8 own; - unsigned long flags; - struct sk_buff *pskb = NULL; - - ring = &rtlpci->tx_ring[BEACON_QUEUE]; - - pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); - - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - - pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - - rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - - __skb_queue_tail(&ring->queue, skb); - - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - - rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - - return true; -} - -static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { - /* page 0 beacon */ - 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 1 beacon */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 2 ps-poll */ - 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 3 null */ - 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 4 probe_resp */ - 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 5 probe_resp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct sk_buff *skb = NULL; - - u32 totalpacketlen; - bool rtstatus; - u8 u1RsvdPageLoc[3] = { 0 }; - bool dlok = false; - - u8 *beacon; - u8 *p_pspoll; - u8 *nullfunc; - u8 *p_probersp; - /*--------------------------------------------------------- - (1) beacon - --------------------------------------------------------- - */ - beacon = &reserved_page_packet[BEACON_PG * 128]; - SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); - SET_80211_HDR_ADDRESS3(beacon, mac->bssid); - - /*------------------------------------------------------- - (2) ps-poll - -------------------------------------------------------- - */ - p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; - SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); - SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); - SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); - - SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); - - /*-------------------------------------------------------- - (3) null data - ---------------------------------------------------------i - */ - nullfunc = &reserved_page_packet[NULL_PG * 128]; - SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); - SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); - SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); - - /*--------------------------------------------------------- - (4) probe response - ---------------------------------------------------------- - */ - p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; - SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); - SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); - SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); - - totalpacketlen = TOTAL_RESERVED_PKT_LEN; - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - &reserved_page_packet[0], totalpacketlen); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - u1RsvdPageLoc, 3); - - skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), - &reserved_page_packet, totalpacketlen); - - rtstatus = _rtl8723ae_cmd_send_packet(hw, skb); - - if (rtstatus) - dlok = true; - - if (dlok) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Set RSVD page location to Fw.\n"); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); - rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE, - sizeof(u1RsvdPageLoc), u1RsvdPageLoc); - } else - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Set RSVD page location to Fw FAIL!!!!!!.\n"); -} - -void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) -{ - u8 u1_joinbssrpt_parm[1] = { 0 }; - - SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); - - rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h deleted file mode 100644 index 89994e16dc83..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL92C__FW__H__ -#define __RTL92C__FW__H__ - -#define FW_8192C_START_ADDRESS 0x1000 -#define FW_8192C_END_ADDRESS 0x3FFF -#define FW_8192C_PAGE_SIZE 4096 -#define FW_8192C_POLLING_DELAY 5 -#define FW_8192C_POLLING_TIMEOUT_COUNT 1000 - -#define BEACON_PG 0 -#define PSPOLL_PG 2 -#define NULL_PG 3 -#define PROBERSP_PG 4 /* ->5 */ - -#define TOTAL_RESERVED_PKT_LEN 768 - -#define IS_FW_HEADER_EXIST(_pfwhdr) \ - ((_pfwhdr->signature&0xFF00) == 0x2300) - -struct rtl8723ae_firmware_header { - u16 signature; - u8 category; - u8 function; - u16 version; - u8 subversion; - u8 rsvd1; - u8 month; - u8 date; - u8 hour; - u8 minute; - u16 ramcodeSize; - u16 rsvd2; - u32 svnindex; - u32 rsvd3; - u32 rsvd4; - u32 rsvd5; -}; - -enum rtl8192c_h2c_cmd { - H2C_AP_OFFLOAD = 0, - H2C_SETPWRMODE = 1, - H2C_JOINBSSRPT = 2, - H2C_RSVDPAGE = 3, - H2C_RSSI_REPORT = 5, - H2C_RA_MASK = 6, - MAX_H2CCMD -}; - -#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) -#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) - -int rtl8723ae_download_fw(struct ieee80211_hw *hw); -void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, - u32 cmd_len, u8 *p_cmdbuffer); -void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); -void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); -void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c deleted file mode 100644 index 3d092e4b0b7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c +++ /dev/null @@ -1,542 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "hal_bt_coexist.h" -#include "../pci.h" -#include "dm.h" -#include "fw.h" -#include "phy.h" -#include "reg.h" -#include "hal_btc.h" - -void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, - bool reject) -{ -} - -void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlpriv->link_info.busytraffic) { - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE; - - if (rtlpriv->link_info.tx_busy_traffic) - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_UPLINK; - else - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_UPLINK; - - if (rtlpriv->link_info.rx_busy_traffic) - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_DOWNLINK; - else - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_DOWNLINK; - } else { - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK; - } - - if (rtlpriv->mac80211.mode == WIRELESS_MODE_G || - rtlpriv->mac80211.mode == WIRELESS_MODE_B) { - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40; - } else { - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY; - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_HT40; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_HT20; - } else { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_HT20; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_HT40; - } - } - - if (rtlpriv->bt_operation_on) - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30; - else - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30; -} - -u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1) - -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth; - u8 bt_rssi_state = 0; - - smooth = rtl8723ae_dm_bt_get_rx_ss(hw); - - if (level_num == 2) { - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= (rssi_thresh + - BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to High\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Low\n"); - } - } else { - if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at High\n"); - } - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 thresh error!!\n"); - return rtlpcipriv->bt_coexist.bt_pre_rssi_state; - } - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= - (rssi_thresh+BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Low\n"); - } - } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_MEDIUM) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_MEDIUM)) { - if (smooth >= (rssi_thresh1 + - BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to High\n"); - } else if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Medium\n"); - } - } else { - if (smooth < rssi_thresh1) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at High\n"); - } - } - } - - rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state; - - return bt_rssi_state; -} - -u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth; - u8 bt_rssi_state = 0; - - smooth = rtl8723ae_dm_bt_get_rx_ss(hw); - - if (level_num == 2) { - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)){ - if (smooth >= - (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to High\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Low\n"); - } - } else { - if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at High\n"); - } - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI thresh error!!\n"); - return rtlpcipriv->bt_coexist.bt_pre_rssi_state; - } - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= - (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Low\n"); - } - } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_MEDIUM) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_MEDIUM)) { - if (smooth >= - (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to High\n"); - } else if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Medium\n"); - } - } else { - if (smooth < rssi_thresh1) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at High\n"); - } - } - } - - rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state; - return bt_rssi_state; -} - -long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth = 0; - - if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) - smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); - else - smooth = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth); - - return smooth; -} - -void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, - bool balance_on, u8 ms0, u8 ms1) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[3] = {0}; - - if (balance_on) { - h2c_parameter[2] = 1; - h2c_parameter[1] = ms1; - h2c_parameter[0] = ms0; - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - h2c_parameter[2] = 0; - h2c_parameter[1] = 0; - h2c_parameter[0] = 0; - } - rtlpcipriv->bt_coexist.balance_on = balance_on; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", - balance_on ? "ON" : "OFF", ms0, ms1, - h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]); - - rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter); -} - - -void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if (type == BT_AGCTABLE_OFF) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]AGCTable Off!\n"); - rtl_write_dword(rtlpriv, 0xc78, 0x641c0001); - rtl_write_dword(rtlpriv, 0xc78, 0x631d0001); - rtl_write_dword(rtlpriv, 0xc78, 0x621e0001); - rtl_write_dword(rtlpriv, 0xc78, 0x611f0001); - rtl_write_dword(rtlpriv, 0xc78, 0x60200001); - - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x32000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x71000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xb0000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xfc000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_G1, 0xfffff, 0x30355); - } else if (type == BT_AGCTABLE_ON) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]AGCTable On!\n"); - rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4a200001); - - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xdc000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x90000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x51000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x12000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_G1, 0xfffff, 0x00355); - - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } -} - -void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if (type == BT_BB_BACKOFF_OFF) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]BBBackOffLevel Off!\n"); - rtl_write_dword(rtlpriv, 0xc04, 0x3a05611); - } else if (type == BT_BB_BACKOFF_ON) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]BBBackOffLevel On!\n"); - rtl_write_dword(rtlpriv, 0xc04, 0x3a07611); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } -} - -void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_fw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.fw_coexist_all_off) - return; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n"); - rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw); - rtlpcipriv->bt_coexist.fw_coexist_all_off = true; -} - -void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_sw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.sw_coexist_all_off) - return; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n"); - rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw); - rtlpcipriv->bt_coexist.sw_coexist_all_off = true; -} - -void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_hw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.hw_coexist_all_off) - return; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n"); - - rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw); - - rtlpcipriv->bt_coexist.hw_coexist_all_off = true; -} - -void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_fw_coex_all_off(hw); - rtl8723ae_dm_bt_sw_coex_all_off(hw); - rtl8723ae_dm_bt_hw_coex_all_off(hw); -} - -bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if ((rtlpcipriv->bt_coexist.previous_state == - rtlpcipriv->bt_coexist.cstate) && - (rtlpcipriv->bt_coexist.previous_state_h == - rtlpcipriv->bt_coexist.cstate_h)) - return false; - else - return true; -} - -bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->link_info.tx_busy_traffic) - return true; - else - return false; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h deleted file mode 100644 index 76f4d122dbc1..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_HAL_BT_COEXIST_H__ -#define __RTL8723E_HAL_BT_COEXIST_H__ - -#include "../wifi.h" - -/* The reg define is for 8723 */ -#define REG_HIGH_PRIORITY_TXRX 0x770 -#define REG_LOW_PRIORITY_TXRX 0x774 - -#define BT_FW_COEX_THRESH_TOL 6 -#define BT_FW_COEX_THRESH_20 20 -#define BT_FW_COEX_THRESH_23 23 -#define BT_FW_COEX_THRESH_25 25 -#define BT_FW_COEX_THRESH_30 30 -#define BT_FW_COEX_THRESH_35 35 -#define BT_FW_COEX_THRESH_40 40 -#define BT_FW_COEX_THRESH_45 45 -#define BT_FW_COEX_THRESH_47 47 -#define BT_FW_COEX_THRESH_50 50 -#define BT_FW_COEX_THRESH_55 55 - -#define BT_COEX_STATE_BT30 BIT(0) -#define BT_COEX_STATE_WIFI_HT20 BIT(1) -#define BT_COEX_STATE_WIFI_HT40 BIT(2) -#define BT_COEX_STATE_WIFI_LEGACY BIT(3) - -#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4) -#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5) -#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6) -#define BT_COEX_STATE_DEC_BT_POWER BIT(7) - -#define BT_COEX_STATE_WIFI_IDLE BIT(8) -#define BT_COEX_STATE_WIFI_UPLINK BIT(9) -#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10) - -#define BT_COEX_STATE_BT_INQ_PAGE BIT(11) -#define BT_COEX_STATE_BT_IDLE BIT(12) -#define BT_COEX_STATE_BT_UPLINK BIT(13) -#define BT_COEX_STATE_BT_DOWNLINK BIT(14) - -#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15) -#define BT_COEX_STATE_BT_RSSI_LOW BIT(19) - -#define BT_COEX_STATE_PROFILE_HID BIT(20) -#define BT_COEX_STATE_PROFILE_A2DP BIT(21) -#define BT_COEX_STATE_PROFILE_PAN BIT(22) -#define BT_COEX_STATE_PROFILE_SCO BIT(23) - -#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24) -#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25) -#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26) - -#define BT_COEX_STATE_BTINFO_COMMON BIT(30) -#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31) -#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29) - -#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0) -#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1) -#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2) -#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3) - -#define BT_RSSI_STATE_HIGH 0 -#define BT_RSSI_STATE_MEDIUM 1 -#define BT_RSSI_STATE_LOW 2 -#define BT_RSSI_STATE_STAY_HIGH 3 -#define BT_RSSI_STATE_STAY_MEDIUM 4 -#define BT_RSSI_STATE_STAY_LOW 5 - -#define BT_AGCTABLE_OFF 0 -#define BT_AGCTABLE_ON 1 -#define BT_BB_BACKOFF_OFF 0 -#define BT_BB_BACKOFF_ON 1 -#define BT_FW_NAV_OFF 0 -#define BT_FW_NAV_ON 1 - -#define BT_COEX_MECH_NONE 0 -#define BT_COEX_MECH_SCO 1 -#define BT_COEX_MECH_HID 2 -#define BT_COEX_MECH_A2DP 3 -#define BT_COEX_MECH_PAN 4 -#define BT_COEX_MECH_HID_A2DP 5 -#define BT_COEX_MECH_HID_PAN 6 -#define BT_COEX_MECH_PAN_A2DP 7 -#define BT_COEX_MECH_HID_SCO_ESCO 8 -#define BT_COEX_MECH_FTP_A2DP 9 -#define BT_COEX_MECH_COMMON 10 -#define BT_COEX_MECH_MAX 11 - -#define BT_DBG_PROFILE_NONE 0 -#define BT_DBG_PROFILE_SCO 1 -#define BT_DBG_PROFILE_HID 2 -#define BT_DBG_PROFILE_A2DP 3 -#define BT_DBG_PROFILE_PAN 4 -#define BT_DBG_PROFILE_HID_A2DP 5 -#define BT_DBG_PROFILE_HID_PAN 6 -#define BT_DBG_PROFILE_PAN_A2DP 7 -#define BT_DBG_PROFILE_MAX 9 - -#define BTINFO_B_FTP BIT(7) -#define BTINFO_B_A2DP BIT(6) -#define BTINFO_B_HID BIT(5) -#define BTINFO_B_SCO_BUSY BIT(4) -#define BTINFO_B_ACL_BUSY BIT(3) -#define BTINFO_B_INQ_PAGE BIT(2) -#define BTINFO_B_SCO_ESCO BIT(1) -#define BTINFO_B_CONNECTION BIT(0) - - -void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw); - -void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw); -long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, - bool balance_on, u8 ms0, u8 ms1); -void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type); -void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type); -u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1); -u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1); -void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, - bool reject); - -bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw); -bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c deleted file mode 100644 index 887d521fe690..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c +++ /dev/null @@ -1,1786 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ -#include "hal_btc.h" -#include "../pci.h" -#include "phy.h" -#include "fw.h" -#include "reg.h" -#include "def.h" - -void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - if (!rtlpcipriv->bt_coexist.bt_coexistence) - return; - - if (ppsc->inactiveps) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BT][DM], Before enter IPS, turn off all Coexist DM\n"); - rtlpcipriv->bt_coexist.cstate = 0; - rtlpcipriv->bt_coexist.previous_state = 0; - rtlpcipriv->bt_coexist.cstate_h = 0; - rtlpcipriv->bt_coexist.previous_state_h = 0; - rtl8723ae_btdm_coex_all_off(hw); - } -} - -static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; - - u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; - - if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) - m_status = RT_MEDIA_CONNECT; - - return m_status; -} - -void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, - bool mstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 h2c_parameter[3] = {0}; - u8 chnl; - - if (!rtlpcipriv->bt_coexist.bt_coexistence) - return; - - if (RT_MEDIA_CONNECT == mstatus) - h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */ - else - h2c_parameter[0] = 0x0; - - if (mgnt_link_status_query(hw)) { - chnl = rtlphy->current_channel; - h2c_parameter[1] = chnl; - } - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) - h2c_parameter[2] = 0x30; - else - h2c_parameter[2] = 0x20; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], FW write 0x19 = 0x%x\n", - h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]); - - rtl8723ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter); - -} - -static bool rtl8723ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (rtlpriv->link_info.busytraffic || - rtlpriv->link_info.rx_busy_traffic || - rtlpriv->link_info.tx_busy_traffic) - return true; - else - return false; -} - -static void rtl8723ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw, - u8 byte1, u8 byte2, u8 byte3, - u8 byte4, u8 byte5) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[5] = {0}; - - h2c_parameter[0] = byte1; - h2c_parameter[1] = byte2; - h2c_parameter[2] = byte3; - h2c_parameter[3] = byte4; - h2c_parameter[4] = byte5; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW write 0x3a(4bytes) = 0x%x%8x\n", - h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 | - h2c_parameter[3]<<8 | h2c_parameter[4]); - rtl8723ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter); -} - -static bool rtl8723ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Need to decrease bt power\n"); - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_DEC_BT_POWER; - return true; - } - - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER; - return false; -} - -static bool rtl8723ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if ((rtlpcipriv->bt_coexist.previous_state == - rtlpcipriv->bt_coexist.cstate) && - (rtlpcipriv->bt_coexist.previous_state_h == - rtlpcipriv->bt_coexist.cstate_h)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], Coexist state do not chang!!\n"); - return true; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], Coexist state changed!!\n"); - return false; - } -} - -static void rtl8723ae_dm_bt_set_coex_table(struct ieee80211_hw *hw, - u32 val_0x6c0, u32 val_0x6c8, - u32 val_0x6cc) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6c0 = 0x%x\n", val_0x6c0); - rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6c8 = 0x%x\n", val_0x6c8); - rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6cc = 0x%x\n", val_0x6cc); - rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc); -} - -static void rtl8723ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool mode) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (BT_PTA_MODE_ON == mode) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on, "); - /* Enable GPIO 0/1/2/3/8 pins for bt */ - rtl_write_byte(rtlpriv, 0x40, 0x20); - rtlpcipriv->bt_coexist.hw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n"); - rtl_write_byte(rtlpriv, 0x40, 0x0); - } -} - -static void rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw, - u8 type) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (BT_RF_RX_LPF_CORNER_SHRINK == type) { - /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu*/ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Shrink RF Rx LPF corner!!\n"); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, - 0xf0ff7); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else if (BT_RF_RX_LPF_CORNER_RESUME == type) { - /*Resume RF Rx LPF corner*/ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Resume RF Rx LPF corner!!\n"); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, - rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); - } -} - -static void rtl8723ae_bt_set_penalty_tx_rate_adap(struct ieee80211_hw *hw, - u8 ra_type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 tmu1; - - tmu1 = rtl_read_byte(rtlpriv, 0x4fd); - tmu1 |= BIT(0); - if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Tx rate adaptive, set low penalty!!\n"); - tmu1 &= ~BIT(2); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Tx rate adaptive, set normal!!\n"); - tmu1 |= BIT(2); - } - rtl_write_byte(rtlpriv, 0x4fd, tmu1); -} - -static void rtl8723ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw, - struct btdm_8723 *btdm) -{ - btdm->all_off = false; - btdm->agc_table_en = false; - btdm->adc_back_off_on = false; - btdm->b2_ant_hid_en = false; - btdm->low_penalty_rate_adaptive = false; - btdm->rf_rx_lpf_shrink = false; - btdm->reject_aggre_pkt = false; - - btdm->tdma_on = false; - btdm->tdma_ant = TDMA_2ANT; - btdm->tdma_nav = TDMA_NAV_OFF; - btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm->fw_dac_swing_lvl = 0x20; - - btdm->tra_tdma_on = false; - btdm->tra_tdma_ant = TDMA_2ANT; - btdm->tra_tdma_nav = TDMA_NAV_OFF; - btdm->ignore_wlan_act = false; - - btdm->ps_tdma_on = false; - btdm->ps_tdma_byte[0] = 0x0; - btdm->ps_tdma_byte[1] = 0x0; - btdm->ps_tdma_byte[2] = 0x0; - btdm->ps_tdma_byte[3] = 0x8; - btdm->ps_tdma_byte[4] = 0x0; - - btdm->pta_on = true; - btdm->val_0x6c0 = 0x5a5aaaaa; - btdm->val_0x6c8 = 0xcc; - btdm->val_0x6cc = 0x3; - - btdm->sw_dac_swing_on = false; - btdm->sw_dac_swing_lvl = 0xc0; - btdm->wlan_act_hi = 0x20; - btdm->wlan_act_lo = 0x10; - btdm->bt_retry_index = 2; - - btdm->dec_bt_pwr = false; -} - -static void dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw, - struct btdm_8723 *btdm) -{ - rtl8723ae_dm_bt_btdm_structure_reload(hw, btdm); - btdm->all_off = true; - btdm->pta_on = false; - btdm->wlan_act_hi = 0x10; -} - -static bool rtl8723ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct btdm_8723 btdm8723; - bool common = false; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - - if (!rtl8723ae_dm_bt_is_wifi_busy(hw) - && !rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi idle + Bt idle, bt coex mechanism always off!!\n"); - dm_bt_btdm_structure_reload_all_off(hw, &btdm8723); - common = true; - } else if (rtl8723ae_dm_bt_is_wifi_busy(hw) - && !rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi non-idle + Bt disabled/idle!!\n"); - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.rf_rx_lpf_shrink = false; - btdm8723.reject_aggre_pkt = false; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - btdm8723.pta_on = true; - btdm8723.val_0x6c0 = 0x5a5aaaaa; - btdm8723.val_0x6c8 = 0xcccc; - btdm8723.val_0x6cc = 0x3; - - btdm8723.tdma_on = false; - btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm8723.b2_ant_hid_en = false; - - common = true; - } else if (rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Bt non-idle!\n"); - if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi connection exist\n"); - common = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "No Wifi connection!\n"); - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = false; - btdm8723.reject_aggre_pkt = false; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - btdm8723.pta_on = true; - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0x0000ffff; - btdm8723.val_0x6cc = 0x3; - - btdm8723.tdma_on = false; - btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm8723.b2_ant_hid_en = false; - - common = true; - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - if (common) - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BTINFO_COMMON; - - if (common && rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); - - return common; -} - -static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw, - bool sw_dac_swing_on, - u32 sw_dac_swing_lvl) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (sw_dac_swing_on) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); - rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, - sw_dac_swing_lvl); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], SwDacSwing Off!\n"); - rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); - } -} - -static void rtl8723ae_dm_bt_set_fw_dec_bt_pwr(struct ieee80211_hw *hw, - bool dec_bt_pwr) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = 0; - - if (dec_bt_pwr) { - h2c_parameter[0] |= BIT(1); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n", - (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw, - bool enable, bool dac_swing_on) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - if (enable) { - h2c_parameter[0] |= BIT(0); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - if (dac_swing_on) - h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15 = 0x%x\n", - (enable ? "ON!!" : "OFF!!"), (dac_swing_on ? "ON" : "OFF"), - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw, - bool enable, u8 ant_num, u8 nav_en, - u8 dac_swing_en) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 h2c_parameter[1] = {0}; - u8 h2c_parameter1[1] = {0}; - - h2c_parameter[0] = 0; - h2c_parameter1[0] = 0; - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set BT PTA update manager to trigger update!!\n"); - h2c_parameter1[0] |= BIT(0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TDMA mode ON!!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - if (TDMA_1ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_1ANT\n"); - h2c_parameter[0] |= BIT(1); - } else if (TDMA_2ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_2ANT\n"); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Unknown Ant\n"); - } - - if (TDMA_NAV_OFF == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_NAV_OFF\n"); - } else if (TDMA_NAV_ON == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_NAV_ON\n"); - h2c_parameter[0] |= BIT(2); - } - - if (TDMA_DAC_SWING_OFF == dac_swing_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_DAC_SWING_OFF\n"); - } else if (TDMA_DAC_SWING_ON == dac_swing_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_DAC_SWING_ON\n"); - h2c_parameter[0] |= BIT(4); - } - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set BT PTA update manager to no update!!\n"); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TDMA mode OFF!!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW2AntTDMA, write 0x26 = 0x%x\n", - h2c_parameter1[0]); - rtl8723ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW2AntTDMA, write 0x14 = 0x%x\n", h2c_parameter[0]); - rtl8723ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw, - bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 h2c_parameter[1] = {0}; - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], BT Ignore Wlan_Act !!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], BT don't ignore Wlan_Act !!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%x\n", - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw, - bool enable, u8 ant_num, - u8 nav_en) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 h2c_parameter[2] = {0}; - - /* Only 8723 B cut should do this */ - if (IS_VENDOR_8723_A_CUT(rtlhal->version)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n"); - return; - } - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TTDMA mode ON!!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - if (TDMA_1ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_1ANT\n"); - h2c_parameter[0] |= BIT(1); - } else if (TDMA_2ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_2ANT\n"); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Unknown Ant\n"); - } - - if (TDMA_NAV_OFF == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_NAV_OFF\n"); - } else if (TDMA_NAV_ON == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_NAV_ON\n"); - h2c_parameter[1] |= BIT(0); - } - - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TTDMA mode OFF!!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW Traditional TDMA, write 0x33 = 0x%x\n", - h2c_parameter[0] << 8 | h2c_parameter[1]); - - rtl8723ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw, - u8 dac_swing_lvl) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = dac_swing_lvl; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x29 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw, - bool enable) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = 0; - - if (enable) { - h2c_parameter[0] |= BIT(0); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set BT HID information = 0x%x\n", enable); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x24 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw, - u8 retry_index) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = retry_index; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set BT Retry Index=%d\n", retry_index); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x23 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw, - u8 wlan_act_hi, u8 wlan_act_lo) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter_hi[1] = {0}; - u8 h2c_parameter_lo[1] = {0}; - - h2c_parameter_hi[0] = wlan_act_hi; - h2c_parameter_lo[0] = wlan_act_lo; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set WLAN_ACT Hi:Lo = 0x%x/0x%x\n", wlan_act_hi, - wlan_act_lo); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x22 = 0x%x\n", h2c_parameter_hi[0]); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x11 = 0x%x\n", h2c_parameter_lo[0]); - - /* WLAN_ACT = High duration, unit:ms */ - rtl8723ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi); - /* WLAN_ACT = Low duration, unit:3*625us */ - rtl8723ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo); -} - -void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8723 *btdm) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct btdm_8723 *btdm_8723 = &rtlhal->hal_coex_8723.btdm; - u8 i; - bool fw_current_inpsmode = false; - bool fw_ps_awake = true; - - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *)(&fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *)(&fw_ps_awake)); - - /* check new setting is different than the old one, - * if all the same, don't do the setting again. - */ - if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], the same coexist setting, return!!\n"); - return; - } else { /* save the new coexist setting */ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], UPDATE TO NEW COEX SETTING!!\n"); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bAllOff = 0x%x/ 0x%x\n", - btdm_8723->all_off, btdm->all_off); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new agc_table_en = 0x%x/ 0x%x\n", - btdm_8723->agc_table_en, btdm->agc_table_en); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new adc_back_off_on = 0x%x/ 0x%x\n", - btdm_8723->adc_back_off_on, btdm->adc_back_off_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new b2_ant_hid_en = 0x%x/ 0x%x\n", - btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bLowPenaltyRateAdaptive = 0x%x/ 0x%x\n", - btdm_8723->low_penalty_rate_adaptive, - btdm->low_penalty_rate_adaptive); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bRfRxLpfShrink = 0x%x/ 0x%x\n", - btdm_8723->rf_rx_lpf_shrink, btdm->rf_rx_lpf_shrink); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bRejectAggrePkt = 0x%x/ 0x%x\n", - btdm_8723->reject_aggre_pkt, btdm->reject_aggre_pkt); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdma_on = 0x%x/ 0x%x\n", - btdm_8723->tdma_on, btdm->tdma_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdmaAnt = 0x%x/ 0x%x\n", - btdm_8723->tdma_ant, btdm->tdma_ant); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdmaNav = 0x%x/ 0x%x\n", - btdm_8723->tdma_nav, btdm->tdma_nav); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdma_dac_swing = 0x%x/ 0x%x\n", - btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new fwDacSwingLvl = 0x%x/ 0x%x\n", - btdm_8723->fw_dac_swing_lvl, btdm->fw_dac_swing_lvl); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bTraTdmaOn = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_on, btdm->tra_tdma_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new traTdmaAnt = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new traTdmaNav = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bPsTdmaOn = 0x%x/ 0x%x\n", - btdm_8723->ps_tdma_on, btdm->ps_tdma_on); - for (i = 0; i < 5; i++) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new psTdmaByte[i] = 0x%x/ 0x%x\n", - btdm_8723->ps_tdma_byte[i], - btdm->ps_tdma_byte[i]); - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bIgnoreWlanAct = 0x%x/ 0x%x\n", - btdm_8723->ignore_wlan_act, btdm->ignore_wlan_act); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bPtaOn = 0x%x/ 0x%x\n", - btdm_8723->pta_on, btdm->pta_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6c0 = 0x%x/ 0x%x\n", - btdm_8723->val_0x6c0, btdm->val_0x6c0); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6c8 = 0x%x/ 0x%x\n", - btdm_8723->val_0x6c8, btdm->val_0x6c8); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6cc = 0x%x/ 0x%x\n", - btdm_8723->val_0x6cc, btdm->val_0x6cc); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new sw_dac_swing_on = 0x%x/ 0x%x\n", - btdm_8723->sw_dac_swing_on, btdm->sw_dac_swing_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new sw_dac_swing_lvl = 0x%x/ 0x%x\n", - btdm_8723->sw_dac_swing_lvl, - btdm->sw_dac_swing_lvl); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new wlanActHi = 0x%x/ 0x%x\n", - btdm_8723->wlan_act_hi, btdm->wlan_act_hi); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new wlanActLo = 0x%x/ 0x%x\n", - btdm_8723->wlan_act_lo, btdm->wlan_act_lo); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new btRetryIndex = 0x%x/ 0x%x\n", - btdm_8723->bt_retry_index, btdm->bt_retry_index); - - memcpy(btdm_8723, btdm, sizeof(struct btdm_8723)); - } - /* - * Here we only consider when Bt Operation - * inquiry/paging/pairing is ON - * we only need to turn off TDMA - */ - - if (rtlpcipriv->bt_coexist.hold_for_bt_operation) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set to ignore wlanAct for BT OP!!\n"); - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, true); - return; - } - - if (btdm->all_off) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], disable all coexist mechanism !!\n"); - rtl8723ae_btdm_coex_all_off(hw); - return; - } - - rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt); - - if (btdm->low_penalty_rate_adaptive) - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, - BT_TX_RATE_ADAPTIVE_LOW_PENALTY); - else - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, - BT_TX_RATE_ADAPTIVE_NORMAL); - - if (btdm->rf_rx_lpf_shrink) - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, - BT_RF_RX_LPF_CORNER_SHRINK); - else - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, - BT_RF_RX_LPF_CORNER_RESUME); - - if (btdm->agc_table_en) - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON); - else - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); - - if (btdm->adc_back_off_on) - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_ON); - else - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); - - rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index); - - rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl); - rtl8723ae_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi, - btdm->wlan_act_lo); - - rtl8723ae_dm_bt_set_coex_table(hw, btdm->val_0x6c0, - btdm->val_0x6c8, btdm->val_0x6cc); - rtl8723ae_dm_bt_set_hw_pta_mode(hw, btdm->pta_on); - - /* Note: There is a constraint between TDMA and 2AntHID - * Only one of 2AntHid and tdma can be turned on - * We should turn off those mechanisms first - * and then turn on them on. - */ - if (btdm->b2_ant_hid_en) { - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, - btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, - btdm->tdma_dac_swing); - - /* turn off Pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - - /* turn on 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, true); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, true, true); - } else if (btdm->tdma_on) { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - - /* turn on tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - } else if (btdm->ps_tdma_on) { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - - /* turn on pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - rtl8723ae_dm_bt_set_fw_3a(hw, - btdm->ps_tdma_byte[0], - btdm->ps_tdma_byte[1], - btdm->ps_tdma_byte[2], - btdm->ps_tdma_byte[3], - btdm->ps_tdma_byte[4]); - } else { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - - /* turn off pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - } - - /* Note: - * We should add delay for making sure sw DacSwing can be set - * sucessfully. Because of that rtl8723ae_dm_bt_set_fw_2_ant_hid() - * and rtl8723ae_dm_bt_set_fw_tdma_ctrl() - * will overwrite the reg 0x880. - */ - mdelay(30); - rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, - btdm->sw_dac_swing_on, btdm->sw_dac_swing_lvl); - rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr); -} - -/*============================================================ - * extern function start with BTDM_ - *============================================================ - */ -static u32 rtl8723ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 counters = 0; - - counters = rtlhal->hal_coex_8723.high_priority_tx + - rtlhal->hal_coex_8723.high_priority_rx; - return counters; -} - -static u32 rtl8723ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - return rtlhal->hal_coex_8723.low_priority_tx + - rtlhal->hal_coex_8723.low_priority_rx; -} - -static u8 rtl8723ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u32 bt_tx_rx_cnt = 0; - u8 bt_tx_rx_cnt_lvl = 0; - - bt_tx_rx_cnt = rtl8723ae_dm_bt_tx_rx_couter_h(hw) + - rtl8723ae_dm_bt_tx_rx_couter_l(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt); - - rtlpcipriv->bt_coexist.cstate_h &= - ~(BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1 | - BT_COEX_STATE_BT_CNT_LEVEL_2); - - if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 3\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_3; - } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 2\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_2; - } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 1\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_1; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 0\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_0; - } - return bt_tx_rx_cnt_lvl; -} - -static void rtl8723ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct btdm_8723 btdm8723; - u8 bt_rssi_state, bt_rssi_state1; - u8 bt_tx_rx_cnt_lvl; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.reject_aggre_pkt = false; - - bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "HT20 or Legacy\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 47, 0); - bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, - 27, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - btdm8723.agc_table_en = true; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - } - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || - (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 high\n"); - /* only rssi high we need to do this, - * when rssi low, the value will modified by fw - */ - rtl_write_byte(rtlpriv, 0x883, 0x40); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */ - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, - bt_tx_rx_cnt_lvl); - if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || - (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); - btdm8723.ps_tdma_on = true; - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - - if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); -} - -static void rtl8723ae_dm_bt_2_ant_fta2dp(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct btdm_8723 btdm8723; - u8 bt_rssi_state, bt_rssi_state1; - u32 bt_tx_rx_cnt_lvl; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.reject_aggre_pkt = false; - - bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 37, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "HT20 or Legacy\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 47, 0); - bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, - 27, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - btdm8723.agc_table_en = true; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - } - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || - (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 high\n"); - /* only rssi high we need to do this, - * when rssi low, the value will modified by fw - */ - rtl_write_byte(rtlpriv, 0x883, 0x40); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, - bt_tx_rx_cnt_lvl); - - if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || - (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); - btdm8723.ps_tdma_on = true; - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } - - if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); -} - -static void rtl8723ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - u32 cur_time = jiffies; - - if (rtlhal->hal_coex_8723.c2h_bt_inquiry_page) { - /* bt inquiry or page is started. */ - if (rtlhal->hal_coex_8723.bt_inq_page_start_time == 0) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BT_INQ_PAGE; - rtlhal->hal_coex_8723.bt_inq_page_start_time = cur_time; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page is started at time : 0x%x\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time); - } - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, cur_time); - - if (rtlhal->hal_coex_8723.bt_inq_page_start_time) { - if ((((long)cur_time - - (long)rtlhal->hal_coex_8723.bt_inq_page_start_time) / HZ) >= - 10) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page >= 10sec!!!"); - rtlhal->hal_coex_8723.bt_inq_page_start_time = 0; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_BT_INQ_PAGE; - } - } -} - -static void rtl8723ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtlpcipriv->bt_coexist.cstate &= - ~(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP | - BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO); - - rtlpcipriv->bt_coexist.cstate &= - ~(BT_COEX_STATE_BTINFO_COMMON | - BT_COEX_STATE_BTINFO_B_HID_SCOESCO | - BT_COEX_STATE_BTINFO_B_FTP_A2DP); -} - -static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 bt_retry_cnt; - u8 bt_info_original; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex] Get bt info by fw!!\n"); - - _rtl8723_dm_bt_check_wifi_state(hw); - - if (rtlhal->hal_coex_8723.c2h_bt_info_req_sent) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex] c2h for btInfo not rcvd yet!!\n"); - } - - bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt; - bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original; - - /* when bt inquiry or page scan, we have to set h2c 0x25 - * ignore wlanact for continuous 4x2secs - */ - rtl8723ae_dm_bt_inq_page_monitor(hw); - rtl8723ae_dm_bt_reset_action_profile_state(hw); - - if (rtl8723ae_dm_bt_is_2_ant_common_action(hw)) { - rtlpcipriv->bt_coexist.bt_profile_case = BT_COEX_MECH_COMMON; - rtlpcipriv->bt_coexist.bt_profile_action = BT_COEX_MECH_COMMON; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Action 2-Ant common.\n"); - } else { - if ((bt_info_original & BTINFO_B_HID) || - (bt_info_original & BTINFO_B_SCO_BUSY) || - (bt_info_original & BTINFO_B_SCO_ESCO)) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_HID_SCOESCO; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_HID_SCO_ESCO; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_HID_SCO_ESCO; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n"); - rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); - } else if ((bt_info_original & BTINFO_B_FTP) || - (bt_info_original & BTINFO_B_A2DP)) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_FTP_A2DP; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_FTP_A2DP; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_FTP_A2DP; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "BTInfo: bFTP|bA2DP\n"); - rtl8723ae_dm_bt_2_ant_fta2dp(hw); - } else { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_HID_SCOESCO; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_NONE; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_NONE; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BTInfo: undefined case!!!!\n"); - rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); - } - } -} - -static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3); - rtl8723ae_dm_bt_set_hw_pta_mode(hw, true); -} - -void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, false); - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false, - TDMA_2ANT, TDMA_NAV_OFF); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT, - TDMA_NAV_OFF, TDMA_DAC_SWING_OFF); - rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, 0); - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, 2); - rtl8723ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10); - rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, false); -} - -void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); - rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, false); - - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, BT_TX_RATE_ADAPTIVE_NORMAL); - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME); - rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0); -} - -static void rtl8723ae_dm_bt_query_bt_information(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - u8 h2c_parameter[1] = {0}; - - rtlhal->hal_coex_8723.c2h_bt_info_req_sent = true; - - h2c_parameter[0] |= BIT(0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Query Bt information, write 0x38 = 0x%x\n", - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u32 reg_htx_rx, reg_ltx_rx, u32_tmp; - u32 reg_htx, reg_hrx, reg_ltx, reg_lrx; - - reg_htx_rx = REG_HIGH_PRIORITY_TXRX; - reg_ltx_rx = REG_LOW_PRIORITY_TXRX; - - u32_tmp = rtl_read_dword(rtlpriv, reg_htx_rx); - reg_htx = u32_tmp & MASKLWORD; - reg_hrx = (u32_tmp & MASKHWORD)>>16; - - u32_tmp = rtl_read_dword(rtlpriv, reg_ltx_rx); - reg_ltx = u32_tmp & MASKLWORD; - reg_lrx = (u32_tmp & MASKHWORD)>>16; - - if (rtlpcipriv->bt_coexist.lps_counter > 1) { - reg_htx %= rtlpcipriv->bt_coexist.lps_counter; - reg_hrx %= rtlpcipriv->bt_coexist.lps_counter; - reg_ltx %= rtlpcipriv->bt_coexist.lps_counter; - reg_lrx %= rtlpcipriv->bt_coexist.lps_counter; - } - - rtlhal->hal_coex_8723.high_priority_tx = reg_htx; - rtlhal->hal_coex_8723.high_priority_rx = reg_hrx; - rtlhal->hal_coex_8723.low_priority_tx = reg_ltx; - rtlhal->hal_coex_8723.low_priority_rx = reg_lrx; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", - reg_htx_rx, reg_htx, reg_htx, reg_hrx, reg_hrx); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", - reg_ltx_rx, reg_ltx, reg_ltx, reg_lrx, reg_lrx); - rtlpcipriv->bt_coexist.lps_counter = 0; -} - -static void rtl8723ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - bool bt_alife = true; - - if (rtlhal->hal_coex_8723.high_priority_tx == 0 && - rtlhal->hal_coex_8723.high_priority_rx == 0 && - rtlhal->hal_coex_8723.low_priority_tx == 0 && - rtlhal->hal_coex_8723.low_priority_rx == 0) - bt_alife = false; - if (rtlhal->hal_coex_8723.high_priority_tx == 0xeaea && - rtlhal->hal_coex_8723.high_priority_rx == 0xeaea && - rtlhal->hal_coex_8723.low_priority_tx == 0xeaea && - rtlhal->hal_coex_8723.low_priority_rx == 0xeaea) - bt_alife = false; - if (rtlhal->hal_coex_8723.high_priority_tx == 0xffff && - rtlhal->hal_coex_8723.high_priority_rx == 0xffff && - rtlhal->hal_coex_8723.low_priority_tx == 0xffff && - rtlhal->hal_coex_8723.low_priority_rx == 0xffff) - bt_alife = false; - if (bt_alife) { - rtlpcipriv->bt_coexist.bt_active_zero_cnt = 0; - rtlpcipriv->bt_coexist.cur_bt_disabled = false; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is enabled !!\n"); - } else { - rtlpcipriv->bt_coexist.bt_active_zero_cnt++; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A bt all counters = 0, %d times!!\n", - rtlpcipriv->bt_coexist.bt_active_zero_cnt); - if (rtlpcipriv->bt_coexist.bt_active_zero_cnt >= 2) { - rtlpcipriv->bt_coexist.cur_bt_disabled = true; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is disabled !!\n"); - } - } - if (rtlpcipriv->bt_coexist.pre_bt_disabled != - rtlpcipriv->bt_coexist.cur_bt_disabled) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is from %s to %s!!\n", - (rtlpcipriv->bt_coexist.pre_bt_disabled ? - "disabled" : "enabled"), - (rtlpcipriv->bt_coexist.cur_bt_disabled ? - "disabled" : "enabled")); - rtlpcipriv->bt_coexist.pre_bt_disabled - = rtlpcipriv->bt_coexist.cur_bt_disabled; - } -} - - -void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtl8723ae_dm_bt_query_bt_information(hw); - rtl8723ae_dm_bt_bt_hw_counters_monitor(hw); - rtl8723ae_dm_bt_bt_enable_disable_check(hw); - - if (rtlpcipriv->bt_coexist.bt_ant_num == ANT_X2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], 2 Ant mechanism\n"); - _rtl8723ae_dm_bt_coexist_2_ant(hw); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], 1 Ant mechanism\n"); - _rtl8723ae_dm_bt_coexist_1_ant(hw); - } - - if (!rtl8723ae_dm_bt_is_same_coexist_state(hw)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n", - rtlpcipriv->bt_coexist.previous_state_h, - rtlpcipriv->bt_coexist.previous_state, - rtlpcipriv->bt_coexist.cstate_h, - rtlpcipriv->bt_coexist.cstate); - rtlpcipriv->bt_coexist.previous_state - = rtlpcipriv->bt_coexist.cstate; - rtlpcipriv->bt_coexist.previous_state_h - = rtlpcipriv->bt_coexist.cstate_h; - } -} - -static void rtl8723ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw, - u8 *tmbuf, u8 len) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 bt_info; - u8 i; - - rtlhal->hal_coex_8723.c2h_bt_info_req_sent = false; - rtlhal->hal_coex_8723.bt_retry_cnt = 0; - for (i = 0; i < len; i++) { - if (i == 0) - rtlhal->hal_coex_8723.c2h_bt_info_original = tmbuf[i]; - else if (i == 1) - rtlhal->hal_coex_8723.bt_retry_cnt = tmbuf[i]; - if (i == len-1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "0x%2x]", tmbuf[i]); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "0x%2x, ", tmbuf[i]); - } - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "BT info bt_info (Data)= 0x%x\n", - rtlhal->hal_coex_8723.c2h_bt_info_original); - bt_info = rtlhal->hal_coex_8723.c2h_bt_info_original; - - if (bt_info & BIT(2)) - rtlhal->hal_coex_8723.c2h_bt_inquiry_page = true; - else - rtlhal->hal_coex_8723.c2h_bt_inquiry_page = false; - - if (bt_info & BTINFO_B_CONNECTION) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTC2H], BTInfo: bConnect=true\n"); - rtlpcipriv->bt_coexist.bt_busy = true; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT_IDLE; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTC2H], BTInfo: bConnect=false\n"); - rtlpcipriv->bt_coexist.bt_busy = false; - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT_IDLE; - } -} -void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct c2h_evt_hdr c2h_event; - u8 *ptmbuf; - u8 index; - u8 u1tmp; - - memset(&c2h_event, 0, sizeof(c2h_event)); - u1tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL); - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1tmp); - c2h_event.cmd_id = u1tmp & 0xF; - c2h_event.cmd_len = (u1tmp & 0xF0) >> 4; - c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1); - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n", - c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq); - u1tmp = rtl_read_byte(rtlpriv, 0x01AF); - if (u1tmp == C2H_EVT_HOST_CLOSE) { - return; - } else if (u1tmp != C2H_EVT_FW_CLOSE) { - rtl_write_byte(rtlpriv, 0x1AF, 0x00); - return; - } - ptmbuf = kmalloc(c2h_event.cmd_len, GFP_KERNEL); - if (ptmbuf == NULL) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "malloc cmd buf failed\n"); - return; - } - - /* Read the content */ - for (index = 0; index < c2h_event.cmd_len; index++) - ptmbuf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + - 2 + index); - - switch (c2h_event.cmd_id) { - case C2H_BT_RSSI: - break; - - case C2H_BT_OP_MODE: - break; - - case BT_INFO: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id); - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq); - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[2] (Data)= 0x%x\n", ptmbuf[0]); - - rtl8723ae_dm_bt_parse_bt_info(hw, ptmbuf, c2h_event.cmd_len); - break; - default: - break; - } - kfree(ptmbuf); - - rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h deleted file mode 100644 index 4325ecd58f0c..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_HAL_BTC_H__ -#define __RTL8723E_HAL_BTC_H__ - -#include "../wifi.h" -#include "btc.h" -#include "hal_bt_coexist.h" - -#define BT_TXRX_CNT_THRES_1 1200 -#define BT_TXRX_CNT_THRES_2 1400 -#define BT_TXRX_CNT_THRES_3 3000 -#define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */ -#define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */ -#define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */ -#define BT_TXRX_CNT_LEVEL_3 3 - -/* TDMA mode definition */ -#define TDMA_2ANT 0 -#define TDMA_1ANT 1 -#define TDMA_NAV_OFF 0 -#define TDMA_NAV_ON 1 -#define TDMA_DAC_SWING_OFF 0 -#define TDMA_DAC_SWING_ON 1 - -/* PTA mode related definition */ -#define BT_PTA_MODE_OFF 0 -#define BT_PTA_MODE_ON 1 - -/* Penalty Tx Rate Adaptive */ -#define BT_TX_RATE_ADAPTIVE_NORMAL 0 -#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1 - -/* RF Corner */ -#define BT_RF_RX_LPF_CORNER_RESUME 0 -#define BT_RF_RX_LPF_CORNER_SHRINK 1 - -#define C2H_EVT_HOST_CLOSE 0x00 -#define C2H_EVT_FW_CLOSE 0xFF - -enum bt_traffic_mode { - BT_MOTOR_EXT_BE = 0x00, - BT_MOTOR_EXT_GUL = 0x01, - BT_MOTOR_EXT_GUB = 0x02, - BT_MOTOR_EXT_GULB = 0x03 -}; - -enum bt_traffic_mode_profile { - BT_PROFILE_NONE, - BT_PROFILE_A2DP, - BT_PROFILE_PAN, - BT_PROFILE_HID, - BT_PROFILE_SCO -}; - -enum hci_ext_bt_operation { - HCI_BT_OP_NONE = 0x0, - HCI_BT_OP_INQUIRE_START = 0x1, - HCI_BT_OP_INQUIRE_FINISH = 0x2, - HCI_BT_OP_PAGING_START = 0x3, - HCI_BT_OP_PAGING_SUCCESS = 0x4, - HCI_BT_OP_PAGING_UNSUCCESS = 0x5, - HCI_BT_OP_PAIRING_START = 0x6, - HCI_BT_OP_PAIRING_FINISH = 0x7, - HCI_BT_OP_BT_DEV_ENABLE = 0x8, - HCI_BT_OP_BT_DEV_DISABLE = 0x9, - HCI_BT_OP_MAX, -}; - -enum bt_spec { - BT_SPEC_1_0_b = 0x00, - BT_SPEC_1_1 = 0x01, - BT_SPEC_1_2 = 0x02, - BT_SPEC_2_0_EDR = 0x03, - BT_SPEC_2_1_EDR = 0x04, - BT_SPEC_3_0_HS = 0x05, - BT_SPEC_4_0 = 0x06 -}; - -struct c2h_evt_hdr { - u8 cmd_id; - u8 cmd_len; - u8 cmd_seq; -}; - -enum bt_state { - BT_INFO_STATE_DISABLED = 0, - BT_INFO_STATE_NO_CONNECTION = 1, - BT_INFO_STATE_CONNECT_IDLE = 2, - BT_INFO_STATE_INQ_OR_PAG = 3, - BT_INFO_STATE_ACL_ONLY_BUSY = 4, - BT_INFO_STATE_SCO_ONLY_BUSY = 5, - BT_INFO_STATE_ACL_SCO_BUSY = 6, - BT_INFO_STATE_HID_BUSY = 7, - BT_INFO_STATE_HID_SCO_BUSY = 8, - BT_INFO_STATE_MAX = 7 -}; - -enum rtl8723ae_c2h_evt { - C2H_DBG = 0, - C2H_TSF = 1, - C2H_AP_RPT_RSP = 2, - C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific */ - /* tx packet. */ - C2H_BT_RSSI = 4, - C2H_BT_OP_MODE = 5, - C2H_HW_INFO_EXCH = 10, - C2H_C2H_H2C_TEST = 11, - BT_INFO = 12, - MAX_C2HEVENT -}; - -void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, - struct btdm_8723 *p_btdm); -void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw); -void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, - bool mstatus); -void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c deleted file mode 100644 index 0a8c03863fb2..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c +++ /dev/null @@ -1,2380 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../efuse.h" -#include "../base.h" -#include "../regd.h" -#include "../cam.h" -#include "../ps.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "fw.h" -#include "led.h" -#include "hw.h" -#include "pwrseqcmd.h" -#include "pwrseq.h" -#include "btc.h" - -static void _rtl8723ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw, - u8 set_bits, u8 clear_bits) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpci->reg_bcn_ctrl_val |= set_bits; - rtlpci->reg_bcn_ctrl_val &= ~clear_bits; - - rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); -} - -static void _rtl8723ae_stop_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte &= ~(BIT(0)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl8723ae_resume_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte |= BIT(1); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw) -{ - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1)); -} - -static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw) -{ - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0); -} - -void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - switch (variable) { - case HW_VAR_RCR: - *((u32 *) (val)) = rtlpci->receive_config; - break; - case HW_VAR_RF_STATE: - *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; - break; - case HW_VAR_FWLPS_RF_ON:{ - enum rf_pwrstate rfState; - u32 val_rcr; - - rtlpriv->cfg->ops->get_hw_reg(hw, - HW_VAR_RF_STATE, - (u8 *) (&rfState)); - if (rfState == ERFOFF) { - *((bool *) (val)) = true; - } else { - val_rcr = rtl_read_dword(rtlpriv, REG_RCR); - val_rcr &= 0x00070000; - if (val_rcr) - *((bool *) (val)) = false; - else - *((bool *) (val)) = true; - } - break; } - case HW_VAR_FW_PSMODE_STATUS: - *((bool *) (val)) = ppsc->fw_current_inpsmode; - break; - case HW_VAR_CORRECT_TSF:{ - u64 tsf; - u32 *ptsf_low = (u32 *)&tsf; - u32 *ptsf_high = ((u32 *)&tsf) + 1; - - *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); - *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); - - *((u64 *) (val)) = tsf; - - break; } - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } -} - -void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - u8 idx; - - switch (variable) { - case HW_VAR_ETHER_ADDR: - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_MACID + idx), - val[idx]); - } - break; - case HW_VAR_BASIC_RATE:{ - u16 rate_cfg = ((u16 *) val)[0]; - u8 rate_index = 0; - rate_cfg = rate_cfg & 0x15f; - rate_cfg |= 0x01; - rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); - rtl_write_byte(rtlpriv, REG_RRSR + 1, - (rate_cfg >> 8) & 0xff); - while (rate_cfg > 0x1) { - rate_cfg = (rate_cfg >> 1); - rate_index++; - } - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, - rate_index); - break; } - case HW_VAR_BSSID: - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_BSSID + idx), - val[idx]); - } - break; - case HW_VAR_SIFS: - rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); - rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); - - rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); - rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); - - if (!mac->ht_enable) - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - 0x0e0e); - else - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - *((u16 *) val)); - break; - case HW_VAR_SLOT_TIME:{ - u8 e_aci; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "HW_VAR_SLOT_TIME %x\n", val[0]); - - rtl_write_byte(rtlpriv, REG_SLOT, val[0]); - - for (e_aci = 0; e_aci < AC_MAX; e_aci++) { - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&e_aci)); - } - break; } - case HW_VAR_ACK_PREAMBLE:{ - u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); - reg_tmp = (mac->cur_40_prime_sc) << 5; - if (short_preamble) - reg_tmp |= 0x80; - - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); - break; } - case HW_VAR_AMPDU_MIN_SPACE:{ - u8 min_spacing_to_set; - u8 sec_min_space; - - min_spacing_to_set = *((u8 *) val); - if (min_spacing_to_set <= 7) { - sec_min_space = 0; - - if (min_spacing_to_set < sec_min_space) - min_spacing_to_set = sec_min_space; - - mac->min_space_cfg = ((mac->min_space_cfg & - 0xf8) | - min_spacing_to_set); - - *val = min_spacing_to_set; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - } - break; } - case HW_VAR_SHORTGI_DENSITY:{ - u8 density_to_set; - - density_to_set = *((u8 *) val); - mac->min_space_cfg |= (density_to_set << 3); - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - - break; } - case HW_VAR_AMPDU_FACTOR:{ - u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; - u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; - u8 factor_toset; - u8 *p_regtoset = NULL; - u8 index; - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - p_regtoset = regtoset_bt; - else - p_regtoset = regtoset_normal; - - factor_toset = *((u8 *) val); - if (factor_toset <= 3) { - factor_toset = (1 << (factor_toset + 2)); - if (factor_toset > 0xf) - factor_toset = 0xf; - - for (index = 0; index < 4; index++) { - if ((p_regtoset[index] & 0xf0) > - (factor_toset << 4)) - p_regtoset[index] = - (p_regtoset[index] & 0x0f) | - (factor_toset << 4); - - if ((p_regtoset[index] & 0x0f) > - factor_toset) - p_regtoset[index] = - (p_regtoset[index] & 0xf0) | - (factor_toset); - - rtl_write_byte(rtlpriv, - (REG_AGGLEN_LMT + index), - p_regtoset[index]); - - } - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset); - } - break; } - case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); - rtl8723ae_dm_init_edca_turbo(hw); - - if (rtlpci->acm_method != eAcmWay2_SW) - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_ACM_CTRL, - (u8 *) (&e_aci)); - break; } - case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); - union aci_aifsn *p_aci_aifsn = - (union aci_aifsn *)(&(mac->ac[0].aifs)); - u8 acm = p_aci_aifsn->f.acm; - u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); - - acm_ctrl |= ((rtlpci->acm_method == 2) ? 0x0 : 0x1); - - if (acm) { - switch (e_aci) { - case AC0_BE: - acm_ctrl |= AcmHw_BeqEn; - break; - case AC2_VI: - acm_ctrl |= AcmHw_ViqEn; - break; - case AC3_VO: - acm_ctrl |= AcmHw_VoqEn; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", - acm); - break; - } - } else { - switch (e_aci) { - case AC0_BE: - acm_ctrl &= (~AcmHw_BeqEn); - break; - case AC2_VI: - acm_ctrl &= (~AcmHw_ViqEn); - break; - case AC3_VO: - acm_ctrl &= (~AcmHw_BeqEn); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - } - - RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", - acm_ctrl); - rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); - break; } - case HW_VAR_RCR: - rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); - rtlpci->receive_config = ((u32 *) (val))[0]; - break; - case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; - - rtl_write_word(rtlpriv, REG_RL, - retry_limit << RETRY_LIMIT_SHORT_SHIFT | - retry_limit << RETRY_LIMIT_LONG_SHIFT); - break; } - case HW_VAR_DUAL_TSF_RST: - rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); - break; - case HW_VAR_EFUSE_BYTES: - rtlefuse->efuse_usedbytes = *((u16 *) val); - break; - case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); - break; - case HW_VAR_IO_CMD: - rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); - break; - case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); - break; - case HW_VAR_SET_RPWM:{ - u8 rpwm_val; - - rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); - udelay(1); - - if (rpwm_val & BIT(7)) { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - (*(u8 *) val)); - } else { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - ((*(u8 *) val) | BIT(7))); - } - - break; } - case HW_VAR_H2C_FW_PWRMODE:{ - u8 psmode = (*(u8 *) val); - - if (psmode != FW_PS_ACTIVE_MODE) - rtl8723ae_dm_rf_saving(hw, true); - - rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); - break; } - case HW_VAR_FW_PSMODE_STATUS: - ppsc->fw_current_inpsmode = *((bool *) val); - break; - case HW_VAR_H2C_FW_JOINBSSRPT:{ - u8 mstatus = (*(u8 *) val); - u8 tmp_regcr, tmp_reg422; - bool recover = false; - - if (mstatus == RT_MEDIA_CONNECT) { - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); - - tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr | BIT(0))); - - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); - - tmp_reg422 = rtl_read_byte(rtlpriv, - REG_FWHW_TXQ_CTRL + 2); - if (tmp_reg422 & BIT(6)) - recover = true; - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, - tmp_reg422 & (~BIT(6))); - - rtl8723ae_set_fw_rsvdpagepkt(hw, 0); - - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); - - if (recover) - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, - tmp_reg422); - - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr & ~(BIT(0)))); - } - rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); - - break; } - case HW_VAR_AID:{ - u16 u2btmp; - u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); - u2btmp &= 0xC000; - rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | - mac->assoc_id)); - break; } - case HW_VAR_CORRECT_TSF:{ - u8 btype_ibss = ((u8 *) (val))[0]; - - if (btype_ibss == true) - _rtl8723ae_stop_tx_beacon(hw); - - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); - - rtl_write_dword(rtlpriv, REG_TSFTR, - (u32) (mac->tsf & 0xffffffff)); - rtl_write_dword(rtlpriv, REG_TSFTR + 4, - (u32) ((mac->tsf >> 32) & 0xffffffff)); - - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); - - if (btype_ibss == true) - _rtl8723ae_resume_tx_beacon(hw); - break; } - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } -} - -static bool _rtl8723ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - bool status = true; - long count = 0; - u32 value = _LLT_INIT_ADDR(address) | - _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); - - rtl_write_dword(rtlpriv, REG_LLT_INIT, value); - - do { - value = rtl_read_dword(rtlpriv, REG_LLT_INIT); - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) - break; - - if (count > POLLING_LLT_THRESHOLD) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to polling write LLT done at address %d!\n", - address); - status = false; - break; - } - } while (++count); - - return status; -} - -static bool _rtl8723ae_llt_table_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - unsigned short i; - u8 txpktbuf_bndy; - u8 maxPage; - bool status; - u8 ubyte; - - maxPage = 255; - txpktbuf_bndy = 246; - - rtl_write_byte(rtlpriv, REG_CR, 0x8B); - - rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); - - rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29); - rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03); - - rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); - rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_PBP, 0x11); - rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); - - for (i = 0; i < (txpktbuf_bndy - 1); i++) { - status = _rtl8723ae_llt_write(hw, i, i + 1); - if (true != status) - return status; - } - - status = _rtl8723ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); - if (true != status) - return status; - - for (i = txpktbuf_bndy; i < maxPage; i++) { - status = _rtl8723ae_llt_write(hw, i, (i + 1)); - if (true != status) - return status; - } - - status = _rtl8723ae_llt_write(hw, maxPage, txpktbuf_bndy); - if (true != status) - return status; - - rtl_write_byte(rtlpriv, REG_CR, 0xff); - ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3); - rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7)); - - return true; -} - -static void _rtl8723ae_gen_refresh_led_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - - if (rtlpriv->rtlhal.up_first_time) - return; - - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) - rtl8723ae_sw_led_on(hw, pLed0); - else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) - rtl8723ae_sw_led_on(hw, pLed0); - else - rtl8723ae_sw_led_off(hw, pLed0); -} - -static bool _rtl8712e_init_mac(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - unsigned char bytetmp; - unsigned short wordtmp; - u16 retry = 0; - u16 tmpu2b; - bool mac_func_enable; - - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); - bytetmp = rtl_read_byte(rtlpriv, REG_CR); - if (bytetmp == 0xFF) - mac_func_enable = true; - else - mac_func_enable = false; - - - /* HW Power on sequence */ - if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_ENABLE_FLOW)) - return false; - - bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2); - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4)); - - /* eMAC time out function enable, 0x369[7]=1 */ - bytetmp = rtl_read_byte(rtlpriv, 0x369); - rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7)); - - /* ePHY reg 0x1e bit[4]=1 using MDIO interface, - * we should do this before Enabling ASPM backdoor. - */ - do { - rtl_write_word(rtlpriv, 0x358, 0x5e); - udelay(100); - rtl_write_word(rtlpriv, 0x356, 0xc280); - rtl_write_word(rtlpriv, 0x354, 0xc290); - rtl_write_word(rtlpriv, 0x358, 0x3e); - udelay(100); - rtl_write_word(rtlpriv, 0x358, 0x5e); - udelay(100); - tmpu2b = rtl_read_word(rtlpriv, 0x356); - retry++; - } while (tmpu2b != 0xc290 && retry < 100); - - if (retry >= 100) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "InitMAC(): ePHY configure fail!!!\n"); - return false; - } - - rtl_write_word(rtlpriv, REG_CR, 0x2ff); - rtl_write_word(rtlpriv, REG_CR + 1, 0x06); - - if (!mac_func_enable) { - if (_rtl8723ae_llt_table_init(hw) == false) - return false; - } - - rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); - rtl_write_byte(rtlpriv, REG_HISRE, 0xff); - - rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); - - wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0xf; - wordtmp |= 0xF771; - rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); - - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); - rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); - - rtl_write_byte(rtlpriv, 0x4d0, 0x0); - - rtl_write_dword(rtlpriv, REG_BCNQ_DESA, - ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_MGQ_DESA, - (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VOQ_DESA, - (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VIQ_DESA, - (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BEQ_DESA, - (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BKQ_DESA, - (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_HQ_DESA, - (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_RX_DESA, - (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & - DMA_BIT_MASK(32)); - - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74); - - rtl_write_dword(rtlpriv, REG_INT_MIG, 0); - - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); - do { - retry++; - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - } while ((retry < 200) && (bytetmp & BIT(7))); - - _rtl8723ae_gen_refresh_led_state(hw); - - rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); - - return true; -} - -static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; - - reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); - - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - - rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); - - rtl_write_byte(rtlpriv, REG_SLOT, 0x09); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); - - rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); - - rtl_write_word(rtlpriv, REG_RL, 0x0707); - - rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); - - rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); - - rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); - rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); - else - rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); - - rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); - - rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); - - rtlpci->reg_bcn_ctrl_val = 0x1f; - rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); - rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); - } else { - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - } - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); - else - rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); - - rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); - - rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); - rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); - - rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); - rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); - - rtl_write_dword(rtlpriv, 0x394, 0x1); -} - -static void _rtl8723ae_enable_aspm_back_door(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - rtl_write_byte(rtlpriv, 0x34b, 0x93); - rtl_write_word(rtlpriv, 0x350, 0x870c); - rtl_write_byte(rtlpriv, 0x352, 0x1); - - if (ppsc->support_backdoor) - rtl_write_byte(rtlpriv, 0x349, 0x1b); - else - rtl_write_byte(rtlpriv, 0x349, 0x03); - - rtl_write_word(rtlpriv, 0x350, 0x2718); - rtl_write_byte(rtlpriv, 0x352, 0x1); -} - -void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 sec_reg_value; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm); - - if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "not open hw encryption\n"); - return; - } - - sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; - - if (rtlpriv->sec.use_defaultkey) { - sec_reg_value |= SCR_TxUseDK; - sec_reg_value |= SCR_RxUseDK; - } - - sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); - - rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "The SECR-value %x\n", sec_reg_value); - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); - -} - -int rtl8723ae_hw_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - bool rtstatus = true; - int err; - u8 tmp_u1b; - - rtlpriv->rtlhal.being_init_adapter = true; - rtlpriv->intf_ops->disable_aspm(hw); - rtstatus = _rtl8712e_init_mac(hw); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); - err = 1; - return err; - } - - err = rtl8723ae_download_fw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Failed to download FW. Init HW without FW now..\n"); - err = 1; - rtlhal->fw_ready = false; - return err; - } else { - rtlhal->fw_ready = true; - } - - rtlhal->last_hmeboxnum = 0; - rtl8723ae_phy_mac_config(hw); - /* because the last function modifies RCR, we update - * rcr var here, or TP will be unstable as ther receive_config - * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx - * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 - */ - rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); - rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - - rtl8723ae_phy_bb_config(hw); - rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; - rtl8723ae_phy_rf_config(hw); - if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); - } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); - rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); - rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); - rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); - } - rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - _rtl8723ae_hw_configure(hw); - rtl_cam_reset_all_entry(hw); - rtl8723ae_enable_hw_security_config(hw); - - ppsc->rfpwr_state = ERFON; - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); - _rtl8723ae_enable_aspm_back_door(hw); - rtlpriv->intf_ops->enable_aspm(hw); - - rtl8723ae_bt_hw_init(hw); - - if (ppsc->rfpwr_state == ERFON) { - rtl8723ae_phy_set_rfpath_switch(hw, 1); - if (rtlphy->iqk_initialized) { - rtl8723ae_phy_iq_calibrate(hw, true); - } else { - rtl8723ae_phy_iq_calibrate(hw, false); - rtlphy->iqk_initialized = true; - } - - rtl8723ae_phy_lc_calibrate(hw); - } - - tmp_u1b = efuse_read_1byte(hw, 0x1FA); - if (!(tmp_u1b & BIT(0))) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); - } - - if (!(tmp_u1b & BIT(4))) { - tmp_u1b = rtl_read_byte(rtlpriv, 0x16) & 0x0F; - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); - udelay(10); - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); - } - rtl8723ae_dm_init(hw); - rtlpriv->rtlhal.being_init_adapter = false; - return err; -} - -static enum version_8723e _rtl8723ae_read_chip_version(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - enum version_8723e version = 0x0000; - u32 value32; - - value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); - if (value32 & TRP_VAUX_EN) { - version = (enum version_8723e)(version | - ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); - /* RTL8723 with BT function. */ - version = (enum version_8723e)(version | - ((value32 & BT_FUNC) ? CHIP_8723 : 0)); - - } else { - /* Normal mass production chip. */ - version = (enum version_8723e) NORMAL_CHIP; - version = (enum version_8723e)(version | - ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); - /* RTL8723 with BT function. */ - version = (enum version_8723e)(version | - ((value32 & BT_FUNC) ? CHIP_8723 : 0)); - if (IS_CHIP_VENDOR_UMC(version)) - version = (enum version_8723e)(version | - ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */ - if (IS_8723_SERIES(version)) { - value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); - /* ROM code version */ - version = (enum version_8723e)(version | - ((value32 & RF_RL_ID)>>20)); - } - } - - if (IS_8723_SERIES(version)) { - value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); - rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ? - RT_POLARITY_HIGH_ACT : - RT_POLARITY_LOW_ACT); - } - switch (version) { - case VERSION_TEST_UMC_CHIP_8723: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n"); - break; - case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n"); - break; - case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Chip Version ID: Unknown. Bug?\n"); - break; - } - - if (IS_8723_SERIES(version)) - rtlphy->rf_type = RF_1T1R; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", - (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); - - return version; -} - -static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; - enum led_ctl_mode ledaction = LED_CTL_NO_LINK; - - rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); - RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD, - "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); - - if (type == NL80211_IFTYPE_UNSPECIFIED || - type == NL80211_IFTYPE_STATION) { - _rtl8723ae_stop_tx_beacon(hw); - _rtl8723ae_enable_bcn_sufunc(hw); - } else if (type == NL80211_IFTYPE_ADHOC || - type == NL80211_IFTYPE_AP) { - _rtl8723ae_resume_tx_beacon(hw); - _rtl8723ae_disable_bcn_sufunc(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", - type); - } - - switch (type) { - case NL80211_IFTYPE_UNSPECIFIED: - bt_msr |= MSR_NOLINK; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to NO LINK!\n"); - break; - case NL80211_IFTYPE_ADHOC: - bt_msr |= MSR_ADHOC; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to Ad Hoc!\n"); - break; - case NL80211_IFTYPE_STATION: - bt_msr |= MSR_INFRA; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to STA!\n"); - break; - case NL80211_IFTYPE_AP: - bt_msr |= MSR_AP; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to AP!\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Network type %d not supported!\n", - type); - return 1; - break; - - } - - rtl_write_byte(rtlpriv, (MSR), bt_msr); - rtlpriv->cfg->ops->led_control(hw, ledaction); - if ((bt_msr & 0x03) == MSR_AP) - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); - else - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); - return 0; -} - -void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - u32 reg_rcr = rtlpci->receive_config; - - if (rtlpriv->psc.rfpwr_state != ERFON) - return; - - if (check_bssid == true) { - reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *)(®_rcr)); - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (check_bssid == false) { - reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *) (®_rcr)); - } -} - -int rtl8723ae_set_network_type(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (_rtl8723ae_set_media_status(hw, type)) - return -EOPNOTSUPP; - - if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { - if (type != NL80211_IFTYPE_AP) - rtl8723ae_set_check_bssid(hw, true); - } else { - rtl8723ae_set_check_bssid(hw, false); - } - return 0; -} - -/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ -void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl8723ae_dm_init_edca_turbo(hw); - switch (aci) { - case AC1_BK: - rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); - break; - case AC0_BE: - /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4ac_param); */ - break; - case AC2_VI: - rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); - break; - case AC3_VO: - rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); - break; - default: - RT_ASSERT(false, "invalid aci: %d !\n", aci); - break; - } -} - -void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF); - rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; -} - -void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED); - rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED); - rtlpci->irq_enabled = false; - synchronize_irq(rtlpci->pdev->irq); -} - -static void _rtl8723ae_poweroff_adapter(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 u1tmp; - - /* Combo (PCIe + USB) Card and PCIe-MF Card */ - /* 1. Run LPS WL RFOFF flow */ - rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_LPS_ENTER_FLOW); - - /* 2. 0x1F[7:0] = 0 */ - /* turn off RF */ - rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) - rtl8723ae_firmware_selfreset(hw); - - /* Reset MCU. Suggested by Filen. */ - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1tmp & (~BIT(2)))); - - /* g. MCUFWDL 0x80[1:0]=0 */ - /* reset MCU ready status */ - rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); - - /* HW card disable configuration. */ - rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_DISABLE_FLOW); - - /* Reset MCU IO Wrapper */ - u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); - rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1tmp & (~BIT(0)))); - u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); - rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1tmp | BIT(0)); - - /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ - /* lock ISO/CLK/Power control register */ - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); -} - -void rtl8723ae_card_disable(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - enum nl80211_iftype opmode; - - mac->link_state = MAC80211_NOLINK; - opmode = NL80211_IFTYPE_UNSPECIFIED; - _rtl8723ae_set_media_status(hw, opmode); - if (rtlpci->driver_is_goingto_unload || - ppsc->rfoff_reason > RF_CHANGE_BY_PS) - rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - _rtl8723ae_poweroff_adapter(hw); - - /* after power off we should do iqk again */ - rtlpriv->phy.iqk_initialized = false; -} - -void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, 0x3a0, *p_inta); -} - -void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw) -{ - - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval, atim_window; - - bcn_interval = mac->beacon_interval; - atim_window = 2; /*FIX MERGE */ - rtl8723ae_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); - rtl_write_byte(rtlpriv, 0x606, 0x30); - rtl8723ae_enable_interrupt(hw); -} - -void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval = mac->beacon_interval; - - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - "beacon_interval:%d\n", bcn_interval); - rtl8723ae_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl8723ae_enable_interrupt(hw); -} - -void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); - - if (add_msr) - rtlpci->irq_mask[0] |= add_msr; - if (rm_msr) - rtlpci->irq_mask[0] &= (~rm_msr); - rtl8723ae_disable_interrupt(hw); - rtl8723ae_enable_interrupt(hw); -} - -static u8 _rtl8723ae_get_chnl_group(u8 chnl) -{ - u8 group; - - if (chnl < 3) - group = 0; - else if (chnl < 9) - group = 1; - else - group = 2; - return group; -} - -static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, - bool autoload_fail, - u8 *hwinfo) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 rf_path, index, tempval; - u16 i; - - for (rf_path = 0; rf_path < 1; rf_path++) { - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i] = - hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i] = - hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * - 3 + i]; - } else { - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - } - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; - else - tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = - (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = - ((tempval & 0xf0) >> 4); - } - - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i]); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i]); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eprom_chnl_txpwr_ht40_2sdf - [rf_path][i]); - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - rtlefuse->txpwrlevel_cck[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][index]; - rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index]; - - if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index] - - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path] - [index]) > 0) { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index] - - rtlefuse->eprom_chnl_txpwr_ht40_2sdf - [rf_path][index]; - } else { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; - } - } - - for (i = 0; i < 14; i++) { - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse->eeprom_pwrlimit_ht40[i] = - hwinfo[EEPROM_TXPWR_GROUP + i]; - rtlefuse->eeprom_pwrlimit_ht20[i] = - hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; - } else { - rtlefuse->eeprom_pwrlimit_ht40[i] = 0; - rtlefuse->eeprom_pwrlimit_ht20[i] = 0; - } - } - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - if (rf_path == RF90_PATH_A) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht20[index] & - 0xf); - rtlefuse->pwrgroup_ht40[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht40[index] & - 0xf); - } else if (rf_path == RF90_PATH_B) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht20[index] & - 0xf0) >> 4); - rtlefuse->pwrgroup_ht40[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht40[index] & - 0xf0) >> 4); - } - - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i]); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i]); - } - } - - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; - else - tempval = EEPROM_DEFAULT_HT20_DIFF; - - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; - - index = _rtl8723ae_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; - else - tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; - - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - } - - rtlefuse->legacy_ht_txpowerdiff = - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; - - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); - - if (!autoload_fail) - rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); - else - rtlefuse->eeprom_regulatory = 0; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); - - if (!autoload_fail) - rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; - else - rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B]); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_THERMAL_METER]; - else - tempval = EEPROM_DEFAULT_THERMALMETER; - rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); - - if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) - rtlefuse->apk_thermalmeterignore = true; - - rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); -} - -static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw, - bool pseudo_test) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u16 i, usvalue; - u8 hwinfo[HWSET_MAX_SIZE]; - u16 eeprom_id; - - if (pseudo_test) { - /* need add */ - return; - } - if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { - rtl_efuse_shadow_map_update(hw); - - memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], - HWSET_MAX_SIZE); - } else if (rtlefuse->epromtype == EEPROM_93C46) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "RTL819X Not boot from eeprom, check it !!"); - } - - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), - hwinfo, HWSET_MAX_SIZE); - - eeprom_id = *((u16 *)&hwinfo[0]); - if (eeprom_id != RTL8190_EEPROM_ID) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "EEPROM ID(%#x) is invalid!!\n", eeprom_id); - rtlefuse->autoload_failflag = true; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); - rtlefuse->autoload_failflag = false; - } - - if (rtlefuse->autoload_failflag == true) - return; - - rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID]; - rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID]; - rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID]; - rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROMId = 0x%4x\n", eeprom_id); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); - - for (i = 0; i < 6; i += 2) { - usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; - *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "dev_addr: %pM\n", rtlefuse->dev_addr); - - _rtl8723ae_read_txpower_info_from_hwpg(hw, - rtlefuse->autoload_failflag, hwinfo); - - rtl8723ae_read_bt_coexist_info_from_hwpg(hw, - rtlefuse->autoload_failflag, hwinfo); - - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; - rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; - rtlefuse->txpwr_fromeprom = true; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); - - /* set channel paln to world wide 13 */ - rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; - - if (rtlhal->oem_id == RT_CID_DEFAULT) { - switch (rtlefuse->eeprom_oemid) { - case EEPROM_CID_DEFAULT: - if (rtlefuse->eeprom_did == 0x8176) { - if (CHK_SVID_SMID(0x10EC, 0x6151) || - CHK_SVID_SMID(0x10EC, 0x6152) || - CHK_SVID_SMID(0x10EC, 0x6154) || - CHK_SVID_SMID(0x10EC, 0x6155) || - CHK_SVID_SMID(0x10EC, 0x6177) || - CHK_SVID_SMID(0x10EC, 0x6178) || - CHK_SVID_SMID(0x10EC, 0x6179) || - CHK_SVID_SMID(0x10EC, 0x6180) || - CHK_SVID_SMID(0x10EC, 0x8151) || - CHK_SVID_SMID(0x10EC, 0x8152) || - CHK_SVID_SMID(0x10EC, 0x8154) || - CHK_SVID_SMID(0x10EC, 0x8155) || - CHK_SVID_SMID(0x10EC, 0x8181) || - CHK_SVID_SMID(0x10EC, 0x8182) || - CHK_SVID_SMID(0x10EC, 0x8184) || - CHK_SVID_SMID(0x10EC, 0x8185) || - CHK_SVID_SMID(0x10EC, 0x9151) || - CHK_SVID_SMID(0x10EC, 0x9152) || - CHK_SVID_SMID(0x10EC, 0x9154) || - CHK_SVID_SMID(0x10EC, 0x9155) || - CHK_SVID_SMID(0x10EC, 0x9181) || - CHK_SVID_SMID(0x10EC, 0x9182) || - CHK_SVID_SMID(0x10EC, 0x9184) || - CHK_SVID_SMID(0x10EC, 0x9185)) - rtlhal->oem_id = RT_CID_TOSHIBA; - else if (rtlefuse->eeprom_svid == 0x1025) - rtlhal->oem_id = RT_CID_819x_Acer; - else if (CHK_SVID_SMID(0x10EC, 0x6191) || - CHK_SVID_SMID(0x10EC, 0x6192) || - CHK_SVID_SMID(0x10EC, 0x6193) || - CHK_SVID_SMID(0x10EC, 0x7191) || - CHK_SVID_SMID(0x10EC, 0x7192) || - CHK_SVID_SMID(0x10EC, 0x7193) || - CHK_SVID_SMID(0x10EC, 0x8191) || - CHK_SVID_SMID(0x10EC, 0x8192) || - CHK_SVID_SMID(0x10EC, 0x8193)) - rtlhal->oem_id = RT_CID_819x_SAMSUNG; - else if (CHK_SVID_SMID(0x10EC, 0x8195) || - CHK_SVID_SMID(0x10EC, 0x9195) || - CHK_SVID_SMID(0x10EC, 0x7194) || - CHK_SVID_SMID(0x10EC, 0x8200) || - CHK_SVID_SMID(0x10EC, 0x8201) || - CHK_SVID_SMID(0x10EC, 0x8202) || - CHK_SVID_SMID(0x10EC, 0x9200)) - rtlhal->oem_id = RT_CID_819x_Lenovo; - else if (CHK_SVID_SMID(0x10EC, 0x8197) || - CHK_SVID_SMID(0x10EC, 0x9196)) - rtlhal->oem_id = RT_CID_819x_CLEVO; - else if (CHK_SVID_SMID(0x1028, 0x8194) || - CHK_SVID_SMID(0x1028, 0x8198) || - CHK_SVID_SMID(0x1028, 0x9197) || - CHK_SVID_SMID(0x1028, 0x9198)) - rtlhal->oem_id = RT_CID_819x_DELL; - else if (CHK_SVID_SMID(0x103C, 0x1629)) - rtlhal->oem_id = RT_CID_819x_HP; - else if (CHK_SVID_SMID(0x1A32, 0x2315)) - rtlhal->oem_id = RT_CID_819x_QMI; - else if (CHK_SVID_SMID(0x10EC, 0x8203)) - rtlhal->oem_id = RT_CID_819x_PRONETS; - else if (CHK_SVID_SMID(0x1043, 0x84B5)) - rtlhal->oem_id = - RT_CID_819x_Edimax_ASUS; - else - rtlhal->oem_id = RT_CID_DEFAULT; - } else if (rtlefuse->eeprom_did == 0x8178) { - if (CHK_SVID_SMID(0x10EC, 0x6181) || - CHK_SVID_SMID(0x10EC, 0x6182) || - CHK_SVID_SMID(0x10EC, 0x6184) || - CHK_SVID_SMID(0x10EC, 0x6185) || - CHK_SVID_SMID(0x10EC, 0x7181) || - CHK_SVID_SMID(0x10EC, 0x7182) || - CHK_SVID_SMID(0x10EC, 0x7184) || - CHK_SVID_SMID(0x10EC, 0x7185) || - CHK_SVID_SMID(0x10EC, 0x8181) || - CHK_SVID_SMID(0x10EC, 0x8182) || - CHK_SVID_SMID(0x10EC, 0x8184) || - CHK_SVID_SMID(0x10EC, 0x8185) || - CHK_SVID_SMID(0x10EC, 0x9181) || - CHK_SVID_SMID(0x10EC, 0x9182) || - CHK_SVID_SMID(0x10EC, 0x9184) || - CHK_SVID_SMID(0x10EC, 0x9185)) - rtlhal->oem_id = RT_CID_TOSHIBA; - else if (rtlefuse->eeprom_svid == 0x1025) - rtlhal->oem_id = RT_CID_819x_Acer; - else if (CHK_SVID_SMID(0x10EC, 0x8186)) - rtlhal->oem_id = RT_CID_819x_PRONETS; - else if (CHK_SVID_SMID(0x1043, 0x8486)) - rtlhal->oem_id = - RT_CID_819x_Edimax_ASUS; - else - rtlhal->oem_id = RT_CID_DEFAULT; - } else { - rtlhal->oem_id = RT_CID_DEFAULT; - } - break; - case EEPROM_CID_TOSHIBA: - rtlhal->oem_id = RT_CID_TOSHIBA; - break; - case EEPROM_CID_CCX: - rtlhal->oem_id = RT_CID_CCX; - break; - case EEPROM_CID_QMI: - rtlhal->oem_id = RT_CID_819x_QMI; - break; - case EEPROM_CID_WHQL: - break; - default: - rtlhal->oem_id = RT_CID_DEFAULT; - break; - - } - } -} - -static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - switch (rtlhal->oem_id) { - case RT_CID_819x_HP: - pcipriv->ledctl.led_opendrain = true; - break; - case RT_CID_819x_Lenovo: - case RT_CID_DEFAULT: - case RT_CID_TOSHIBA: - case RT_CID_CCX: - case RT_CID_819x_Acer: - case RT_CID_WHQL: - default: - break; - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "RT Customized ID: 0x%02X\n", rtlhal->oem_id); -} - -void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_u1b; - u32 value32; - - value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]); - value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); - rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32); - - rtlhal->version = _rtl8723ae_read_chip_version(hw); - - if (get_rf_type(rtlphy) == RF_1T1R) - rtlpriv->dm.rfpath_rxenable[0] = true; - else - rtlpriv->dm.rfpath_rxenable[0] = - rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", - rtlhal->version); - - tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); - if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); - rtlefuse->epromtype = EEPROM_93C46; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); - rtlefuse->epromtype = EEPROM_BOOT_EFUSE; - } - if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); - rtlefuse->autoload_failflag = false; - _rtl8723ae_read_adapter_info(hw, false); - } else { - rtlefuse->autoload_failflag = true; - _rtl8723ae_read_adapter_info(hw, false); - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); - } - _rtl8723ae_hal_customized_behavior(hw); -} - -static void rtl8723ae_update_hal_rate_table(struct ieee80211_hw *hw, - struct ieee80211_sta *sta) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 ratr_value; - u8 ratr_index = 0; - u8 nmode = mac->ht_enable; - u8 mimo_ps = IEEE80211_SMPS_OFF; - u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? - 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? - 1 : 0; - enum wireless_mode wirelessmode = mac->mode; - - if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; - else - ratr_value = sta->supp_rates[0]; - if (mac->opmode == NL80211_IFTYPE_ADHOC) - ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); - switch (wirelessmode) { - case WIRELESS_MODE_B: - if (ratr_value & 0x0000000c) - ratr_value &= 0x0000000d; - else - ratr_value &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_value &= 0x00000FF5; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - nmode = 1; - if (mimo_ps == IEEE80211_SMPS_STATIC) { - ratr_value &= 0x0007F005; - } else { - u32 ratr_mask; - - if (get_rf_type(rtlphy) == RF_1T2R || - get_rf_type(rtlphy) == RF_1T1R) - ratr_mask = 0x000ff005; - else - ratr_mask = 0x0f0ff005; - - ratr_value &= ratr_mask; - } - break; - default: - if (rtlphy->rf_type == RF_1T2R) - ratr_value &= 0x000ff0ff; - else - ratr_value &= 0x0f0ff0ff; - - break; - } - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) && - (pcipriv->bt_coexist.bt_cur_state) && - (pcipriv->bt_coexist.bt_ant_isolation) && - ((pcipriv->bt_coexist.bt_service == BT_SCO) || - (pcipriv->bt_coexist.bt_service == BT_BUSY))) - ratr_value &= 0x0fffcfc0; - else - ratr_value &= 0x0FFFFFFF; - - if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || - (!curtxbw_40mhz && curshortgi_20mhz))) - ratr_value |= 0x10000000; - - rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); -} - -static void rtl8723ae_update_hal_rate_mask(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_sta_info *sta_entry = NULL; - u32 ratr_bitmap; - u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) - ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? - 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? - 1 : 0; - enum wireless_mode wirelessmode = 0; - bool shortgi = false; - u8 rate_mask[5]; - u8 macid = 0; - u8 mimo_ps = IEEE80211_SMPS_OFF; - - sta_entry = (struct rtl_sta_info *) sta->drv_priv; - wirelessmode = sta_entry->wireless_mode; - if (mac->opmode == NL80211_IFTYPE_STATION) - curtxbw_40mhz = mac->bw_40; - else if (mac->opmode == NL80211_IFTYPE_AP || - mac->opmode == NL80211_IFTYPE_ADHOC) - macid = sta->aid + 1; - - if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; - else - ratr_bitmap = sta->supp_rates[0]; - if (mac->opmode == NL80211_IFTYPE_ADHOC) - ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); - switch (wirelessmode) { - case WIRELESS_MODE_B: - ratr_index = RATR_INX_WIRELESS_B; - if (ratr_bitmap & 0x0000000c) - ratr_bitmap &= 0x0000000d; - else - ratr_bitmap &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_index = RATR_INX_WIRELESS_GB; - - if (rssi_level == 1) - ratr_bitmap &= 0x00000f00; - else if (rssi_level == 2) - ratr_bitmap &= 0x00000ff0; - else - ratr_bitmap &= 0x00000ff5; - break; - case WIRELESS_MODE_A: - ratr_index = RATR_INX_WIRELESS_A; - ratr_bitmap &= 0x00000ff0; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (mimo_ps == IEEE80211_SMPS_STATIC) { - if (rssi_level == 1) - ratr_bitmap &= 0x00070000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0007f000; - else - ratr_bitmap &= 0x0007f005; - } else { - if (rtlphy->rf_type == RF_1T2R || - rtlphy->rf_type == RF_1T1R) { - if (curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff005; - } - } else { - if (curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff005; - } - } - } - - if ((curtxbw_40mhz && curshortgi_40mhz) || - (!curtxbw_40mhz && curshortgi_20mhz)) { - if (macid == 0) - shortgi = true; - else if (macid == 1) - shortgi = false; - } - break; - default: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (rtlphy->rf_type == RF_1T2R) - ratr_bitmap &= 0x000ff0ff; - else - ratr_bitmap &= 0x0f0ff0ff; - break; - } - sta_entry->ratr_index = ratr_index; - - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "ratr_bitmap :%x\n", ratr_bitmap); - /* convert ratr_bitmap to le byte array */ - rate_mask[0] = ratr_bitmap; - rate_mask[1] = (ratr_bitmap >>= 8); - rate_mask[2] = (ratr_bitmap >>= 8); - rate_mask[3] = ((ratr_bitmap >> 8) & 0x0f) | (ratr_index << 4); - rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "Rate_index:%x, ratr_bitmap: %*phC\n", - ratr_index, 5, rate_mask); - rtl8723ae_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); -} - -void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->dm.useramask) - rtl8723ae_update_hal_rate_mask(hw, sta, rssi_level); - else - rtl8723ae_update_hal_rate_table(hw, sta); -} - -void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 sifs_timer; - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); - if (!mac->ht_enable) - sifs_timer = 0x0a0a; - else - sifs_timer = 0x1010; - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); -} - -bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; - u8 u1tmp; - bool actuallyset = false; - - if (rtlpriv->rtlhal.being_init_adapter) - return false; - - if (ppsc->swrf_processing) - return false; - - spin_lock(&rtlpriv->locks.rf_ps_lock); - if (ppsc->rfchange_inprogress) { - spin_unlock(&rtlpriv->locks.rf_ps_lock); - return false; - } else { - ppsc->rfchange_inprogress = true; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } - - cur_rfstate = ppsc->rfpwr_state; - - rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, - rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1))); - - u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); - - if (rtlphy->polarity_ctl) - e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; - else - e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; - - if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "GPIOChangeRF - HW Radio ON, RF ON\n"); - - e_rfpowerstate_toset = ERFON; - ppsc->hwradiooff = false; - actuallyset = true; - } else if ((ppsc->hwradiooff == false) - && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "GPIOChangeRF - HW Radio OFF, RF OFF\n"); - - e_rfpowerstate_toset = ERFOFF; - ppsc->hwradiooff = true; - actuallyset = true; - } - - if (actuallyset) { - spin_lock(&rtlpriv->locks.rf_ps_lock); - ppsc->rfchange_inprogress = false; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } else { - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - - spin_lock(&rtlpriv->locks.rf_ps_lock); - ppsc->rfchange_inprogress = false; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } - - *valid = 1; - return !ppsc->hwradiooff; -} - -void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 *macaddr = p_macaddr; - u32 entry_id = 0; - bool is_pairwise = false; - static u8 cam_const_addr[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} - }; - static u8 cam_const_broad[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - if (clear_all) { - u8 idx = 0; - u8 cam_offset = 0; - u8 clear_number = 5; - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); - - for (idx = 0; idx < clear_number; idx++) { - rtl_cam_mark_invalid(hw, cam_offset + idx); - rtl_cam_empty_entry(hw, cam_offset + idx); - - if (idx < 5) { - memset(rtlpriv->sec.key_buf[idx], 0, - MAX_KEY_LEN); - rtlpriv->sec.key_len[idx] = 0; - } - } - } else { - switch (enc_algo) { - case WEP40_ENCRYPTION: - enc_algo = CAM_WEP40; - break; - case WEP104_ENCRYPTION: - enc_algo = CAM_WEP104; - break; - case TKIP_ENCRYPTION: - enc_algo = CAM_TKIP; - break; - case AESCCMP_ENCRYPTION: - enc_algo = CAM_AES; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - enc_algo = CAM_TKIP; - break; - } - - if (is_wepkey || rtlpriv->sec.use_defaultkey) { - macaddr = cam_const_addr[key_index]; - entry_id = key_index; - } else { - if (is_group) { - macaddr = cam_const_broad; - entry_id = key_index; - } else { - if (mac->opmode == NL80211_IFTYPE_AP) { - entry_id = rtl_cam_get_free_entry(hw, - macaddr); - if (entry_id >= TOTAL_CAM_ENTRY) { - RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, - "Can not find free hw security cam entry\n"); - return; - } - } else { - entry_id = CAM_PAIRWISE_KEY_POSITION; - } - - key_index = PAIRWISE_KEYIDX; - is_pairwise = true; - } - } - - if (rtlpriv->sec.key_len[key_index] == 0) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "delete one entry, entry_id is %d\n", - entry_id); - if (mac->opmode == NL80211_IFTYPE_AP) - rtl_cam_del_entry(hw, p_macaddr); - rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "add one entry\n"); - if (is_pairwise) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set Pairwiase key\n"); - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf[key_index]); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set group key\n"); - - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - rtl_cam_add_one_entry(hw, - rtlefuse->dev_addr, - PAIRWISE_KEYIDX, - CAM_PAIRWISE_KEY_POSITION, - enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf - [entry_id]); - } - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf[entry_id]); - } - - } - } -} - -static void rtl8723ae_bt_var_init(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - pcipriv->bt_coexist.bt_coexistence = - pcipriv->bt_coexist.eeprom_bt_coexist; - pcipriv->bt_coexist.bt_ant_num = - pcipriv->bt_coexist.eeprom_bt_ant_num; - pcipriv->bt_coexist.bt_coexist_type = - pcipriv->bt_coexist.eeprom_bt_type; - - pcipriv->bt_coexist.bt_ant_isolation = - pcipriv->bt_coexist.eeprom_bt_ant_isol; - - pcipriv->bt_coexist.bt_radio_shared_type = - pcipriv->bt_coexist.eeprom_bt_radio_shared; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BT Coexistance = 0x%x\n", - pcipriv->bt_coexist.bt_coexistence); - - if (pcipriv->bt_coexist.bt_coexistence) { - pcipriv->bt_coexist.bt_busy_traffic = false; - pcipriv->bt_coexist.bt_traffic_mode_set = false; - pcipriv->bt_coexist.bt_non_traffic_mode_set = false; - - pcipriv->bt_coexist.cstate = 0; - pcipriv->bt_coexist.previous_state = 0; - - if (pcipriv->bt_coexist.bt_ant_num == ANT_X2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_Num = Antx2\n"); - } else if (pcipriv->bt_coexist.bt_ant_num == ANT_X1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_Num = Antx1\n"); - } - - switch (pcipriv->bt_coexist.bt_coexist_type) { - case BT_2WIRE: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_2Wire\n"); - break; - case BT_ISSC_3WIRE: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); - break; - case BT_ACCEL: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_ACCEL\n"); - break; - case BT_CSR_BC4: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_CSR_BC4\n"); - break; - case BT_CSR_BC8: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_CSR_BC8\n"); - break; - case BT_RTL8756: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_RTL8756\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = Unknown\n"); - break; - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_isolation = %d\n", - pcipriv->bt_coexist.bt_ant_isolation); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BT_RadioSharedType = 0x%x\n", - pcipriv->bt_coexist.bt_radio_shared_type); - pcipriv->bt_coexist.bt_active_zero_cnt = 0; - pcipriv->bt_coexist.cur_bt_disabled = false; - pcipriv->bt_coexist.pre_bt_disabled = false; - } -} - -void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, - bool auto_load_fail, u8 *hwinfo) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value; - u32 tmpu_32; - - if (!auto_load_fail) { - tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); - if (tmpu_32 & BIT(18)) - pcipriv->bt_coexist.eeprom_bt_coexist = 1; - else - pcipriv->bt_coexist.eeprom_bt_coexist = 0; - value = hwinfo[RF_OPTION4]; - pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; - pcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); - pcipriv->bt_coexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4); - pcipriv->bt_coexist.eeprom_bt_radio_shared = - ((value & 0x20) >> 5); - } else { - pcipriv->bt_coexist.eeprom_bt_coexist = 0; - pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; - pcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; - pcipriv->bt_coexist.eeprom_bt_ant_isol = 0; - pcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; - } - - rtl8723ae_bt_var_init(hw); -} - -void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - - /* 0:Low, 1:High, 2:From Efuse. */ - pcipriv->bt_coexist.reg_bt_iso = 2; - /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ - pcipriv->bt_coexist.reg_bt_sco = 3; - /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ - pcipriv->bt_coexist.reg_bt_sco = 0; -} - - -void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_suspend(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_resume(struct ieee80211_hw *hw) -{ -} - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, - bool allow_all_da, bool write_into_reg) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - if (allow_all_da) /* Set BIT0 */ - rtlpci->receive_config |= RCR_AAP; - else /* Clear BIT0 */ - rtlpci->receive_config &= ~RCR_AAP; - - if (write_into_reg) - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - - - RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, - "receive_config=0x%08X, write_into_reg=%d\n", - rtlpci->receive_config, write_into_reg); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h deleted file mode 100644 index 6fa24f79b1d7..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_HW_H__ -#define __RTL8723E_HW_H__ - -#define CHK_SVID_SMID(_val1, _val2) \ - ((rtlefuse->eeprom_svid == (_val1)) && \ - (rtlefuse->eeprom_smid == (_val2))) - -void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw); - -void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); -int rtl8723ae_hw_init(struct ieee80211_hw *hw); -void rtl8723ae_card_disable(struct ieee80211_hw *hw); -void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw); -void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw); -int rtl8723ae_set_network_type(struct ieee80211_hw *hw, - enum nl80211_iftype type); -void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); -void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci); -void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw); -void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw); -void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr); -void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level); -void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw); -bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); -void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw); -void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all); - -void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, - bool autoload_fail, u8 *hwinfo); -void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw); -void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw); -void rtl8723ae_suspend(struct ieee80211_hw *hw); -void rtl8723ae_resume(struct ieee80211_hw *hw); -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, - bool allow_all_da, bool write_into_reg); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c deleted file mode 100644 index 9c4e1d811187..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "reg.h" -#include "led.h" - -static void _rtl8723ae_init_led(struct ieee80211_hw *hw, - struct rtl_led *pled, enum rtl_led_pin ledpin) -{ - pled->hw = hw; - pled->ledpin = ledpin; - pled->ledon = false; -} - -void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 ledcfg; - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - rtl_write_byte(rtlpriv, - REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); - break; - case LED_PIN_LED1: - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - pled->ledon = true; -} - -void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - u8 ledcfg; - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain) - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(1) | BIT(5) | BIT(6))); - else - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(3) | BIT(5) | BIT(6))); - break; - case LED_PIN_LED1: - ledcfg &= 0x0f; - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - pled->ledon = false; -} - -void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - - _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); - _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); -} - -static void _rtl8723ae_sw_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - - switch (ledaction) { - case LED_CTL_POWER_ON: - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - rtl8723ae_sw_led_on(hw, pLed0); - break; - case LED_CTL_POWER_OFF: - rtl8723ae_sw_led_off(hw, pLed0); - break; - default: - break; - } -} - -void rtl8723ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && - (ledaction == LED_CTL_TX || - ledaction == LED_CTL_RX || - ledaction == LED_CTL_SITE_SURVEY || - ledaction == LED_CTL_LINK || - ledaction == LED_CTL_NO_LINK || - ledaction == LED_CTL_START_TO_LINK || - ledaction == LED_CTL_POWER_ON)) { - return; - } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); - _rtl8723ae_sw_led_control(hw, ledaction); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h deleted file mode 100644 index 2cb88e78f62a..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_LED_H__ -#define __RTL92CE_LED_H__ - -void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw); -void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl8723ae_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c deleted file mode 100644 index 39cc7938eedf..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +++ /dev/null @@ -1,2044 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../ps.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "rf.h" -#include "dm.h" -#include "table.h" - -/* static forward definitions */ -static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 offset, u32 data); -static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data); -static u32 _phy_calculate_bit_shift(u32 bitmask); -static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw); -static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw); -static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype); -static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); -static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); -static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, - u32 para1, u32 para2, - u32 msdelay); -static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, - u8 *stage, u8 *step, u32 *delay); -static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); -static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, u8 txpwridx); -static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); - -u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, - u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 returnvalue, originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, regaddr, - originalvalue); - - return returnvalue; -} - -void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, - bitmask, data); - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - - rtl_write_dword(rtlpriv, regaddr, data); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data); -} - -u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 original_value, readback_value, bitshift; - struct rtl_phy *rtlphy = &(rtlpriv->phy); - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) - original_value = _phy_rf_serial_read(hw, rfpath, regaddr); - else - original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr); - - bitshift = _phy_calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value); - - return readback_value; -} - -void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 original_value, bitshift; - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _phy_rf_serial_read(hw, rfpath, - regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | - (data << bitshift)); - } - - _phy_rf_serial_write(hw, rfpath, regaddr, data); - } else { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _phy_fw_rf_serial_read(hw, rfpath, - regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | - (data << bitshift)); - } - _phy_fw_rf_serial_write(hw, rfpath, regaddr, data); - } - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); -} - -static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - RT_ASSERT(false, "deprecated!\n"); - return 0; -} - -static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 offset, u32 data) -{ - RT_ASSERT(false, "deprecated!\n"); -} - -static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - u32 newoffset; - u32 tmplong, tmplong2; - u8 rfpi_enable = 0; - u32 retvalue; - - offset &= 0x3f; - newoffset = offset; - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); - return 0xFFFFFFFF; - } - tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); - if (rfpath == RF90_PATH_A) - tmplong2 = tmplong; - else - tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); - tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | - (newoffset << 23) | BLSSIREADEDGE; - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong & (~BLSSIREADEDGE)); - mdelay(1); - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); - mdelay(1); - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong | BLSSIREADEDGE); - mdelay(1); - if (rfpath == RF90_PATH_A) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - else if (rfpath == RF90_PATH_B) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, - BIT(8)); - if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, - BLSSIREADBACKDATA); - else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, - BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); - return retvalue; -} - -static void _phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data) -{ - u32 data_and_addr; - u32 newoffset; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); - return; - } - offset &= 0x3f; - newoffset = offset; - data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; - rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr); -} - -static u32 _phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - -static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); - rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); - rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); - rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); -} - -bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - bool rtstatus = _phy_cfg_mac_w_header(hw); - rtl_write_byte(rtlpriv, 0x04CA, 0x0A); - return rtstatus; -} - -bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw) -{ - bool rtstatus = true; - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmpu1b; - u8 reg_hwparafile = 1; - - _phy_init_bb_rf_reg_def(hw); - - /* 1. 0x28[1] = 1 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); - udelay(2); - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1))); - udelay(2); - /* 2. 0x29[7:0] = 0xFF */ - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff); - udelay(2); - - /* 3. 0x02[1:0] = 2b'11 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b | - FEN_BB_GLB_RSTn | FEN_BBRSTB)); - - /* 4. 0x25[6] = 0 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6)))); - - /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4)))); - - /* 6. 0x1f[7:0] = 0x07 */ - rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07); - - if (reg_hwparafile == 1) - rtstatus = _phy_bb8192c_config_parafile(hw); - return rtstatus; -} - -bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw) -{ - return rtl8723ae_phy_rf6052_config(hw); -} - -static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - bool rtstatus; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); - rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); - return false; - } - - if (rtlphy->rf_type == RF_1T2R) { - _rtl8723ae_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); - } - if (rtlefuse->autoload_failflag == false) { - rtlphy->pwrgroup_cnt = 0; - rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG); - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); - return false; - } - rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); - return false; - } - rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, 0x200)); - return true; -} - -static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - u32 arraylength; - u32 *ptrarray; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n"); - arraylength = RTL8723E_MACARRAYLENGTH; - ptrarray = RTL8723EMAC_ARRAY; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Img:RTL8192CEMAC_2T_ARRAY\n"); - for (i = 0; i < arraylength; i = i + 2) - rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); - return true; -} - -static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype) -{ - int i; - u32 *phy_regarray_table; - u32 *agctab_array_table; - u16 phy_reg_arraylen, agctab_arraylen; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH; - agctab_array_table = RTL8723EAGCTAB_1TARRAY; - phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH; - phy_regarray_table = RTL8723EPHY_REG_1TARRAY; - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_reg_arraylen; i = i + 2) { - if (phy_regarray_table[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table[i] == 0xfb) - udelay(50); - else if (phy_regarray_table[i] == 0xfa) - udelay(5); - else if (phy_regarray_table[i] == 0xf9) - udelay(1); - rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, - phy_regarray_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1]); - } - } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { - for (i = 0; i < agctab_arraylen; i = i + 2) { - rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, - agctab_array_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1]); - } - } - return true; -} - -static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr, - u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - switch (regaddr) { - case RTXAGC_A_RATE18_06: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]); - break; - case RTXAGC_A_RATE54_24: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]); - break; - case RTXAGC_A_CCK1_MCS32: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]); - break; - case RTXAGC_B_CCK11_A_CCK2_11: - if (bitmask == 0xffffff00) { - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]); - } - if (bitmask == 0x000000ff) { - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]); - } - break; - case RTXAGC_A_MCS03_MCS00: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]); - break; - case RTXAGC_A_MCS07_MCS04: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]); - break; - case RTXAGC_A_MCS11_MCS08: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]); - break; - case RTXAGC_A_MCS15_MCS12: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]); - break; - case RTXAGC_B_RATE18_06: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]); - break; - case RTXAGC_B_RATE54_24: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]); - break; - case RTXAGC_B_CCK1_55_MCS32: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]); - break; - case RTXAGC_B_MCS03_MCS00: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]); - break; - case RTXAGC_B_MCS07_MCS04: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]); - break; - case RTXAGC_B_MCS11_MCS08: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]); - break; - case RTXAGC_B_MCS15_MCS12: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]); - rtlphy->pwrgroup_cnt++; - break; - } -} - -static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int i; - u32 *phy_regarray_table_pg; - u16 phy_regarray_pg_len; - - phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH; - phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG; - - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_regarray_pg_len; i = i + 3) { - if (phy_regarray_table_pg[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table_pg[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table_pg[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table_pg[i] == 0xfb) - udelay(50); - else if (phy_regarray_table_pg[i] == 0xfa) - udelay(5); - else if (phy_regarray_table_pg[i] == 0xf9) - udelay(1); - - _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i], - phy_regarray_table_pg[i + 1], - phy_regarray_table_pg[i + 2]); - } - } else { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "configtype != BaseBand_Config_PHY_REG\n"); - } - return true; -} - -bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int i; - bool rtstatus = true; - u32 *radioa_array_table; - u32 *radiob_array_table; - u16 radioa_arraylen, radiob_arraylen; - - radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH; - radioa_array_table = RTL8723E_RADIOA_1TARRAY; - radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH; - radiob_array_table = RTL8723E_RADIOB_1TARRAY; - - rtstatus = true; - - switch (rfpath) { - case RF90_PATH_A: - for (i = 0; i < radioa_arraylen; i = i + 2) { - if (radioa_array_table[i] == 0xfe) - mdelay(50); - else if (radioa_array_table[i] == 0xfd) - mdelay(5); - else if (radioa_array_table[i] == 0xfc) - mdelay(1); - else if (radioa_array_table[i] == 0xfb) - udelay(50); - else if (radioa_array_table[i] == 0xfa) - udelay(5); - else if (radioa_array_table[i] == 0xf9) - udelay(1); - else { - rtl_set_rfreg(hw, rfpath, radioa_array_table[i], - RFREG_OFFSET_MASK, - radioa_array_table[i + 1]); - udelay(1); - } - } - break; - case RF90_PATH_B: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - case RF90_PATH_C: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - case RF90_PATH_D: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - return true; -} - -void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->default_initialgain[0] = - (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[1] = - (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[2] = - (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[3] = - (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3]); - - rtlphy->framesync = (u8) rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR3, MASKBYTE0); - rtlphy->framesync_c34 = rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR2, MASKDWORD); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync); -} - -static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = - RFPGA0_XA_LSSIPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = - RFPGA0_XB_LSSIPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; - - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; -} - -void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 txpwr_level; - long txpwr_dbm; - - txpwr_level = rtlphy->cur_cck_txpwridx; - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx + - rtlefuse->legacy_ht_txpowerdiff; - if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, - txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx; - if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) > - txpwr_dbm) - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, - txpwr_level); - *powerlevel = txpwr_dbm; -} - -static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel, - u8 *cckpowerlevel, u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 index = (channel - 1); - - cckpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; - cckpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; - if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; - } else if (get_rf_type(rtlphy) == RF_2T2R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; - } -} - -static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw, - u8 channel, u8 *cckpowerlevel, - u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; - rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; -} - -void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 cckpowerlevel[2], ofdmpowerlevel[2]; - - if (rtlefuse->txpwr_fromeprom == false) - return; - _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); - rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); -} - -bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 idx; - u8 rf_path; - u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B, - power_indbm); - u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G, - power_indbm); - if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) - ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; - else - ofdmtxpwridx = 0; - RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx); - for (idx = 0; idx < 14; idx++) { - for (rf_path = 0; rf_path < 2; rf_path++) { - rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; - rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = - ofdmtxpwridx; - rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = - ofdmtxpwridx; - } - } - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - return true; -} - -static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm) -{ - u8 txpwridx; - long offset; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - - if ((power_indbm - offset) > 0) - txpwridx = (u8) ((power_indbm - offset) * 2); - else - txpwridx = 0; - - if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) - txpwridx = MAX_TXPWR_IDX_NMODE_92S; - - return txpwridx; -} - -static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, u8 txpwridx) -{ - long offset; - long pwrout_dbm; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - pwrout_dbm = txpwridx / 2 + offset; - return pwrout_dbm; -} - -void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - enum io_type iotype; - - if (!is_hal_stop(rtlhal)) { - switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - - break; - case SCAN_OPT_RESTORE: - iotype = IO_CMD_RESUME_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Unknown Scan Backup operation.\n"); - break; - } - } -} - -void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u8 reg_bw_opmode; - u8 reg_prsr_rsc; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - "Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz"); - - if (is_hal_stop(rtlhal)) { - rtlphy->set_bwmode_inprogress = false; - return; - } - - reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); - reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - reg_bw_opmode |= BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - break; - case HT_CHANNEL_WIDTH_20_40: - reg_bw_opmode &= ~BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - reg_prsr_rsc = - (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); - break; - } - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - break; - case HT_CHANNEL_WIDTH_20_40: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); - - rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, - (mac->cur_40_prime_sc >> 1)); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); - - rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), - (mac->cur_40_prime_sc == - HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); - break; - } - rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); - rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); -} - -void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_bw = rtlphy->current_chan_bw; - - if (rtlphy->set_bwmode_inprogress) - return; - rtlphy->set_bwmode_inprogress = true; - if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl8723ae_phy_set_bw_mode_callback(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "FALSE driver sleep or unload\n"); - rtlphy->set_bwmode_inprogress = false; - rtlphy->current_chan_bw = tmp_bw; - } -} - -void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 delay; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - "switch to channel%d\n", rtlphy->current_channel); - if (is_hal_stop(rtlhal)) - return; - do { - if (!rtlphy->sw_chnl_inprogress) - break; - if (!_phy_sw_chnl_step_by_step - (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, - &rtlphy->sw_chnl_step, &delay)) { - if (delay > 0) - mdelay(delay); - else - continue; - } else { - rtlphy->sw_chnl_inprogress = false; - } - break; - } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); -} - -u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->sw_chnl_inprogress) - return 0; - if (rtlphy->set_bwmode_inprogress) - return 0; - RT_ASSERT((rtlphy->current_channel <= 14), - "WIRELESS_MODE_G but channel>14"); - rtlphy->sw_chnl_inprogress = true; - rtlphy->sw_chnl_stage = 0; - rtlphy->sw_chnl_step = 0; - if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl8723ae_phy_sw_chnl_callback(hw); - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false schdule workitem\n"); - rtlphy->sw_chnl_inprogress = false; - } else { - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false driver sleep or unload\n"); - rtlphy->sw_chnl_inprogress = false; - } - return 1; -} - -static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - if (channel == 6 && rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - 0x00255); - else{ - u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, - RF_RX_G1, RFREG_OFFSET_MASK); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - backupRF0x1A); - } - } -} - -static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, - u8 *stage, u8 *step, u32 *delay) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; - u32 precommoncmdcnt; - struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; - u32 postcommoncmdcnt; - struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; - u32 rfdependcmdcnt; - struct swchnlcmd *currentcmd = NULL; - u8 rfpath; - u8 num_total_rfpath = rtlphy->num_total_rfpath; - - precommoncmdcnt = 0; - _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, - 0, 0, 0); - _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); - postcommoncmdcnt = 0; - - _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, - MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); - rfdependcmdcnt = 0; - - RT_ASSERT((channel >= 1 && channel <= 14), - "illegal channel for Zebra: %d\n", channel); - - _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, - RF_CHNLBW, channel, 10); - - _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); - - do { - switch (*stage) { - case 0: - currentcmd = &precommoncmd[*step]; - break; - case 1: - currentcmd = &rfdependcmd[*step]; - break; - case 2: - currentcmd = &postcommoncmd[*step]; - break; - } - - if (currentcmd->cmdid == CMDID_END) { - if ((*stage) == 2) { - return true; - } else { - (*stage)++; - (*step) = 0; - continue; - } - } - - switch (currentcmd->cmdid) { - case CMDID_SET_TXPOWEROWER_LEVEL: - rtl8723ae_phy_set_txpower_level(hw, channel); - break; - case CMDID_WRITEPORT_ULONG: - rtl_write_dword(rtlpriv, currentcmd->para1, - currentcmd->para2); - break; - case CMDID_WRITEPORT_USHORT: - rtl_write_word(rtlpriv, currentcmd->para1, - (u16) currentcmd->para2); - break; - case CMDID_WRITEPORT_UCHAR: - rtl_write_byte(rtlpriv, currentcmd->para1, - (u8) currentcmd->para2); - break; - case CMDID_RF_WRITEREG: - for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { - rtlphy->rfreg_chnlval[rfpath] = - ((rtlphy->rfreg_chnlval[rfpath] & - 0xfffffc00) | currentcmd->para2); - - rtl_set_rfreg(hw, (enum radio_path)rfpath, - currentcmd->para1, - RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[rfpath]); - } - _rtl8723ae_phy_sw_rf_seting(hw, channel); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - - break; - } while (true); - - (*delay) = currentcmd->msdelay; - (*step)++; - return false; -} - -static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, u32 para1, - u32 para2, u32 msdelay) -{ - struct swchnlcmd *pcmd; - - if (cmdtable == NULL) { - RT_ASSERT(false, "cmdtable cannot be NULL.\n"); - return false; - } - - if (cmdtableidx >= cmdtablesz) - return false; - - pcmd = cmdtable + cmdtableidx; - pcmd->cmdid = cmdid; - pcmd->para1 = para1; - pcmd->para2 = para2; - pcmd->msdelay = msdelay; - return true; -} - -static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) -{ - u32 reg_eac, reg_e94, reg_e9c, reg_ea4; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe3c, MASKDWORD, - config_pathb ? 0x28160202 : 0x28160502); - - if (config_pathb) { - rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); - } - - rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); - - mdelay(IQK_DELAY_TIME); - - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); - reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); - reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); - - if (!(reg_eac & BIT(28)) && - (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && - (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(27)) && - (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_eac & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw) -{ - u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); - mdelay(IQK_DELAY_TIME); - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); - reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); - reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); - reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); - - if (!(reg_eac & BIT(31)) && - (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && - (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - if (!(reg_eac & BIT(30)) && - (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok, - long result[][8], u8 final_candidate, - bool btxonly) -{ - u32 oldval_0, x, tx0_a, reg; - long y, tx0_c; - - if (final_candidate == 0xFF) { - return; - } else if (iqk_ok) { - oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][0]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx0_a = (x * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), - ((x * oldval_0 >> 7) & 0x1)); - y = result[final_candidate][1]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx0_c = (y * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, - ((tx0_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, - (tx0_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), - ((y * oldval_0 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][2]; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][3] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][3] >> 6) & 0xF; - rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); - } -} - -static void phy_save_adda_regs(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 registernum) -{ - u32 i; - - for (i = 0; i < registernum; i++) - addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); -} - -static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg, - u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); - macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); -} - -static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg, - u32 *addabackup, u32 regiesternum) -{ - u32 i; - - for (i = 0; i < regiesternum; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); -} - -static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg, - u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); - rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); -} - -static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw, - u32 *addareg, bool is_patha_on, - bool is2t) -{ - u32 pathOn; - u32 i; - - pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2t) { - pathOn = 0x0bdb25a0; - rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); - } else { - rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); - } - - for (i = 1; i < IQK_ADDA_REG_NUM; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); -} - -static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i = 0; - - rtl_write_byte(rtlpriv, macreg[i], 0x3F); - - for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], - (u8) (macbackup[i] & (~BIT(3)))); - rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); -} - -static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); -} - -static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) -{ - u32 mode; - - mode = pi_mode ? 0x01000100 : 0x01000000; - rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); - rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); -} - -static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8], - u8 c1, u8 c2) -{ - u32 i, j, diff, simularity_bitmap, bound; - - u8 final_candidate[2] = { 0xFF, 0xFF }; - bool bresult = true; - - bound = 4; - - simularity_bitmap = 0; - - for (i = 0; i < bound; i++) { - diff = (result[c1][i] > result[c2][i]) ? - (result[c1][i] - result[c2][i]) : - (result[c2][i] - result[c1][i]); - - if (diff > MAX_TOLERANCE) { - if ((i == 2 || i == 6) && !simularity_bitmap) { - if (result[c1][i] + result[c1][i + 1] == 0) - final_candidate[(i / 4)] = c2; - else if (result[c2][i] + result[c2][i + 1] == 0) - final_candidate[(i / 4)] = c1; - else - simularity_bitmap = simularity_bitmap | - (1 << i); - } else - simularity_bitmap = - simularity_bitmap | (1 << i); - } - } - - if (simularity_bitmap == 0) { - for (i = 0; i < (bound / 4); i++) { - if (final_candidate[i] != 0xFF) { - for (j = i * 4; j < (i + 1) * 4 - 2; j++) - result[3][j] = - result[final_candidate[i]][j]; - bresult = false; - } - } - return bresult; - } else if (!(simularity_bitmap & 0x0F)) { - for (i = 0; i < 4; i++) - result[3][i] = result[c1][i]; - return false; - } else { - return false; - } - -} - -static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, - long result[][8], u8 t, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 i; - u8 patha_ok, pathb_ok; - u32 adda_reg[IQK_ADDA_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, - 0xe78, 0xe7c, 0xe80, 0xe84, - 0xe88, 0xe8c, 0xed0, 0xed4, - 0xed8, 0xedc, 0xee0, 0xeec - }; - u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - const u32 retrycount = 2; - u32 bbvalue; - - if (t == 0) { - bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); - - phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); - phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); - } - _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t); - if (t == 0) { - rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - } - - if (!rtlphy->rfpi_enable) - _rtl8723ae_phy_pi_mode_switch(hw, true); - if (t == 0) { - rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); - rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); - rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); - rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); - if (is2t) { - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); - } - _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); - if (is2t) - rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); - rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); - rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); - for (i = 0; i < retrycount; i++) { - patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t); - if (patha_ok == 0x03) { - result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && patha_ok == 0x01) - - result[t][0] = (rtl_get_bbreg(hw, 0xe94, - MASKDWORD) & 0x3FF0000) >> 16; - result[t][1] = - (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; - - } - - if (is2t) { - _rtl8723ae_phy_path_a_standby(hw); - _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t); - for (i = 0; i < retrycount; i++) { - pathb_ok = _rtl8723ae_phy_path_b_iqk(hw); - if (pathb_ok == 0x03) { - result[t][4] = - (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][5] = - (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][6] = - (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][7] = - (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && pathb_ok == 0x01) { - result[t][4] = - (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & - 0x3FF0000) >> 16; - } - result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - } - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); - rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); - if (is2t) - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); - if (t != 0) { - if (!rtlphy->rfpi_enable) - _rtl8723ae_phy_pi_mode_switch(hw, false); - phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); - phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); - } -} - -static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmpreg; - u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; - - tmpreg = rtl_read_byte(rtlpriv, 0xd03); - - if ((tmpreg & 0x70) != 0) - rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); - else - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - - if ((tmpreg & 0x70) != 0) { - rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); - - if (is2t) - rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, - MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, - (rf_a_mode & 0x8FFFF) | 0x10000); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - (rf_b_mode & 0x8FFFF) | 0x10000); - } - lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); - - mdelay(100); - - if ((tmpreg & 0x70) != 0) { - rtl_write_byte(rtlpriv, 0xd03, tmpreg); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - rf_b_mode); - } else { - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - } -} - -static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, - bool bmain, bool is2t) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (is_hal_stop(rtlhal)) { - rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - } - if (is2t) { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x1); - else - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x2); - } else { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); - else - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); - - } -} - -#undef IQK_ADDA_REG_NUM -#undef IQK_DELAY_TIME - -void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - long result[4][8]; - u8 i, final_candidate; - bool patha_ok, pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; - bool is12simular, is13simular, is23simular; - bool start_conttx = false, singletone = false; - u32 iqk_bb_reg[10] = { - ROFDM0_XARXIQIMBALANCE, - ROFDM0_XBRXIQIMBALANCE, - ROFDM0_ECCATHRESHOLD, - ROFDM0_AGCRSSITABLE, - ROFDM0_XATXIQIMBALANCE, - ROFDM0_XBTXIQIMBALANCE, - ROFDM0_XCTXIQIMBALANCE, - ROFDM0_XCTXAFE, - ROFDM0_XDTXAFE, - ROFDM0_RXIQEXTANTA - }; - - if (recovery) { - phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); - return; - } - if (start_conttx || singletone) - return; - for (i = 0; i < 8; i++) { - result[0][i] = 0; - result[1][i] = 0; - result[2][i] = 0; - result[3][i] = 0; - } - final_candidate = 0xff; - patha_ok = false; - pathb_ok = false; - is12simular = false; - is23simular = false; - is13simular = false; - for (i = 0; i < 3; i++) { - _rtl8723ae_phy_iq_calibrate(hw, result, i, false); - if (i == 1) { - is12simular = phy_simularity_comp(hw, result, 0, 1); - if (is12simular) { - final_candidate = 0; - break; - } - } - if (i == 2) { - is13simular = phy_simularity_comp(hw, result, 0, 2); - if (is13simular) { - final_candidate = 0; - break; - } - is23simular = phy_simularity_comp(hw, result, 1, 2); - if (is23simular) { - final_candidate = 1; - } else { - for (i = 0; i < 8; i++) - reg_tmp += result[3][i]; - - if (reg_tmp != 0) - final_candidate = 3; - else - final_candidate = 0xFF; - } - } - } - for (i = 0; i < 4; i++) { - reg_e94 = result[i][0]; - reg_e9c = result[i][1]; - reg_ea4 = result[i][2]; - reg_eac = result[i][3]; - reg_eb4 = result[i][4]; - reg_ebc = result[i][5]; - reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; - } - if (final_candidate != 0xff) { - rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; - rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; - reg_ea4 = result[final_candidate][2]; - reg_eac = result[final_candidate][3]; - rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; - rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; - reg_ec4 = result[final_candidate][6]; - reg_ecc = result[final_candidate][7]; - patha_ok = pathb_ok = true; - } else { - rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; - rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; - } - if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ - phy_path_a_fill_iqk_matrix(hw, patha_ok, result, - final_candidate, (reg_ea4 == 0)); - phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); -} - -void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw) -{ - bool start_conttx = false, singletone = false; - - if (start_conttx || singletone) - return; - _rtl8723ae_phy_lc_calibrate(hw, false); -} - -void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) -{ - _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false); -} - -bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - bool postprocessing = false; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress); - do { - switch (iotype) { - case IO_CMD_RESUME_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "[IO CMD] Resume DM after scan.\n"); - postprocessing = true; - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "[IO CMD] Pause DM before scan.\n"); - postprocessing = true; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - } while (false); - if (postprocessing && !rtlphy->set_io_inprogress) { - rtlphy->set_io_inprogress = true; - rtlphy->current_io_type = iotype; - } else { - return false; - } - rtl8723ae_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); - return true; -} - -static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress); - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; - rtl8723ae_dm_write_dig(hw); - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; - dm_digtable->cur_igvalue = 0x17; - rtl8723ae_dm_write_dig(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "<---(%#x)\n", rtlphy->current_io_type); -} - -static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); -} - -static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 u4b_tmp; - u8 delay = 5; - - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - while (u4b_tmp != 0 && delay > 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - delay--; - } - if (delay == 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "Switch RF timeout !!!.\n"); - return; - } - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); -} - -static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl8192_tx_ring *ring = NULL; - bool bresult = true; - u8 i, queue_id; - - switch (rfpwr_state) { - case ERFON: - if ((ppsc->rfpwr_state == ERFOFF) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { - bool rtstatus; - u32 InitializeCount = 0; - do { - InitializeCount++; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic enable\n"); - rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) && (InitializeCount < 10)); - RT_CLEAR_PS_LEVEL(ppsc, - RT_RF_OFF_LEVL_HALT_NIC); - } else { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies)); - ppsc->last_awake_jiffies = jiffies; - rtl8723ae_phy_set_rf_on(hw); - } - if (mac->link_state == MAC80211_LINKED) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } - break; - case ERFOFF: - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic disable\n"); - rtl_ps_disable_nic(hw); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - } else { - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_POWER_OFF); - } - } - break; - case ERFSLEEP: - if (ppsc->rfpwr_state == ERFOFF) - break; - for (queue_id = 0, i = 0; - queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { - ring = &pcipriv->dev.tx_ring[queue_id]; - if (skb_queue_len(&ring->queue) == 0) { - queue_id++; - continue; - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue)); - - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue)); - break; - } - } - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); - ppsc->last_sleep_jiffies = jiffies; - _rtl8723ae_phy_set_rf_sleep(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - bresult = false; - break; - } - if (bresult) - ppsc->rfpwr_state = rfpwr_state; - return bresult; -} - -bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool bresult = false; - - if (rfpwr_state == ppsc->rfpwr_state) - return bresult; - bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state); - return bresult; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h deleted file mode 100644 index e7a59eba351a..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h +++ /dev/null @@ -1,224 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_PHY_H__ -#define __RTL92C_PHY_H__ - -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -#define MAX_DOZE_WAITING_TIMES_9x 64 - -#define RT_CANNOT_IO(hw) false -#define HIGHPOWER_RADIOA_ARRAYLEN 22 - -#define MAX_TOLERANCE 5 -#define IQK_DELAY_TIME 1 - -#define APK_BB_REG_NUM 5 -#define APK_AFE_REG_NUM 16 -#define APK_CURVE_REG_NUM 4 -#define PATH_NUM 2 - -#define LOOP_LIMIT 5 -#define MAX_STALL_TIME 50 -#define AntennaDiversityValue 0x80 -#define MAX_TXPWR_IDX_NMODE_92S 63 -#define Reset_Cnt_Limit 3 - -#define IQK_MAC_REG_NUM 4 - -#define RF6052_MAX_PATH 2 - -#define CT_OFFSET_MAC_ADDR 0X16 - -#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A -#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 -#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 -#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 -#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C - -#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F -#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 - -#define CT_OFFSET_CHANNEL_PLAH 0x75 -#define CT_OFFSET_THERMAL_METER 0x78 -#define CT_OFFSET_RF_OPTION 0x79 -#define CT_OFFSET_VERSION 0x7E -#define CT_OFFSET_CUSTOMER_ID 0x7F - -#define RTL92C_MAX_PATH_NUM 2 - -enum swchnlcmd_id { - CMDID_END, - CMDID_SET_TXPOWEROWER_LEVEL, - CMDID_BBREGWRITE10, - CMDID_WRITEPORT_ULONG, - CMDID_WRITEPORT_USHORT, - CMDID_WRITEPORT_UCHAR, - CMDID_RF_WRITEREG, -}; - -struct swchnlcmd { - enum swchnlcmd_id cmdid; - u32 para1; - u32 para2; - u32 msdelay; -}; - -enum hw90_block_e { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, -}; - -enum baseband_config_type { - BASEBAND_CONFIG_PHY_REG = 0, - BASEBAND_CONFIG_AGC_TAB = 1, -}; - -enum ra_offset_area { - RA_OFFSET_LEGACY_OFDM1, - RA_OFFSET_LEGACY_OFDM2, - RA_OFFSET_HT_OFDM1, - RA_OFFSET_HT_OFDM2, - RA_OFFSET_HT_OFDM3, - RA_OFFSET_HT_OFDM4, - RA_OFFSET_HT_CCK, -}; - -enum antenna_path { - ANTENNA_NONE, - ANTENNA_D, - ANTENNA_C, - ANTENNA_CD, - ANTENNA_B, - ANTENNA_BD, - ANTENNA_BC, - ANTENNA_BCD, - ANTENNA_A, - ANTENNA_AD, - ANTENNA_AC, - ANTENNA_ACD, - ANTENNA_AB, - ANTENNA_ABD, - ANTENNA_ABC, - ANTENNA_ABCD -}; - -struct r_antenna_select_ofdm { - u32 r_tx_antenna:4; - u32 r_ant_l:4; - u32 r_ant_non_ht:4; - u32 r_ant_ht1:4; - u32 r_ant_ht2:4; - u32 r_ant_ht_s1:4; - u32 r_ant_non_ht_s1:4; - u32 ofdm_txsc:2; - u32 reserved:2; -}; - -struct r_antenna_select_cck { - u8 r_cckrx_enable_2:2; - u8 r_cckrx_enable:2; - u8 r_ccktx_enable:4; -}; - -struct efuse_contents { - u8 mac_addr[ETH_ALEN]; - u8 cck_tx_power_idx[6]; - u8 ht40_1s_tx_power_idx[6]; - u8 ht40_2s_tx_power_idx_diff[3]; - u8 ht20_tx_power_idx_diff[3]; - u8 ofdm_tx_power_idx_diff[3]; - u8 ht40_max_power_offset[3]; - u8 ht20_max_power_offset[3]; - u8 channel_plan; - u8 thermal_meter; - u8 rf_option[5]; - u8 version; - u8 oem_id; - u8 regulatory; -}; - -struct tx_power_struct { - u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_txpowerdiff; - u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 pwrgroup_cnt; - u32 mcs_original_offset[4][16]; -}; - -extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, - u8 channel); -extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, - long power_indbm); -extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, - u8 operation); -extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); -void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); -void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); -bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c deleted file mode 100644 index df6ca9a57f7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "pwrseqcmd.h" -#include "pwrseq.h" - -/* drivers should parse arrays below and do the corresponding actions */ - -/*3 Power on Array*/ -struct wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3Radio off GPIO Array */ -struct wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_END -}; - -/*3Card Disable Array*/ -struct wlan_pwr_cfg -rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_CARDDIS, - RTL8723A_TRANS_END -}; - -/*3 Card Enable Array*/ -struct wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_CARDDIS_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3Suspend Array*/ -struct wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_SUS, - RTL8723A_TRANS_END -}; - -/*3 Resume Array*/ -struct wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_SUS_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3HWPDN Array*/ -struct wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_PDN, - RTL8723A_TRANS_END -}; - -/*3 Enter LPS */ -struct wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS - + RTL8723A_TRANS_END_STPS] = { - /*FW behavior*/ - RTL8723A_TRANS_ACT_TO_LPS, - RTL8723A_TRANS_END -}; - -/*3 Leave LPS */ -struct wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS] = { - /*FW behavior*/ - RTL8723A_TRANS_LPS_TO_ACT, - RTL8723A_TRANS_END -}; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h deleted file mode 100644 index 7a46f9fdf558..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h +++ /dev/null @@ -1,322 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_PWRSEQ_H__ -#define __RTL8723E_PWRSEQ_H__ - -#include "pwrseqcmd.h" -/* - Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd - There are 6 HW Power States: - 0: POFF--Power Off - 1: PDN--Power Down - 2: CARDEMU--Card Emulation - 3: ACT--Active Mode - 4: LPS--Low Power State - 5: SUS--Suspend - - The transision from different states are defined below - TRANS_CARDEMU_TO_ACT - TRANS_ACT_TO_CARDEMU - TRANS_CARDEMU_TO_SUS - TRANS_SUS_TO_CARDEMU - TRANS_CARDEMU_TO_PDN - TRANS_ACT_TO_LPS - TRANS_LPS_TO_ACT - - TRANS_END -*/ - -#define RTL8723A_TRANS_CARDEMU_TO_ACT_STPS 10 -#define RTL8723A_TRANS_ACT_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_CARDEMU_TO_SUS_STPS 10 -#define RTL8723A_TRANS_SUS_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_CARDEMU_TO_PDN_STPS 10 -#define RTL8723A_TRANS_PDN_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_ACT_TO_LPS_STPS 15 -#define RTL8723A_TRANS_LPS_TO_ACT_STPS 15 -#define RTL8723A_TRANS_END_STPS 1 - - -#define RTL8723A_TRANS_CARDEMU_TO_ACT \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0}, \ - /* disable SW LPS 0x04[10]=0*/ \ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /* wait till 0x04[17] = 1 power ready*/ \ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /* release WLON reset 0x04[16]=1*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ - /* disable HWPDN 0x04[15]=0*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \ - /* disable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /* polling until return 0*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0} - -#define RTL8723A_TRANS_ACT_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \ - /*0x1F[7:0] = 0 turn off RF*/ \ - {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0} - -#define RTL8723A_TRANS_CARDEMU_TO_SUS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), \ - (BIT(4)|BIT(3))}, \ - /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK | \ - PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ - /*0x04[12:11] = 2b'01 enable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, \ - PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, \ - /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, \ - PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, \ - PWR_CMD_POLLING, BIT(1), 0} \ - /*wait power state to suspend*/ - -#define RTL8723A_TRANS_SUS_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /*wait power state to suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0} \ - /*0x04[12:11] = 2b'01enable WL suspend*/ - -#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ - PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ - /*0x04[12:11] = 2b'01 enable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \ - /*0x04[10] = 1, enable SW LPS*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0} \ - /*wait power state to suspend*/ - -#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /*wait power state to suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ - /*0x04[12:11] = 2b'00enable WL suspend*/ \ - {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ - /*PCIe DMA start*/ - -#define RTL8723A_TRANS_CARDEMU_TO_PDN \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ - /* 0x04[16] = 0*/\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)} \ - /* 0x04[15] = 1*/ - -#define RTL8723A_TRANS_PDN_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0} \ - /* 0x04[15] = 0*/ - -#define RTL8723A_TRANS_ACT_TO_LPS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ - /*PCIe DMA stop*/ \ - {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F}, \ - /*Tx Pause*/ \ - {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ - /*CCK and OFDM are disabled,and clock are gated*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \ - /*Delay 1us*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ - /*Whole BB is reset*/ \ - {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F}, \ - /*Reset MAC TRX*/ \ - {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ - /*check if removed later*/ \ - {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)} \ - /*Respond TxOK to scheduler*/ - -#define RTL8723A_TRANS_LPS_TO_ACT \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*SDIO RPWM*/ \ - {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*USB RPWM*/ \ - {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*PCIe RPWM*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \ - /*Delay*/ \ - {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ - /* 0x08[4] = 0 switch TSF to 40M*/ \ - {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \ - /*Polling 0x109[7]=0 TSF in 40M*/ \ - {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \ - /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ - {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ - /*. 0x101[1] = 1*/ \ - {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ - /* 0x100[7:0] = 0xFF enable WMAC TRX*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), \ - BIT(1)|BIT(0)}, \ - /* 0x02[1:0] = 2b'11 enable BB macro*/ \ - {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ - /*. 0x522 = 0*/ - -#define RTL8723A_TRANS_END \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - 0, PWR_CMD_END, 0, 0} - -extern struct -wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS]; - -/* RTL8723 Power Configuration CMDs for PCIe interface */ -#define Rtl8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow -#define Rtl8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow -#define Rtl8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow -#define Rtl8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow -#define Rtl8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow -#define Rtl8723_NIC_RESUME_FLOW rtl8723A_resume_flow -#define Rtl8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow -#define Rtl8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow -#define Rtl8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c deleted file mode 100644 index 2044b5936b7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "pwrseq.h" - -/* Description: - * This routine deals with the Power Configuration CMD - * parsing for RTL8723/RTL8188E Series IC. - * Assumption: - * We should follow specific format that was released from HW SD. - */ -bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, - u8 faversion, u8 interface_type, - struct wlan_pwr_cfg pwrcfgcmd[]) -{ - struct wlan_pwr_cfg cfg_cmd = {0}; - bool polling_bit = false; - u32 ary_idx = 0; - u8 value = 0; - u32 offset = 0; - u32 polling_count = 0; - u32 max_polling_cnt = 5000; - - do { - cfg_cmd = pwrcfgcmd[ary_idx]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x)," - "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", - GET_PWR_CFG_OFFSET(cfg_cmd), - GET_PWR_CFG_CUT_MASK(cfg_cmd), - GET_PWR_CFG_FAB_MASK(cfg_cmd), - GET_PWR_CFG_INTF_MASK(cfg_cmd), - GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), - GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); - - if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && - (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && - (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { - switch (GET_PWR_CFG_CMD(cfg_cmd)) { - case PWR_CMD_READ: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); - break; - case PWR_CMD_WRITE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"); - offset = GET_PWR_CFG_OFFSET(cfg_cmd); - - /*Read the value from system register*/ - value = rtl_read_byte(rtlpriv, offset); - value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); - value |= (GET_PWR_CFG_VALUE(cfg_cmd) & - GET_PWR_CFG_MASK(cfg_cmd)); - - /*Write the value back to sytem register*/ - rtl_write_byte(rtlpriv, offset, value); - break; - case PWR_CMD_POLLING: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); - polling_bit = false; - offset = GET_PWR_CFG_OFFSET(cfg_cmd); - - do { - value = rtl_read_byte(rtlpriv, offset); - - value &= GET_PWR_CFG_MASK(cfg_cmd); - if (value == - (GET_PWR_CFG_VALUE(cfg_cmd) - & GET_PWR_CFG_MASK(cfg_cmd))) - polling_bit = true; - else - udelay(10); - - if (polling_count++ > max_polling_cnt) - return false; - } while (!polling_bit); - break; - case PWR_CMD_DELAY: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); - if (GET_PWR_CFG_VALUE(cfg_cmd) == - PWRSEQ_DELAY_US) - udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); - else - mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); - break; - case PWR_CMD_END: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); - return true; - default: - RT_ASSERT(false, - "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); - break; - } - - } - ary_idx++; - } while (1); - - return true; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h deleted file mode 100644 index 6e0f3ea37ec0..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_PWRSEQCMD_H__ -#define __RTL8723E_PWRSEQCMD_H__ - -#include "../wifi.h" -/*--------------------------------------------- - * 3 The value of cmd: 4 bits - *--------------------------------------------- - */ -#define PWR_CMD_READ 0x00 -#define PWR_CMD_WRITE 0x01 -#define PWR_CMD_POLLING 0x02 -#define PWR_CMD_DELAY 0x03 -#define PWR_CMD_END 0x04 - -/* define the base address of each block */ -#define PWR_BASEADDR_MAC 0x00 -#define PWR_BASEADDR_USB 0x01 -#define PWR_BASEADDR_PCIE 0x02 -#define PWR_BASEADDR_SDIO 0x03 - -#define PWR_INTF_SDIO_MSK BIT(0) -#define PWR_INTF_USB_MSK BIT(1) -#define PWR_INTF_PCI_MSK BIT(2) -#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) - -#define PWR_FAB_TSMC_MSK BIT(0) -#define PWR_FAB_UMC_MSK BIT(1) -#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) - -#define PWR_CUT_TESTCHIP_MSK BIT(0) -#define PWR_CUT_A_MSK BIT(1) -#define PWR_CUT_B_MSK BIT(2) -#define PWR_CUT_C_MSK BIT(3) -#define PWR_CUT_D_MSK BIT(4) -#define PWR_CUT_E_MSK BIT(5) -#define PWR_CUT_F_MSK BIT(6) -#define PWR_CUT_G_MSK BIT(7) -#define PWR_CUT_ALL_MSK 0xFF - -enum pwrseq_delay_unit { - PWRSEQ_DELAY_US, - PWRSEQ_DELAY_MS, -}; - -struct wlan_pwr_cfg { - u16 offset; - u8 cut_msk; - u8 fab_msk:4; - u8 interface_msk:4; - u8 base:4; - u8 cmd:4; - u8 msk; - u8 value; -}; - -#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) -#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) -#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) -#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) -#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) -#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) -#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) -#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) - -bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, - u8 fab_version, u8 interface_type, - struct wlan_pwr_cfg pwrcfgcmd[]); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h deleted file mode 100644 index 199da366c6da..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h +++ /dev/null @@ -1,2097 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_REG_H__ -#define __RTL8723E_REG_H__ - -#define REG_SYS_ISO_CTRL 0x0000 -#define REG_SYS_FUNC_EN 0x0002 -#define REG_APS_FSMCO 0x0004 -#define REG_SYS_CLKR 0x0008 -#define REG_9346CR 0x000A -#define REG_EE_VPD 0x000C -#define REG_AFE_MISC 0x0010 -#define REG_SPS0_CTRL 0x0011 -#define REG_SPS_OCP_CFG 0x0018 -#define REG_RSV_CTRL 0x001C -#define REG_RF_CTRL 0x001F -#define REG_LDOA15_CTRL 0x0020 -#define REG_LDOV12D_CTRL 0x0021 -#define REG_LDOHCI12_CTRL 0x0022 -#define REG_LPLDO_CTRL 0x0023 -#define REG_AFE_XTAL_CTRL 0x0024 -#define REG_AFE_PLL_CTRL 0x0028 -#define REG_EFUSE_CTRL 0x0030 -#define REG_EFUSE_TEST 0x0034 -#define REG_PWR_DATA 0x0038 -#define REG_CAL_TIMER 0x003C -#define REG_ACLK_MON 0x003E -#define REG_GPIO_MUXCFG 0x0040 -#define REG_GPIO_IO_SEL 0x0042 -#define REG_MAC_PINMUX_CFG 0x0043 -#define REG_GPIO_PIN_CTRL 0x0044 -#define REG_GPIO_INTM 0x0048 -#define REG_LEDCFG0 0x004C -#define REG_LEDCFG1 0x004D -#define REG_LEDCFG2 0x004E -#define REG_LEDCFG3 0x004F -#define REG_FSIMR 0x0050 -#define REG_FSISR 0x0054 -#define REG_GPIO_PIN_CTRL_2 0x0060 -#define REG_GPIO_IO_SEL_2 0x0062 -#define REG_MULTI_FUNC_CTRL 0x0068 - -#define REG_MCUFWDL 0x0080 - -#define REG_HMEBOX_EXT_0 0x0088 -#define REG_HMEBOX_EXT_1 0x008A -#define REG_HMEBOX_EXT_2 0x008C -#define REG_HMEBOX_EXT_3 0x008E - -#define REG_BIST_SCAN 0x00D0 -#define REG_BIST_RPT 0x00D4 -#define REG_BIST_ROM_RPT 0x00D8 -#define REG_USB_SIE_INTF 0x00E0 -#define REG_PCIE_MIO_INTF 0x00E4 -#define REG_PCIE_MIO_INTD 0x00E8 -#define REG_SYS_CFG 0x00F0 -#define REG_GPIO_OUTSTS 0x00F4 - -#define REG_CR 0x0100 -#define REG_PBP 0x0104 -#define REG_TRXDMA_CTRL 0x010C -#define REG_TRXFF_BNDY 0x0114 -#define REG_TRXFF_STATUS 0x0118 -#define REG_RXFF_PTR 0x011C -#define REG_HIMR 0x0120 -#define REG_HISR 0x0124 -#define REG_HIMRE 0x0128 -#define REG_HISRE 0x012C -#define REG_CPWM 0x012F -#define REG_FWIMR 0x0130 -#define REG_FWISR 0x0134 -#define REG_PKTBUF_DBG_CTRL 0x0140 -#define REG_PKTBUF_DBG_DATA_L 0x0144 -#define REG_PKTBUF_DBG_DATA_H 0x0148 - -#define REG_TC0_CTRL 0x0150 -#define REG_TC1_CTRL 0x0154 -#define REG_TC2_CTRL 0x0158 -#define REG_TC3_CTRL 0x015C -#define REG_TC4_CTRL 0x0160 -#define REG_TCUNIT_BASE 0x0164 -#define REG_MBIST_START 0x0174 -#define REG_MBIST_DONE 0x0178 -#define REG_MBIST_FAIL 0x017C -#define REG_C2HEVT_MSG_NORMAL 0x01A0 -#define REG_C2HEVT_MSG_TEST 0x01B8 -#define REG_MCUTST_1 0x01c0 -#define REG_FMETHR 0x01C8 -#define REG_HMETFR 0x01CC -#define REG_HMEBOX_0 0x01D0 -#define REG_HMEBOX_1 0x01D4 -#define REG_HMEBOX_2 0x01D8 -#define REG_HMEBOX_3 0x01DC - -#define REG_LLT_INIT 0x01E0 -#define REG_BB_ACCEESS_CTRL 0x01E8 -#define REG_BB_ACCESS_DATA 0x01EC - -#define REG_RQPN 0x0200 -#define REG_FIFOPAGE 0x0204 -#define REG_TDECTRL 0x0208 -#define REG_TXDMA_OFFSET_CHK 0x020C -#define REG_TXDMA_STATUS 0x0210 -#define REG_RQPN_NPQ 0x0214 - -#define REG_RXDMA_AGG_PG_TH 0x0280 -#define REG_RXPKT_NUM 0x0284 -#define REG_RXDMA_STATUS 0x0288 - -#define REG_PCIE_CTRL_REG 0x0300 -#define REG_INT_MIG 0x0304 -#define REG_BCNQ_DESA 0x0308 -#define REG_HQ_DESA 0x0310 -#define REG_MGQ_DESA 0x0318 -#define REG_VOQ_DESA 0x0320 -#define REG_VIQ_DESA 0x0328 -#define REG_BEQ_DESA 0x0330 -#define REG_BKQ_DESA 0x0338 -#define REG_RX_DESA 0x0340 -#define REG_DBI 0x0348 -#define REG_MDIO 0x0354 -#define REG_DBG_SEL 0x0360 -#define REG_PCIE_HRPWM 0x0361 -#define REG_PCIE_HCPWM 0x0363 -#define REG_UART_CTRL 0x0364 -#define REG_UART_TX_DESA 0x0370 -#define REG_UART_RX_DESA 0x0378 - -#define REG_HDAQ_DESA_NODEF 0x0000 -#define REG_CMDQ_DESA_NODEF 0x0000 - -#define REG_VOQ_INFORMATION 0x0400 -#define REG_VIQ_INFORMATION 0x0404 -#define REG_BEQ_INFORMATION 0x0408 -#define REG_BKQ_INFORMATION 0x040C -#define REG_MGQ_INFORMATION 0x0410 -#define REG_HGQ_INFORMATION 0x0414 -#define REG_BCNQ_INFORMATION 0x0418 - -#define REG_CPU_MGQ_INFORMATION 0x041C -#define REG_FWHW_TXQ_CTRL 0x0420 -#define REG_HWSEQ_CTRL 0x0423 -#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 -#define REG_TXPKTBUF_MGQ_BDNY 0x0425 -#define REG_MULTI_BCNQ_EN 0x0426 -#define REG_MULTI_BCNQ_OFFSET 0x0427 -#define REG_SPEC_SIFS 0x0428 -#define REG_RL 0x042A -#define REG_DARFRC 0x0430 -#define REG_RARFRC 0x0438 -#define REG_RRSR 0x0440 -#define REG_ARFR0 0x0444 -#define REG_ARFR1 0x0448 -#define REG_ARFR2 0x044C -#define REG_ARFR3 0x0450 -#define REG_AGGLEN_LMT 0x0458 -#define REG_AMPDU_MIN_SPACE 0x045C -#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D -#define REG_FAST_EDCA_CTRL 0x0460 -#define REG_RD_RESP_PKT_TH 0x0463 -#define REG_INIRTS_RATE_SEL 0x0480 -#define REG_INIDATA_RATE_SEL 0x0484 -#define REG_POWER_STATUS 0x04A4 -#define REG_POWER_STAGE1 0x04B4 -#define REG_POWER_STAGE2 0x04B8 -#define REG_PKT_LIFE_TIME 0x04C0 -#define REG_STBC_SETTING 0x04C4 -#define REG_PROT_MODE_CTRL 0x04C8 -#define REG_BAR_MODE_CTRL 0x04CC -#define REG_RA_TRY_RATE_AGG_LMT 0x04CF -#define REG_NQOS_SEQ 0x04DC -#define REG_QOS_SEQ 0x04DE -#define REG_NEED_CPU_HANDLE 0x04E0 -#define REG_PKT_LOSE_RPT 0x04E1 -#define REG_PTCL_ERR_STATUS 0x04E2 -#define REG_DUMMY 0x04FC - -#define REG_EDCA_VO_PARAM 0x0500 -#define REG_EDCA_VI_PARAM 0x0504 -#define REG_EDCA_BE_PARAM 0x0508 -#define REG_EDCA_BK_PARAM 0x050C -#define REG_BCNTCFG 0x0510 -#define REG_PIFS 0x0512 -#define REG_RDG_PIFS 0x0513 -#define REG_SIFS_CTX 0x0514 -#define REG_SIFS_TRX 0x0516 -#define REG_AGGR_BREAK_TIME 0x051A -#define REG_SLOT 0x051B -#define REG_TX_PTCL_CTRL 0x0520 -#define REG_TXPAUSE 0x0522 -#define REG_DIS_TXREQ_CLR 0x0523 -#define REG_RD_CTRL 0x0524 -#define REG_TBTT_PROHIBIT 0x0540 -#define REG_RD_NAV_NXT 0x0544 -#define REG_NAV_PROT_LEN 0x0546 -#define REG_BCN_CTRL 0x0550 -#define REG_USTIME_TSF 0x0551 -#define REG_MBID_NUM 0x0552 -#define REG_DUAL_TSF_RST 0x0553 -#define REG_BCN_INTERVAL 0x0554 -#define REG_MBSSID_BCN_SPACE 0x0554 -#define REG_DRVERLYINT 0x0558 -#define REG_BCNDMATIM 0x0559 -#define REG_ATIMWND 0x055A -#define REG_BCN_MAX_ERR 0x055D -#define REG_RXTSF_OFFSET_CCK 0x055E -#define REG_RXTSF_OFFSET_OFDM 0x055F -#define REG_TSFTR 0x0560 -#define REG_INIT_TSFTR 0x0564 -#define REG_PSTIMER 0x0580 -#define REG_TIMER0 0x0584 -#define REG_TIMER1 0x0588 -#define REG_ACMHWCTRL 0x05C0 -#define REG_ACMRSTCTRL 0x05C1 -#define REG_ACMAVG 0x05C2 -#define REG_VO_ADMTIME 0x05C4 -#define REG_VI_ADMTIME 0x05C6 -#define REG_BE_ADMTIME 0x05C8 -#define REG_EDCA_RANDOM_GEN 0x05CC -#define REG_SCH_TXCMD 0x05D0 - -#define REG_APSD_CTRL 0x0600 -#define REG_BWOPMODE 0x0603 -#define REG_TCR 0x0604 -#define REG_RCR 0x0608 -#define REG_RX_PKT_LIMIT 0x060C -#define REG_RX_DLK_TIME 0x060D -#define REG_RX_DRVINFO_SZ 0x060F - -#define REG_MACID 0x0610 -#define REG_BSSID 0x0618 -#define REG_MAR 0x0620 -#define REG_MBIDCAMCFG 0x0628 - -#define REG_USTIME_EDCA 0x0638 -#define REG_MAC_SPEC_SIFS 0x063A -#define REG_RESP_SIFS_CCK 0x063C -#define REG_RESP_SIFS_OFDM 0x063E -#define REG_ACKTO 0x0640 -#define REG_CTS2TO 0x0641 -#define REG_EIFS 0x0642 - -#define REG_NAV_CTRL 0x0650 -#define REG_BACAMCMD 0x0654 -#define REG_BACAMCONTENT 0x0658 -#define REG_LBDLY 0x0660 -#define REG_FWDLY 0x0661 -#define REG_RXERR_RPT 0x0664 -#define REG_WMAC_TRXPTCL_CTL 0x0668 - -#define REG_CAMCMD 0x0670 -#define REG_CAMWRITE 0x0674 -#define REG_CAMREAD 0x0678 -#define REG_CAMDBG 0x067C -#define REG_SECCFG 0x0680 - -#define REG_WOW_CTRL 0x0690 -#define REG_PSSTATUS 0x0691 -#define REG_PS_RX_INFO 0x0692 -#define REG_LPNAV_CTRL 0x0694 -#define REG_WKFMCAM_CMD 0x0698 -#define REG_WKFMCAM_RWD 0x069C -#define REG_RXFLTMAP0 0x06A0 -#define REG_RXFLTMAP1 0x06A2 -#define REG_RXFLTMAP2 0x06A4 -#define REG_BCN_PSR_RPT 0x06A8 -#define REG_CALB32K_CTRL 0x06AC -#define REG_PKT_MON_CTRL 0x06B4 -#define REG_BT_COEX_TABLE 0x06C0 -#define REG_WMAC_RESP_TXINFO 0x06D8 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_TEST_USB_TXQS 0xFE48 -#define REG_TEST_SIE_VID 0xFE60 -#define REG_TEST_SIE_PID 0xFE62 -#define REG_TEST_SIE_OPTIONAL 0xFE64 -#define REG_TEST_SIE_CHIRP_K 0xFE65 -#define REG_TEST_SIE_PHY 0xFE66 -#define REG_TEST_SIE_MAC_ADDR 0xFE70 -#define REG_TEST_SIE_STRING 0xFE80 - -#define REG_NORMAL_SIE_VID 0xFE60 -#define REG_NORMAL_SIE_PID 0xFE62 -#define REG_NORMAL_SIE_OPTIONAL 0xFE64 -#define REG_NORMAL_SIE_EP 0xFE65 -#define REG_NORMAL_SIE_PHY 0xFE68 -#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 -#define REG_NORMAL_SIE_STRING 0xFE80 - -#define CR9346 REG_9346CR -#define MSR (REG_CR + 2) -#define ISR REG_HISR -#define TSFR REG_TSFTR - -#define MACIDR0 REG_MACID -#define MACIDR4 (REG_MACID + 4) - -#define PBP REG_PBP - -#define IDR0 MACIDR0 -#define IDR4 MACIDR4 - -#define UNUSED_REGISTER 0x1BF -#define DCAM UNUSED_REGISTER -#define PSR UNUSED_REGISTER -#define BBADDR UNUSED_REGISTER -#define PHYDATAR UNUSED_REGISTER - -#define INVALID_BBRF_VALUE 0x12345678 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define CMDEEPROM_EN BIT(5) -#define CMDEEPROM_SEL BIT(4) -#define CMD9346CR_9356SEL BIT(4) -#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) -#define AUTOLOAD_EFUSE CMDEEPROM_EN - -#define GPIOSEL_GPIO 0 -#define GPIOSEL_ENBT BIT(5) - -#define GPIO_IN REG_GPIO_PIN_CTRL -#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) -#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) -#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) - -#define MSR_NOLINK 0x00 -#define MSR_ADHOC 0x01 -#define MSR_INFRA 0x02 -#define MSR_AP 0x03 - -#define RRSR_RSC_OFFSET 21 -#define RRSR_SHORT_OFFSET 23 -#define RRSR_RSC_BW_40M 0x600000 -#define RRSR_RSC_UPSUBCHNL 0x400000 -#define RRSR_RSC_LOWSUBCHNL 0x200000 -#define RRSR_SHORT 0x800000 -#define RRSR_1M BIT(0) -#define RRSR_2M BIT(1) -#define RRSR_5_5M BIT(2) -#define RRSR_11M BIT(3) -#define RRSR_6M BIT(4) -#define RRSR_9M BIT(5) -#define RRSR_12M BIT(6) -#define RRSR_18M BIT(7) -#define RRSR_24M BIT(8) -#define RRSR_36M BIT(9) -#define RRSR_48M BIT(10) -#define RRSR_54M BIT(11) -#define RRSR_MCS0 BIT(12) -#define RRSR_MCS1 BIT(13) -#define RRSR_MCS2 BIT(14) -#define RRSR_MCS3 BIT(15) -#define RRSR_MCS4 BIT(16) -#define RRSR_MCS5 BIT(17) -#define RRSR_MCS6 BIT(18) -#define RRSR_MCS7 BIT(19) -#define BRSR_ACKSHORTPMB BIT(23) - -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 - -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ - RATR_24M | RATR_36M | RATR_48M | RATR_54M) -#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ - RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ - RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ - RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ - RATR_MCS14 | RATR_MCS15) - -#define BW_OPMODE_20MHZ BIT(2) -#define BW_OPMODE_5G BIT(1) -#define BW_OPMODE_11J BIT(0) - -#define CAM_VALID BIT(15) -#define CAM_NOTVALID 0x0000 -#define CAM_USEDK BIT(5) - -#define CAM_NONE 0x0 -#define CAM_WEP40 0x01 -#define CAM_TKIP 0x02 -#define CAM_AES 0x04 -#define CAM_WEP104 0x05 - -#define TOTAL_CAM_ENTRY 32 -#define HALF_CAM_ENTRY 16 - -#define CAM_WRITE BIT(16) -#define CAM_READ 0x00000000 -#define CAM_POLLINIG BIT(31) - -#define SCR_USEDK 0x01 -#define SCR_TXSEC_ENABLE 0x02 -#define SCR_RXSEC_ENABLE 0x04 - -#define WOW_PMEN BIT(0) -#define WOW_WOMEN BIT(1) -#define WOW_MAGIC BIT(2) -#define WOW_UWF BIT(3) - -#define IMR8190_DISABLED 0x0 -#define IMR_BCNDMAINT6 BIT(31) -#define IMR_BCNDMAINT5 BIT(30) -#define IMR_BCNDMAINT4 BIT(29) -#define IMR_BCNDMAINT3 BIT(28) -#define IMR_BCNDMAINT2 BIT(27) -#define IMR_BCNDMAINT1 BIT(26) -#define IMR_BCNDOK8 BIT(25) -#define IMR_BCNDOK7 BIT(24) -#define IMR_BCNDOK6 BIT(23) -#define IMR_BCNDOK5 BIT(22) -#define IMR_BCNDOK4 BIT(21) -#define IMR_BCNDOK3 BIT(20) -#define IMR_BCNDOK2 BIT(19) -#define IMR_BCNDOK1 BIT(18) -#define IMR_TIMEOUT2 BIT(17) -#define IMR_TIMEOUT1 BIT(16) -#define IMR_TXFOVW BIT(15) -#define IMR_PSTIMEOUT BIT(14) -#define IMR_BCNINT BIT(13) -#define IMR_RXFOVW BIT(12) -#define IMR_RDU BIT(11) -#define IMR_ATIMEND BIT(10) -#define IMR_BDOK BIT(9) -#define IMR_HIGHDOK BIT(8) -#define IMR_TBDOK BIT(7) -#define IMR_MGNTDOK BIT(6) -#define IMR_TBDER BIT(5) -#define IMR_BKDOK BIT(4) -#define IMR_BEDOK BIT(3) -#define IMR_VIDOK BIT(2) -#define IMR_VODOK BIT(1) -#define IMR_ROK BIT(0) - -#define IMR_TXERR BIT(11) -#define IMR_RXERR BIT(10) -#define IMR_CPWM BIT(8) -#define IMR_OCPINT BIT(1) -#define IMR_WLANOFF BIT(0) - -/* 8723E series PCIE Host IMR/ISR bit */ -/* IMR DW0 Bit 0-31 */ -#define PHIMR_TIMEOUT2 BIT(31) -#define PHIMR_TIMEOUT1 BIT(30) -#define PHIMR_PSTIMEOUT BIT(29) -#define PHIMR_GTINT4 BIT(28) -#define PHIMR_GTINT3 BIT(27) -#define PHIMR_TXBCNERR BIT(26) -#define PHIMR_TXBCNOK BIT(25) -#define PHIMR_TSF_BIT32_TOGGLE BIT(24) -#define PHIMR_BCNDMAINT3 BIT(23) -#define PHIMR_BCNDMAINT2 BIT(22) -#define PHIMR_BCNDMAINT1 BIT(21) -#define PHIMR_BCNDMAINT0 BIT(20) -#define PHIMR_BCNDOK3 BIT(19) -#define PHIMR_BCNDOK2 BIT(18) -#define PHIMR_BCNDOK1 BIT(17) -#define PHIMR_BCNDOK0 BIT(16) -#define PHIMR_HSISR_IND_ON BIT(15) -#define PHIMR_BCNDMAINT_E BIT(14) -#define PHIMR_ATIMEND_E BIT(13) -#define PHIMR_ATIM_CTW_END BIT(12) -#define PHIMR_HISRE_IND BIT(11) -#define PHIMR_C2HCMD BIT(10) -#define PHIMR_CPWM2 BIT(9) -#define PHIMR_CPWM BIT(8) -#define PHIMR_HIGHDOK BIT(7) -#define PHIMR_MGNTDOK BIT(6) -#define PHIMR_BKDOK BIT(5) -#define PHIMR_BEDOK BIT(4) -#define PHIMR_VIDOK BIT(3) -#define PHIMR_VODOK BIT(2) -#define PHIMR_RDU BIT(1) -#define PHIMR_ROK BIT(0) - -/* PCIE Host Interrupt Status Extension bit */ -#define PHIMR_BCNDMAINT7 BIT(23) -#define PHIMR_BCNDMAINT6 BIT(22) -#define PHIMR_BCNDMAINT5 BIT(21) -#define PHIMR_BCNDMAINT4 BIT(20) -#define PHIMR_BCNDOK7 BIT(19) -#define PHIMR_BCNDOK6 BIT(18) -#define PHIMR_BCNDOK5 BIT(17) -#define PHIMR_BCNDOK4 BIT(16) -/* bit12-15: RSVD */ -#define PHIMR_TXERR BIT(11) -#define PHIMR_RXERR BIT(10) -#define PHIMR_TXFOVW BIT(9) -#define PHIMR_RXFOVW BIT(8) -/* bit2-7: RSV */ -#define PHIMR_OCPINT BIT(1) - -#define HWSET_MAX_SIZE 256 -#define EFUSE_MAX_SECTION 32 -#define EFUSE_REAL_CONTENT_LEN 512 -#define EFUSE_OOB_PROTECT_BYTES 15 - -#define EEPROM_DEFAULT_TSSI 0x0 -#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_BOARDTYPE 0x02 -#define EEPROM_DEFAULT_TXPOWER 0x1010 -#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 - -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_THERMALMETER 0x12 -#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 -#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 -#define EEPROM_DEFAULT_HT20_DIFF 2 -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 -#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 - - -#define EEPROM_DEFAULT_PID 0x1234 -#define EEPROM_DEFAULT_VID 0x5678 -#define EEPROM_DEFAULT_CUSTOMERID 0xAB -#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD -#define EEPROM_DEFAULT_VERSION 0 - -#define EEPROM_CHANNEL_PLAN_FCC 0x0 -#define EEPROM_CHANNEL_PLAN_IC 0x1 -#define EEPROM_CHANNEL_PLAN_ETSI 0x2 -#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 -#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 -#define EEPROM_CHANNEL_PLAN_MKK 0x5 -#define EEPROM_CHANNEL_PLAN_MKK1 0x6 -#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 -#define EEPROM_CHANNEL_PLAN_TELEC 0x8 -#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 -#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA -#define EEPROM_CHANNEL_PLAN_NCC 0xB -#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 - -#define EEPROM_CID_DEFAULT 0x0 -#define EEPROM_CID_TOSHIBA 0x4 -#define EEPROM_CID_CCX 0x10 -#define EEPROM_CID_QMI 0x0D -#define EEPROM_CID_WHQL 0xFE - -#define RTL8192_EEPROM_ID 0x8129 - -#define RTL8190_EEPROM_ID 0x8129 -#define EEPROM_HPON 0x02 -#define EEPROM_CLK 0x06 -#define EEPROM_TESTR 0x08 - -#define EEPROM_VID 0x49 -#define EEPROM_DID 0x4B -#define EEPROM_SVID 0x4D -#define EEPROM_SMID 0x4F - -#define EEPROM_MAC_ADDR 0x67 - -#define EEPROM_CCK_TX_PWR_INX 0x5A -#define EEPROM_HT40_1S_TX_PWR_INX 0x60 -#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 -#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 -#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C -#define EEPROM_HT40_MAX_PWR_OFFSET 0x25 -#define EEPROM_HT20_MAX_PWR_OFFSET 0x22 - -#define EEPROM_THERMAL_METER 0x2a -#define EEPROM_XTAL_K 0x78 -#define EEPROM_RF_OPT1 0x79 -#define EEPROM_RF_OPT2 0x7A -#define EEPROM_RF_OPT3 0x7B -#define EEPROM_RF_OPT4 0x7C -#define EEPROM_CHANNEL_PLAN 0x28 -#define EEPROM_VERSION 0x30 -#define EEPROM_CUSTOMER_ID 0x31 - -#define EEPROM_PWRDIFF 0x54 - -#define EEPROM_TXPOWERCCK 0x10 -#define EEPROM_TXPOWERHT40_1S 0x16 -#define EEPROM_TXPOWERHT40_2SDIFF 0x66 -#define EEPROM_TXPOWERHT20DIFF 0x1C -#define EEPROM_TXPOWER_OFDMDIFF 0x1F - -#define EEPROM_TXPWR_GROUP 0x22 - -#define EEPROM_TSSI_A 0x29 -#define EEPROM_TSSI_B 0x77 - -#define EEPROM_CHANNELPLAN 0x28 - -#define RF_OPTION1 0x2B -#define RF_OPTION2 0x2C -#define RF_OPTION3 0x2D -#define RF_OPTION4 0x2E - -#define STOPBECON BIT(6) -#define STOPHIGHT BIT(5) -#define STOPMGT BIT(4) -#define STOPVO BIT(3) -#define STOPVI BIT(2) -#define STOPBE BIT(1) -#define STOPBK BIT(0) - -#define RCR_APPFCS BIT(31) -#define RCR_APP_MIC BIT(30) -#define RCR_APP_ICV BIT(29) -#define RCR_APP_PHYST_RXFF BIT(28) -#define RCR_APP_BA_SSN BIT(27) -#define RCR_ENMBID BIT(24) -#define RCR_LSIGEN BIT(23) -#define RCR_MFBEN BIT(22) -#define RCR_HTC_LOC_CTRL BIT(14) -#define RCR_AMF BIT(13) -#define RCR_ACF BIT(12) -#define RCR_ADF BIT(11) -#define RCR_AICV BIT(9) -#define RCR_ACRC32 BIT(8) -#define RCR_CBSSID_BCN BIT(7) -#define RCR_CBSSID_DATA BIT(6) -#define RCR_CBSSID RCR_CBSSID_DATA -#define RCR_APWRMGT BIT(5) -#define RCR_ADD3 BIT(4) -#define RCR_AB BIT(3) -#define RCR_AM BIT(2) -#define RCR_APM BIT(1) -#define RCR_AAP BIT(0) -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 - -#define RSV_CTRL 0x001C -#define RD_CTRL 0x0524 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_USB_VID 0xFE60 -#define REG_USB_PID 0xFE62 -#define REG_USB_OPTIONAL 0xFE64 -#define REG_USB_CHIRP_K 0xFE65 -#define REG_USB_PHY 0xFE66 -#define REG_USB_MAC_ADDR 0xFE70 -#define REG_USB_HRPWM 0xFE58 -#define REG_USB_HCPWM 0xFE57 - -#define SW18_FPWM BIT(3) - -#define ISO_MD2PP BIT(0) -#define ISO_UA2USB BIT(1) -#define ISO_UD2CORE BIT(2) -#define ISO_PA2PCIE BIT(3) -#define ISO_PD2CORE BIT(4) -#define ISO_IP2MAC BIT(5) -#define ISO_DIOP BIT(6) -#define ISO_DIOE BIT(7) -#define ISO_EB2CORE BIT(8) -#define ISO_DIOR BIT(9) - -#define PWC_EV25V BIT(14) -#define PWC_EV12V BIT(15) - -#define FEN_BBRSTB BIT(0) -#define FEN_BB_GLB_RSTn BIT(1) -#define FEN_USBA BIT(2) -#define FEN_UPLL BIT(3) -#define FEN_USBD BIT(4) -#define FEN_DIO_PCIE BIT(5) -#define FEN_PCIEA BIT(6) -#define FEN_PPLL BIT(7) -#define FEN_PCIED BIT(8) -#define FEN_DIOE BIT(9) -#define FEN_CPUEN BIT(10) -#define FEN_DCORE BIT(11) -#define FEN_ELDR BIT(12) -#define FEN_DIO_RF BIT(13) -#define FEN_HWPDN BIT(14) -#define FEN_MREGEN BIT(15) - -#define PFM_LDALL BIT(0) -#define PFM_ALDN BIT(1) -#define PFM_LDKP BIT(2) -#define PFM_WOWL BIT(3) -#define EnPDN BIT(4) -#define PDN_PL BIT(5) -#define APFM_ONMAC BIT(8) -#define APFM_OFF BIT(9) -#define APFM_RSM BIT(10) -#define AFSM_HSUS BIT(11) -#define AFSM_PCIE BIT(12) -#define APDM_MAC BIT(13) -#define APDM_HOST BIT(14) -#define APDM_HPDN BIT(15) -#define RDY_MACON BIT(16) -#define SUS_HOST BIT(17) -#define ROP_ALD BIT(20) -#define ROP_PWR BIT(21) -#define ROP_SPS BIT(22) -#define SOP_MRST BIT(25) -#define SOP_FUSE BIT(26) -#define SOP_ABG BIT(27) -#define SOP_AMB BIT(28) -#define SOP_RCK BIT(29) -#define SOP_A8M BIT(30) -#define XOP_BTCK BIT(31) - -#define ANAD16V_EN BIT(0) -#define ANA8M BIT(1) -#define MACSLP BIT(4) -#define LOADER_CLK_EN BIT(5) -#define _80M_SSC_DIS BIT(7) -#define _80M_SSC_EN_HO BIT(8) -#define PHY_SSC_RSTB BIT(9) -#define SEC_CLK_EN BIT(10) -#define MAC_CLK_EN BIT(11) -#define SYS_CLK_EN BIT(12) -#define RING_CLK_EN BIT(13) - -#define BOOT_FROM_EEPROM BIT(4) -#define EEPROM_EN BIT(5) - -#define AFE_BGEN BIT(0) -#define AFE_MBEN BIT(1) -#define MAC_ID_EN BIT(7) - -#define WLOCK_ALL BIT(0) -#define WLOCK_00 BIT(1) -#define WLOCK_04 BIT(2) -#define WLOCK_08 BIT(3) -#define WLOCK_40 BIT(4) -#define R_DIS_PRST_0 BIT(5) -#define R_DIS_PRST_1 BIT(6) -#define LOCK_ALL_EN BIT(7) - -#define RF_EN BIT(0) -#define RF_RSTB BIT(1) -#define RF_SDMRSTB BIT(2) - -#define LDA15_EN BIT(0) -#define LDA15_STBY BIT(1) -#define LDA15_OBUF BIT(2) -#define LDA15_REG_VOS BIT(3) -#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) - -#define LDV12_EN BIT(0) -#define LDV12_SDBY BIT(1) -#define LPLDO_HSM BIT(2) -#define LPLDO_LSM_DIS BIT(3) -#define _LDV12_VADJ(x) (((x) & 0xF) << 4) - -#define XTAL_EN BIT(0) -#define XTAL_BSEL BIT(1) -#define _XTAL_BOSC(x) (((x) & 0x3) << 2) -#define _XTAL_CADJ(x) (((x) & 0xF) << 4) -#define XTAL_GATE_USB BIT(8) -#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) -#define XTAL_GATE_AFE BIT(11) -#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) -#define XTAL_RF_GATE BIT(14) -#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) -#define XTAL_GATE_DIG BIT(17) -#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) -#define XTAL_BT_GATE BIT(20) -#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) -#define _XTAL_GPIO(x) (((x) & 0x7) << 23) - -#define CKDLY_AFE BIT(26) -#define CKDLY_USB BIT(27) -#define CKDLY_DIG BIT(28) -#define CKDLY_BT BIT(29) - -#define APLL_EN BIT(0) -#define APLL_320_EN BIT(1) -#define APLL_FREF_SEL BIT(2) -#define APLL_EDGE_SEL BIT(3) -#define APLL_WDOGB BIT(4) -#define APLL_LPFEN BIT(5) - -#define APLL_REF_CLK_13MHZ 0x1 -#define APLL_REF_CLK_19_2MHZ 0x2 -#define APLL_REF_CLK_20MHZ 0x3 -#define APLL_REF_CLK_25MHZ 0x4 -#define APLL_REF_CLK_26MHZ 0x5 -#define APLL_REF_CLK_38_4MHZ 0x6 -#define APLL_REF_CLK_40MHZ 0x7 - -#define APLL_320EN BIT(14) -#define APLL_80EN BIT(15) -#define APLL_1MEN BIT(24) - -#define ALD_EN BIT(18) -#define EF_PD BIT(19) -#define EF_FLAG BIT(31) - -#define EF_TRPT BIT(7) -#define LDOE25_EN BIT(31) - -#define RSM_EN BIT(0) -#define Timer_EN BIT(4) - -#define TRSW0EN BIT(2) -#define TRSW1EN BIT(3) -#define EROM_EN BIT(4) -#define EnBT BIT(5) -#define EnUart BIT(8) -#define Uart_910 BIT(9) -#define EnPMAC BIT(10) -#define SIC_SWRST BIT(11) -#define EnSIC BIT(12) -#define SIC_23 BIT(13) -#define EnHDP BIT(14) -#define SIC_LBK BIT(15) - -#define LED0PL BIT(4) -#define LED1PL BIT(12) -#define LED0DIS BIT(7) - -#define MCUFWDL_EN BIT(0) -#define MCUFWDL_RDY BIT(1) -#define FWDL_ChkSum_rpt BIT(2) -#define MACINI_RDY BIT(3) -#define BBINI_RDY BIT(4) -#define RFINI_RDY BIT(5) -#define WINTINI_RDY BIT(6) -#define CPRST BIT(23) - -#define XCLK_VLD BIT(0) -#define ACLK_VLD BIT(1) -#define UCLK_VLD BIT(2) -#define PCLK_VLD BIT(3) -#define PCIRSTB BIT(4) -#define V15_VLD BIT(5) -#define TRP_B15V_EN BIT(7) -#define SIC_IDLE BIT(8) -#define BD_MAC2 BIT(9) -#define BD_MAC1 BIT(10) -#define IC_MACPHY_MODE BIT(11) -#define BT_FUNC BIT(16) -#define VENDOR_ID BIT(19) -#define PAD_HWPD_IDN BIT(22) -#define TRP_VAUX_EN BIT(23) -#define TRP_BT_EN BIT(24) -#define BD_PKG_SEL BIT(25) -#define BD_HCI_SEL BIT(26) -#define TYPE_ID BIT(27) - -#define CHIP_VER_RTL_MASK 0xF000 -#define CHIP_VER_RTL_SHIFT 12 - -#define REG_LBMODE (REG_CR + 3) - -#define HCI_TXDMA_EN BIT(0) -#define HCI_RXDMA_EN BIT(1) -#define TXDMA_EN BIT(2) -#define RXDMA_EN BIT(3) -#define PROTOCOL_EN BIT(4) -#define SCHEDULE_EN BIT(5) -#define MACTXEN BIT(6) -#define MACRXEN BIT(7) -#define ENSWBCN BIT(8) -#define ENSEC BIT(9) - -#define _NETTYPE(x) (((x) & 0x3) << 16) -#define MASK_NETTYPE 0x30000 -#define NT_NO_LINK 0x0 -#define NT_LINK_AD_HOC 0x1 -#define NT_LINK_AP 0x2 -#define NT_AS_AP 0x3 - -#define _LBMODE(x) (((x) & 0xF) << 24) -#define MASK_LBMODE 0xF000000 -#define LOOPBACK_NORMAL 0x0 -#define LOOPBACK_IMMEDIATELY 0xB -#define LOOPBACK_MAC_DELAY 0x3 -#define LOOPBACK_PHY 0x1 -#define LOOPBACK_DMA 0x7 - -#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) -#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) -#define _PSRX_MASK 0xF -#define _PSTX_MASK 0xF0 -#define _PSRX(x) (x) -#define _PSTX(x) ((x) << 4) - -#define PBP_64 0x0 -#define PBP_128 0x1 -#define PBP_256 0x2 -#define PBP_512 0x3 -#define PBP_1024 0x4 - -#define RXDMA_ARBBW_EN BIT(0) -#define RXSHFT_EN BIT(1) -#define RXDMA_AGG_EN BIT(2) -#define QS_VO_QUEUE BIT(8) -#define QS_VI_QUEUE BIT(9) -#define QS_BE_QUEUE BIT(10) -#define QS_BK_QUEUE BIT(11) -#define QS_MANAGER_QUEUE BIT(12) -#define QS_HIGH_QUEUE BIT(13) - -#define HQSEL_VOQ BIT(0) -#define HQSEL_VIQ BIT(1) -#define HQSEL_BEQ BIT(2) -#define HQSEL_BKQ BIT(3) -#define HQSEL_MGTQ BIT(4) -#define HQSEL_HIQ BIT(5) - -#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) -#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) -#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) -#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) -#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) -#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) - -#define QUEUE_LOW 1 -#define QUEUE_NORMAL 2 -#define QUEUE_HIGH 3 - -#define _LLT_NO_ACTIVE 0x0 -#define _LLT_WRITE_ACCESS 0x1 -#define _LLT_READ_ACCESS 0x2 - -#define _LLT_INIT_DATA(x) ((x) & 0xFF) -#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) -#define _LLT_OP(x) (((x) & 0x3) << 30) -#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) - -#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) -#define BB_WRITE_EN BIT(30) -#define BB_READ_EN BIT(31) - -#define _HPQ(x) ((x) & 0xFF) -#define _LPQ(x) (((x) & 0xFF) << 8) -#define _PUBQ(x) (((x) & 0xFF) << 16) -#define _NPQ(x) ((x) & 0xFF) - -#define HPQ_PUBLIC_DIS BIT(24) -#define LPQ_PUBLIC_DIS BIT(25) -#define LD_RQPN BIT(31) - -#define BCN_VALID BIT(16) -#define BCN_HEAD(x) (((x) & 0xFF) << 8) -#define BCN_HEAD_MASK 0xFF00 - -#define BLK_DESC_NUM_SHIFT 4 -#define BLK_DESC_NUM_MASK 0xF - -#define DROP_DATA_EN BIT(9) - -#define EN_AMPDU_RTY_NEW BIT(7) - -#define _INIRTSMCS_SEL(x) ((x) & 0x3F) - -#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) -#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) - -#define RATE_REG_BITMAP_ALL 0xFFFFF - -#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) - -#define _RRSR_RSC(x) (((x) & 0x3) << 21) -#define RRSR_RSC_RESERVED 0x0 -#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 -#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 -#define RRSR_RSC_DUPLICATE_MODE 0x3 - -#define USE_SHORT_G1 BIT(20) - -#define _AGGLMT_MCS0(x) ((x) & 0xF) -#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) -#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) -#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) -#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) -#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) -#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) -#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) - -#define RETRY_LIMIT_SHORT_SHIFT 8 -#define RETRY_LIMIT_LONG_SHIFT 0 - -#define _DARF_RC1(x) ((x) & 0x1F) -#define _DARF_RC2(x) (((x) & 0x1F) << 8) -#define _DARF_RC3(x) (((x) & 0x1F) << 16) -#define _DARF_RC4(x) (((x) & 0x1F) << 24) -#define _DARF_RC5(x) ((x) & 0x1F) -#define _DARF_RC6(x) (((x) & 0x1F) << 8) -#define _DARF_RC7(x) (((x) & 0x1F) << 16) -#define _DARF_RC8(x) (((x) & 0x1F) << 24) - -#define _RARF_RC1(x) ((x) & 0x1F) -#define _RARF_RC2(x) (((x) & 0x1F) << 8) -#define _RARF_RC3(x) (((x) & 0x1F) << 16) -#define _RARF_RC4(x) (((x) & 0x1F) << 24) -#define _RARF_RC5(x) ((x) & 0x1F) -#define _RARF_RC6(x) (((x) & 0x1F) << 8) -#define _RARF_RC7(x) (((x) & 0x1F) << 16) -#define _RARF_RC8(x) (((x) & 0x1F) << 24) - -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - -#define _AIFS(x) (x) -#define _ECW_MAX_MIN(x) ((x) << 8) -#define _TXOP_LIMIT(x) ((x) << 16) - -#define _BCNIFS(x) ((x) & 0xFF) -#define _BCNECW(x) ((((x) & 0xF)) << 8) - -#define _LRL(x) ((x) & 0x3F) -#define _SRL(x) (((x) & 0x3F) << 8) - -#define _SIFS_CCK_CTX(x) ((x) & 0xFF) -#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); - -#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) -#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); - -#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) - -#define DIS_EDCA_CNT_DWN BIT(11) - -#define EN_MBSSID BIT(1) -#define EN_TXBCN_RPT BIT(2) -#define EN_BCN_FUNCTION BIT(3) - -#define TSFTR_RST BIT(0) -#define TSFTR1_RST BIT(1) - -#define STOP_BCNQ BIT(6) - -#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) -#define DIS_TSF_UDT0_TEST_CHIP BIT(5) - -#define AcmHw_HwEn BIT(0) -#define AcmHw_BeqEn BIT(1) -#define AcmHw_ViqEn BIT(2) -#define AcmHw_VoqEn BIT(3) -#define AcmHw_BeqStatus BIT(4) -#define AcmHw_ViqStatus BIT(5) -#define AcmHw_VoqStatus BIT(6) - -#define APSDOFF BIT(6) -#define APSDOFF_STATUS BIT(7) - -#define BW_20MHZ BIT(2) - -#define RATE_BITMAP_ALL 0xFFFFF - -#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 - -#define TSFRST BIT(0) -#define DIS_GCLK BIT(1) -#define PAD_SEL BIT(2) -#define PWR_ST BIT(6) -#define PWRBIT_OW_EN BIT(7) -#define ACRC BIT(8) -#define CFENDFORM BIT(9) -#define ICV BIT(10) - -#define AAP BIT(0) -#define APM BIT(1) -#define AM BIT(2) -#define AB BIT(3) -#define ADD3 BIT(4) -#define APWRMGT BIT(5) -#define CBSSID BIT(6) -#define CBSSID_DATA BIT(6) -#define CBSSID_BCN BIT(7) -#define ACRC32 BIT(8) -#define AICV BIT(9) -#define ADF BIT(11) -#define ACF BIT(12) -#define AMF BIT(13) -#define HTC_LOC_CTRL BIT(14) -#define UC_DATA_EN BIT(16) -#define BM_DATA_EN BIT(17) -#define MFBEN BIT(22) -#define LSIGEN BIT(23) -#define EnMBID BIT(24) -#define APP_BASSN BIT(27) -#define APP_PHYSTS BIT(28) -#define APP_ICV BIT(29) -#define APP_MIC BIT(30) -#define APP_FCS BIT(31) - -#define _MIN_SPACE(x) ((x) & 0x7) -#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) - -#define RXERR_TYPE_OFDM_PPDU 0 -#define RXERR_TYPE_OFDM_FALSE_ALARM 1 -#define RXERR_TYPE_OFDM_MPDU_OK 2 -#define RXERR_TYPE_OFDM_MPDU_FAIL 3 -#define RXERR_TYPE_CCK_PPDU 4 -#define RXERR_TYPE_CCK_FALSE_ALARM 5 -#define RXERR_TYPE_CCK_MPDU_OK 6 -#define RXERR_TYPE_CCK_MPDU_FAIL 7 -#define RXERR_TYPE_HT_PPDU 8 -#define RXERR_TYPE_HT_FALSE_ALARM 9 -#define RXERR_TYPE_HT_MPDU_TOTAL 10 -#define RXERR_TYPE_HT_MPDU_OK 11 -#define RXERR_TYPE_HT_MPDU_FAIL 12 -#define RXERR_TYPE_RX_FULL_DROP 15 - -#define RXERR_COUNTER_MASK 0xFFFFF -#define RXERR_RPT_RST BIT(27) -#define _RXERR_RPT_SEL(type) ((type) << 28) - -#define SCR_TxUseDK BIT(0) -#define SCR_RxUseDK BIT(1) -#define SCR_TxEncEnable BIT(2) -#define SCR_RxDecEnable BIT(3) -#define SCR_SKByA2 BIT(4) -#define SCR_NoSKMC BIT(5) -#define SCR_TXBCUSEDK BIT(6) -#define SCR_RXBCUSEDK BIT(7) - -#define USB_IS_HIGH_SPEED 0 -#define USB_IS_FULL_SPEED 1 -#define USB_SPEED_MASK BIT(5) - -#define USB_NORMAL_SIE_EP_MASK 0xF -#define USB_NORMAL_SIE_EP_SHIFT 4 - -#define USB_TEST_EP_MASK 0x30 -#define USB_TEST_EP_SHIFT 4 - -#define USB_AGG_EN BIT(3) - -#define MAC_ADDR_LEN 6 -#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 - -#define POLLING_LLT_THRESHOLD 20 -#define POLLING_READY_TIMEOUT_COUNT 1000 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) -#define EPROM_CMD_CONFIG 0x3 -#define EPROM_CMD_LOAD 1 - -#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE - -#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) - -#define RPMAC_RESET 0x100 -#define RPMAC_TXSTART 0x104 -#define RPMAC_TXLEGACYSIG 0x108 -#define RPMAC_TXHTSIG1 0x10c -#define RPMAC_TXHTSIG2 0x110 -#define RPMAC_PHYDEBUG 0x114 -#define RPMAC_TXPACKETNUM 0x118 -#define RPMAC_TXIDLE 0x11c -#define RPMAC_TXMACHEADER0 0x120 -#define RPMAC_TXMACHEADER1 0x124 -#define RPMAC_TXMACHEADER2 0x128 -#define RPMAC_TXMACHEADER3 0x12c -#define RPMAC_TXMACHEADER4 0x130 -#define RPMAC_TXMACHEADER5 0x134 -#define RPMAC_TXDADATYPE 0x138 -#define RPMAC_TXRANDOMSEED 0x13c -#define RPMAC_CCKPLCPPREAMBLE 0x140 -#define RPMAC_CCKPLCPHEADER 0x144 -#define RPMAC_CCKCRC16 0x148 -#define RPMAC_OFDMRXCRC32OK 0x170 -#define RPMAC_OFDMRXCRC32Er 0x174 -#define RPMAC_OFDMRXPARITYER 0x178 -#define RPMAC_OFDMRXCRC8ER 0x17c -#define RPMAC_CCKCRXRC16ER 0x180 -#define RPMAC_CCKCRXRC32ER 0x184 -#define RPMAC_CCKCRXRC32OK 0x188 -#define RPMAC_TXSTATUS 0x18c - -#define RFPGA0_RFMOD 0x800 - -#define RFPGA0_TXINFO 0x804 -#define RFPGA0_PSDFUNCTION 0x808 - -#define RFPGA0_TXGAINSTAGE 0x80c - -#define RFPGA0_RFTIMING1 0x810 -#define RFPGA0_RFTIMING2 0x814 - -#define RFPGA0_XA_HSSIPARAMETER1 0x820 -#define RFPGA0_XA_HSSIPARAMETER2 0x824 -#define RFPGA0_XB_HSSIPARAMETER1 0x828 -#define RFPGA0_XB_HSSIPARAMETER2 0x82c - -#define RFPGA0_XA_LSSIPARAMETER 0x840 -#define RFPGA0_XB_LSSIPARAMETER 0x844 - -#define RFPGA0_RFWAKEUPPARAMETER 0x850 -#define RFPGA0_RFSLEEPUPPARAMETER 0x854 - -#define RFPGA0_XAB_SWITCHCONTROL 0x858 -#define RFPGA0_XCD_SWITCHCONTROL 0x85c - -#define RFPGA0_XA_RFINTERFACEOE 0x860 -#define RFPGA0_XB_RFINTERFACEOE 0x864 - -#define RFPGA0_XAB_RFINTERFACESW 0x870 -#define RFPGA0_XCD_RFINTERFACESW 0x874 - -#define rFPGA0_XAB_RFPARAMETER 0x878 -#define rFPGA0_XCD_RFPARAMETER 0x87c - -#define RFPGA0_ANALOGPARAMETER1 0x880 -#define RFPGA0_ANALOGPARAMETER2 0x884 -#define RFPGA0_ANALOGPARAMETER3 0x888 -#define RFPGA0_ANALOGPARAMETER4 0x88c - -#define RFPGA0_XA_LSSIREADBACK 0x8a0 -#define RFPGA0_XB_LSSIREADBACK 0x8a4 -#define RFPGA0_XC_LSSIREADBACK 0x8a8 -#define RFPGA0_XD_LSSIREADBACK 0x8ac - -#define RFPGA0_PSDREPORT 0x8b4 -#define TRANSCEIVEA_HSPI_READBACK 0x8b8 -#define TRANSCEIVEB_HSPI_READBACK 0x8bc -#define RFPGA0_XAB_RFINTERFACERB 0x8e0 -#define RFPGA0_XCD_RFINTERFACERB 0x8e4 - -#define RFPGA1_RFMOD 0x900 - -#define RFPGA1_TXBLOCK 0x904 -#define RFPGA1_DEBUGSELECT 0x908 -#define RFPGA1_TXINFO 0x90c - -#define RCCK0_SYSTEM 0xa00 - -#define RCCK0_AFESETTING 0xa04 -#define RCCK0_CCA 0xa08 - -#define RCCK0_RXAGC1 0xa0c -#define RCCK0_RXAGC2 0xa10 - -#define RCCK0_RXHP 0xa14 - -#define RCCK0_DSPPARAMETER1 0xa18 -#define RCCK0_DSPPARAMETER2 0xa1c - -#define RCCK0_TXFILTER1 0xa20 -#define RCCK0_TXFILTER2 0xa24 -#define RCCK0_DEBUGPORT 0xa28 -#define RCCK0_FALSEALARMREPORT 0xa2c -#define RCCK0_TRSSIREPORT 0xa50 -#define RCCK0_RXREPORT 0xa54 -#define RCCK0_FACOUNTERLOWER 0xa5c -#define RCCK0_FACOUNTERUPPER 0xa58 - -#define ROFDM0_LSTF 0xc00 - -#define ROFDM0_TRXPATHENABLE 0xc04 -#define ROFDM0_TRMUXPAR 0xc08 -#define ROFDM0_TRSWISOLATION 0xc0c - -#define ROFDM0_XARXAFE 0xc10 -#define ROFDM0_XARXIQIMBALANCE 0xc14 -#define ROFDM0_XBRXAFE 0xc18 -#define ROFDM0_XBRXIQIMBALANCE 0xc1c -#define ROFDM0_XCRXAFE 0xc20 -#define ROFDM0_XCRXIQIMBANLANCE 0xc24 -#define ROFDM0_XDRXAFE 0xc28 -#define ROFDM0_XDRXIQIMBALANCE 0xc2c - -#define ROFDM0_RXDETECTOR1 0xc30 -#define ROFDM0_RXDETECTOR2 0xc34 -#define ROFDM0_RXDETECTOR3 0xc38 -#define ROFDM0_RXDETECTOR4 0xc3c - -#define ROFDM0_RXDSP 0xc40 -#define ROFDM0_CFOANDDAGC 0xc44 -#define ROFDM0_CCADROPTHRESHOLD 0xc48 -#define ROFDM0_ECCATHRESHOLD 0xc4c - -#define ROFDM0_XAAGCCORE1 0xc50 -#define ROFDM0_XAAGCCORE2 0xc54 -#define ROFDM0_XBAGCCORE1 0xc58 -#define ROFDM0_XBAGCCORE2 0xc5c -#define ROFDM0_XCAGCCORE1 0xc60 -#define ROFDM0_XCAGCCORE2 0xc64 -#define ROFDM0_XDAGCCORE1 0xc68 -#define ROFDM0_XDAGCCORE2 0xc6c - -#define ROFDM0_AGCPARAMETER1 0xc70 -#define ROFDM0_AGCPARAMETER2 0xc74 -#define ROFDM0_AGCRSSITABLE 0xc78 -#define ROFDM0_HTSTFAGC 0xc7c - -#define ROFDM0_XATXIQIMBALANCE 0xc80 -#define ROFDM0_XATXAFE 0xc84 -#define ROFDM0_XBTXIQIMBALANCE 0xc88 -#define ROFDM0_XBTXAFE 0xc8c -#define ROFDM0_XCTXIQIMBALANCE 0xc90 -#define ROFDM0_XCTXAFE 0xc94 -#define ROFDM0_XDTXIQIMBALANCE 0xc98 -#define ROFDM0_XDTXAFE 0xc9c - -#define ROFDM0_RXIQEXTANTA 0xca0 - -#define ROFDM0_RXHPPARAMETER 0xce0 -#define ROFDM0_TXPSEUDONOISEWGT 0xce4 -#define ROFDM0_FRAMESYNC 0xcf0 -#define ROFDM0_DFSREPORT 0xcf4 -#define ROFDM0_TXCOEFF1 0xca4 -#define ROFDM0_TXCOEFF2 0xca8 -#define ROFDM0_TXCOEFF3 0xcac -#define ROFDM0_TXCOEFF4 0xcb0 -#define ROFDM0_TXCOEFF5 0xcb4 -#define ROFDM0_TXCOEFF6 0xcb8 - -#define ROFDM1_LSTF 0xd00 -#define ROFDM1_TRXPATHENABLE 0xd04 - -#define ROFDM1_CF0 0xd08 -#define ROFDM1_CSI1 0xd10 -#define ROFDM1_SBD 0xd14 -#define ROFDM1_CSI2 0xd18 -#define ROFDM1_CFOTRACKING 0xd2c -#define ROFDM1_TRXMESAURE1 0xd34 -#define ROFDM1_INTFDET 0xd3c -#define ROFDM1_PSEUDONOISESTATEAB 0xd50 -#define ROFDM1_PSEUDONOISESTATECD 0xd54 -#define ROFDM1_RXPSEUDONOISEWGT 0xd58 - -#define ROFDM_PHYCOUNTER1 0xda0 -#define ROFDM_PHYCOUNTER2 0xda4 -#define ROFDM_PHYCOUNTER3 0xda8 - -#define ROFDM_SHORTCFOAB 0xdac -#define ROFDM_SHORTCFOCD 0xdb0 -#define ROFDM_LONGCFOAB 0xdb4 -#define ROFDM_LONGCFOCD 0xdb8 -#define ROFDM_TAILCF0AB 0xdbc -#define ROFDM_TAILCF0CD 0xdc0 -#define ROFDM_PWMEASURE1 0xdc4 -#define ROFDM_PWMEASURE2 0xdc8 -#define ROFDM_BWREPORT 0xdcc -#define ROFDM_AGCREPORT 0xdd0 -#define ROFDM_RXSNR 0xdd4 -#define ROFDM_RXEVMCSI 0xdd8 -#define ROFDM_SIGREPORT 0xddc - -#define RTXAGC_A_RATE18_06 0xe00 -#define RTXAGC_A_RATE54_24 0xe04 -#define RTXAGC_A_CCK1_MCS32 0xe08 -#define RTXAGC_A_MCS03_MCS00 0xe10 -#define RTXAGC_A_MCS07_MCS04 0xe14 -#define RTXAGC_A_MCS11_MCS08 0xe18 -#define RTXAGC_A_MCS15_MCS12 0xe1c - -#define RTXAGC_B_RATE18_06 0x830 -#define RTXAGC_B_RATE54_24 0x834 -#define RTXAGC_B_CCK1_55_MCS32 0x838 -#define RTXAGC_B_MCS03_MCS00 0x83c -#define RTXAGC_B_MCS07_MCS04 0x848 -#define RTXAGC_B_MCS11_MCS08 0x84c -#define RTXAGC_B_MCS15_MCS12 0x868 -#define RTXAGC_B_CCK11_A_CCK2_11 0x86c - -#define RZEBRA1_HSSIENABLE 0x0 -#define RZEBRA1_TRXENABLE1 0x1 -#define RZEBRA1_TRXENABLE2 0x2 -#define RZEBRA1_AGC 0x4 -#define RZEBRA1_CHARGEPUMP 0x5 -#define RZEBRA1_CHANNEL 0x7 - -#define RZEBRA1_TXGAIN 0x8 -#define RZEBRA1_TXLPF 0x9 -#define RZEBRA1_RXLPF 0xb -#define RZEBRA1_RXHPFCORNER 0xc - -#define RGLOBALCTRL 0 -#define RRTL8256_TXLPF 19 -#define RRTL8256_RXLPF 11 -#define RRTL8258_TXLPF 0x11 -#define RRTL8258_RXLPF 0x13 -#define RRTL8258_RSSILPF 0xa - -#define RF_AC 0x00 - -#define RF_IQADJ_G1 0x01 -#define RF_IQADJ_G2 0x02 -#define RF_POW_TRSW 0x05 - -#define RF_GAIN_RX 0x06 -#define RF_GAIN_TX 0x07 - -#define RF_TXM_IDAC 0x08 -#define RF_BS_IQGEN 0x0F - -#define RF_MODE1 0x10 -#define RF_MODE2 0x11 - -#define RF_RX_AGC_HP 0x12 -#define RF_TX_AGC 0x13 -#define RF_BIAS 0x14 -#define RF_IPA 0x15 -#define RF_POW_ABILITY 0x17 -#define RF_MODE_AG 0x18 -#define RRFCHANNEL 0x18 -#define RF_CHNLBW 0x18 -#define RF_TOP 0x19 - -#define RF_RX_G1 0x1A -#define RF_RX_G2 0x1B - -#define RF_RX_BB2 0x1C -#define RF_RX_BB1 0x1D - -#define RF_RCK1 0x1E -#define RF_RCK2 0x1F - -#define RF_TX_G1 0x20 -#define RF_TX_G2 0x21 -#define RF_TX_G3 0x22 - -#define RF_TX_BB1 0x23 -#define RF_T_METER 0x24 - -#define RF_SYN_G1 0x25 -#define RF_SYN_G2 0x26 -#define RF_SYN_G3 0x27 -#define RF_SYN_G4 0x28 -#define RF_SYN_G5 0x29 -#define RF_SYN_G6 0x2A -#define RF_SYN_G7 0x2B -#define RF_SYN_G8 0x2C - -#define RF_RCK_OS 0x30 -#define RF_TXPA_G1 0x31 -#define RF_TXPA_G2 0x32 -#define RF_TXPA_G3 0x33 - -#define BBBRESETB 0x100 -#define BGLOBALRESETB 0x200 -#define BOFDMTXSTART 0x4 -#define BCCKTXSTART 0x8 -#define BCRC32DEBUG 0x100 -#define BPMACLOOPBACK 0x10 -#define BTXLSIG 0xffffff -#define BOFDMTXRATE 0xf -#define BOFDMTXRESERVED 0x10 -#define BOFDMTXLENGTH 0x1ffe0 -#define BOFDMTXPARITY 0x20000 -#define BTXHTSIG1 0xffffff -#define BTXHTMCSRATE 0x7f -#define BTXHTBW 0x80 -#define BTXHTLENGTH 0xffff00 -#define BTXHTSIG2 0xffffff -#define BTXHTSMOOTHING 0x1 -#define BTXHTSOUNDING 0x2 -#define BTXHTRESERVED 0x4 -#define BTXHTAGGREATION 0x8 -#define BTXHTSTBC 0x30 -#define BTXHTADVANCECODING 0x40 -#define BTXHTSHORTGI 0x80 -#define BTXHTNUMBERHT_LTF 0x300 -#define BTXHTCRC8 0x3fc00 -#define BCOUNTERRESET 0x10000 -#define BNUMOFOFDMTX 0xffff -#define BNUMOFCCKTX 0xffff0000 -#define BTXIDLEINTERVAL 0xffff -#define BOFDMSERVICE 0xffff0000 -#define BTXMACHEADER 0xffffffff -#define BTXDATAINIT 0xff -#define BTXHTMODE 0x100 -#define BTXDATATYPE 0x30000 -#define BTXRANDOMSEED 0xffffffff -#define BCCKTXPREAMBLE 0x1 -#define BCCKTXSFD 0xffff0000 -#define BCCKTXSIG 0xff -#define BCCKTXSERVICE 0xff00 -#define BCCKLENGTHEXT 0x8000 -#define BCCKTXLENGHT 0xffff0000 -#define BCCKTXCRC16 0xffff -#define BCCKTXSTATUS 0x1 -#define BOFDMTXSTATUS 0x2 -#define IS_BB_REG_OFFSET_92S(_Offset) \ - ((_Offset >= 0x800) && (_Offset <= 0xfff)) - -#define BRFMOD 0x1 -#define BJAPANMODE 0x2 -#define BCCKTXSC 0x30 -#define BCCKEN 0x1000000 -#define BOFDMEN 0x2000000 - -#define BOFDMRXADCPHASE 0x10000 -#define BOFDMTXDACPHASE 0x40000 -#define BXATXAGC 0x3f - -#define BXBTXAGC 0xf00 -#define BXCTXAGC 0xf000 -#define BXDTXAGC 0xf0000 - -#define BPASTART 0xf0000000 -#define BTRSTART 0x00f00000 -#define BRFSTART 0x0000f000 -#define BBBSTART 0x000000f0 -#define BBBCCKSTART 0x0000000f -#define BPAEND 0xf -#define BTREND 0x0f000000 -#define BRFEND 0x000f0000 -#define BCCAMASK 0x000000f0 -#define BR2RCCAMASK 0x00000f00 -#define BHSSI_R2TDELAY 0xf8000000 -#define BHSSI_T2RDELAY 0xf80000 -#define BCONTXHSSI 0x400 -#define BIGFROMCCK 0x200 -#define BAGCADDRESS 0x3f -#define BRXHPTX 0x7000 -#define BRXHP2RX 0x38000 -#define BRXHPCCKINI 0xc0000 -#define BAGCTXCODE 0xc00000 -#define BAGCRXCODE 0x300000 - -#define B3WIREDATALENGTH 0x800 -#define B3WIREADDREAALENGTH 0x400 - -#define B3WIRERFPOWERDOWN 0x1 -#define B5GPAPEPOLARITY 0x40000000 -#define B2GPAPEPOLARITY 0x80000000 -#define BRFSW_TXDEFAULTANT 0x3 -#define BRFSW_TXOPTIONANT 0x30 -#define BRFSW_RXDEFAULTANT 0x300 -#define BRFSW_RXOPTIONANT 0x3000 -#define BRFSI_3WIREDATA 0x1 -#define BRFSI_3WIRECLOCK 0x2 -#define BRFSI_3WIRELOAD 0x4 -#define BRFSI_3WIRERW 0x8 -#define BRFSI_3WIRE 0xf - -#define BRFSI_RFENV 0x10 - -#define BRFSI_TRSW 0x20 -#define BRFSI_TRSWB 0x40 -#define BRFSI_ANTSW 0x100 -#define BRFSI_ANTSWB 0x200 -#define BRFSI_PAPE 0x400 -#define BRFSI_PAPE5G 0x800 -#define BBANDSELECT 0x1 -#define BHTSIG2_GI 0x80 -#define BHTSIG2_SMOOTHING 0x01 -#define BHTSIG2_SOUNDING 0x02 -#define BHTSIG2_AGGREATON 0x08 -#define BHTSIG2_STBC 0x30 -#define BHTSIG2_ADVCODING 0x40 -#define BHTSIG2_NUMOFHTLTF 0x300 -#define BHTSIG2_CRC8 0x3fc -#define BHTSIG1_MCS 0x7f -#define BHTSIG1_BANDWIDTH 0x80 -#define BHTSIG1_HTLENGTH 0xffff -#define BLSIG_RATE 0xf -#define BLSIG_RESERVED 0x10 -#define BLSIG_LENGTH 0x1fffe -#define BLSIG_PARITY 0x20 -#define BCCKRXPHASE 0x4 - -#define BLSSIREADADDRESS 0x7f800000 -#define BLSSIREADEDGE 0x80000000 - -#define BLSSIREADBACKDATA 0xfffff - -#define BLSSIREADOKFLAG 0x1000 -#define BCCKSAMPLERATE 0x8 -#define BREGULATOR0STANDBY 0x1 -#define BREGULATORPLLSTANDBY 0x2 -#define BREGULATOR1STANDBY 0x4 -#define BPLLPOWERUP 0x8 -#define BDPLLPOWERUP 0x10 -#define BDA10POWERUP 0x20 -#define BAD7POWERUP 0x200 -#define BDA6POWERUP 0x2000 -#define BXTALPOWERUP 0x4000 -#define B40MDCLKPOWERUP 0x8000 -#define BDA6DEBUGMODE 0x20000 -#define BDA6SWING 0x380000 - -#define BADCLKPHASE 0x4000000 -#define B80MCLKDELAY 0x18000000 -#define BAFEWATCHDOGENABLE 0x20000000 - -#define BXTALCAP01 0xc0000000 -#define BXTALCAP23 0x3 -#define BXTALCAP92X 0x0f000000 -#define BXTALCAP 0x0f000000 - -#define BINTDIFCLKENABLE 0x400 -#define BEXTSIGCLKENABLE 0x800 -#define BBANDGAP_MBIAS_POWERUP 0x10000 -#define BAD11SH_GAIN 0xc0000 -#define BAD11NPUT_RANGE 0x700000 -#define BAD110P_CURRENT 0x3800000 -#define BLPATH_LOOPBACK 0x4000000 -#define BQPATH_LOOPBACK 0x8000000 -#define BAFE_LOOPBACK 0x10000000 -#define BDA10_SWING 0x7e0 -#define BDA10_REVERSE 0x800 -#define BDA_CLK_SOURCE 0x1000 -#define BDA7INPUT_RANGE 0x6000 -#define BDA7_GAIN 0x38000 -#define BDA7OUTPUT_CM_MODE 0x40000 -#define BDA7INPUT_CM_MODE 0x380000 -#define BDA7CURRENT 0xc00000 -#define BREGULATOR_ADJUST 0x7000000 -#define BAD11POWERUP_ATTX 0x1 -#define BDA10PS_ATTX 0x10 -#define BAD11POWERUP_ATRX 0x100 -#define BDA10PS_ATRX 0x1000 -#define BCCKRX_AGC_FORMAT 0x200 -#define BPSDFFT_SAMPLE_POINT 0xc000 -#define BPSD_AVERAGE_NUM 0x3000 -#define BIQPATH_CONTROL 0xc00 -#define BPSD_FREQ 0x3ff -#define BPSD_ANTENNA_PATH 0x30 -#define BPSD_IQ_SWITCH 0x40 -#define BPSD_RX_TRIGGER 0x400000 -#define BPSD_TX_TRIGGER 0x80000000 -#define BPSD_SINE_TONE_SCALE 0x7f000000 -#define BPSD_REPORT 0xffff - -#define BOFDM_TXSC 0x30000000 -#define BCCK_TXON 0x1 -#define BOFDM_TXON 0x2 -#define BDEBUG_PAGE 0xfff -#define BDEBUG_ITEM 0xff -#define BANTL 0x10 -#define BANT_NONHT 0x100 -#define BANT_HT1 0x1000 -#define BANT_HT2 0x10000 -#define BANT_HT1S1 0x100000 -#define BANT_NONHTS1 0x1000000 - -#define BCCK_BBMODE 0x3 -#define BCCK_TXPOWERSAVING 0x80 -#define BCCK_RXPOWERSAVING 0x40 - -#define BCCK_SIDEBAND 0x10 - -#define BCCK_SCRAMBLE 0x8 -#define BCCK_ANTDIVERSITY 0x8000 -#define BCCK_CARRIER_RECOVERY 0x4000 -#define BCCK_TXRATE 0x3000 -#define BCCK_DCCANCEL 0x0800 -#define BCCK_ISICANCEL 0x0400 -#define BCCK_MATCH_FILTER 0x0200 -#define BCCK_EQUALIZER 0x0100 -#define BCCK_PREAMBLE_DETECT 0x800000 -#define BCCK_FAST_FALSECCAi 0x400000 -#define BCCK_CH_ESTSTARTi 0x300000 -#define BCCK_CCA_COUNTi 0x080000 -#define BCCK_CS_LIM 0x070000 -#define BCCK_BIST_MODEi 0x80000000 -#define BCCK_CCAMASK 0x40000000 -#define BCCK_TX_DAC_PHASE 0x4 -#define BCCK_RX_ADC_PHASE 0x20000000 -#define BCCKR_CP_MODE 0x0100 -#define BCCK_TXDC_OFFSET 0xf0 -#define BCCK_RXDC_OFFSET 0xf -#define BCCK_CCA_MODE 0xc000 -#define BCCK_FALSECS_LIM 0x3f00 -#define BCCK_CS_RATIO 0xc00000 -#define BCCK_CORGBIT_SEL 0x300000 -#define BCCK_PD_LIM 0x0f0000 -#define BCCK_NEWCCA 0x80000000 -#define BCCK_RXHP_OF_IG 0x8000 -#define BCCK_RXIG 0x7f00 -#define BCCK_LNA_POLARITY 0x800000 -#define BCCK_RX1ST_BAIN 0x7f0000 -#define BCCK_RF_EXTEND 0x20000000 -#define BCCK_RXAGC_SATLEVEL 0x1f000000 -#define BCCK_RXAGC_SATCOUNT 0xe0 -#define bCCKRxRFSettle 0x1f -#define BCCK_FIXED_RXAGC 0x8000 -#define BCCK_ANTENNA_POLARITY 0x2000 -#define BCCK_TXFILTER_TYPE 0x0c00 -#define BCCK_RXAGC_REPORTTYPE 0x0300 -#define BCCK_RXDAGC_EN 0x80000000 -#define BCCK_RXDAGC_PERIOD 0x20000000 -#define BCCK_RXDAGC_SATLEVEL 0x1f000000 -#define BCCK_TIMING_RECOVERY 0x800000 -#define BCCK_TXC0 0x3f0000 -#define BCCK_TXC1 0x3f000000 -#define BCCK_TXC2 0x3f -#define BCCK_TXC3 0x3f00 -#define BCCK_TXC4 0x3f0000 -#define BCCK_TXC5 0x3f000000 -#define BCCK_TXC6 0x3f -#define BCCK_TXC7 0x3f00 -#define BCCK_DEBUGPORT 0xff0000 -#define BCCK_DAC_DEBUG 0x0f000000 -#define BCCK_FALSEALARM_ENABLE 0x8000 -#define BCCK_FALSEALARM_READ 0x4000 -#define BCCK_TRSSI 0x7f -#define BCCK_RXAGC_REPORT 0xfe -#define BCCK_RXREPORT_ANTSEL 0x80000000 -#define BCCK_RXREPORT_MFOFF 0x40000000 -#define BCCK_RXREPORT_SQLOSS 0x20000000 -#define BCCK_RXREPORT_PKTLOSS 0x10000000 -#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 -#define BCCK_RXREPORT_RATEERROR 0x04000000 -#define BCCK_RXREPORT_RXRATE 0x03000000 -#define BCCK_RXFA_COUNTER_LOWER 0xff -#define BCCK_RXFA_COUNTER_UPPER 0xff000000 -#define BCCK_RXHPAGC_START 0xe000 -#define BCCK_RXHPAGC_FINAL 0x1c00 -#define BCCK_RXFALSEALARM_ENABLE 0x8000 -#define BCCK_FACOUNTER_FREEZE 0x4000 -#define BCCK_TXPATH_SEL 0x10000000 -#define BCCK_DEFAULT_RXPATH 0xc000000 -#define BCCK_OPTION_RXPATH 0x3000000 - -#define BNUM_OFSTF 0x3 -#define BSHIFT_L 0xc0 -#define BGI_TH 0xc -#define BRXPATH_A 0x1 -#define BRXPATH_B 0x2 -#define BRXPATH_C 0x4 -#define BRXPATH_D 0x8 -#define BTXPATH_A 0x1 -#define BTXPATH_B 0x2 -#define BTXPATH_C 0x4 -#define BTXPATH_D 0x8 -#define BTRSSI_FREQ 0x200 -#define BADC_BACKOFF 0x3000 -#define BDFIR_BACKOFF 0xc000 -#define BTRSSI_LATCH_PHASE 0x10000 -#define BRX_LDC_OFFSET 0xff -#define BRX_QDC_OFFSET 0xff00 -#define BRX_DFIR_MODE 0x1800000 -#define BRX_DCNF_TYPE 0xe000000 -#define BRXIQIMB_A 0x3ff -#define BRXIQIMB_B 0xfc00 -#define BRXIQIMB_C 0x3f0000 -#define BRXIQIMB_D 0xffc00000 -#define BDC_DC_NOTCH 0x60000 -#define BRXNB_NOTCH 0x1f000000 -#define BPD_TH 0xf -#define BPD_TH_OPT2 0xc000 -#define BPWED_TH 0x700 -#define BIFMF_WIN_L 0x800 -#define BPD_OPTION 0x1000 -#define BMF_WIN_L 0xe000 -#define BBW_SEARCH_L 0x30000 -#define BWIN_ENH_L 0xc0000 -#define BBW_TH 0x700000 -#define BED_TH2 0x3800000 -#define BBW_OPTION 0x4000000 -#define BRADIO_TH 0x18000000 -#define BWINDOW_L 0xe0000000 -#define BSBD_OPTION 0x1 -#define BFRAME_TH 0x1c -#define BFS_OPTION 0x60 -#define BDC_SLOPE_CHECK 0x80 -#define BFGUARD_COUNTER_DC_L 0xe00 -#define BFRAME_WEIGHT_SHORT 0x7000 -#define BSUB_TUNE 0xe00000 -#define BFRAME_DC_LENGTH 0xe000000 -#define BSBD_START_OFFSET 0x30000000 -#define BFRAME_TH_2 0x7 -#define BFRAME_GI2_TH 0x38 -#define BGI2_SYNC_EN 0x40 -#define BSARCH_SHORT_EARLY 0x300 -#define BSARCH_SHORT_LATE 0xc00 -#define BSARCH_GI2_LATE 0x70000 -#define BCFOANTSUM 0x1 -#define BCFOACC 0x2 -#define BCFOSTARTOFFSET 0xc -#define BCFOLOOPBACK 0x70 -#define BCFOSUMWEIGHT 0x80 -#define BDAGCENABLE 0x10000 -#define BTXIQIMB_A 0x3ff -#define BTXIQIMB_b 0xfc00 -#define BTXIQIMB_C 0x3f0000 -#define BTXIQIMB_D 0xffc00000 -#define BTXIDCOFFSET 0xff -#define BTXIQDCOFFSET 0xff00 -#define BTXDFIRMODE 0x10000 -#define BTXPESUDO_NOISEON 0x4000000 -#define BTXPESUDO_NOISE_A 0xff -#define BTXPESUDO_NOISE_B 0xff00 -#define BTXPESUDO_NOISE_C 0xff0000 -#define BTXPESUDO_NOISE_D 0xff000000 -#define BCCA_DROPOPTION 0x20000 -#define BCCA_DROPTHRES 0xfff00000 -#define BEDCCA_H 0xf -#define BEDCCA_L 0xf0 -#define BLAMBDA_ED 0x300 -#define BRX_INITIALGAIN 0x7f -#define BRX_ANTDIV_EN 0x80 -#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 -#define BRX_HIGHPOWER_FLOW 0x8000 -#define BRX_AGC_FREEZE_THRES 0xc0000 -#define BRX_FREEZESTEP_AGC1 0x300000 -#define BRX_FREEZESTEP_AGC2 0xc00000 -#define BRX_FREEZESTEP_AGC3 0x3000000 -#define BRX_FREEZESTEP_AGC0 0xc000000 -#define BRXRSSI_CMP_EN 0x10000000 -#define BRXQUICK_AGCEN 0x20000000 -#define BRXAGC_FREEZE_THRES_MODE 0x40000000 -#define BRX_OVERFLOW_CHECKTYPE 0x80000000 -#define BRX_AGCSHIFT 0x7f -#define BTRSW_TRI_ONLY 0x80 -#define BPOWER_THRES 0x300 -#define BRXAGC_EN 0x1 -#define BRXAGC_TOGETHER_EN 0x2 -#define BRXAGC_MIN 0x4 -#define BRXHP_INI 0x7 -#define BRXHP_TRLNA 0x70 -#define BRXHP_RSSI 0x700 -#define BRXHP_BBP1 0x7000 -#define BRXHP_BBP2 0x70000 -#define BRXHP_BBP3 0x700000 -#define BRSSI_H 0x7f0000 -#define BRSSI_GEN 0x7f000000 -#define BRXSETTLE_TRSW 0x7 -#define BRXSETTLE_LNA 0x38 -#define BRXSETTLE_RSSI 0x1c0 -#define BRXSETTLE_BBP 0xe00 -#define BRXSETTLE_RXHP 0x7000 -#define BRXSETTLE_ANTSW_RSSI 0x38000 -#define BRXSETTLE_ANTSW 0xc0000 -#define BRXPROCESS_TIME_DAGC 0x300000 -#define BRXSETTLE_HSSI 0x400000 -#define BRXPROCESS_TIME_BBPPW 0x800000 -#define BRXANTENNA_POWER_SHIFT 0x3000000 -#define BRSSI_TABLE_SELECT 0xc000000 -#define BRXHP_FINAL 0x7000000 -#define BRXHPSETTLE_BBP 0x7 -#define BRXHTSETTLE_HSSI 0x8 -#define BRXHTSETTLE_RXHP 0x70 -#define BRXHTSETTLE_BBPPW 0x80 -#define BRXHTSETTLE_IDLE 0x300 -#define BRXHTSETTLE_RESERVED 0x1c00 -#define BRXHT_RXHP_EN 0x8000 -#define BRXAGC_FREEZE_THRES 0x30000 -#define BRXAGC_TOGETHEREN 0x40000 -#define BRXHTAGC_MIN 0x80000 -#define BRXHTAGC_EN 0x100000 -#define BRXHTDAGC_EN 0x200000 -#define BRXHT_RXHP_BBP 0x1c00000 -#define BRXHT_RXHP_FINAL 0xe0000000 -#define BRXPW_RADIO_TH 0x3 -#define BRXPW_RADIO_EN 0x4 -#define BRXMF_HOLD 0x3800 -#define BRXPD_DELAY_TH1 0x38 -#define BRXPD_DELAY_TH2 0x1c0 -#define BRXPD_DC_COUNT_MAX 0x600 -#define BRXPD_DELAY_TH 0x8000 -#define BRXPROCESS_DELAY 0xf0000 -#define BRXSEARCHRANGE_GI2_EARLY 0x700000 -#define BRXFRAME_FUARD_COUNTER_L 0x3800000 -#define BRXSGI_GUARD_L 0xc000000 -#define BRXSGI_SEARCH_L 0x30000000 -#define BRXSGI_TH 0xc0000000 -#define BDFSCNT0 0xff -#define BDFSCNT1 0xff00 -#define BDFSFLAG 0xf0000 -#define BMF_WEIGHT_SUM 0x300000 -#define BMINIDX_TH 0x7f000000 -#define BDAFORMAT 0x40000 -#define BTXCH_EMU_ENABLE 0x01000000 -#define BTRSW_ISOLATION_A 0x7f -#define BTRSW_ISOLATION_B 0x7f00 -#define BTRSW_ISOLATION_C 0x7f0000 -#define BTRSW_ISOLATION_D 0x7f000000 -#define BEXT_LNA_GAIN 0x7c00 - -#define BSTBC_EN 0x4 -#define BANTENNA_MAPPING 0x10 -#define BNSS 0x20 -#define BCFO_ANTSUM_ID 0x200 -#define BPHY_COUNTER_RESET 0x8000000 -#define BCFO_REPORT_GET 0x4000000 -#define BOFDM_CONTINUE_TX 0x10000000 -#define BOFDM_SINGLE_CARRIER 0x20000000 -#define BOFDM_SINGLE_TONE 0x40000000 -#define BHT_DETECT 0x100 -#define BCFOEN 0x10000 -#define BCFOVALUE 0xfff00000 -#define BSIGTONE_RE 0x3f -#define BSIGTONE_IM 0x7f00 -#define BCOUNTER_CCA 0xffff -#define BCOUNTER_PARITYFAIL 0xffff0000 -#define BCOUNTER_RATEILLEGAL 0xffff -#define BCOUNTER_CRC8FAIL 0xffff0000 -#define BCOUNTER_MCSNOSUPPORT 0xffff -#define BCOUNTER_FASTSYNC 0xffff -#define BSHORTCFO 0xfff -#define BSHORTCFOT_LENGTH 12 -#define BSHORTCFOF_LENGTH 11 -#define BLONGCFO 0x7ff -#define BLONGCFOT_LENGTH 11 -#define BLONGCFOF_LENGTH 11 -#define BTAILCFO 0x1fff -#define BTAILCFOT_LENGTH 13 -#define BTAILCFOF_LENGTH 12 -#define BNOISE_EN_PWDB 0xffff -#define BCC_POWER_DB 0xffff0000 -#define BMOISE_PWDB 0xffff -#define BPOWERMEAST_LENGTH 10 -#define BPOWERMEASF_LENGTH 3 -#define BRX_HT_BW 0x1 -#define BRXSC 0x6 -#define BRX_HT 0x8 -#define BNB_INTF_DET_ON 0x1 -#define BINTF_WIN_LEN_CFG 0x30 -#define BNB_INTF_TH_CFG 0x1c0 -#define BRFGAIN 0x3f -#define BTABLESEL 0x40 -#define BTRSW 0x80 -#define BRXSNR_A 0xff -#define BRXSNR_B 0xff00 -#define BRXSNR_C 0xff0000 -#define BRXSNR_D 0xff000000 -#define BSNR_EVMT_LENGTH 8 -#define BSNR_EVMF_LENGTH 1 -#define BCSI1ST 0xff -#define BCSI2ND 0xff00 -#define BRXEVM1ST 0xff0000 -#define BRXEVM2ND 0xff000000 -#define BSIGEVM 0xff -#define BPWDB 0xff00 -#define BSGIEN 0x10000 - -#define BSFACTOR_QMA1 0xf -#define BSFACTOR_QMA2 0xf0 -#define BSFACTOR_QMA3 0xf00 -#define BSFACTOR_QMA4 0xf000 -#define BSFACTOR_QMA5 0xf0000 -#define BSFACTOR_QMA6 0xf0000 -#define BSFACTOR_QMA7 0xf00000 -#define BSFACTOR_QMA8 0xf000000 -#define BSFACTOR_QMA9 0xf0000000 -#define BCSI_SCHEME 0x100000 - -#define BNOISE_LVL_TOP_SET 0x3 -#define BCHSMOOTH 0x4 -#define BCHSMOOTH_CFG1 0x38 -#define BCHSMOOTH_CFG2 0x1c0 -#define BCHSMOOTH_CFG3 0xe00 -#define BCHSMOOTH_CFG4 0x7000 -#define BMRCMODE 0x800000 -#define BTHEVMCFG 0x7000000 - -#define BLOOP_FIT_TYPE 0x1 -#define BUPD_CFO 0x40 -#define BUPD_CFO_OFFDATA 0x80 -#define BADV_UPD_CFO 0x100 -#define BADV_TIME_CTRL 0x800 -#define BUPD_CLKO 0x1000 -#define BFC 0x6000 -#define BTRACKING_MODE 0x8000 -#define BPHCMP_ENABLE 0x10000 -#define BUPD_CLKO_LTF 0x20000 -#define BCOM_CH_CFO 0x40000 -#define BCSI_ESTI_MODE 0x80000 -#define BADV_UPD_EQZ 0x100000 -#define BUCHCFG 0x7000000 -#define BUPDEQZ 0x8000000 - -#define BRX_PESUDO_NOISE_ON 0x20000000 -#define BRX_PESUDO_NOISE_A 0xff -#define BRX_PESUDO_NOISE_B 0xff00 -#define BRX_PESUDO_NOISE_C 0xff0000 -#define BRX_PESUDO_NOISE_D 0xff000000 -#define BRX_PESUDO_NOISESTATE_A 0xffff -#define BRX_PESUDO_NOISESTATE_B 0xffff0000 -#define BRX_PESUDO_NOISESTATE_C 0xffff -#define BRX_PESUDO_NOISESTATE_D 0xffff0000 - -#define BZEBRA1_HSSIENABLE 0x8 -#define BZEBRA1_TRXCONTROL 0xc00 -#define BZEBRA1_TRXGAINSETTING 0x07f -#define BZEBRA1_RXCOUNTER 0xc00 -#define BZEBRA1_TXCHANGEPUMP 0x38 -#define BZEBRA1_RXCHANGEPUMP 0x7 -#define BZEBRA1_CHANNEL_NUM 0xf80 -#define BZEBRA1_TXLPFBW 0x400 -#define BZEBRA1_RXLPFBW 0x600 - -#define BRTL8256REG_MODE_CTRL1 0x100 -#define BRTL8256REG_MODE_CTRL0 0x40 -#define BRTL8256REG_TXLPFBW 0x18 -#define BRTL8256REG_RXLPFBW 0x600 - -#define BRTL8258_TXLPFBW 0xc -#define BRTL8258_RXLPFBW 0xc00 -#define BRTL8258_RSSILPFBW 0xc0 - -#define BBYTE0 0x1 -#define BBYTE1 0x2 -#define BBYTE2 0x4 -#define BBYTE3 0x8 -#define BWORD0 0x3 -#define BWORD1 0xc -#define BWORD 0xf - -#define MASKBYTE0 0xff -#define MASKBYTE1 0xff00 -#define MASKBYTE2 0xff0000 -#define MASKBYTE3 0xff000000 -#define MASKHWORD 0xffff0000 -#define MASKLWORD 0x0000ffff -#define MASKDWORD 0xffffffff -#define MASK12BITS 0xfff -#define MASKH4BITS 0xf0000000 -#define MASKOFDM_D 0xffc00000 -#define MASKCCK 0x3f3f3f3f - -#define MASK4BITS 0x0f -#define MASK20BITS 0xfffff -#define RFREG_OFFSET_MASK 0xfffff - -#define BENABLE 0x1 -#define BDISABLE 0x0 - -#define LEFT_ANTENNA 0x0 -#define RIGHT_ANTENNA 0x1 - -#define TCHECK_TXSTATUS 500 -#define TUPDATE_RXCOUNTER 100 - -/* 2 EFUSE_TEST (For RTL8723 partially) */ -#define EFUSE_SEL(x) (((x) & 0x3) << 8) -#define EFUSE_SEL_MASK 0x300 -#define EFUSE_WIFI_SEL_0 0x0 - -/* Enable GPIO[9] as WiFi HW PDn source*/ -#define WL_HWPDN_EN BIT(0) -/* WiFi HW PDn polarity control*/ -#define WL_HWPDN_SL BIT(1) - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c deleted file mode 100644 index 50dd2fb2c93d..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c +++ /dev/null @@ -1,505 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "rf.h" -#include "dm.h" - -void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - switch (bandwidth) { - case HT_CHANNEL_WIDTH_20: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff) | 0x0400); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - case HT_CHANNEL_WIDTH_20_40: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff)); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", bandwidth); - break; - } -} - -void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 tx_agc[2] = {0, 0}, tmpval; - bool turbo_scanoff = false; - u8 idx1, idx2; - u8 *ptr; - - if (rtlefuse->eeprom_regulatory != 0) - turbo_scanoff = true; - - if (mac->act_scanning == true) { - tx_agc[RF90_PATH_A] = 0x3f3f3f3f; - tx_agc[RF90_PATH_B] = 0x3f3f3f3f; - - if (turbo_scanoff) { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - } - } else { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - - if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); - tx_agc[RF90_PATH_A] += tmpval; - - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); - tx_agc[RF90_PATH_B] += tmpval; - } - } - - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - ptr = (u8 *) (&(tx_agc[idx1])); - for (idx2 = 0; idx2 < 4; idx2++) { - if (*ptr > RF6052_MAX_TX_PWR) - *ptr = RF6052_MAX_TX_PWR; - ptr++; - } - } - - tmpval = tx_agc[RF90_PATH_A] & 0xff; - rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32); - - tmpval = tx_agc[RF90_PATH_A] >> 8; - - tmpval = tmpval & 0xff00ffff; - - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11); - - tmpval = tx_agc[RF90_PATH_B] >> 24; - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11); - - tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; - rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32); -} - -static void rtl8723ae_phy_get_power_base(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel, - u32 *ofdmbase, u32 *mcsbase) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 powerBase0, powerBase1; - u8 legacy_pwrdiff, ht20_pwrdiff; - u8 i, powerlevel[2]; - - for (i = 0; i < 2; i++) { - powerlevel[i] = ppowerlevel[i]; - legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; - powerBase0 = powerlevel[i] + legacy_pwrdiff; - - powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | - (powerBase0 << 8) | powerBase0; - *(ofdmbase + i) = powerBase0; - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - " [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); - } - - for (i = 0; i < 2; i++) { - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { - ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; - powerlevel[i] += ht20_pwrdiff; - } - powerBase1 = powerlevel[i]; - powerBase1 = (powerBase1 << 24) | - (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; - - *(mcsbase + i) = powerBase1; - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - " [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); - } -} - -static void rtl8723ae_get_txpwr_val_by_reg(struct ieee80211_hw *hw, - u8 channel, u8 index, - u32 *powerBase0, - u32 *powerBase1, - u32 *p_outwriteval) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 i, chnlgroup = 0, pwr_diff_limit[4]; - u32 writeVal, customer_limit, rf; - - for (rf = 0; rf < 2; rf++) { - switch (rtlefuse->eeprom_regulatory) { - case 0: - chnlgroup = 0; - - writeVal = rtlphy->mcs_offset[chnlgroup] - [index + (rf ? 8 : 0)] + - ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - case 1: - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - writeVal = ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - } else { - if (rtlphy->pwrgroup_cnt == 1) - chnlgroup = 0; - if (rtlphy->pwrgroup_cnt >= 3) { - if (channel <= 3) - chnlgroup = 0; - else if (channel >= 4 && channel <= 9) - chnlgroup = 1; - else if (channel > 9) - chnlgroup = 2; - if (rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - chnlgroup++; - else - chnlgroup += 4; - } - - writeVal = rtlphy->mcs_offset[chnlgroup] - [index + (rf ? 8 : 0)] + ((index < 2) ? - powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - } - break; - case 2: - writeVal = - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Better regulatory, writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - case 3: - chnlgroup = 0; - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "customer's limit, 40MHz rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel-1]); - } else { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "customer's limit, 20MHz rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel-1]); - } - for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = - (u8) ((rtlphy->mcs_offset - [chnlgroup][index + (rf ? 8 : 0)] & - (0x7f << (i * 8))) >> (i * 8)); - - if (rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20_40) { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht40[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht40[rf] - [channel - 1]; - } else { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht20[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht20[rf] - [channel - 1]; - } - } - - customer_limit = (pwr_diff_limit[3] << 24) | - (pwr_diff_limit[2] << 16) | - (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit); - - writeVal = customer_limit + - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - default: - chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup][index + - (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "RTK better performance, writeVal rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - } - - if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) - writeVal = writeVal - 0x06060606; - else if (rtlpriv->dm.dynamic_txhighpower_lvl == - TXHIGHPWRLEVEL_BT2) - writeVal = writeVal - 0x0c0c0c0c; - *(p_outwriteval + rf) = writeVal; - } -} - -static void _rtl8723ae_write_ofdm_power_reg(struct ieee80211_hw *hw, - u8 index, u32 *pValue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - u16 regoffset_a[6] = { - RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, - RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, - RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 - }; - u16 regoffset_b[6] = { - RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, - RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, - RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 - }; - u8 i, rf, pwr_val[4]; - u32 writeVal; - u16 regoffset; - - for (rf = 0; rf < 2; rf++) { - writeVal = pValue[rf]; - for (i = 0; i < 4; i++) { - pwr_val[i] = (u8) ((writeVal & (0x7f << - (i * 8))) >> (i * 8)); - - if (pwr_val[i] > RF6052_MAX_TX_PWR) - pwr_val[i] = RF6052_MAX_TX_PWR; - } - writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | - (pwr_val[1] << 8) | pwr_val[0]; - - if (rf == 0) - regoffset = regoffset_a[index]; - else - regoffset = regoffset_b[index]; - rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Set 0x%x = %08x\n", regoffset, writeVal); - - if (((get_rf_type(rtlphy) == RF_2T2R) && - (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS15_MCS12)) || - ((get_rf_type(rtlphy) != RF_2T2R) && - (regoffset == RTXAGC_A_MCS07_MCS04 || - regoffset == RTXAGC_B_MCS07_MCS04))) { - - writeVal = pwr_val[3]; - if (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_A_MCS07_MCS04) - regoffset = 0xc90; - if (regoffset == RTXAGC_B_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS07_MCS04) - regoffset = 0xc98; - - for (i = 0; i < 3; i++) { - writeVal = (writeVal > 6) ? (writeVal - 6) : 0; - rtl_write_byte(rtlpriv, (u32) (regoffset + i), - (u8) writeVal); - } - } - } -} - -void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel) -{ - u32 writeVal[2], powerBase0[2], powerBase1[2]; - u8 index; - - rtl8723ae_phy_get_power_base(hw, ppowerlevel, - channel, &powerBase0[0], &powerBase1[0]); - - for (index = 0; index < 6; index++) { - rtl8723ae_get_txpwr_val_by_reg(hw, channel, index, - &powerBase0[0], - &powerBase1[0], - &writeVal[0]); - - _rtl8723ae_write_ofdm_power_reg(hw, index, &writeVal[0]); - } -} - -static bool _rtl8723ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 u4_regvalue = 0; - u8 rfpath; - bool rtstatus = true; - struct bb_reg_def *pphyreg; - - for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { - - pphyreg = &rtlphy->phyreg_def[rfpath]; - - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV); - break; - case RF90_PATH_B: - case RF90_PATH_D: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16); - break; - } - - rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, - B3WIREADDREAALENGTH, 0x0); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); - udelay(1); - - switch (rfpath) { - case RF90_PATH_A: - rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, - (enum radio_path)rfpath); - break; - case RF90_PATH_B: - rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, - (enum radio_path)rfpath); - break; - case RF90_PATH_C: - break; - case RF90_PATH_D: - break; - } - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV, u4_regvalue); - break; - case RF90_PATH_B: - case RF90_PATH_D: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16, u4_regvalue); - break; - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Radio[%d] Fail!!", rfpath); - return false; - } - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); - return rtstatus; -} - -bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlphy->rf_type == RF_1T1R) - rtlphy->num_total_rfpath = 1; - else - rtlphy->num_total_rfpath = 2; - - return _rtl8723ae_phy_rf6052_config_parafile(hw); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h deleted file mode 100644 index d0f9dd79abea..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_RF_H__ -#define __RTL8723E_RF_H__ - -#define RF6052_MAX_TX_PWR 0x3F - -extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c deleted file mode 100644 index 0afdc240f2fd..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ /dev/null @@ -1,387 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include -#include - -#include "../core.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "hw.h" -#include "sw.h" -#include "trx.h" -#include "led.h" -#include "table.h" -#include "hal_btc.h" - -static void rtl8723ae_init_aspm_vars(struct ieee80211_hw *hw) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - /*close ASPM for AMD defaultly */ - rtlpci->const_amdpci_aspm = 0; - - /* ASPM PS mode. - * 0 - Disable ASPM, - * 1 - Enable ASPM without Clock Req, - * 2 - Enable ASPM with Clock Req, - * 3 - Alwyas Enable ASPM with Clock Req, - * 4 - Always Enable ASPM without Clock Req. - * set defult to RTL8192CE:3 RTL8192E:2 - */ - rtlpci->const_pci_aspm = 3; - - /*Setting for PCI-E device */ - rtlpci->const_devicepci_aspm_setting = 0x03; - - /*Setting for PCI-E bridge */ - rtlpci->const_hostpci_aspm_setting = 0x02; - - /* In Hw/Sw Radio Off situation. - * 0 - Default, - * 1 - From ASPM setting without low Mac Pwr, - * 2 - From ASPM setting with low Mac Pwr, - * 3 - Bus D3 - * set default to RTL8192CE:0 RTL8192SE:2 - */ - rtlpci->const_hwsw_rfoff_d3 = 0; - - /* This setting works for those device with - * backdoor ASPM setting such as EPHY setting. - * 0 - Not support ASPM, - * 1 - Support ASPM, - * 2 - According to chipset. - */ - rtlpci->const_support_pciaspm = 1; -} - -int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - int err; - - rtl8723ae_bt_reg_init(hw); - rtlpriv->dm.dm_initialgain_enable = 1; - rtlpriv->dm.dm_flag = 0; - rtlpriv->dm.disable_framebursting = 0; - rtlpriv->dm.thermalvalue = 0; - rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); - - /* compatible 5G band 88ce just 2.4G band & smsp */ - rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; - rtlpriv->rtlhal.bandset = BAND_ON_2_4G; - rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; - - rtlpci->receive_config = (RCR_APPFCS | - RCR_APP_MIC | - RCR_APP_ICV | - RCR_APP_PHYST_RXFF | - RCR_HTC_LOC_CTRL | - RCR_AMF | - RCR_ACF | - RCR_ADF | - RCR_AICV | - RCR_AB | - RCR_AM | - RCR_APM | - 0); - - rtlpci->irq_mask[0] = - (u32) (PHIMR_ROK | - PHIMR_RDU | - PHIMR_VODOK | - PHIMR_VIDOK | - PHIMR_BEDOK | - PHIMR_BKDOK | - PHIMR_MGNTDOK | - PHIMR_HIGHDOK | - PHIMR_C2HCMD | - PHIMR_HISRE_IND | - PHIMR_TSF_BIT32_TOGGLE | - PHIMR_TXBCNOK | - PHIMR_PSTIMEOUT | - 0); - - rtlpci->irq_mask[1] = (u32)(PHIMR_RXFOVW | 0); - - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; - /* for LPS & IPS */ - rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; - rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; - rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; - rtlpriv->psc.reg_fwctrl_lps = 3; - rtlpriv->psc.reg_max_lps_awakeintvl = 5; - /* for ASPM, you can close aspm through - * set const_support_pciaspm = 0 - */ - rtl8723ae_init_aspm_vars(hw); - - if (rtlpriv->psc.reg_fwctrl_lps == 1) - rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; - else if (rtlpriv->psc.reg_fwctrl_lps == 2) - rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; - else if (rtlpriv->psc.reg_fwctrl_lps == 3) - rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; - - /* for firmware buf */ - rtlpriv->rtlhal.pfirmware = vmalloc(0x6000); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Can't alloc buffer for fw.\n"); - return 1; - } - - if (IS_VENDOR_8723_A_CUT(rtlhal->version)) - rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin"; - else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin"; - - rtlpriv->max_fw_size = 0x6000; - pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); - err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, - rtlpriv->io.dev, GFP_KERNEL, hw, - rtl_fw_cb); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to request firmware!\n"); - return 1; - } - return 0; -} - -void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->rtlhal.pfirmware) { - vfree(rtlpriv->rtlhal.pfirmware); - rtlpriv->rtlhal.pfirmware = NULL; - } -} - -static struct rtl_hal_ops rtl8723ae_hal_ops = { - .init_sw_vars = rtl8723ae_init_sw_vars, - .deinit_sw_vars = rtl8723ae_deinit_sw_vars, - .read_eeprom_info = rtl8723ae_read_eeprom_info, - .interrupt_recognized = rtl8723ae_interrupt_recognized, - .hw_init = rtl8723ae_hw_init, - .hw_disable = rtl8723ae_card_disable, - .hw_suspend = rtl8723ae_suspend, - .hw_resume = rtl8723ae_resume, - .enable_interrupt = rtl8723ae_enable_interrupt, - .disable_interrupt = rtl8723ae_disable_interrupt, - .set_network_type = rtl8723ae_set_network_type, - .set_chk_bssid = rtl8723ae_set_check_bssid, - .set_qos = rtl8723ae_set_qos, - .set_bcn_reg = rtl8723ae_set_beacon_related_registers, - .set_bcn_intv = rtl8723ae_set_beacon_interval, - .update_interrupt_mask = rtl8723ae_update_interrupt_mask, - .get_hw_reg = rtl8723ae_get_hw_reg, - .set_hw_reg = rtl8723ae_set_hw_reg, - .update_rate_tbl = rtl8723ae_update_hal_rate_tbl, - .fill_tx_desc = rtl8723ae_tx_fill_desc, - .fill_tx_cmddesc = rtl8723ae_tx_fill_cmddesc, - .query_rx_desc = rtl8723ae_rx_query_desc, - .set_channel_access = rtl8723ae_update_channel_access_setting, - .radio_onoff_checking = rtl8723ae_gpio_radio_on_off_checking, - .set_bw_mode = rtl8723ae_phy_set_bw_mode, - .switch_channel = rtl8723ae_phy_sw_chnl, - .dm_watchdog = rtl8723ae_dm_watchdog, - .scan_operation_backup = rtl8723ae_phy_scan_operation_backup, - .set_rf_power_state = rtl8723ae_phy_set_rf_power_state, - .led_control = rtl8723ae_led_control, - .set_desc = rtl8723ae_set_desc, - .get_desc = rtl8723ae_get_desc, - .tx_polling = rtl8723ae_tx_polling, - .enable_hw_sec = rtl8723ae_enable_hw_security_config, - .set_key = rtl8723ae_set_key, - .init_sw_leds = rtl8723ae_init_sw_leds, - .allow_all_destaddr = rtl8723ae_allow_all_destaddr, - .get_bbreg = rtl8723ae_phy_query_bb_reg, - .set_bbreg = rtl8723ae_phy_set_bb_reg, - .get_rfreg = rtl8723ae_phy_query_rf_reg, - .set_rfreg = rtl8723ae_phy_set_rf_reg, - .c2h_command_handle = rtl_8723e_c2h_command_handle, - .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, - .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, -}; - -static struct rtl_mod_params rtl8723ae_mod_params = { - .sw_crypto = false, - .inactiveps = true, - .swctrl_lps = false, - .fwctrl_lps = true, - .debug = DBG_EMERG, -}; - -static struct rtl_hal_cfg rtl8723ae_hal_cfg = { - .bar_id = 2, - .write_readback = true, - .name = "rtl8723ae_pci", - .fw_name = "rtlwifi/rtl8723aefw.bin", - .ops = &rtl8723ae_hal_ops, - .mod_params = &rtl8723ae_mod_params, - .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, - .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, - .maps[SYS_CLK] = REG_SYS_CLKR, - .maps[MAC_RCR_AM] = AM, - .maps[MAC_RCR_AB] = AB, - .maps[MAC_RCR_ACRC32] = ACRC32, - .maps[MAC_RCR_ACF] = ACF, - .maps[MAC_RCR_AAP] = AAP, - .maps[EFUSE_TEST] = REG_EFUSE_TEST, - .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_CLK] = 0, - .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_PWC_EV12V] = PWC_EV12V, - .maps[EFUSE_FEN_ELDR] = FEN_ELDR, - .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, - .maps[EFUSE_ANA8M] = ANA8M, - .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, - .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, - .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, - .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, - - .maps[RWCAM] = REG_CAMCMD, - .maps[WCAMI] = REG_CAMWRITE, - .maps[RCAMO] = REG_CAMREAD, - .maps[CAMDBG] = REG_CAMDBG, - .maps[SECR] = REG_SECCFG, - .maps[SEC_CAM_NONE] = CAM_NONE, - .maps[SEC_CAM_WEP40] = CAM_WEP40, - .maps[SEC_CAM_TKIP] = CAM_TKIP, - .maps[SEC_CAM_AES] = CAM_AES, - .maps[SEC_CAM_WEP104] = CAM_WEP104, - - .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, - .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, - .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, - .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, - .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, - .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, - .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, - .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, - .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, - .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, - .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, - .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, - .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, - .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, - .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, - .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, - - .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW, - .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT, - .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0, - .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW, - .maps[RTL_IMR_RDU] = PHIMR_RDU, - .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E, - .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0, - .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK, - .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR, - .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK, - .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK, - .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK, - .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK, - .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK, - .maps[RTL_IMR_VODOK] = PHIMR_VODOK, - .maps[RTL_IMR_ROK] = PHIMR_ROK, - .maps[RTL_IBSS_INT_MASKS] = (PHIMR_BCNDMAINT0 | - PHIMR_TXBCNOK | PHIMR_TXBCNERR), - .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD, - - - .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, - .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, - .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, - .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, - .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, - .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, - .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, - .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, - .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, - .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, - .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, - .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, - - .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, - .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, -}; - -static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = { - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)}, - {}, -}; - -MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids); - -MODULE_AUTHOR("lizhaoming "); -MODULE_AUTHOR("Realtek WlanFAE "); -MODULE_AUTHOR("Larry Finger "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); -MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); -MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); - -module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); -module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444); -module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444); -module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444); -MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); -MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); -MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); -MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); - -static const struct dev_pm_ops rtlwifi_pm_ops = { - .suspend = rtl_pci_suspend, - .resume = rtl_pci_resume, - .freeze = rtl_pci_suspend, - .thaw = rtl_pci_resume, - .poweroff = rtl_pci_suspend, - .restore = rtl_pci_resume, -}; - -static struct pci_driver rtl8723ae_driver = { - .name = KBUILD_MODNAME, - .id_table = rtl8723ae_pci_ids, - .probe = rtl_pci_probe, - .remove = rtl_pci_disconnect, - .driver.pm = &rtlwifi_pm_ops, -}; - -module_pci_driver(rtl8723ae_driver); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h deleted file mode 100644 index fc4fde5e3eb5..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_SW_H__ -#define __RTL8723E_SW_H__ - -int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw); -void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw); -void rtl8723ae_init_var_map(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c deleted file mode 100644 index 9b0b50cc4ade..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c +++ /dev/null @@ -1,738 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#include "table.h" - -u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = { - 0x800, 0x80040000, - 0x804, 0x00000003, - 0x808, 0x0000fc00, - 0x80c, 0x0000000a, - 0x810, 0x10005388, - 0x814, 0x020c3d10, - 0x818, 0x02200385, - 0x81c, 0x00000000, - 0x820, 0x01000100, - 0x824, 0x00390004, - 0x828, 0x00000000, - 0x82c, 0x00000000, - 0x830, 0x00000000, - 0x834, 0x00000000, - 0x838, 0x00000000, - 0x83c, 0x00000000, - 0x840, 0x00010000, - 0x844, 0x00000000, - 0x848, 0x00000000, - 0x84c, 0x00000000, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x569a569a, - 0x85c, 0x001b25a4, - 0x860, 0x66f60110, - 0x864, 0x061f0130, - 0x868, 0x00000000, - 0x86c, 0x32323200, - 0x870, 0x07000760, - 0x874, 0x22004000, - 0x878, 0x00000808, - 0x87c, 0x00000000, - 0x880, 0xc0083070, - 0x884, 0x000004d5, - 0x888, 0x00000000, - 0x88c, 0xccc000c0, - 0x890, 0x00000800, - 0x894, 0xfffffffe, - 0x898, 0x40302010, - 0x89c, 0x00706050, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x81121111, - 0xa00, 0x00d047c8, - 0xa04, 0x80ff000c, - 0xa08, 0x8c838300, - 0xa0c, 0x2e68120f, - 0xa10, 0x9500bb78, - 0xa14, 0x11144028, - 0xa18, 0x00881117, - 0xa1c, 0x89140f00, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00d30000, - 0xa70, 0x101fbf00, - 0xa74, 0x00000007, - 0xa78, 0x00000900, - 0xc00, 0x48071d40, - 0xc04, 0x03a05611, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08800000, - 0xc1c, 0x40000100, - 0xc20, 0x00000000, - 0xc24, 0x00000000, - 0xc28, 0x00000000, - 0xc2c, 0x00000000, - 0xc30, 0x69e9ac44, - 0xc34, 0x469652cf, - 0xc38, 0x49795994, - 0xc3c, 0x0a97971c, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020107, - 0xc4c, 0x007f037f, - 0xc50, 0x69543420, - 0xc54, 0x43bc0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x00000000, - 0xc64, 0x7116848b, - 0xc68, 0x47c00bff, - 0xc6c, 0x00000036, - 0xc70, 0x2c7f000d, - 0xc74, 0x018610db, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20f60000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x00121820, - 0xc94, 0x00000000, - 0xc98, 0x00121820, - 0xc9c, 0x00007f7f, - 0xca0, 0x00000000, - 0xca4, 0x00000080, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x28000000, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xce4, 0x00000000, - 0xce8, 0x37644302, - 0xcec, 0x2f97d40c, - 0xd00, 0x00080740, - 0xd04, 0x00020401, - 0xd08, 0x0000907f, - 0xd0c, 0x20010201, - 0xd10, 0xa0633333, - 0xd14, 0x3333bc43, - 0xd18, 0x7a8f5b6b, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x80608000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x00000000, - 0xd58, 0x00000000, - 0xd5c, 0x30032064, - 0xd60, 0x4653de68, - 0xd64, 0x04518a3c, - 0xd68, 0x00002101, - 0xd6c, 0x2a201c16, - 0xd70, 0x1812362e, - 0xd74, 0x322c2220, - 0xd78, 0x000e3c24, - 0xe00, 0x2a2a2a2a, - 0xe04, 0x2a2a2a2a, - 0xe08, 0x03902a2a, - 0xe10, 0x2a2a2a2a, - 0xe14, 0x2a2a2a2a, - 0xe18, 0x2a2a2a2a, - 0xe1c, 0x2a2a2a2a, - 0xe28, 0x00000000, - 0xe30, 0x1000dc1f, - 0xe34, 0x10008c1f, - 0xe38, 0x02140102, - 0xe3c, 0x681604c2, - 0xe40, 0x01007c00, - 0xe44, 0x01004800, - 0xe48, 0xfb000000, - 0xe4c, 0x000028d1, - 0xe50, 0x1000dc1f, - 0xe54, 0x10008c1f, - 0xe58, 0x02140102, - 0xe5c, 0x28160d05, - 0xe60, 0x00000008, - 0xe68, 0x001b25a4, - 0xe6c, 0x631b25a0, - 0xe70, 0x631b25a0, - 0xe74, 0x081b25a0, - 0xe78, 0x081b25a0, - 0xe7c, 0x081b25a0, - 0xe80, 0x081b25a0, - 0xe84, 0x631b25a0, - 0xe88, 0x081b25a0, - 0xe8c, 0x631b25a0, - 0xed0, 0x631b25a0, - 0xed4, 0x631b25a0, - 0xed8, 0x631b25a0, - 0xedc, 0x001b25a0, - 0xee0, 0x001b25a0, - 0xeec, 0x6b1b25a0, - 0xf14, 0x00000003, - 0xf4c, 0x00000000, - 0xf00, 0x00000300, -}; - -u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = { - 0xe00, 0xffffffff, 0x0a0c0c0c, - 0xe04, 0xffffffff, 0x02040608, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x0a0c0d0e, - 0xe14, 0xffffffff, 0x02040608, - 0xe18, 0xffffffff, 0x0a0c0d0e, - 0xe1c, 0xffffffff, 0x02040608, - 0x830, 0xffffffff, 0x0a0c0c0c, - 0x834, 0xffffffff, 0x02040608, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x0a0c0d0e, - 0x848, 0xffffffff, 0x02040608, - 0x84c, 0xffffffff, 0x0a0c0d0e, - 0x868, 0xffffffff, 0x02040608, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x04040404, - 0xe04, 0xffffffff, 0x00020204, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x06060606, - 0xe14, 0xffffffff, 0x00020406, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x04040404, - 0x834, 0xffffffff, 0x00020204, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x06060606, - 0x848, 0xffffffff, 0x00020406, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x04040404, - 0xe04, 0xffffffff, 0x00020204, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x04040404, - 0x834, 0xffffffff, 0x00020204, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, -}; - -u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH] = { - 0x000, 0x00030159, - 0x001, 0x00031284, - 0x002, 0x00098000, - 0x003, 0x00018c63, - 0x004, 0x000210e7, - 0x009, 0x0002044f, - 0x00a, 0x0001a3f1, - 0x00b, 0x00014787, - 0x00c, 0x000896fe, - 0x00d, 0x0000e02c, - 0x00e, 0x00039ce7, - 0x00f, 0x00000451, - 0x019, 0x00000000, - 0x01a, 0x00030355, - 0x01b, 0x00060a00, - 0x01c, 0x000fc378, - 0x01d, 0x000a1250, - 0x01e, 0x0004445f, - 0x01f, 0x00080001, - 0x020, 0x0000b614, - 0x021, 0x0006c000, - 0x022, 0x00000000, - 0x023, 0x00001558, - 0x024, 0x00000060, - 0x025, 0x00000483, - 0x026, 0x0004f000, - 0x027, 0x000ec7d9, - 0x028, 0x00057730, - 0x029, 0x00004783, - 0x02a, 0x00000001, - 0x02b, 0x00021334, - 0x02a, 0x00000000, - 0x02b, 0x00000054, - 0x02a, 0x00000001, - 0x02b, 0x00000808, - 0x02b, 0x00053333, - 0x02c, 0x0000000c, - 0x02a, 0x00000002, - 0x02b, 0x00000808, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000003, - 0x02b, 0x00000808, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000004, - 0x02b, 0x00000808, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000005, - 0x02b, 0x00000808, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x00000006, - 0x02b, 0x00000709, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000007, - 0x02b, 0x00000709, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000008, - 0x02b, 0x0000060a, - 0x02b, 0x0004b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000009, - 0x02b, 0x0000060a, - 0x02b, 0x00053333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000a, - 0x02b, 0x0000060a, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000b, - 0x02b, 0x0000060a, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000c, - 0x02b, 0x0000060a, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000d, - 0x02b, 0x0000060a, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000e, - 0x02b, 0x0000050b, - 0x02b, 0x00066666, - 0x02c, 0x0000001a, - 0x02a, 0x000e0000, - 0x010, 0x0004000f, - 0x011, 0x000e31fc, - 0x010, 0x0006000f, - 0x011, 0x000ff9f8, - 0x010, 0x0002000f, - 0x011, 0x000203f9, - 0x010, 0x0003000f, - 0x011, 0x000ff500, - 0x010, 0x00000000, - 0x011, 0x00000000, - 0x010, 0x0008000f, - 0x011, 0x0003f100, - 0x010, 0x0009000f, - 0x011, 0x00023100, - 0x012, 0x00032000, - 0x012, 0x00071000, - 0x012, 0x000b0000, - 0x012, 0x000fc000, - 0x013, 0x000287b3, - 0x013, 0x000244b7, - 0x013, 0x000204ab, - 0x013, 0x0001c49f, - 0x013, 0x00018493, - 0x013, 0x0001429b, - 0x013, 0x00010299, - 0x013, 0x0000c29c, - 0x013, 0x000081a0, - 0x013, 0x000040ac, - 0x013, 0x00000020, - 0x014, 0x0001944c, - 0x014, 0x00059444, - 0x014, 0x0009944c, - 0x014, 0x000d9444, - 0x015, 0x0000f424, - 0x015, 0x0004f407, - 0x015, 0x0008f424, - 0x015, 0x000cf424, - 0x016, 0x00000339, - 0x016, 0x00040339, - 0x016, 0x00080339, - 0x016, 0x000c0336, - 0x000, 0x00010159, - 0x018, 0x0000f401, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01f, 0x00080003, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01e, 0x00044457, - 0x01f, 0x00080000, - 0x000, 0x00030159, -}; - - -u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = { - 0x0, -}; - - -u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = { - 0x420, 0x00000080, - 0x423, 0x00000000, - 0x430, 0x00000000, - 0x431, 0x00000000, - 0x432, 0x00000000, - 0x433, 0x00000001, - 0x434, 0x00000004, - 0x435, 0x00000005, - 0x436, 0x00000006, - 0x437, 0x00000007, - 0x438, 0x00000000, - 0x439, 0x00000000, - 0x43a, 0x00000000, - 0x43b, 0x00000001, - 0x43c, 0x00000004, - 0x43d, 0x00000005, - 0x43e, 0x00000006, - 0x43f, 0x00000007, - 0x440, 0x0000005d, - 0x441, 0x00000001, - 0x442, 0x00000000, - 0x444, 0x00000015, - 0x445, 0x000000f0, - 0x446, 0x0000000f, - 0x447, 0x00000000, - 0x458, 0x00000041, - 0x459, 0x000000a8, - 0x45a, 0x00000072, - 0x45b, 0x000000b9, - 0x460, 0x00000066, - 0x461, 0x00000066, - 0x462, 0x00000008, - 0x463, 0x00000003, - 0x4c8, 0x000000ff, - 0x4c9, 0x00000008, - 0x4cc, 0x000000ff, - 0x4cd, 0x000000ff, - 0x4ce, 0x00000001, - 0x500, 0x00000026, - 0x501, 0x000000a2, - 0x502, 0x0000002f, - 0x503, 0x00000000, - 0x504, 0x00000028, - 0x505, 0x000000a3, - 0x506, 0x0000005e, - 0x507, 0x00000000, - 0x508, 0x0000002b, - 0x509, 0x000000a4, - 0x50a, 0x0000005e, - 0x50b, 0x00000000, - 0x50c, 0x0000004f, - 0x50d, 0x000000a4, - 0x50e, 0x00000000, - 0x50f, 0x00000000, - 0x512, 0x0000001c, - 0x514, 0x0000000a, - 0x515, 0x00000010, - 0x516, 0x0000000a, - 0x517, 0x00000010, - 0x51a, 0x00000016, - 0x524, 0x0000000f, - 0x525, 0x0000004f, - 0x546, 0x00000040, - 0x547, 0x00000000, - 0x550, 0x00000010, - 0x551, 0x00000010, - 0x559, 0x00000002, - 0x55a, 0x00000002, - 0x55d, 0x000000ff, - 0x605, 0x00000030, - 0x608, 0x0000000e, - 0x609, 0x0000002a, - 0x652, 0x00000020, - 0x63c, 0x0000000a, - 0x63d, 0x0000000e, - 0x63e, 0x0000000a, - 0x63f, 0x0000000e, - 0x66e, 0x00000005, - 0x700, 0x00000021, - 0x701, 0x00000043, - 0x702, 0x00000065, - 0x703, 0x00000087, - 0x708, 0x00000021, - 0x709, 0x00000043, - 0x70a, 0x00000065, - 0x70b, 0x00000087, -}; - -u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = { - 0xc78, 0x7b000001, - 0xc78, 0x7b010001, - 0xc78, 0x7b020001, - 0xc78, 0x7b030001, - 0xc78, 0x7b040001, - 0xc78, 0x7b050001, - 0xc78, 0x7a060001, - 0xc78, 0x79070001, - 0xc78, 0x78080001, - 0xc78, 0x77090001, - 0xc78, 0x760a0001, - 0xc78, 0x750b0001, - 0xc78, 0x740c0001, - 0xc78, 0x730d0001, - 0xc78, 0x720e0001, - 0xc78, 0x710f0001, - 0xc78, 0x70100001, - 0xc78, 0x6f110001, - 0xc78, 0x6e120001, - 0xc78, 0x6d130001, - 0xc78, 0x6c140001, - 0xc78, 0x6b150001, - 0xc78, 0x6a160001, - 0xc78, 0x69170001, - 0xc78, 0x68180001, - 0xc78, 0x67190001, - 0xc78, 0x661a0001, - 0xc78, 0x651b0001, - 0xc78, 0x641c0001, - 0xc78, 0x631d0001, - 0xc78, 0x621e0001, - 0xc78, 0x611f0001, - 0xc78, 0x60200001, - 0xc78, 0x49210001, - 0xc78, 0x48220001, - 0xc78, 0x47230001, - 0xc78, 0x46240001, - 0xc78, 0x45250001, - 0xc78, 0x44260001, - 0xc78, 0x43270001, - 0xc78, 0x42280001, - 0xc78, 0x41290001, - 0xc78, 0x402a0001, - 0xc78, 0x262b0001, - 0xc78, 0x252c0001, - 0xc78, 0x242d0001, - 0xc78, 0x232e0001, - 0xc78, 0x222f0001, - 0xc78, 0x21300001, - 0xc78, 0x20310001, - 0xc78, 0x06320001, - 0xc78, 0x05330001, - 0xc78, 0x04340001, - 0xc78, 0x03350001, - 0xc78, 0x02360001, - 0xc78, 0x01370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7b400001, - 0xc78, 0x7b410001, - 0xc78, 0x7b420001, - 0xc78, 0x7b430001, - 0xc78, 0x7b440001, - 0xc78, 0x7b450001, - 0xc78, 0x7a460001, - 0xc78, 0x79470001, - 0xc78, 0x78480001, - 0xc78, 0x77490001, - 0xc78, 0x764a0001, - 0xc78, 0x754b0001, - 0xc78, 0x744c0001, - 0xc78, 0x734d0001, - 0xc78, 0x724e0001, - 0xc78, 0x714f0001, - 0xc78, 0x70500001, - 0xc78, 0x6f510001, - 0xc78, 0x6e520001, - 0xc78, 0x6d530001, - 0xc78, 0x6c540001, - 0xc78, 0x6b550001, - 0xc78, 0x6a560001, - 0xc78, 0x69570001, - 0xc78, 0x68580001, - 0xc78, 0x67590001, - 0xc78, 0x665a0001, - 0xc78, 0x655b0001, - 0xc78, 0x645c0001, - 0xc78, 0x635d0001, - 0xc78, 0x625e0001, - 0xc78, 0x615f0001, - 0xc78, 0x60600001, - 0xc78, 0x49610001, - 0xc78, 0x48620001, - 0xc78, 0x47630001, - 0xc78, 0x46640001, - 0xc78, 0x45650001, - 0xc78, 0x44660001, - 0xc78, 0x43670001, - 0xc78, 0x42680001, - 0xc78, 0x41690001, - 0xc78, 0x406a0001, - 0xc78, 0x266b0001, - 0xc78, 0x256c0001, - 0xc78, 0x246d0001, - 0xc78, 0x236e0001, - 0xc78, 0x226f0001, - 0xc78, 0x21700001, - 0xc78, 0x20710001, - 0xc78, 0x06720001, - 0xc78, 0x05730001, - 0xc78, 0x04740001, - 0xc78, 0x03750001, - 0xc78, 0x02760001, - 0xc78, 0x01770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x3800001e, - 0xc78, 0x3801001e, - 0xc78, 0x3802001e, - 0xc78, 0x3803001e, - 0xc78, 0x3804001e, - 0xc78, 0x3805001e, - 0xc78, 0x3806001e, - 0xc78, 0x3807001e, - 0xc78, 0x3808001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3e0a001e, - 0xc78, 0x400b001e, - 0xc78, 0x440c001e, - 0xc78, 0x480d001e, - 0xc78, 0x4c0e001e, - 0xc78, 0x500f001e, - 0xc78, 0x5210001e, - 0xc78, 0x5611001e, - 0xc78, 0x5a12001e, - 0xc78, 0x5e13001e, - 0xc78, 0x6014001e, - 0xc78, 0x6015001e, - 0xc78, 0x6016001e, - 0xc78, 0x6217001e, - 0xc78, 0x6218001e, - 0xc78, 0x6219001e, - 0xc78, 0x621a001e, - 0xc78, 0x621b001e, - 0xc78, 0x621c001e, - 0xc78, 0x621d001e, - 0xc78, 0x621e001e, - 0xc78, 0x621f001e, -}; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h deleted file mode 100644 index f5ce71375c20..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_TABLE__H_ -#define __RTL8723E_TABLE__H_ - -#include - -#define RTL8723E_PHY_REG_1TARRAY_LENGTH 372 -extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH]; -#define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336 -extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH]; -#define Rtl8723ERADIOA_1TARRAYLENGTH 282 -extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH]; -#define RTL8723E_RADIOB_1TARRAYLENGTH 1 -extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH]; -#define RTL8723E_MACARRAYLENGTH 172 -extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH]; -#define RTL8723E_AGCTAB_1TARRAYLENGTH 320 -extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH]; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c deleted file mode 100644 index 9719d541e380..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ /dev/null @@ -1,670 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "../stats.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "trx.h" -#include "led.h" - -static u8 _rtl8723ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) -{ - __le16 fc = rtl_get_fc(skb); - - if (unlikely(ieee80211_is_beacon(fc))) - return QSLT_BEACON; - if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) - return QSLT_MGNT; - - return skb->priority; -} - -static void _rtl8723ae_query_rxphystatus(struct ieee80211_hw *hw, - struct rtl_stats *pstatus, u8 *pdesc, - struct rx_fwinfo_8723e *p_drvinfo, - bool bpacket_match_bssid, - bool bpacket_toself, bool packet_beacon) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); - struct phy_sts_cck_8723e_t *cck_buf; - s8 rx_pwr_all, rx_pwr[4]; - u8 rf_rx_num = 0, evm, pwdb_all; - u8 i, max_spatial_stream; - u32 rssi, total_rssi = 0; - bool is_cck = pstatus->is_cck; - - /* Record it for next packet processing */ - pstatus->packet_matchbssid = bpacket_match_bssid; - pstatus->packet_toself = bpacket_toself; - pstatus->packet_beacon = packet_beacon; - pstatus->rx_mimo_sig_qual[0] = -1; - pstatus->rx_mimo_sig_qual[1] = -1; - - if (is_cck) { - u8 report, cck_highpwr; - - /* CCK Driver info Structure is not the same as OFDM packet. */ - cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; - - /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by - * hardware (for rate adaptive) - */ - if (ppsc->rfpwr_state == ERFON) - cck_highpwr = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - BIT(9)); - else - cck_highpwr = false; - - if (!cck_highpwr) { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = cck_buf->cck_agc_rpt & 0xc0; - report = report >> 6; - switch (report) { - case 0x3: - rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); - break; - case 0x2: - rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); - break; - case 0x1: - rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); - break; - case 0x0: - rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); - break; - } - } else { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = p_drvinfo->cfosho[0] & 0x60; - report = report >> 5; - switch (report) { - case 0x3: - rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); - break; - } - } - - pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); - /* CCK gain is smaller than OFDM/MCS gain, - * so we add gain diff. From experience, the val is 6 - */ - pwdb_all += 6; - if (pwdb_all > 100) - pwdb_all = 100; - /* modify the offset to make the same - * gain index with OFDM. - */ - if (pwdb_all > 34 && pwdb_all <= 42) - pwdb_all -= 2; - else if (pwdb_all > 26 && pwdb_all <= 34) - pwdb_all -= 6; - else if (pwdb_all > 14 && pwdb_all <= 26) - pwdb_all -= 8; - else if (pwdb_all > 4 && pwdb_all <= 14) - pwdb_all -= 4; - - pstatus->rx_pwdb_all = pwdb_all; - pstatus->recvsignalpower = rx_pwr_all; - - /* (3) Get Signal Quality (EVM) */ - if (bpacket_match_bssid) { - u8 sq; - - if (pstatus->rx_pwdb_all > 40) { - sq = 100; - } else { - sq = cck_buf->sq_rpt; - if (sq > 64) - sq = 0; - else if (sq < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - - pstatus->signalquality = sq; - pstatus->rx_mimo_sig_qual[0] = sq; - pstatus->rx_mimo_sig_qual[1] = -1; - } - } else { - rtlpriv->dm.rfpath_rxenable[0] = - rtlpriv->dm.rfpath_rxenable[1] = true; - - /* (1)Get RSSI for HT rate */ - for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { - - /* we will judge RF RX path now. */ - if (rtlpriv->dm.rfpath_rxenable[i]) - rf_rx_num++; - - rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110; - - /* Translate DBM to percentage. */ - rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); - total_rssi += rssi; - - /* Get Rx snr value in DB */ - rtlpriv->stats.rx_snr_db[i] = (p_drvinfo->rxsnr[i] / 2); - - /* Record Signal Strength for next packet */ - if (bpacket_match_bssid) - pstatus->rx_mimo_signalstrength[i] = (u8) rssi; - } - - /* (2)PWDB, Average PWDB cacluated by - * hardware (for rate adaptive) - */ - rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; - - pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); - pstatus->rx_pwdb_all = pwdb_all; - pstatus->rxpower = rx_pwr_all; - pstatus->recvsignalpower = rx_pwr_all; - - /* (3)EVM of HT rate */ - if (pstatus->is_ht && pstatus->rate >= DESC92_RATEMCS8 && - pstatus->rate <= DESC92_RATEMCS15) - max_spatial_stream = 2; - else - max_spatial_stream = 1; - - for (i = 0; i < max_spatial_stream; i++) { - evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); - - if (bpacket_match_bssid) { - /* Fill value in RFD, Get the first - * spatial stream only - */ - if (i == 0) - pstatus->signalquality = (evm & 0xff); - pstatus->rx_mimo_sig_qual[i] = (evm & 0xff); - } - } - } - - /* UI BSS List signal strength(in percentage), - * make it good looking, from 0~100. - */ - if (is_cck) - pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, - pwdb_all)); - else if (rf_rx_num != 0) - pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, - total_rssi /= rf_rx_num)); -} - -static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw, - struct sk_buff *skb, struct rtl_stats *pstatus, - u8 *pdesc, struct rx_fwinfo_8723e *p_drvinfo) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct ieee80211_hdr *hdr; - u8 *tmp_buf; - u8 *praddr; - u8 *psaddr; - __le16 fc; - u16 type; - bool packet_matchbssid, packet_toself, packet_beacon; - - tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; - - hdr = (struct ieee80211_hdr *)tmp_buf; - fc = hdr->frame_control; - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - psaddr = ieee80211_get_SA(hdr); - - packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, - (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (le16_to_cpu(fc) & - IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) && - (!pstatus->crc) && (!pstatus->icv)); - - packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); - - if (ieee80211_is_beacon(fc)) - packet_beacon = true; - - _rtl8723ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, - packet_matchbssid, packet_toself, - packet_beacon); - - rtl_process_phyinfo(hw, tmp_buf, pstatus); -} - -bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *status, - struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb) -{ - struct rx_fwinfo_8723e *p_drvinfo; - struct ieee80211_hdr *hdr; - u32 phystatus = GET_RX_DESC_PHYST(pdesc); - - status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); - status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * - RX_DRV_INFO_SIZE_UNIT; - status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); - status->icv = (u16) GET_RX_DESC_ICV(pdesc); - status->crc = (u16) GET_RX_DESC_CRC32(pdesc); - status->hwerror = (status->crc | status->icv); - status->decrypted = !GET_RX_DESC_SWDEC(pdesc); - status->rate = (u8) GET_RX_DESC_RXMCS(pdesc); - status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); - status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); - status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) - && (GET_RX_DESC_FAGGR(pdesc) == 1)); - status->timestamp_low = GET_RX_DESC_TSFL(pdesc); - status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); - status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc); - - status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); - - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; - - hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size - + status->rx_bufshift); - - if (status->crc) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - - if (status->rx_is40Mhzpacket) - rx_status->flag |= RX_FLAG_40MHZ; - - if (status->is_ht) - rx_status->flag |= RX_FLAG_HT; - - rx_status->flag |= RX_FLAG_MACTIME_MPDU; - - /* hw will set status->decrypted true, if it finds the - * frame is open data frame or mgmt frame. - * Thus hw will not decrypt a robust managment frame - * for IEEE80211w but still set status->decrypted - * true, so here we should set it back to undecrypted - * for IEEE80211w frame, and mac80211 sw will help - * to decrypt it - */ - if (status->decrypted) { - if ((ieee80211_is_robust_mgmt_frame(hdr)) && - (ieee80211_has_protected(hdr->frame_control))) - rx_status->flag &= ~RX_FLAG_DECRYPTED; - else - rx_status->flag |= RX_FLAG_DECRYPTED; - } - - /* rate_idx: index of data rate into band's - * supported rates or MCS index if HT rates - * are use (RX_FLAG_HT) - */ - rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, - status->rate, false); - - rx_status->mactime = status->timestamp_low; - if (phystatus == true) { - p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data + - status->rx_bufshift); - - _rtl8723ae_translate_rx_signal_stuff(hw, - skb, status, pdesc, p_drvinfo); - } - - /*rx_status->qual = status->signal; */ - rx_status->signal = status->recvsignalpower + 10; - /*rx_status->noise = -status->noise; */ - - return true; -} - -void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, u8 hw_queue, - struct rtl_tcb_desc *ptcdesc) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool defaultadapter = true; - u8 *pdesc = (u8 *) pdesc_tx; - u16 seq_number; - __le16 fc = hdr->frame_control; - u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); - bool firstseg = ((hdr->seq_ctrl & - cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); - bool lastseg = ((hdr->frame_control & - cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - u8 bw_40 = 0; - - if (mac->opmode == NL80211_IFTYPE_STATION) { - bw_40 = mac->bw_40; - } else if (mac->opmode == NL80211_IFTYPE_AP || - mac->opmode == NL80211_IFTYPE_ADHOC) { - if (sta) - bw_40 = sta->ht_cap.cap & - IEEE80211_HT_CAP_SUP_WIDTH_20_40; - } - - seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; - - rtl_get_tcb_desc(hw, info, sta, skb, ptcdesc); - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e)); - - if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { - firstseg = true; - lastseg = true; - } - - if (firstseg) { - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, ptcdesc->hw_rate); - - if (ptcdesc->use_shortgi || ptcdesc->use_shortpreamble) - SET_TX_DESC_DATA_SHORTGI(pdesc, 1); - - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - SET_TX_DESC_AGG_BREAK(pdesc, 1); - SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); - } - SET_TX_DESC_SEQ(pdesc, seq_number); - - SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcdesc->rts_enable && - !ptcdesc-> - cts_enable) ? 1 : 0)); - SET_TX_DESC_HW_RTS_ENABLE(pdesc, - ((ptcdesc->rts_enable - || ptcdesc->cts_enable) ? 1 : 0)); - SET_TX_DESC_CTS2SELF(pdesc, ((ptcdesc->cts_enable) ? 1 : 0)); - SET_TX_DESC_RTS_STBC(pdesc, ((ptcdesc->rts_stbc) ? 1 : 0)); - - SET_TX_DESC_RTS_RATE(pdesc, ptcdesc->rts_rate); - SET_TX_DESC_RTS_BW(pdesc, 0); - SET_TX_DESC_RTS_SC(pdesc, ptcdesc->rts_sc); - SET_TX_DESC_RTS_SHORT(pdesc, - ((ptcdesc->rts_rate <= DESC92_RATE54M) ? - (ptcdesc->rts_use_shortpreamble ? 1 : 0) - : (ptcdesc->rts_use_shortgi ? 1 : 0))); - - if (bw_40) { - if (ptcdesc->packet_bw) { - SET_TX_DESC_DATA_BW(pdesc, 1); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, - mac->cur_40_prime_sc); - } - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); - } - - SET_TX_DESC_LINIP(pdesc, 0); - SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); - - if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; - SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); - } - - if (info->control.hw_key) { - struct ieee80211_key_conf *keyconf = - info->control.hw_key; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x1); - break; - case WLAN_CIPHER_SUITE_CCMP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x3); - break; - default: - SET_TX_DESC_SEC_TYPE(pdesc, 0x0); - break; - } - } - - SET_TX_DESC_PKT_ID(pdesc, 0); - SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); - - SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); - SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); - SET_TX_DESC_DISABLE_FB(pdesc, 0); - SET_TX_DESC_USE_RATE(pdesc, ptcdesc->use_driver_rate ? 1 : 0); - - if (ieee80211_is_data_qos(fc)) { - if (mac->rdg_en) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "Enable RDG function.\n"); - SET_TX_DESC_RDG_ENABLE(pdesc, 1); - SET_TX_DESC_HTC(pdesc, 1); - } - } - } - - SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); - SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); - - if (rtlpriv->dm.useramask) { - SET_TX_DESC_RATE_ID(pdesc, ptcdesc->ratr_index); - SET_TX_DESC_MACID(pdesc, ptcdesc->mac_id); - } else { - SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcdesc->ratr_index); - SET_TX_DESC_MACID(pdesc, ptcdesc->ratr_index); - } - - if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { - SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); - - if (!defaultadapter) - SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1); - } - - SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); - - if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || - is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { - SET_TX_DESC_BMC(pdesc, 1); - } - - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); -} - -void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, - u8 *pdesc, bool firstseg, - bool lastseg, struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u8 fw_queue = QSLT_BEACON; - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - __le16 fc = hdr->frame_control; - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); - - if (firstseg) - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); - - SET_TX_DESC_SEQ(pdesc, 0); - - SET_TX_DESC_LINIP(pdesc, 0); - - SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); - - SET_TX_DESC_RATE_ID(pdesc, 7); - SET_TX_DESC_MACID(pdesc, 0); - - SET_TX_DESC_OWN(pdesc, 1); - - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_OFFSET(pdesc, 0x20); - - SET_TX_DESC_USE_RATE(pdesc, 1); - - if (!ieee80211_is_data_qos(fc)) { - SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); - /* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */ - /* SET_TX_DESC_PKT_ID(pdesc, 8); */ - } - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); -} - -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) -{ - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - SET_TX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_TX_NEXTDESC_ADDR: - SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); - break; - default: - RT_ASSERT(false, "ERR txdesc :%d not process\n", - desc_name); - break; - } - } else { - switch (desc_name) { - case HW_DESC_RXOWN: - SET_RX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_RXBUFF_ADDR: - SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); - break; - case HW_DESC_RXPKT_LEN: - SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); - break; - case HW_DESC_RXERO: - SET_RX_DESC_EOR(pdesc, 1); - break; - default: - RT_ASSERT(false, "ERR rxdesc :%d not process\n", - desc_name); - break; - } - } -} - -u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name) -{ - u32 ret = 0; - - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_TX_DESC_OWN(pdesc); - break; - case HW_DESC_TXBUFF_ADDR: - ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc); - break; - default: - RT_ASSERT(false, "ERR txdesc :%d not process\n", - desc_name); - break; - } - } else { - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_RX_DESC_OWN(pdesc); - break; - case HW_DESC_RXPKT_LEN: - ret = GET_RX_DESC_PKT_LEN(pdesc); - break; - default: - RT_ASSERT(false, "ERR rxdesc :%d not process\n", - desc_name); - break; - } - } - return ret; -} - -void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (hw_queue == BEACON_QUEUE) { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); - } else { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, - BIT(0) << (hw_queue)); - } -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h deleted file mode 100644 index ad05b54bc0f1..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h +++ /dev/null @@ -1,725 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_TRX_H__ -#define __RTL8723E_TRX_H__ - -#define TX_DESC_SIZE 64 -#define TX_DESC_AGGR_SUBFRAME_SIZE 32 - -#define RX_DESC_SIZE 32 -#define RX_DRV_INFO_SIZE_UNIT 8 - -#define TX_DESC_NEXT_DESC_OFFSET 40 -#define USB_HWDESC_HEADER_LEN 32 -#define CRCLENGTH 4 - -#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) -#define SET_TX_DESC_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) -#define SET_TX_DESC_BMC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) -#define SET_TX_DESC_HTC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) -#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) -#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) -#define SET_TX_DESC_LINIP(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) -#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) -#define SET_TX_DESC_GF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_TX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_TX_DESC_PKT_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 16) -#define GET_TX_DESC_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 8) -#define GET_TX_DESC_BMC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 1) -#define GET_TX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 25, 1) -#define GET_TX_DESC_LAST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_TX_DESC_FIRST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_TX_DESC_LINIP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_TX_DESC_NO_ACM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_TX_DESC_GF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_TX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_TX_DESC_MACID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) -#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) -#define SET_TX_DESC_BK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) -#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) -#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) -#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) -#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) -#define SET_TX_DESC_PIFS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) -#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) -#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) -#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) -#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) -#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) - -#define GET_TX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) -#define GET_TX_DESC_AGG_BREAK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) -#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) -#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) -#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) -#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_TX_DESC_PIFS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_TX_DESC_RATE_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) -#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) -#define GET_TX_DESC_SEC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) -#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) - -#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) -#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) -#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) -#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) -#define SET_TX_DESC_RAW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) -#define SET_TX_DESC_CCX(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) -#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) -#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) -#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) -#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) -#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) -#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) - -#define GET_TX_DESC_RTS_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) -#define GET_TX_DESC_DATA_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) -#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) -#define GET_TX_DESC_MORE_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) -#define GET_TX_DESC_RAW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) -#define GET_TX_DESC_CCX(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) -#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) -#define GET_TX_DESC_ANTSEL_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) -#define GET_TX_DESC_ANTSEL_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) -#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) -#define GET_TX_DESC_TX_ANTL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) -#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) - -#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) -#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) -#define SET_TX_DESC_SEQ(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) -#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) - -#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) -#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) -#define GET_TX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) -#define GET_TX_DESC_PKT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) - -/* For RTL8723 */ -#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val) -#define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val) -#define SET_TX_DESC_HWSEQ_SEL_8723(__pTxDesc, __Value) \ - SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 6, 2, __Value) - -#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) -#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) -#define SET_TX_DESC_QOS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) -#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) -#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) -#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) -#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) -#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) -#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) -#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) -#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) -#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) -#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) -#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) -#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) -#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) -#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) -#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) -#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) -#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) -#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) - -#define GET_TX_DESC_RTS_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) -#define GET_TX_DESC_AP_DCFE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) -#define GET_TX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) -#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) -#define GET_TX_DESC_USE_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) -#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) -#define GET_TX_DESC_DISABLE_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) -#define GET_TX_DESC_CTS2SELF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) -#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) -#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) -#define GET_TX_DESC_PORT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) -#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) -#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) -#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) -#define GET_TX_DESC_TX_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) -#define GET_TX_DESC_DATA_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) -#define GET_TX_DESC_DATA_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) -#define GET_TX_DESC_RTS_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) -#define GET_TX_DESC_RTS_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) -#define GET_TX_DESC_RTS_SC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) -#define GET_TX_DESC_RTS_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) - -#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) -#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) -#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) -#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) -#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) -#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) -#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) -#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) - -#define GET_TX_DESC_TX_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) -#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) -#define GET_TX_DESC_CCX_TAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) -#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) -#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) -#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) -#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) -#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) - -#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) -#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) -#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) -#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) -#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) -#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) -#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) -#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) - -#define GET_TX_DESC_TXAGC_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) -#define GET_TX_DESC_TXAGC_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) -#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) -#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) -#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) -#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) -#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) -#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) -#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) -#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) -#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) -#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) - -#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) -#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) -#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) -#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) -#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) -#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) - -#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) -#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) - -#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) -#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) - -#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) -#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) - -#define GET_RX_DESC_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 14) -#define GET_RX_DESC_CRC32(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 14, 1) -#define GET_RX_DESC_ICV(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 15, 1) -#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 4) -#define GET_RX_DESC_SECURITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 20, 3) -#define GET_RX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 23, 1) -#define GET_RX_DESC_SHIFT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 2) -#define GET_RX_DESC_PHYST(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_RX_DESC_SWDEC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_RX_DESC_LS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_RX_DESC_FS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_RX_DESC_EOR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_RX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) -#define SET_RX_DESC_EOR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_RX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_RX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_RX_DESC_TID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) -#define GET_RX_DESC_HWRSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) -#define GET_RX_DESC_PAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_RX_DESC_FAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_RX_DESC_A1_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_RX_DESC_A2_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) -#define GET_RX_DESC_PAM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) -#define GET_RX_DESC_PWR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) -#define GET_RX_DESC_MD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) -#define GET_RX_DESC_MF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) -#define GET_RX_DESC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) -#define GET_RX_DESC_MC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) -#define GET_RX_DESC_BC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) -#define GET_RX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) -#define GET_RX_DESC_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) -#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) -#define GET_RX_DESC_NEXT_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) -#define GET_RX_DESC_RSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) - -#define GET_RX_DESC_RXMCS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) -#define GET_RX_DESC_RXHT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) -#define GET_RX_DESC_SPLCP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) -#define GET_RX_DESC_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) -#define GET_RX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) -#define GET_RX_DESC_HWPC_ERR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) -#define GET_RX_DESC_HWPC_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) -#define GET_RX_DESC_IV0(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) - -#define GET_RX_DESC_IV1(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) -#define GET_RX_DESC_TSFL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) - -#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) -#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) - -#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) -#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) - -#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ -do { \ - if (_size > TX_DESC_NEXT_DESC_OFFSET) \ - memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ - else \ - memset(__pdesc, 0, _size); \ -} while (0) - -#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \ - ((rxmcs) == DESC92_RATE1M || \ - (rxmcs) == DESC92_RATE2M || \ - (rxmcs) == DESC92_RATE5_5M || \ - (rxmcs) == DESC92_RATE11M) - -struct rx_fwinfo_8723e { - u8 gain_trsw[4]; - u8 pwdb_all; - u8 cfosho[4]; - u8 cfotail[4]; - char rxevm[2]; - char rxsnr[4]; - u8 pdsnr[2]; - u8 csi_current[2]; - u8 csi_target[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 ex_intf_flag:1; - u8 sgi_en:1; - u8 rxsc:2; - u8 reserve:4; -} __packed; - -struct tx_desc_8723e { - u32 pktsize:16; - u32 offset:8; - u32 bmc:1; - u32 htc:1; - u32 lastseg:1; - u32 firstseg:1; - u32 linip:1; - u32 noacm:1; - u32 gf:1; - u32 own:1; - - u32 macid:5; - u32 agg_en:1; - u32 bk:1; - u32 rdg_en:1; - u32 queuesel:5; - u32 rd_nav_ext:1; - u32 lsig_txop_en:1; - u32 pifs:1; - u32 rateid:4; - u32 nav_usehdr:1; - u32 en_descid:1; - u32 sectype:2; - u32 pktoffset:8; - - u32 rts_rc:6; - u32 data_rc:6; - u32 rsvd0:2; - u32 bar_retryht:2; - u32 rsvd1:1; - u32 morefrag:1; - u32 raw:1; - u32 ccx:1; - u32 ampdudensity:3; - u32 rsvd2:1; - u32 ant_sela:1; - u32 ant_selb:1; - u32 txant_cck:2; - u32 txant_l:2; - u32 txant_ht:2; - - u32 nextheadpage:8; - u32 tailpage:8; - u32 seq:12; - u32 pktid:4; - - u32 rtsrate:5; - u32 apdcfe:1; - u32 qos:1; - u32 hwseq_enable:1; - u32 userrate:1; - u32 dis_rtsfb:1; - u32 dis_datafb:1; - u32 cts2self:1; - u32 rts_en:1; - u32 hwrts_en:1; - u32 portid:1; - u32 rsvd3:3; - u32 waitdcts:1; - u32 cts2ap_en:1; - u32 txsc:2; - u32 stbc:2; - u32 txshort:1; - u32 txbw:1; - u32 rtsshort:1; - u32 rtsbw:1; - u32 rtssc:2; - u32 rtsstbc:2; - - u32 txrate:6; - u32 shortgi:1; - u32 ccxt:1; - u32 txrate_fb_lmt:5; - u32 rtsrate_fb_lmt:4; - u32 retrylmt_en:1; - u32 txretrylmt:6; - u32 usb_txaggnum:8; - - u32 txagca:5; - u32 txagcb:5; - u32 usemaxlen:1; - u32 maxaggnum:5; - u32 mcsg1maxlen:4; - u32 mcsg2maxlen:4; - u32 mcsg3maxlen:4; - u32 mcs7sgimaxlen:4; - - u32 txbuffersize:16; - u32 mcsg4maxlen:4; - u32 mcsg5maxlen:4; - u32 mcsg6maxlen:4; - u32 mcsg15sgimaxlen:4; - - u32 txbuffaddr; - u32 txbufferaddr64; - u32 nextdescaddress; - u32 nextdescaddress64; - - u32 reserve_pass_pcie_mm_limit[4]; -} __packed; - -struct rx_desc_8723e { - u32 length:14; - u32 crc32:1; - u32 icverror:1; - u32 drv_infosize:4; - u32 security:3; - u32 qos:1; - u32 shift:2; - u32 phystatus:1; - u32 swdec:1; - u32 lastseg:1; - u32 firstseg:1; - u32 eor:1; - u32 own:1; - - u32 macid:5; - u32 tid:4; - u32 hwrsvd:5; - u32 paggr:1; - u32 faggr:1; - u32 a1_fit:4; - u32 a2_fit:4; - u32 pam:1; - u32 pwr:1; - u32 moredata:1; - u32 morefrag:1; - u32 type:2; - u32 mc:1; - u32 bc:1; - - u32 seq:12; - u32 frag:4; - u32 nextpktlen:14; - u32 nextind:1; - u32 rsvd:1; - - u32 rxmcs:6; - u32 rxht:1; - u32 amsdu:1; - u32 splcp:1; - u32 bandwidth:1; - u32 htc:1; - u32 tcpchk_rpt:1; - u32 ipcchk_rpt:1; - u32 tcpchk_valid:1; - u32 hwpcerr:1; - u32 hwpcind:1; - u32 iv0:16; - - u32 iv1; - - u32 tsfl; - - u32 bufferaddress; - u32 bufferaddress64; - -} __packed; - -void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, u8 hw_queue, - struct rtl_tcb_desc *ptcb_desc); -bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *status, - struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb); -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); -u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name); -void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); -void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, - bool b_firstseg, bool b_lastseg, - struct sk_buff *skb); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/stats.c b/trunk/drivers/net/wireless/rtlwifi/stats.c deleted file mode 100644 index 8ed31744a054..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/stats.c +++ /dev/null @@ -1,268 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ -#include "wifi.h" -#include "stats.h" -#include - -u8 rtl_query_rxpwrpercentage(char antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} -EXPORT_SYMBOL(rtl_query_rxpwrpercentage); - -u8 rtl_evm_db_to_percentage(char value) -{ - char ret_val; - ret_val = value; - - if (ret_val >= 0) - ret_val = 0; - if (ret_val <= -33) - ret_val = -33; - ret_val = 0 - ret_val; - ret_val *= 3; - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} -EXPORT_SYMBOL(rtl_evm_db_to_percentage); - -static long rtl_translate_todbm(struct ieee80211_hw *hw, - u8 signal_strength_index) -{ - long signal_power; - - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - return signal_power; -} - -long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) -{ - long retsig; - - if (currsig >= 61 && currsig <= 100) - retsig = 90 + ((currsig - 60) / 4); - else if (currsig >= 41 && currsig <= 60) - retsig = 78 + ((currsig - 40) / 2); - else if (currsig >= 31 && currsig <= 40) - retsig = 66 + (currsig - 30); - else if (currsig >= 21 && currsig <= 30) - retsig = 54 + (currsig - 20); - else if (currsig >= 5 && currsig <= 20) - retsig = 42 + (((currsig - 5) * 2) / 3); - else if (currsig == 4) - retsig = 36; - else if (currsig == 3) - retsig = 27; - else if (currsig == 2) - retsig = 18; - else if (currsig == 1) - retsig = 9; - else - retsig = currsig; - - return retsig; -} -EXPORT_SYMBOL(rtl_signal_scale_mapping); - -static void rtl_process_ui_rssi(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 rfpath; - u32 last_rssi, tmpval; - - rtlpriv->stats.rssi_calculate_cnt++; - - if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { - rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; - last_rssi = rtlpriv->stats.ui_rssi.elements[ - rtlpriv->stats.ui_rssi.index]; - rtlpriv->stats.ui_rssi.total_val -= last_rssi; - } - rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; - rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = - pstatus->signalstrength; - if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) - rtlpriv->stats.ui_rssi.index = 0; - tmpval = rtlpriv->stats.ui_rssi.total_val / - rtlpriv->stats.ui_rssi.total_num; - rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, - (u8) tmpval); - pstatus->rssi = rtlpriv->stats.signal_strength; - - if (pstatus->is_cck) - return; - - for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; - rfpath++) { - if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - pstatus->rx_mimo_signalstrength[rfpath]; - - } - if (pstatus->rx_mimo_signalstrength[rfpath] > - rtlpriv->stats.rx_rssi_percentage[rfpath]) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats.rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - rtlpriv->stats.rx_rssi_percentage[rfpath] = - rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; - } else { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats.rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - } - } -} - -static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int weighting = 0; - - if (rtlpriv->stats.recv_signal_power == 0) - rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; - if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) - weighting = 5; - else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) - weighting = (-5); - rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * - 5 + pstatus->recvsignalpower + weighting) / 6; -} - -static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_sta_info *drv_priv = NULL; - struct ieee80211_sta *sta = NULL; - long undec_sm_pwdb; - - rcu_read_lock(); - if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) - sta = rtl_find_sta(hw, pstatus->psaddr); - - /* adhoc or ap mode */ - if (sta) { - drv_priv = (struct rtl_sta_info *) sta->drv_priv; - undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; - } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; - } - - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstatus->rx_pwdb_all; - if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb = undec_sm_pwdb + 1; - } else { - undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - } - - if (sta) { - drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; - } else { - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; - } - rcu_read_unlock(); - - rtl_update_rxsignalstatistics(hw, pstatus); -} - -static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 last_evm, n_stream, tmpval; - - if (pstatus->signalquality == 0) - return; - - if (rtlpriv->stats.ui_link_quality.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - rtlpriv->stats.ui_link_quality.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = rtlpriv->stats.ui_link_quality.elements[ - rtlpriv->stats.ui_link_quality.index]; - rtlpriv->stats.ui_link_quality.total_val -= last_evm; - } - rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; - rtlpriv->stats.ui_link_quality.elements[ - rtlpriv->stats.ui_link_quality.index++] = - pstatus->signalquality; - if (rtlpriv->stats.ui_link_quality.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - rtlpriv->stats.ui_link_quality.index = 0; - tmpval = rtlpriv->stats.ui_link_quality.total_val / - rtlpriv->stats.ui_link_quality.total_num; - rtlpriv->stats.signal_quality = tmpval; - rtlpriv->stats.last_sigstrength_inpercent = tmpval; - for (n_stream = 0; n_stream < 2; n_stream++) { - if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { - if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { - rtlpriv->stats.rx_evm_percentage[n_stream] = - pstatus->rx_mimo_sig_qual[n_stream]; - } - rtlpriv->stats.rx_evm_percentage[n_stream] = - ((rtlpriv->stats.rx_evm_percentage[n_stream] - * (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / - (RX_SMOOTH_FACTOR); - } - } -} - -void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, - struct rtl_stats *pstatus) -{ - - if (!pstatus->packet_matchbssid) - return; - - rtl_process_ui_rssi(hw, pstatus); - rtl_process_pwdb(hw, pstatus); - rtl_process_ui_link_quality(hw, pstatus); -} -EXPORT_SYMBOL(rtl_process_phyinfo); diff --git a/trunk/drivers/net/wireless/rtlwifi/stats.h b/trunk/drivers/net/wireless/rtlwifi/stats.h deleted file mode 100644 index 0dbdc5203830..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/stats.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL_STATS_H__ -#define __RTL_STATS_H__ - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_LINKQUALITY_SLID_WIN_MAX 20 -#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 - -/* Rx smooth factor */ -#define RX_SMOOTH_FACTOR 20 - -u8 rtl_query_rxpwrpercentage(char antpower); -u8 rtl_evm_db_to_percentage(char value); -long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); -void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, - struct rtl_stats *pstatus); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index e3ea4b346889..030beb45d8b0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -673,7 +673,7 @@ static int rtl_usb_start(struct ieee80211_hw *hw) set_hal_start(rtlhal); /* Start bulk IN */ - err = _rtl_usb_receive(hw); + _rtl_usb_receive(hw); } return err; diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index 21a5f4f4a135..f1b6bc693b0a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -198,15 +198,15 @@ struct bb_reg_def { u32 rftxgain_stage; u32 rfhssi_para1; u32 rfhssi_para2; - u32 rfsw_ctrl; + u32 rfswitch_control; u32 rfagc_control1; u32 rfagc_control2; - u32 rfrxiq_imbal; + u32 rfrxiq_imbalance; u32 rfrx_afe; - u32 rftxiq_imbal; + u32 rftxiq_imbalance; u32 rftx_afe; - u32 rf_rb; /* rflssi_readback */ - u32 rf_rbpi; /* rflssi_readbackpi */ + u32 rflssi_readback; + u32 rflssi_readbackpi; }; enum io_type { @@ -350,11 +350,6 @@ enum rt_oem_id { RT_CID_819x_WNC_COREGA = 31, RT_CID_819x_Foxcoon = 32, RT_CID_819x_DELL = 33, - RT_CID_819x_PRONETS = 34, - RT_CID_819x_Edimax_ASUS = 35, - RT_CID_NETGEAR = 36, - RT_CID_PLANEX = 37, - RT_CID_CC_C = 38, }; enum hw_descs { @@ -510,7 +505,6 @@ enum rtl_var_map { RTL_IMR_ROK, /*Receive DMA OK Interrupt */ RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | * RTL_IMR_TBDER) */ - RTL_IMR_C2HCMD, /*fw interrupt*/ /*CCK Rates, TxHT = 0 */ RTL_RC_CCK_RATE1M, @@ -667,11 +661,6 @@ enum ba_action { ACT_DELBA = 2, }; -enum rt_polarity_ctl { - RT_POLARITY_LOW_ACT = 0, - RT_POLARITY_HIGH_ACT = 1, -}; - struct octet_string { u8 *octet; u16 length; @@ -896,7 +885,7 @@ struct rtl_phy { u8 pwrgroup_cnt; u8 cck_high_power; /* MAX_PG_GROUP groups of pwr diff by rates */ - u32 mcs_offset[MAX_PG_GROUP][16]; + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; u8 default_initialgain[4]; /* the current Tx power level */ @@ -914,8 +903,6 @@ struct rtl_phy { u8 num_total_rfpath; struct phy_parameters hwparam_tables[MAX_TAB]; u16 rf_pathmap; - - enum rt_polarity_ctl polarity_ctl; }; #define MAX_TID_COUNT 9 @@ -946,7 +933,7 @@ struct rtl_tid_data { }; struct rssi_sta { - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; }; struct rtl_sta_info { @@ -1055,64 +1042,13 @@ struct rtl_mac { /*QOS & EDCA */ struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; struct rtl_qos_parameters ac[AC_MAX]; - - /* counters */ - u64 last_txok_cnt; - u64 last_rxok_cnt; - u32 last_bt_edca_ul; - u32 last_bt_edca_dl; -}; - -struct btdm_8723 { - bool all_off; - bool agc_table_en; - bool adc_back_off_on; - bool b2_ant_hid_en; - bool low_penalty_rate_adaptive; - bool rf_rx_lpf_shrink; - bool reject_aggre_pkt; - bool tra_tdma_on; - u8 tra_tdma_nav; - u8 tra_tdma_ant; - bool tdma_on; - u8 tdma_ant; - u8 tdma_nav; - u8 tdma_dac_swing; - u8 fw_dac_swing_lvl; - bool ps_tdma_on; - u8 ps_tdma_byte[5]; - bool pta_on; - u32 val_0x6c0; - u32 val_0x6c8; - u32 val_0x6cc; - bool sw_dac_swing_on; - u32 sw_dac_swing_lvl; - u32 wlan_act_hi; - u32 wlan_act_lo; - u32 bt_retry_index; - bool dec_bt_pwr; - bool ignore_wlan_act; -}; - -struct bt_coexist_8723 { - u32 high_priority_tx; - u32 high_priority_rx; - u32 low_priority_tx; - u32 low_priority_rx; - u8 c2h_bt_info; - bool c2h_bt_info_req_sent; - bool c2h_bt_inquiry_page; - u32 bt_inq_page_start_time; - u8 bt_retry_cnt; - u8 c2h_bt_info_original; - u8 bt_inquiry_page_cnt; - struct btdm_8723 btdm; }; struct rtl_hal { struct ieee80211_hw *hw; - struct bt_coexist_8723 hal_coex_8723; + bool up_first_time; + bool first_init; bool being_init_adapter; bool bbrf_ready; @@ -1195,9 +1131,9 @@ struct rtl_security { struct rtl_dm { /*PHY status for Dynamic Management */ - long entry_min_undec_sm_pwdb; - long undec_sm_pwdb; /*out dm */ - long entry_max_undec_sm_pwdb; + long entry_min_undecoratedsmoothed_pwdb; + long undecorated_smoothed_pwdb; /*out dm */ + long entry_max_undecoratedsmoothed_pwdb; bool dm_initialgain_enable; bool dynamic_txpower_enable; bool current_turbo_edca; @@ -1273,7 +1209,7 @@ struct rtl_efuse { u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; - u8 eprom_chnl_txpwr_ht40_2sdf[2][CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX]; u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ @@ -1376,7 +1312,6 @@ struct rtl_ps_ctl { }; struct rtl_stats { - u8 psaddr[ETH_ALEN]; u32 mac_time[2]; s8 rssi; u8 signal; @@ -1416,7 +1351,7 @@ struct rtl_stats { bool rx_is40Mhzpacket; u32 rx_pwdb_all; u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ - s8 rx_mimo_sig_qual[2]; + s8 rx_mimo_signalquality[2]; bool packet_matchbssid; bool is_cck; bool is_ht; @@ -1568,10 +1503,6 @@ struct rtl_hal_ops { void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); - void (*c2h_command_handle) (struct ieee80211_hw *hw); - void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, - bool mstate); - void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); }; struct rtl_intf_ops { @@ -1748,7 +1679,7 @@ struct dig_t { u32 rssi_highthresh; u32 fa_lowthresh; u32 fa_highthresh; - long last_min_undec_pwdb_for_dm; + long last_min_undecorated_pwdb_for_dm; long rssi_highpower_lowthresh; long rssi_highpower_highthresh; u32 recover_cnt; @@ -1761,15 +1692,15 @@ struct dig_t { u8 dig_twoport_algorithm; u8 dig_dbgmode; u8 dig_slgorithm_switch; - u8 cursta_cstate; - u8 presta_cstate; - u8 curmultista_cstate; - char back_val; - char back_range_max; - char back_range_min; + u8 cursta_connectstate; + u8 presta_connectstate; + u8 curmultista_connectstate; + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; u8 rx_gain_range_max; u8 rx_gain_range_min; - u8 min_undec_pwdb_for_dm; + u8 min_undecorated_pwdb_for_dm; u8 rssi_val_min; u8 pre_cck_pd_state; u8 cur_cck_pd_state; @@ -1781,10 +1712,10 @@ struct dig_t { u8 forbidden_igi; u8 dig_state; u8 dig_highpwrstate; - u8 cur_sta_cstate; - u8 pre_sta_cstate; - u8 cur_ap_cstate; - u8 pre_ap_cstate; + u8 cur_sta_connectstate; + u8 pre_sta_connectstate; + u8 cur_ap_connectstate; + u8 pre_ap_connectstate; u8 cur_pd_thstate; u8 pre_pd_thstate; u8 cur_cs_ratiostate; @@ -1850,22 +1781,9 @@ struct rtl_priv { struct dig_t dm_digtable; struct ps_t dm_pstable; - /* section shared by individual drivers */ - union { - struct { /* data buffer pointer for USB reads */ - __le32 *usb_data; - int usb_data_index; - bool initialized; - }; - struct { /* section for 8723ae */ - bool reg_init; /* true if regs saved */ - u32 reg_874; - u32 reg_c70; - u32 reg_85c; - u32 reg_a74; - bool bt_operation_on; - }; - }; + /* data buffer pointer for USB reads */ + __le32 *usb_data; + int usb_data_index; /*This must be the last item so that it points to the data allocated @@ -1897,7 +1815,6 @@ enum bt_co_type { BT_CSR_BC4 = 3, BT_CSR_BC8 = 4, BT_RTL8756 = 5, - BT_RTL8723A = 6, }; enum bt_cur_state { @@ -1929,7 +1846,7 @@ struct bt_coexist_info { u8 eeprom_bt_coexist; u8 eeprom_bt_type; u8 eeprom_bt_ant_num; - u8 eeprom_bt_ant_isol; + u8 eeprom_bt_ant_isolation; u8 eeprom_bt_radio_shared; u8 bt_coexistence; @@ -1956,27 +1873,13 @@ struct bt_coexist_info { bool fw_coexist_all_off; bool sw_coexist_all_off; - bool hw_coexist_all_off; - u32 cstate; + u32 current_state; u32 previous_state; - u32 cstate_h; - u32 previous_state_h; - u8 bt_pre_rssi_state; - u8 bt_pre_rssi_state1; u8 reg_bt_iso; u8 reg_bt_sco; - bool balance_on; - u8 bt_active_zero_cnt; - bool cur_bt_disabled; - bool pre_bt_disabled; - - u8 bt_profile_case; - u8 bt_profile_action; - bool bt_busy; - bool hold_for_bt_operation; - u8 lps_counter; + }; diff --git a/trunk/drivers/net/wireless/ti/wlcore/main.c b/trunk/drivers/net/wireless/ti/wlcore/main.c index 380cf1ff6cd1..25530c8760cb 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/main.c +++ b/trunk/drivers/net/wireless/ti/wlcore/main.c @@ -677,7 +677,7 @@ static void wl12xx_get_vif_count(struct ieee80211_hw *hw, memset(data, 0, sizeof(*data)); data->cur_vif = cur_vif; - ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, + ieee80211_iterate_active_interfaces(hw, wl12xx_vif_count_iter, data); } diff --git a/trunk/drivers/nfc/Makefile b/trunk/drivers/nfc/Makefile index 36c359043f54..bf05831fdf09 100644 --- a/trunk/drivers/nfc/Makefile +++ b/trunk/drivers/nfc/Makefile @@ -2,7 +2,7 @@ # Makefile for nfc devices # -obj-$(CONFIG_PN544_HCI_NFC) += pn544/ +obj-$(CONFIG_PN544_HCI_NFC) += pn544_hci.o obj-$(CONFIG_NFC_PN533) += pn533.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o diff --git a/trunk/drivers/nfc/pn533.c b/trunk/drivers/nfc/pn533.c index ada681b01a17..97c440a8cd61 100644 --- a/trunk/drivers/nfc/pn533.c +++ b/trunk/drivers/nfc/pn533.c @@ -84,10 +84,6 @@ MODULE_DEVICE_TABLE(usb, pn533_table); #define PN533_LISTEN_TIME 2 /* frame definitions */ -#define PN533_NORMAL_FRAME_MAX_LEN 262 /* 6 (PREAMBLE, SOF, LEN, LCS, TFI) - 254 (DATA) - 2 (DCS, postamble) */ - #define PN533_FRAME_TAIL_SIZE 2 #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ PN533_FRAME_TAIL_SIZE) @@ -702,14 +698,13 @@ static void pn533_wq_cmd(struct work_struct *work) cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); - list_del(&cmd->queue); - mutex_unlock(&dev->cmd_lock); __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, cmd->arg, cmd->flags); + list_del(&cmd->queue); kfree(cmd); } @@ -1170,7 +1165,8 @@ static void pn533_poll_create_mod_list(struct pn533 *dev, pn533_poll_add_mod(dev, PN533_LISTEN_MOD); } -static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_len) +static int pn533_start_poll_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) { struct pn533_poll_response *resp; int rc; @@ -1308,7 +1304,8 @@ static void pn533_wq_tg_get_data(struct work_struct *work) } #define ATR_REQ_GB_OFFSET 17 -static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_len) +static int pn533_init_target_complete(struct pn533 *dev, void *arg, + u8 *params, int params_len) { struct pn533_cmd_init_target_response *resp; u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; @@ -1405,9 +1402,9 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, if (cur_mod->len == 0) { del_timer(&dev->listen_timer); - return pn533_init_target_complete(dev, params, params_len); + return pn533_init_target_complete(dev, arg, params, params_len); } else { - rc = pn533_start_poll_complete(dev, params, params_len); + rc = pn533_start_poll_complete(dev, arg, params, params_len); if (!rc) return rc; } @@ -1681,14 +1678,11 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { + struct pn533_cmd_jump_dep *cmd; struct pn533_cmd_jump_dep_response *resp; struct nfc_target nfc_target; u8 target_gt_len; int rc; - struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; - u8 active = cmd->active; - - kfree(arg); if (params_len == -ENOENT) { nfc_dev_dbg(&dev->interface->dev, ""); @@ -1710,6 +1704,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } resp = (struct pn533_cmd_jump_dep_response *) params; + cmd = (struct pn533_cmd_jump_dep *) arg; rc = resp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, @@ -1739,7 +1734,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, dev->nfc_dev->targets[0].idx, - !active, NFC_RF_INITIATOR); + !cmd->active, NFC_RF_INITIATOR); return 0; } @@ -1824,8 +1819,12 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, dev->in_maxlen, pn533_in_dep_link_up_complete, cmd, GFP_KERNEL); - if (rc < 0) - kfree(cmd); + if (rc) + goto out; + + +out: + kfree(cmd); return rc; } @@ -2079,12 +2078,8 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, static int pn533_tm_send_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { - struct sk_buff *skb_out = arg; - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - dev_kfree_skb(skb_out); - if (params_len < 0) { nfc_dev_err(&dev->interface->dev, "Error %d when sending data", @@ -2122,7 +2117,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, dev->in_maxlen, pn533_tm_send_complete, - skb, GFP_KERNEL); + NULL, GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); @@ -2378,9 +2373,9 @@ static int pn533_probe(struct usb_interface *interface, goto error; } - dev->in_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL); + dev->in_frame = kmalloc(dev->in_maxlen, GFP_KERNEL); dev->in_urb = usb_alloc_urb(0, GFP_KERNEL); - dev->out_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL); + dev->out_frame = kmalloc(dev->out_maxlen, GFP_KERNEL); dev->out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!dev->in_frame || !dev->out_frame || diff --git a/trunk/drivers/nfc/pn544/Makefile b/trunk/drivers/nfc/pn544/Makefile deleted file mode 100644 index 725733881eb3..000000000000 --- a/trunk/drivers/nfc/pn544/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for PN544 HCI based NFC driver -# - -obj-$(CONFIG_PN544_HCI_NFC) += pn544_i2c.o - -pn544_i2c-y := pn544.o i2c.o diff --git a/trunk/drivers/nfc/pn544/i2c.c b/trunk/drivers/nfc/pn544/i2c.c deleted file mode 100644 index 7da9071b68b6..000000000000 --- a/trunk/drivers/nfc/pn544/i2c.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * I2C Link Layer for PN544 HCI based Driver - * - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "pn544.h" - -#define PN544_I2C_FRAME_HEADROOM 1 -#define PN544_I2C_FRAME_TAILROOM 2 - -/* framing in HCI mode */ -#define PN544_HCI_I2C_LLC_LEN 1 -#define PN544_HCI_I2C_LLC_CRC 2 -#define PN544_HCI_I2C_LLC_LEN_CRC (PN544_HCI_I2C_LLC_LEN + \ - PN544_HCI_I2C_LLC_CRC) -#define PN544_HCI_I2C_LLC_MIN_SIZE (1 + PN544_HCI_I2C_LLC_LEN_CRC) -#define PN544_HCI_I2C_LLC_MAX_PAYLOAD 29 -#define PN544_HCI_I2C_LLC_MAX_SIZE (PN544_HCI_I2C_LLC_LEN_CRC + 1 + \ - PN544_HCI_I2C_LLC_MAX_PAYLOAD) - -static struct i2c_device_id pn544_hci_i2c_id_table[] = { - {"pn544", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table); - -#define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" - -struct pn544_i2c_phy { - struct i2c_client *i2c_dev; - struct nfc_hci_dev *hdev; - - unsigned int gpio_en; - unsigned int gpio_irq; - unsigned int gpio_fw; - unsigned int en_polarity; - - int powered; - - int hard_fault; /* - * < 0 if hardware error occured (e.g. i2c err) - * and prevents normal operation. - */ -}; - -#define I2C_DUMP_SKB(info, skb) \ -do { \ - pr_debug("%s:\n", info); \ - print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \ - 16, 1, (skb)->data, (skb)->len, 0); \ -} while (0) - -static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) -{ - int polarity, retry, ret; - char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; - int count = sizeof(rset_cmd); - - pr_info(DRIVER_DESC ": %s\n", __func__); - dev_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); - - /* Disable fw download */ - gpio_set_value(phy->gpio_fw, 0); - - for (polarity = 0; polarity < 2; polarity++) { - phy->en_polarity = polarity; - retry = 3; - while (retry--) { - /* power off */ - gpio_set_value(phy->gpio_en, !phy->en_polarity); - usleep_range(10000, 15000); - - /* power on */ - gpio_set_value(phy->gpio_en, phy->en_polarity); - usleep_range(10000, 15000); - - /* send reset */ - dev_dbg(&phy->i2c_dev->dev, "Sending reset cmd\n"); - ret = i2c_master_send(phy->i2c_dev, rset_cmd, count); - if (ret == count) { - dev_info(&phy->i2c_dev->dev, - "nfc_en polarity : active %s\n", - (polarity == 0 ? "low" : "high")); - goto out; - } - } - } - - dev_err(&phy->i2c_dev->dev, - "Could not detect nfc_en polarity, fallback to active high\n"); - -out: - gpio_set_value(phy->gpio_en, !phy->en_polarity); -} - -static int pn544_hci_i2c_enable(void *phy_id) -{ - struct pn544_i2c_phy *phy = phy_id; - - pr_info(DRIVER_DESC ": %s\n", __func__); - - gpio_set_value(phy->gpio_fw, 0); - gpio_set_value(phy->gpio_en, phy->en_polarity); - usleep_range(10000, 15000); - - phy->powered = 1; - - return 0; -} - -static void pn544_hci_i2c_disable(void *phy_id) -{ - struct pn544_i2c_phy *phy = phy_id; - - pr_info(DRIVER_DESC ": %s\n", __func__); - - gpio_set_value(phy->gpio_fw, 0); - gpio_set_value(phy->gpio_en, !phy->en_polarity); - usleep_range(10000, 15000); - - gpio_set_value(phy->gpio_en, phy->en_polarity); - usleep_range(10000, 15000); - - gpio_set_value(phy->gpio_en, !phy->en_polarity); - usleep_range(10000, 15000); - - phy->powered = 0; -} - -static void pn544_hci_i2c_add_len_crc(struct sk_buff *skb) -{ - u16 crc; - int len; - - len = skb->len + 2; - *skb_push(skb, 1) = len; - - crc = crc_ccitt(0xffff, skb->data, skb->len); - crc = ~crc; - *skb_put(skb, 1) = crc & 0xff; - *skb_put(skb, 1) = crc >> 8; -} - -static void pn544_hci_i2c_remove_len_crc(struct sk_buff *skb) -{ - skb_pull(skb, PN544_I2C_FRAME_HEADROOM); - skb_trim(skb, PN544_I2C_FRAME_TAILROOM); -} - -/* - * Writing a frame must not return the number of written bytes. - * It must return either zero for success, or <0 for error. - * In addition, it must not alter the skb - */ -static int pn544_hci_i2c_write(void *phy_id, struct sk_buff *skb) -{ - int r; - struct pn544_i2c_phy *phy = phy_id; - struct i2c_client *client = phy->i2c_dev; - - if (phy->hard_fault != 0) - return phy->hard_fault; - - usleep_range(3000, 6000); - - pn544_hci_i2c_add_len_crc(skb); - - I2C_DUMP_SKB("i2c frame written", skb); - - r = i2c_master_send(client, skb->data, skb->len); - - if (r == -EREMOTEIO) { /* Retry, chip was in standby */ - usleep_range(6000, 10000); - r = i2c_master_send(client, skb->data, skb->len); - } - - if (r >= 0) { - if (r != skb->len) - r = -EREMOTEIO; - else - r = 0; - } - - pn544_hci_i2c_remove_len_crc(skb); - - return r; -} - -static int check_crc(u8 *buf, int buflen) -{ - int len; - u16 crc; - - len = buf[0] + 1; - crc = crc_ccitt(0xffff, buf, len - 2); - crc = ~crc; - - if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { - pr_err(PN544_HCI_I2C_DRIVER_NAME - ": CRC error 0x%x != 0x%x 0x%x\n", - crc, buf[len - 1], buf[len - 2]); - - pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); - print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, - 16, 2, buf, buflen, false); - return -EPERM; - } - return 0; -} - -/* - * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees - * that i2c bus will be flushed and that next read will start on a new frame. - * returned skb contains only LLC header and payload. - * returns: - * -EREMOTEIO : i2c read error (fatal) - * -EBADMSG : frame was incorrect and discarded - * -ENOMEM : cannot allocate skb, frame dropped - */ -static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb) -{ - int r; - u8 len; - u8 tmp[PN544_HCI_I2C_LLC_MAX_SIZE - 1]; - struct i2c_client *client = phy->i2c_dev; - - r = i2c_master_recv(client, &len, 1); - if (r != 1) { - dev_err(&client->dev, "cannot read len byte\n"); - return -EREMOTEIO; - } - - if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) || - (len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) { - dev_err(&client->dev, "invalid len byte\n"); - r = -EBADMSG; - goto flush; - } - - *skb = alloc_skb(1 + len, GFP_KERNEL); - if (*skb == NULL) { - r = -ENOMEM; - goto flush; - } - - *skb_put(*skb, 1) = len; - - r = i2c_master_recv(client, skb_put(*skb, len), len); - if (r != len) { - kfree_skb(*skb); - return -EREMOTEIO; - } - - I2C_DUMP_SKB("i2c frame read", *skb); - - r = check_crc((*skb)->data, (*skb)->len); - if (r != 0) { - kfree_skb(*skb); - r = -EBADMSG; - goto flush; - } - - skb_pull(*skb, 1); - skb_trim(*skb, (*skb)->len - 2); - - usleep_range(3000, 6000); - - return 0; - -flush: - if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) - r = -EREMOTEIO; - - usleep_range(3000, 6000); - - return r; -} - -/* - * Reads an shdlc frame from the chip. This is not as straightforward as it - * seems. There are cases where we could loose the frame start synchronization. - * The frame format is len-data-crc, and corruption can occur anywhere while - * transiting on i2c bus, such that we could read an invalid len. - * In order to recover synchronization with the next frame, we must be sure - * to read the real amount of data without using the len byte. We do this by - * assuming the following: - * - the chip will always present only one single complete frame on the bus - * before triggering the interrupt - * - the chip will not present a new frame until we have completely read - * the previous one (or until we have handled the interrupt). - * The tricky case is when we read a corrupted len that is less than the real - * len. We must detect this here in order to determine that we need to flush - * the bus. This is the reason why we check the crc here. - */ -static irqreturn_t pn544_hci_i2c_irq_thread_fn(int irq, void *phy_id) -{ - struct pn544_i2c_phy *phy = phy_id; - struct i2c_client *client; - struct sk_buff *skb = NULL; - int r; - - if (!phy || irq != phy->i2c_dev->irq) { - WARN_ON_ONCE(1); - return IRQ_NONE; - } - - client = phy->i2c_dev; - dev_dbg(&client->dev, "IRQ\n"); - - if (phy->hard_fault != 0) - return IRQ_HANDLED; - - r = pn544_hci_i2c_read(phy, &skb); - if (r == -EREMOTEIO) { - phy->hard_fault = r; - - nfc_hci_recv_frame(phy->hdev, NULL); - - return IRQ_HANDLED; - } else if ((r == -ENOMEM) || (r == -EBADMSG)) { - return IRQ_HANDLED; - } - - nfc_hci_recv_frame(phy->hdev, skb); - - return IRQ_HANDLED; -} - -static struct nfc_phy_ops i2c_phy_ops = { - .write = pn544_hci_i2c_write, - .enable = pn544_hci_i2c_enable, - .disable = pn544_hci_i2c_disable, -}; - -static int __devinit pn544_hci_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct pn544_i2c_phy *phy; - struct pn544_nfc_platform_data *pdata; - int r = 0; - - dev_dbg(&client->dev, "%s\n", __func__); - dev_dbg(&client->dev, "IRQ: %d\n", client->irq); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); - return -ENODEV; - } - - phy = kzalloc(sizeof(struct pn544_i2c_phy), GFP_KERNEL); - if (!phy) { - dev_err(&client->dev, - "Cannot allocate memory for pn544 i2c phy.\n"); - r = -ENOMEM; - goto err_phy_alloc; - } - - phy->i2c_dev = client; - i2c_set_clientdata(client, phy); - - pdata = client->dev.platform_data; - if (pdata == NULL) { - dev_err(&client->dev, "No platform data\n"); - r = -EINVAL; - goto err_pdata; - } - - if (pdata->request_resources == NULL) { - dev_err(&client->dev, "request_resources() missing\n"); - r = -EINVAL; - goto err_pdata; - } - - r = pdata->request_resources(client); - if (r) { - dev_err(&client->dev, "Cannot get platform resources\n"); - goto err_pdata; - } - - phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); - phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); - phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); - - pn544_hci_i2c_platform_init(phy); - - r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - PN544_HCI_I2C_DRIVER_NAME, phy); - if (r < 0) { - dev_err(&client->dev, "Unable to register IRQ handler\n"); - goto err_rti; - } - - r = pn544_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, - PN544_I2C_FRAME_HEADROOM, PN544_I2C_FRAME_TAILROOM, - PN544_HCI_I2C_LLC_MAX_PAYLOAD, &phy->hdev); - if (r < 0) - goto err_hci; - - return 0; - -err_hci: - free_irq(client->irq, phy); - -err_rti: - if (pdata->free_resources != NULL) - pdata->free_resources(); - -err_pdata: - kfree(phy); - -err_phy_alloc: - return r; -} - -static __devexit int pn544_hci_i2c_remove(struct i2c_client *client) -{ - struct pn544_i2c_phy *phy = i2c_get_clientdata(client); - struct pn544_nfc_platform_data *pdata = client->dev.platform_data; - - dev_dbg(&client->dev, "%s\n", __func__); - - pn544_hci_remove(phy->hdev); - - if (phy->powered) - pn544_hci_i2c_disable(phy); - - free_irq(client->irq, phy); - if (pdata->free_resources) - pdata->free_resources(); - - kfree(phy); - - return 0; -} - -static struct i2c_driver pn544_hci_i2c_driver = { - .driver = { - .name = PN544_HCI_I2C_DRIVER_NAME, - }, - .probe = pn544_hci_i2c_probe, - .id_table = pn544_hci_i2c_id_table, - .remove = __devexit_p(pn544_hci_i2c_remove), -}; - -static int __init pn544_hci_i2c_init(void) -{ - int r; - - pr_debug(DRIVER_DESC ": %s\n", __func__); - - r = i2c_add_driver(&pn544_hci_i2c_driver); - if (r) { - pr_err(PN544_HCI_I2C_DRIVER_NAME - ": driver registration failed\n"); - return r; - } - - return 0; -} - -static void __exit pn544_hci_i2c_exit(void) -{ - i2c_del_driver(&pn544_hci_i2c_driver); -} - -module_init(pn544_hci_i2c_init); -module_exit(pn544_hci_i2c_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/trunk/drivers/nfc/pn544/pn544.h b/trunk/drivers/nfc/pn544/pn544.h deleted file mode 100644 index f47c6454914b..000000000000 --- a/trunk/drivers/nfc/pn544/pn544.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2011 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __LOCAL_PN544_H_ -#define __LOCAL_PN544_H_ - -#include - -#define DRIVER_DESC "HCI NFC driver for PN544" - -int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, - int phy_headroom, int phy_tailroom, int phy_payload, - struct nfc_hci_dev **hdev); -void pn544_hci_remove(struct nfc_hci_dev *hdev); - -#endif /* __LOCAL_PN544_H_ */ diff --git a/trunk/drivers/nfc/pn544/pn544.c b/trunk/drivers/nfc/pn544_hci.c similarity index 58% rename from trunk/drivers/nfc/pn544/pn544.c rename to trunk/drivers/nfc/pn544_hci.c index cc666de3b8e5..c9c8570273ab 100644 --- a/trunk/drivers/nfc/pn544/pn544.c +++ b/trunk/drivers/nfc/pn544_hci.c @@ -18,21 +18,47 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include #include #include +#include +#include +#include +#include #include #include #include -#include "pn544.h" +#include + +#define DRIVER_DESC "HCI NFC driver for PN544" + +#define PN544_HCI_DRIVER_NAME "pn544_hci" /* Timing restrictions (ms) */ #define PN544_HCI_RESETVEN_TIME 30 +static struct i2c_device_id pn544_hci_id_table[] = { + {"pn544", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, pn544_hci_id_table); + #define HCI_MODE 0 #define FW_MODE 1 +/* framing in HCI mode */ +#define PN544_HCI_LLC_LEN 1 +#define PN544_HCI_LLC_CRC 2 +#define PN544_HCI_LLC_LEN_CRC (PN544_HCI_LLC_LEN + PN544_HCI_LLC_CRC) +#define PN544_HCI_LLC_MIN_SIZE (1 + PN544_HCI_LLC_LEN_CRC) +#define PN544_HCI_LLC_MAX_PAYLOAD 29 +#define PN544_HCI_LLC_MAX_SIZE (PN544_HCI_LLC_LEN_CRC + 1 + \ + PN544_HCI_LLC_MAX_PAYLOAD) + enum pn544_state { PN544_ST_COLD, PN544_ST_FW_READY, @@ -74,10 +100,6 @@ enum pn544_state { #define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02 #define PN544_POLLING_LOOP_MGMT_GATE 0x94 -#define PN544_DEP_MODE 0x01 -#define PN544_DEP_ATR_REQ 0x02 -#define PN544_DEP_ATR_RES 0x03 -#define PN544_DEP_MERGE 0x0D #define PN544_PL_RDPHASES 0x06 #define PN544_PL_EMULATION 0x07 #define PN544_PL_NFCT_DEACTIVATED 0x09 @@ -86,15 +108,6 @@ enum pn544_state { #define PN544_NFC_WI_MGMT_GATE 0xA1 -#define PN544_HCI_EVT_SND_DATA 0x01 -#define PN544_HCI_EVT_ACTIVATED 0x02 -#define PN544_HCI_EVT_DEACTIVATED 0x03 -#define PN544_HCI_EVT_RCV_DATA 0x04 -#define PN544_HCI_EVT_CONTINUE_MI 0x05 - -#define PN544_HCI_CMD_ATTREQUEST 0x12 -#define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13 - static struct nfc_hci_gate pn544_gates[] = { {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, @@ -115,22 +128,259 @@ static struct nfc_hci_gate pn544_gates[] = { /* Largest headroom needed for outgoing custom commands */ #define PN544_CMDS_HEADROOM 2 +#define PN544_FRAME_HEADROOM 1 +#define PN544_FRAME_TAILROOM 2 struct pn544_hci_info { - struct nfc_phy_ops *phy_ops; - void *phy_id; - + struct i2c_client *i2c_dev; struct nfc_hci_dev *hdev; enum pn544_state state; struct mutex info_lock; + unsigned int gpio_en; + unsigned int gpio_irq; + unsigned int gpio_fw; + unsigned int en_polarity; + + int hard_fault; /* + * < 0 if hardware error occured (e.g. i2c err) + * and prevents normal operation. + */ int async_cb_type; data_exchange_cb_t async_cb; void *async_cb_context; }; +static void pn544_hci_platform_init(struct pn544_hci_info *info) +{ + int polarity, retry, ret; + char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; + int count = sizeof(rset_cmd); + + pr_info(DRIVER_DESC ": %s\n", __func__); + dev_info(&info->i2c_dev->dev, "Detecting nfc_en polarity\n"); + + /* Disable fw download */ + gpio_set_value(info->gpio_fw, 0); + + for (polarity = 0; polarity < 2; polarity++) { + info->en_polarity = polarity; + retry = 3; + while (retry--) { + /* power off */ + gpio_set_value(info->gpio_en, !info->en_polarity); + usleep_range(10000, 15000); + + /* power on */ + gpio_set_value(info->gpio_en, info->en_polarity); + usleep_range(10000, 15000); + + /* send reset */ + dev_dbg(&info->i2c_dev->dev, "Sending reset cmd\n"); + ret = i2c_master_send(info->i2c_dev, rset_cmd, count); + if (ret == count) { + dev_info(&info->i2c_dev->dev, + "nfc_en polarity : active %s\n", + (polarity == 0 ? "low" : "high")); + goto out; + } + } + } + + dev_err(&info->i2c_dev->dev, + "Could not detect nfc_en polarity, fallback to active high\n"); + +out: + gpio_set_value(info->gpio_en, !info->en_polarity); +} + +static int pn544_hci_enable(struct pn544_hci_info *info, int mode) +{ + pr_info(DRIVER_DESC ": %s\n", __func__); + + gpio_set_value(info->gpio_fw, 0); + gpio_set_value(info->gpio_en, info->en_polarity); + usleep_range(10000, 15000); + + return 0; +} + +static void pn544_hci_disable(struct pn544_hci_info *info) +{ + pr_info(DRIVER_DESC ": %s\n", __func__); + + gpio_set_value(info->gpio_fw, 0); + gpio_set_value(info->gpio_en, !info->en_polarity); + usleep_range(10000, 15000); + + gpio_set_value(info->gpio_en, info->en_polarity); + usleep_range(10000, 15000); + + gpio_set_value(info->gpio_en, !info->en_polarity); + usleep_range(10000, 15000); +} + +static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) +{ + int r; + + usleep_range(3000, 6000); + + r = i2c_master_send(client, buf, len); + + if (r == -EREMOTEIO) { /* Retry, chip was in standby */ + usleep_range(6000, 10000); + r = i2c_master_send(client, buf, len); + } + + if (r >= 0) { + if (r != len) + return -EREMOTEIO; + else + return 0; + } + + return r; +} + +static int check_crc(u8 *buf, int buflen) +{ + int len; + u16 crc; + + len = buf[0] + 1; + crc = crc_ccitt(0xffff, buf, len - 2); + crc = ~crc; + + if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { + pr_err(PN544_HCI_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", + crc, buf[len - 1], buf[len - 2]); + + pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); + print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, + 16, 2, buf, buflen, false); + return -EPERM; + } + return 0; +} + +/* + * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees + * that i2c bus will be flushed and that next read will start on a new frame. + * returned skb contains only LLC header and payload. + * returns: + * -EREMOTEIO : i2c read error (fatal) + * -EBADMSG : frame was incorrect and discarded + * -ENOMEM : cannot allocate skb, frame dropped + */ +static int pn544_hci_i2c_read(struct i2c_client *client, struct sk_buff **skb) +{ + int r; + u8 len; + u8 tmp[PN544_HCI_LLC_MAX_SIZE - 1]; + + r = i2c_master_recv(client, &len, 1); + if (r != 1) { + dev_err(&client->dev, "cannot read len byte\n"); + return -EREMOTEIO; + } + + if ((len < (PN544_HCI_LLC_MIN_SIZE - 1)) || + (len > (PN544_HCI_LLC_MAX_SIZE - 1))) { + dev_err(&client->dev, "invalid len byte\n"); + r = -EBADMSG; + goto flush; + } + + *skb = alloc_skb(1 + len, GFP_KERNEL); + if (*skb == NULL) { + r = -ENOMEM; + goto flush; + } + + *skb_put(*skb, 1) = len; + + r = i2c_master_recv(client, skb_put(*skb, len), len); + if (r != len) { + kfree_skb(*skb); + return -EREMOTEIO; + } + + r = check_crc((*skb)->data, (*skb)->len); + if (r != 0) { + kfree_skb(*skb); + r = -EBADMSG; + goto flush; + } + + skb_pull(*skb, 1); + skb_trim(*skb, (*skb)->len - 2); + + usleep_range(3000, 6000); + + return 0; + +flush: + if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) + r = -EREMOTEIO; + + usleep_range(3000, 6000); + + return r; +} + +/* + * Reads an shdlc frame from the chip. This is not as straightforward as it + * seems. There are cases where we could loose the frame start synchronization. + * The frame format is len-data-crc, and corruption can occur anywhere while + * transiting on i2c bus, such that we could read an invalid len. + * In order to recover synchronization with the next frame, we must be sure + * to read the real amount of data without using the len byte. We do this by + * assuming the following: + * - the chip will always present only one single complete frame on the bus + * before triggering the interrupt + * - the chip will not present a new frame until we have completely read + * the previous one (or until we have handled the interrupt). + * The tricky case is when we read a corrupted len that is less than the real + * len. We must detect this here in order to determine that we need to flush + * the bus. This is the reason why we check the crc here. + */ +static irqreturn_t pn544_hci_irq_thread_fn(int irq, void *dev_id) +{ + struct pn544_hci_info *info = dev_id; + struct i2c_client *client; + struct sk_buff *skb = NULL; + int r; + + if (!info || irq != info->i2c_dev->irq) { + WARN_ON_ONCE(1); + return IRQ_NONE; + } + + client = info->i2c_dev; + dev_dbg(&client->dev, "IRQ\n"); + + if (info->hard_fault != 0) + return IRQ_HANDLED; + + r = pn544_hci_i2c_read(client, &skb); + if (r == -EREMOTEIO) { + info->hard_fault = r; + + nfc_hci_recv_frame(info->hdev, NULL); + + return IRQ_HANDLED; + } else if ((r == -ENOMEM) || (r == -EBADMSG)) { + return IRQ_HANDLED; + } + + nfc_hci_recv_frame(info->hdev, skb); + + return IRQ_HANDLED; +} + static int pn544_hci_open(struct nfc_hci_dev *hdev) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); @@ -143,7 +393,7 @@ static int pn544_hci_open(struct nfc_hci_dev *hdev) goto out; } - r = info->phy_ops->enable(info->phy_id); + r = pn544_hci_enable(info, HCI_MODE); if (r == 0) info->state = PN544_ST_READY; @@ -162,7 +412,7 @@ static void pn544_hci_close(struct nfc_hci_dev *hdev) if (info->state == PN544_ST_COLD) goto out; - info->phy_ops->disable(info->phy_id); + pn544_hci_disable(info); info->state = PN544_ST_COLD; @@ -337,11 +587,40 @@ static int pn544_hci_ready(struct nfc_hci_dev *hdev) return 0; } +static void pn544_hci_add_len_crc(struct sk_buff *skb) +{ + u16 crc; + int len; + + len = skb->len + 2; + *skb_push(skb, 1) = len; + + crc = crc_ccitt(0xffff, skb->data, skb->len); + crc = ~crc; + *skb_put(skb, 1) = crc & 0xff; + *skb_put(skb, 1) = crc >> 8; +} + +static void pn544_hci_remove_len_crc(struct sk_buff *skb) +{ + skb_pull(skb, PN544_FRAME_HEADROOM); + skb_trim(skb, PN544_FRAME_TAILROOM); +} + static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) { struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); + struct i2c_client *client = info->i2c_dev; + int r; - return info->phy_ops->write(info->phy_id, skb); + if (info->hard_fault != 0) + return info->hard_fault; + + pn544_hci_add_len_crc(skb); + r = pn544_hci_i2c_write(client, skb->data, skb->len); + pn544_hci_remove_len_crc(skb); + + return r; } static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, @@ -351,9 +630,6 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, int r; u8 duration[2]; u8 activated; - u8 i_mode = 0x3f; /* Enable all supported modes */ - u8 t_mode = 0x0f; - u8 t_merge = 0x01; /* Enable merge by default */ pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", __func__, im_protocols, tm_protocols); @@ -391,61 +667,6 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, if (r < 0) return r; - if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { - hdev->gb = nfc_get_local_general_bytes(hdev->ndev, - &hdev->gb_len); - pr_debug("generate local bytes %p", hdev->gb); - if (hdev->gb == NULL || hdev->gb_len == 0) { - im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; - tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; - } - } - - if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { - r = nfc_hci_send_event(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - if (r < 0) - return r; - - r = nfc_hci_set_param(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - PN544_DEP_MODE, &i_mode, 1); - if (r < 0) - return r; - - r = nfc_hci_set_param(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - PN544_DEP_ATR_REQ, hdev->gb, hdev->gb_len); - if (r < 0) - return r; - - r = nfc_hci_send_event(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - NFC_HCI_EVT_READER_REQUESTED, NULL, 0); - if (r < 0) - nfc_hci_send_event(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - } - - if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { - r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, - PN544_DEP_MODE, &t_mode, 1); - if (r < 0) - return r; - - r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, - PN544_DEP_ATR_RES, hdev->gb, hdev->gb_len); - if (r < 0) - return r; - - r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, - PN544_DEP_MERGE, &t_merge, 1); - if (r < 0) - return r; - } - r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, NFC_HCI_EVT_READER_REQUESTED, NULL, 0); if (r < 0) @@ -455,43 +676,6 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, return r; } -static int pn544_hci_dep_link_up(struct nfc_hci_dev *hdev, - struct nfc_target *target, u8 comm_mode, - u8 *gb, size_t gb_len) -{ - struct sk_buff *rgb_skb = NULL; - int r; - - r = nfc_hci_get_param(hdev, target->hci_reader_gate, - PN544_DEP_ATR_RES, &rgb_skb); - if (r < 0) - return r; - - if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) { - r = -EPROTO; - goto exit; - } - print_hex_dump(KERN_DEBUG, "remote gb: ", DUMP_PREFIX_OFFSET, - 16, 1, rgb_skb->data, rgb_skb->len, true); - - r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data, - rgb_skb->len); - - if (r == 0) - r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode, - NFC_RF_INITIATOR); -exit: - kfree_skb(rgb_skb); - return r; -} - -static int pn544_hci_dep_link_down(struct nfc_hci_dev *hdev) -{ - - return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, - NFC_HCI_EVT_END_OPERATION, NULL, 0); -} - static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target) { @@ -503,9 +687,6 @@ static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, target->supported_protocols = NFC_PROTO_JEWEL_MASK; target->sens_res = 0x0c00; break; - case PN544_RF_READER_NFCIP1_INITIATOR_GATE: - target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; - break; default: return -EPROTO; } @@ -520,18 +701,7 @@ static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev, struct sk_buff *uid_skb; int r = 0; - if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) - return r; - - if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) { - r = nfc_hci_send_cmd(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL); - if (r < 0) - return r; - - target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; - } else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { + if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && target->nfcid1_len != 10) return -EPROTO; @@ -554,16 +724,6 @@ static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev, PN544_RF_READER_CMD_ACTIVATE_NEXT, uid_skb->data, uid_skb->len, NULL); kfree_skb(uid_skb); - - r = nfc_hci_send_cmd(hdev, - PN544_RF_READER_NFCIP1_INITIATOR_GATE, - PN544_HCI_CMD_CONTINUE_ACTIVATION, - NULL, 0, NULL); - if (r < 0) - return r; - - target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; - target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) { /* * TODO: maybe other ISO 14443 require some kind of continue @@ -609,7 +769,7 @@ static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb, * <= 0: driver handled the data exchange * 1: driver doesn't especially handle, please do standard processing */ -static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, +static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) @@ -662,110 +822,17 @@ static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, PN544_JEWEL_RAW_CMD, skb->data, skb->len, cb, cb_context); - case PN544_RF_READER_NFCIP1_INITIATOR_GATE: - *skb_push(skb, 1) = 0; - - return nfc_hci_send_event(hdev, target->hci_reader_gate, - PN544_HCI_EVT_SND_DATA, skb->data, - skb->len); default: return 1; } } -static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) -{ - /* Set default false for multiple information chaining */ - *skb_push(skb, 1) = 0; - - return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, - PN544_HCI_EVT_SND_DATA, skb->data, skb->len); -} - static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, struct nfc_target *target) { - pr_debug("supported protocol %d", target->supported_protocols); - if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK | - NFC_PROTO_ISO14443_B_MASK)) { - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_RF_READER_CMD_PRESENCE_CHECK, - NULL, 0, NULL); - } else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { - if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && - target->nfcid1_len != 10) - return -EOPNOTSUPP; - - return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, - PN544_RF_READER_CMD_ACTIVATE_NEXT, - target->nfcid1, target->nfcid1_len, NULL); - } else if (target->supported_protocols & NFC_PROTO_JEWEL_MASK) { - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_JEWEL_RAW_CMD, NULL, 0, NULL); - } else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) { - return nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE, - PN544_FELICA_RAW, NULL, 0, NULL); - } else if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) { - return nfc_hci_send_cmd(hdev, target->hci_reader_gate, - PN544_HCI_CMD_ATTREQUEST, - NULL, 0, NULL); - } - - return 0; -} - -static void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, - u8 event, struct sk_buff *skb) -{ - struct sk_buff *rgb_skb = NULL; - int r = 0; - - pr_debug("hci event %d", event); - switch (event) { - case PN544_HCI_EVT_ACTIVATED: - if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) - nfc_hci_target_discovered(hdev, gate); - else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { - r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, - &rgb_skb); - - if (r < 0) - goto exit; - - nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, - NFC_COMM_PASSIVE, rgb_skb->data, - rgb_skb->len); - - kfree_skb(rgb_skb); - } - - break; - case PN544_HCI_EVT_DEACTIVATED: - nfc_hci_send_event(hdev, gate, - NFC_HCI_EVT_END_OPERATION, NULL, 0); - break; - case PN544_HCI_EVT_RCV_DATA: - if (skb->len < 2) { - r = -EPROTO; - goto exit; - } - - if (skb->data[0] != 0) { - pr_debug("data0 %d", skb->data[0]); - r = -EPROTO; - goto exit; - } - - skb_pull(skb, 2); - nfc_tm_data_received(hdev->ndev, skb); - - return; - default: - break; - } - -exit: - kfree_skb(skb); + return nfc_hci_send_cmd(hdev, target->hci_reader_gate, + PN544_RF_READER_CMD_PRESENCE_CHECK, + NULL, 0, NULL); } static struct nfc_hci_ops pn544_hci_ops = { @@ -774,36 +841,74 @@ static struct nfc_hci_ops pn544_hci_ops = { .hci_ready = pn544_hci_ready, .xmit = pn544_hci_xmit, .start_poll = pn544_hci_start_poll, - .dep_link_up = pn544_hci_dep_link_up, - .dep_link_down = pn544_hci_dep_link_down, .target_from_gate = pn544_hci_target_from_gate, .complete_target_discovered = pn544_hci_complete_target_discovered, - .im_transceive = pn544_hci_im_transceive, - .tm_send = pn544_hci_tm_send, + .data_exchange = pn544_hci_data_exchange, .check_presence = pn544_hci_check_presence, - .event_received = pn544_hci_event_received, }; -int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, - int phy_headroom, int phy_tailroom, int phy_payload, - struct nfc_hci_dev **hdev) +static int __devinit pn544_hci_probe(struct i2c_client *client, + const struct i2c_device_id *id) { struct pn544_hci_info *info; + struct pn544_nfc_platform_data *pdata; + int r = 0; u32 protocols; struct nfc_hci_init_data init_data; - int r; + + dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(&client->dev, "IRQ: %d\n", client->irq); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); + return -ENODEV; + } info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); if (!info) { - pr_err("Cannot allocate memory for pn544_hci_info.\n"); + dev_err(&client->dev, + "Cannot allocate memory for pn544_hci_info.\n"); r = -ENOMEM; goto err_info_alloc; } - info->phy_ops = phy_ops; - info->phy_id = phy_id; + info->i2c_dev = client; info->state = PN544_ST_COLD; mutex_init(&info->info_lock); + i2c_set_clientdata(client, info); + + pdata = client->dev.platform_data; + if (pdata == NULL) { + dev_err(&client->dev, "No platform data\n"); + r = -EINVAL; + goto err_pdata; + } + + if (pdata->request_resources == NULL) { + dev_err(&client->dev, "request_resources() missing\n"); + r = -EINVAL; + goto err_pdata; + } + + r = pdata->request_resources(client); + if (r) { + dev_err(&client->dev, "Cannot get platform resources\n"); + goto err_pdata; + } + + info->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); + info->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); + info->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); + + pn544_hci_platform_init(info); + + r = request_threaded_irq(client->irq, NULL, pn544_hci_irq_thread_fn, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + PN544_HCI_DRIVER_NAME, info); + if (r < 0) { + dev_err(&client->dev, "Unable to register IRQ handler\n"); + goto err_rti; + } init_data.gate_count = ARRAY_SIZE(pn544_gates); @@ -823,11 +928,13 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, NFC_PROTO_NFC_DEP_MASK; info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, - protocols, llc_name, - phy_headroom + PN544_CMDS_HEADROOM, - phy_tailroom, phy_payload); + protocols, LLC_SHDLC_NAME, + PN544_FRAME_HEADROOM + + PN544_CMDS_HEADROOM, + PN544_FRAME_TAILROOM, + PN544_HCI_LLC_MAX_PAYLOAD); if (!info->hdev) { - pr_err("Cannot allocate nfc hdev.\n"); + dev_err(&client->dev, "Cannot allocate nfc hdev.\n"); r = -ENOMEM; goto err_alloc_hdev; } @@ -838,25 +945,79 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, if (r) goto err_regdev; - *hdev = info->hdev; - return 0; err_regdev: nfc_hci_free_device(info->hdev); err_alloc_hdev: + free_irq(client->irq, info); + +err_rti: + if (pdata->free_resources != NULL) + pdata->free_resources(); + +err_pdata: kfree(info); err_info_alloc: return r; } -void pn544_hci_remove(struct nfc_hci_dev *hdev) +static __devexit int pn544_hci_remove(struct i2c_client *client) { - struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); + struct pn544_hci_info *info = i2c_get_clientdata(client); + struct pn544_nfc_platform_data *pdata = client->dev.platform_data; + + dev_dbg(&client->dev, "%s\n", __func__); + + nfc_hci_free_device(info->hdev); + + if (info->state != PN544_ST_COLD) { + if (pdata->disable) + pdata->disable(); + } + + free_irq(client->irq, info); + if (pdata->free_resources) + pdata->free_resources(); - nfc_hci_unregister_device(hdev); - nfc_hci_free_device(hdev); kfree(info); + + return 0; } + +static struct i2c_driver pn544_hci_driver = { + .driver = { + .name = PN544_HCI_DRIVER_NAME, + }, + .probe = pn544_hci_probe, + .id_table = pn544_hci_id_table, + .remove = __devexit_p(pn544_hci_remove), +}; + +static int __init pn544_hci_init(void) +{ + int r; + + pr_debug(DRIVER_DESC ": %s\n", __func__); + + r = i2c_add_driver(&pn544_hci_driver); + if (r) { + pr_err(PN544_HCI_DRIVER_NAME ": driver registration failed\n"); + return r; + } + + return 0; +} + +static void __exit pn544_hci_exit(void) +{ + i2c_del_driver(&pn544_hci_driver); +} + +module_init(pn544_hci_init); +module_exit(pn544_hci_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/trunk/drivers/ssb/b43_pci_bridge.c b/trunk/drivers/ssb/b43_pci_bridge.c index 19396dc4ee47..266aa1648a02 100644 --- a/trunk/drivers/ssb/b43_pci_bridge.c +++ b/trunk/drivers/ssb/b43_pci_bridge.c @@ -37,7 +37,6 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) }, { 0, }, }; MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); diff --git a/trunk/drivers/ssb/driver_chipcommon_pmu.c b/trunk/drivers/ssb/driver_chipcommon_pmu.c index d7d58044b4bc..b58fef780ea0 100644 --- a/trunk/drivers/ssb/driver_chipcommon_pmu.c +++ b/trunk/drivers/ssb/driver_chipcommon_pmu.c @@ -346,8 +346,6 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0); } break; - case 43222: - break; default: ssb_printk(KERN_ERR PFX "ERROR: PLL init unknown for device %04X\n", @@ -436,7 +434,6 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) min_msk = 0xCBB; break; case 0x4322: - case 43222: /* We keep the default settings: * min_msk = 0xCBB * max_msk = 0x7FFFF diff --git a/trunk/drivers/ssb/driver_mipscore.c b/trunk/drivers/ssb/driver_mipscore.c index b918ba922306..c6250867a95d 100644 --- a/trunk/drivers/ssb/driver_mipscore.c +++ b/trunk/drivers/ssb/driver_mipscore.c @@ -192,10 +192,9 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) /* When there is no chipcommon on the bus there is 4MB flash */ if (!bus->chipco.dev) { - mcore->pflash.present = true; - mcore->pflash.buswidth = 2; - mcore->pflash.window = SSB_FLASH1; - mcore->pflash.window_size = SSB_FLASH1_SZ; + mcore->flash_buswidth = 2; + mcore->flash_window = SSB_FLASH1; + mcore->flash_window_size = SSB_FLASH1_SZ; return; } @@ -207,14 +206,13 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) break; case SSB_CHIPCO_FLASHT_PARA: pr_debug("Found parallel flash\n"); - mcore->pflash.present = true; - mcore->pflash.window = SSB_FLASH2; - mcore->pflash.window_size = SSB_FLASH2_SZ; + mcore->flash_window = SSB_FLASH2; + mcore->flash_window_size = SSB_FLASH2_SZ; if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) & SSB_CHIPCO_CFG_DS16) == 0) - mcore->pflash.buswidth = 1; + mcore->flash_buswidth = 1; else - mcore->pflash.buswidth = 2; + mcore->flash_buswidth = 2; break; } } diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index fd15d9829705..4180eb78d575 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -251,7 +251,7 @@ struct bcma_bus { u8 num; struct bcma_drv_cc drv_cc; - struct bcma_drv_pci drv_pci[2]; + struct bcma_drv_pci drv_pci; struct bcma_drv_mips drv_mips; struct bcma_drv_gmac_cmn drv_gmac_cmn; diff --git a/trunk/include/linux/bcma/bcma_driver_chipcommon.h b/trunk/include/linux/bcma/bcma_driver_chipcommon.h index 145f3c56227f..1cf1749440ac 100644 --- a/trunk/include/linux/bcma/bcma_driver_chipcommon.h +++ b/trunk/include/linux/bcma/bcma_driver_chipcommon.h @@ -510,7 +510,6 @@ struct bcma_chipcommon_pmu { #ifdef CONFIG_BCMA_DRIVER_MIPS struct bcma_pflash { - bool present; u8 buswidth; u32 window; u32 window_size; @@ -533,7 +532,6 @@ struct mtd_info; struct bcma_nflash { bool present; - bool boot; /* This is the flash the SoC boots from */ struct mtd_info *mtd; }; @@ -554,7 +552,6 @@ struct bcma_drv_cc { u32 capabilities; u32 capabilities_ext; u8 setup_done:1; - u8 early_setup_done:1; /* Fast Powerup Delay constant */ u16 fast_pwrup_delay; struct bcma_chipcommon_pmu pmu; @@ -586,7 +583,6 @@ struct bcma_drv_cc { bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); -extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); extern void bcma_chipco_resume(struct bcma_drv_cc *cc); @@ -610,7 +606,6 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); /* PMU support */ extern void bcma_pmu_init(struct bcma_drv_cc *cc); -extern void bcma_pmu_early_init(struct bcma_drv_cc *cc); extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value); diff --git a/trunk/include/linux/bcma/bcma_driver_mips.h b/trunk/include/linux/bcma/bcma_driver_mips.h index 0baf8a56b794..c0043645cdcb 100644 --- a/trunk/include/linux/bcma/bcma_driver_mips.h +++ b/trunk/include/linux/bcma/bcma_driver_mips.h @@ -35,16 +35,13 @@ struct bcma_device; 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 extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); -extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); #else static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } -static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } #endif extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); diff --git a/trunk/include/linux/bcma/bcma_regs.h b/trunk/include/linux/bcma/bcma_regs.h index 7e8104bb7a7e..6c9cb93ae3de 100644 --- a/trunk/include/linux/bcma/bcma_regs.h +++ b/trunk/include/linux/bcma/bcma_regs.h @@ -85,9 +85,6 @@ * (2 ZettaBytes), high 32 bits */ -#define BCMA_SOC_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -#define BCMA_SOC_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define BCMA_SOC_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -#define BCMA_SOC_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ +#define BCMA_SFLASH 0x1c000000 #endif /* LINUX_BCMA_REGS_H_ */ diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h index 4530d4960953..2385119f8bb0 100644 --- a/trunk/include/linux/ieee80211.h +++ b/trunk/include/linux/ieee80211.h @@ -905,38 +905,6 @@ struct ieee80211_tdls_data { } u; } __packed; -/* - * Peer-to-Peer IE attribute related definitions. - */ -/** - * enum ieee80211_p2p_attr_id - identifies type of peer-to-peer attribute. - */ -enum ieee80211_p2p_attr_id { - IEEE80211_P2P_ATTR_STATUS = 0, - IEEE80211_P2P_ATTR_MINOR_REASON, - IEEE80211_P2P_ATTR_CAPABILITY, - IEEE80211_P2P_ATTR_DEVICE_ID, - IEEE80211_P2P_ATTR_GO_INTENT, - IEEE80211_P2P_ATTR_GO_CONFIG_TIMEOUT, - IEEE80211_P2P_ATTR_LISTEN_CHANNEL, - IEEE80211_P2P_ATTR_GROUP_BSSID, - IEEE80211_P2P_ATTR_EXT_LISTEN_TIMING, - IEEE80211_P2P_ATTR_INTENDED_IFACE_ADDR, - IEEE80211_P2P_ATTR_MANAGABILITY, - IEEE80211_P2P_ATTR_CHANNEL_LIST, - IEEE80211_P2P_ATTR_ABSENCE_NOTICE, - IEEE80211_P2P_ATTR_DEVICE_INFO, - IEEE80211_P2P_ATTR_GROUP_INFO, - IEEE80211_P2P_ATTR_GROUP_ID, - IEEE80211_P2P_ATTR_INTERFACE, - IEEE80211_P2P_ATTR_OPER_CHANNEL, - IEEE80211_P2P_ATTR_INVITE_FLAGS, - /* 19 - 220: Reserved */ - IEEE80211_P2P_ATTR_VENDOR_SPECIFIC = 221, - - IEEE80211_P2P_ATTR_MAX -}; - /** * struct ieee80211_bar - HT Block Ack Request * @@ -1139,6 +1107,20 @@ struct ieee80211_ht_operation { #define WLAN_HT_SMPS_CONTROL_STATIC 1 #define WLAN_HT_SMPS_CONTROL_DYNAMIC 3 +#define VHT_MCS_SUPPORTED_SET_SIZE 8 + +struct ieee80211_vht_capabilities { + __le32 vht_capabilities_info; + u8 vht_supported_mcs_set[VHT_MCS_SUPPORTED_SET_SIZE]; +} __packed; + +struct ieee80211_vht_operation { + u8 vht_op_info_chwidth; + u8 vht_op_info_chan_center_freq_seg1_idx; + u8 vht_op_info_chan_center_freq_seg2_idx; + __le16 vht_basic_mcs_set; +} __packed; + /** * struct ieee80211_vht_mcs_info - VHT MCS information * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams @@ -1159,37 +1141,6 @@ struct ieee80211_vht_mcs_info { __le16 tx_highest; } __packed; -/** - * struct ieee80211_vht_cap - VHT capabilities - * - * This structure is the "VHT capabilities element" as - * described in 802.11ac D3.0 8.4.2.160 - * @vht_cap_info: VHT capability info - * @supp_mcs: VHT MCS supported rates - */ -struct ieee80211_vht_cap { - __le32 vht_cap_info; - struct ieee80211_vht_mcs_info supp_mcs; -} __packed; - -/** - * struct ieee80211_vht_operation - VHT operation IE - * - * This structure is the "VHT operation element" as - * described in 802.11ac D3.0 8.4.2.161 - * @chan_width: Operating channel width - * @center_freq_seg1_idx: center freq segment 1 index - * @center_freq_seg2_idx: center freq segment 2 index - * @basic_mcs_set: VHT Basic MCS rate set - */ -struct ieee80211_vht_operation { - u8 chan_width; - u8 center_freq_seg1_idx; - u8 center_freq_seg2_idx; - __le16 basic_mcs_set; -} __packed; - - #define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 #define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 #define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 @@ -1489,6 +1440,8 @@ enum ieee80211_eid { WLAN_EID_RSN = 48, WLAN_EID_MMIE = 76, + WLAN_EID_WPA = 221, + WLAN_EID_GENERIC = 221, WLAN_EID_VENDOR_SPECIFIC = 221, WLAN_EID_QOS_PARAMETER = 222, diff --git a/trunk/include/linux/nfc/pn544.h b/trunk/include/linux/nfc/pn544.h new file mode 100644 index 000000000000..9890bbaf4328 --- /dev/null +++ b/trunk/include/linux/nfc/pn544.h @@ -0,0 +1,104 @@ +/* + * Driver include for the PN544 NFC chip. + * + * Copyright (C) Nokia Corporation + * + * Author: Jari Vanhala + * Contact: Matti Aaltoenn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PN544_H_ +#define _PN544_H_ + +#include + +#define PN544_DRIVER_NAME "pn544" +#define PN544_MAXWINDOW_SIZE 7 +#define PN544_WINDOW_SIZE 4 +#define PN544_RETRIES 10 +#define PN544_MAX_I2C_TRANSFER 0x0400 +#define PN544_MSG_MAX_SIZE 0x21 /* at normal HCI mode */ + +/* ioctl */ +#define PN544_CHAR_BASE 'P' +#define PN544_IOR(num, dtype) _IOR(PN544_CHAR_BASE, num, dtype) +#define PN544_IOW(num, dtype) _IOW(PN544_CHAR_BASE, num, dtype) +#define PN544_GET_FW_MODE PN544_IOW(1, unsigned int) +#define PN544_SET_FW_MODE PN544_IOW(2, unsigned int) +#define PN544_GET_DEBUG PN544_IOW(3, unsigned int) +#define PN544_SET_DEBUG PN544_IOW(4, unsigned int) + +/* Timing restrictions (ms) */ +#define PN544_RESETVEN_TIME 30 /* 7 */ +#define PN544_PVDDVEN_TIME 0 +#define PN544_VBATVEN_TIME 0 +#define PN544_GPIO4VEN_TIME 0 +#define PN544_WAKEUP_ACK 5 +#define PN544_WAKEUP_GUARD (PN544_WAKEUP_ACK + 1) +#define PN544_INACTIVITY_TIME 1000 +#define PN544_INTERFRAME_DELAY 200 /* us */ +#define PN544_BAUDRATE_CHANGE 150 /* us */ + +/* Debug bits */ +#define PN544_DEBUG_BUF 0x01 +#define PN544_DEBUG_READ 0x02 +#define PN544_DEBUG_WRITE 0x04 +#define PN544_DEBUG_IRQ 0x08 +#define PN544_DEBUG_CALLS 0x10 +#define PN544_DEBUG_MODE 0x20 + +/* Normal (HCI) mode */ +#define PN544_LLC_HCI_OVERHEAD 3 /* header + crc (to length) */ +#define PN544_LLC_MIN_SIZE (1 + PN544_LLC_HCI_OVERHEAD) /* length + */ +#define PN544_LLC_MAX_DATA (PN544_MSG_MAX_SIZE - 2) +#define PN544_LLC_MAX_HCI_SIZE (PN544_LLC_MAX_DATA - 2) + +struct pn544_llc_packet { + unsigned char length; /* of rest of packet */ + unsigned char header; + unsigned char data[PN544_LLC_MAX_DATA]; /* includes crc-ccitt */ +}; + +/* Firmware upgrade mode */ +#define PN544_FW_HEADER_SIZE 3 +/* max fw transfer is 1024bytes, but I2C limits it to 0xC0 */ +#define PN544_MAX_FW_DATA (PN544_MAX_I2C_TRANSFER - PN544_FW_HEADER_SIZE) + +struct pn544_fw_packet { + unsigned char command; /* status in answer */ + unsigned char length[2]; /* big-endian order (msf) */ + unsigned char data[PN544_MAX_FW_DATA]; +}; + +#ifdef __KERNEL__ +enum { + NFC_GPIO_ENABLE, + NFC_GPIO_FW_RESET, + NFC_GPIO_IRQ +}; + +/* board config */ +struct pn544_nfc_platform_data { + int (*request_resources) (struct i2c_client *client); + void (*free_resources) (void); + void (*enable) (int fw); + int (*test) (void); + void (*disable) (void); + int (*get_gpio)(int type); +}; +#endif /* __KERNEL__ */ + +#endif /* _PN544_H_ */ diff --git a/trunk/include/linux/platform_data/pn544.h b/trunk/include/linux/platform_data/pn544.h deleted file mode 100644 index 713bfd703342..000000000000 --- a/trunk/include/linux/platform_data/pn544.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Driver include for the PN544 NFC chip. - * - * Copyright (C) Nokia Corporation - * - * Author: Jari Vanhala - * Contact: Matti Aaltoenn - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _PN544_H_ -#define _PN544_H_ - -#include - -enum { - NFC_GPIO_ENABLE, - NFC_GPIO_FW_RESET, - NFC_GPIO_IRQ -}; - -/* board config */ -struct pn544_nfc_platform_data { - int (*request_resources) (struct i2c_client *client); - void (*free_resources) (void); - void (*enable) (int fw); - int (*test) (void); - void (*disable) (void); - int (*get_gpio)(int type); -}; - -#endif /* _PN544_H_ */ diff --git a/trunk/include/linux/ssb/ssb_driver_mips.h b/trunk/include/linux/ssb/ssb_driver_mips.h index 07a9c7a2e088..5f44e9740cd2 100644 --- a/trunk/include/linux/ssb/ssb_driver_mips.h +++ b/trunk/include/linux/ssb/ssb_driver_mips.h @@ -13,12 +13,6 @@ struct ssb_serial_port { unsigned int reg_shift; }; -struct ssb_pflash { - bool present; - u8 buswidth; - u32 window; - u32 window_size; -}; struct ssb_mipscore { struct ssb_device *dev; @@ -26,7 +20,9 @@ struct ssb_mipscore { int nr_serial_ports; struct ssb_serial_port serial_ports[4]; - struct ssb_pflash pflash; + u8 flash_buswidth; + u32 flash_window; + u32 flash_window_size; }; extern void ssb_mipscore_init(struct ssb_mipscore *mcore); diff --git a/trunk/include/linux/ssb/ssb_regs.h b/trunk/include/linux/ssb/ssb_regs.h index 6ecfa02ddbac..a0525019e1d1 100644 --- a/trunk/include/linux/ssb/ssb_regs.h +++ b/trunk/include/linux/ssb/ssb_regs.h @@ -485,7 +485,7 @@ #define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4 #define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020 #define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5 -#define SSB_SPROM8_TEMPDELTA 0x00BC +#define SSB_SPROM8_TEMPDELTA 0x00BA #define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff #define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0 #define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00 diff --git a/trunk/include/net/bluetooth/a2mp.h b/trunk/include/net/bluetooth/a2mp.h index 42f21766c538..6a76e0a0705e 100644 --- a/trunk/include/net/bluetooth/a2mp.h +++ b/trunk/include/net/bluetooth/a2mp.h @@ -19,25 +19,13 @@ #define A2MP_FEAT_EXT 0x8000 -enum amp_mgr_state { - READ_LOC_AMP_INFO, - READ_LOC_AMP_ASSOC, - READ_LOC_AMP_ASSOC_FINAL, -}; - struct amp_mgr { - struct list_head list; struct l2cap_conn *l2cap_conn; struct l2cap_chan *a2mp_chan; - struct l2cap_chan *bredr_chan; struct kref kref; __u8 ident; __u8 handle; - enum amp_mgr_state state; unsigned long flags; - - struct list_head amp_ctrls; - struct mutex amp_ctrls_lock; }; struct a2mp_cmd { @@ -130,19 +118,9 @@ struct a2mp_physlink_rsp { #define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 #define A2MP_STATUS_SECURITY_VIOLATION 0x06 -extern struct list_head amp_mgr_list; -extern struct mutex amp_mgr_list_lock; - -struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr); +void amp_mgr_get(struct amp_mgr *mgr); int amp_mgr_put(struct amp_mgr *mgr); -u8 __next_ident(struct amp_mgr *mgr); struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, struct sk_buff *skb); -struct amp_mgr *amp_mgr_lookup_by_state(u8 state); -void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data); -void a2mp_discover_amp(struct l2cap_chan *chan); -void a2mp_send_getinfo_rsp(struct hci_dev *hdev); -void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); -void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); #endif /* __A2MP_H */ diff --git a/trunk/include/net/bluetooth/amp.h b/trunk/include/net/bluetooth/amp.h deleted file mode 100644 index 7ea3db77ba89..000000000000 --- a/trunk/include/net/bluetooth/amp.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only version 2 as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -#ifndef __AMP_H -#define __AMP_H - -struct amp_ctrl { - struct list_head list; - struct kref kref; - __u8 id; - __u16 assoc_len_so_far; - __u16 assoc_rem_len; - __u16 assoc_len; - __u8 *assoc; -}; - -int amp_ctrl_put(struct amp_ctrl *ctrl); -void amp_ctrl_get(struct amp_ctrl *ctrl); -struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id); -struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); -void amp_ctrl_list_flush(struct amp_mgr *mgr); - -struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, - u8 remote_id, bool out); - -int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); - -void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); -void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); -void amp_read_loc_assoc_final_data(struct hci_dev *hdev, - struct hci_conn *hcon); -void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon); -void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon); -void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); -void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon); -void amp_create_logical_link(struct l2cap_chan *chan); -void amp_disconnect_logical_link(struct hci_chan *hchan); -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason); - -#endif /* __AMP_H */ diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 2554b3f5222a..ede036977ae8 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -180,6 +180,7 @@ static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) } void baswap(bdaddr_t *dst, bdaddr_t *src); +char *batostr(bdaddr_t *ba); /* Common socket structures and functions */ diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index 45eee08157bb..76b2b6bdcf36 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -33,8 +33,6 @@ #define HCI_LINK_KEY_SIZE 16 #define HCI_AMP_LINK_KEY_SIZE (2 * HCI_LINK_KEY_SIZE) -#define HCI_MAX_AMP_ASSOC_SIZE 672 - /* HCI dev events */ #define HCI_DEV_REG 1 #define HCI_DEV_UNREG 2 @@ -115,7 +113,6 @@ enum { HCI_SSP_ENABLED, HCI_HS_ENABLED, HCI_LE_ENABLED, - HCI_LE_PERIPHERAL, HCI_CONNECTABLE, HCI_DISCOVERABLE, HCI_LINK_SECURITY, @@ -154,7 +151,7 @@ enum { #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ #define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ #define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ -#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ +#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ @@ -199,7 +196,6 @@ enum { #define ACL_START_NO_FLUSH 0x00 #define ACL_CONT 0x01 #define ACL_START 0x02 -#define ACL_COMPLETE 0x03 #define ACL_ACTIVE_BCAST 0x04 #define ACL_PICO_BCAST 0x08 @@ -209,7 +205,6 @@ enum { #define ESCO_LINK 0x02 /* Low Energy links do not have defined link type. Use invented one */ #define LE_LINK 0x80 -#define AMP_LINK 0x81 /* LMP features */ #define LMP_3SLOT 0x01 @@ -319,9 +314,6 @@ enum { #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 -/* The core spec defines 127 as the "not available" value */ -#define HCI_TX_POWER_INVALID 127 - /* Extended Inquiry Response field types */ #define EIR_FLAGS 0x01 /* flags */ #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ @@ -338,13 +330,6 @@ enum { #define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ #define EIR_DEVICE_ID 0x10 /* device ID */ -/* Low Energy Advertising Flags */ -#define LE_AD_LIMITED 0x01 /* Limited Discoverable */ -#define LE_AD_GENERAL 0x02 /* General Discoverable */ -#define LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */ -#define LE_AD_SIM_LE_BREDR_CTRL 0x08 /* Simultaneous LE & BR/EDR Controller */ -#define LE_AD_SIM_LE_BREDR_HOST 0x10 /* Simultaneous LE & BR/EDR Host */ - /* ----- HCI Commands ---- */ #define HCI_OP_NOP 0x0000 @@ -571,46 +556,12 @@ struct hci_cp_accept_phy_link { __u8 key[HCI_AMP_LINK_KEY_SIZE]; } __packed; -#define HCI_OP_DISCONN_PHY_LINK 0x0437 +#define HCI_OP_DISCONN_PHY_LINK 0x0437 struct hci_cp_disconn_phy_link { __u8 phy_handle; __u8 reason; } __packed; -struct ext_flow_spec { - __u8 id; - __u8 stype; - __le16 msdu; - __le32 sdu_itime; - __le32 acc_lat; - __le32 flush_to; -} __packed; - -#define HCI_OP_CREATE_LOGICAL_LINK 0x0438 -#define HCI_OP_ACCEPT_LOGICAL_LINK 0x0439 -struct hci_cp_create_accept_logical_link { - __u8 phy_handle; - struct ext_flow_spec tx_flow_spec; - struct ext_flow_spec rx_flow_spec; -} __packed; - -#define HCI_OP_DISCONN_LOGICAL_LINK 0x043a -struct hci_cp_disconn_logical_link { - __le16 log_handle; -} __packed; - -#define HCI_OP_LOGICAL_LINK_CANCEL 0x043b -struct hci_cp_logical_link_cancel { - __u8 phy_handle; - __u8 flow_spec_id; -} __packed; - -struct hci_rp_logical_link_cancel { - __u8 status; - __u8 phy_handle; - __u8 flow_spec_id; -} __packed; - #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { __le16 handle; @@ -943,22 +894,6 @@ struct hci_rp_le_read_buffer_size { __u8 le_max_pkt; } __packed; -#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 -struct hci_rp_le_read_adv_tx_power { - __u8 status; - __s8 tx_power; -} __packed; - -#define HCI_MAX_AD_LENGTH 31 - -#define HCI_OP_LE_SET_ADV_DATA 0x2008 -struct hci_cp_le_set_adv_data { - __u8 length; - __u8 data[HCI_MAX_AD_LENGTH]; -} __packed; - -#define HCI_OP_LE_SET_ADV_ENABLE 0x200a - #define HCI_OP_LE_SET_SCAN_PARAM 0x200b struct hci_cp_le_set_scan_param { __u8 type; diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index ef5b85dac3f7..e7d454609881 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -73,7 +73,6 @@ struct discovery_state { struct hci_conn_hash { struct list_head list; unsigned int acl_num; - unsigned int amp_num; unsigned int sco_num; unsigned int le_num; }; @@ -125,14 +124,6 @@ struct le_scan_params { #define HCI_MAX_SHORT_NAME_LENGTH 10 -struct amp_assoc { - __u16 len; - __u16 offset; - __u16 rem_len; - __u16 len_so_far; - __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; -}; - #define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; @@ -186,8 +177,6 @@ struct hci_dev { __u32 amp_max_flush_to; __u32 amp_be_flush_to; - struct amp_assoc loc_assoc; - __u8 flow_ctl_mode; unsigned int auto_accept_delay; @@ -263,6 +252,8 @@ struct hci_dev { struct sk_buff_head driver_init; + void *core_data; + atomic_t promisc; struct dentry *debugfs; @@ -278,10 +269,6 @@ struct hci_dev { struct work_struct le_scan; struct le_scan_params le_scan_params; - __s8 adv_tx_power; - __u8 adv_data[HCI_MAX_AD_LENGTH]; - __u8 adv_data_len; - int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -290,8 +277,6 @@ struct hci_dev { int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); }; -#define HCI_PHY_HANDLE(handle) (handle & 0xff) - struct hci_conn { struct list_head list; @@ -325,7 +310,6 @@ struct hci_conn { __u8 remote_cap; __u8 remote_auth; - __u8 remote_id; bool flush_key; unsigned int sent; @@ -355,11 +339,10 @@ struct hci_conn { struct hci_chan { struct list_head list; - __u16 handle; + struct hci_conn *conn; struct sk_buff_head data_q; unsigned int sent; - __u8 state; }; extern struct list_head hci_dev_list; @@ -455,9 +438,6 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) case ACL_LINK: h->acl_num++; break; - case AMP_LINK: - h->amp_num++; - break; case LE_LINK: h->le_num++; break; @@ -479,9 +459,6 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) case ACL_LINK: h->acl_num--; break; - case AMP_LINK: - h->amp_num--; - break; case LE_LINK: h->le_num--; break; @@ -498,8 +475,6 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) switch (type) { case ACL_LINK: return h->acl_num; - case AMP_LINK: - return h->amp_num; case LE_LINK: return h->le_num; case SCO_LINK: @@ -581,7 +556,6 @@ void hci_conn_check_pending(struct hci_dev *hdev); struct hci_chan *hci_chan_create(struct hci_conn *conn); void hci_chan_del(struct hci_chan *chan); void hci_chan_list_flush(struct hci_conn *conn); -struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 dst_type, __u8 sec_level, __u8 auth_type); @@ -610,10 +584,7 @@ static inline void hci_conn_put(struct hci_conn *conn) if (atomic_dec_and_test(&conn->refcnt)) { unsigned long timeo; - - switch (conn->type) { - case ACL_LINK: - case LE_LINK: + if (conn->type == ACL_LINK || conn->type == LE_LINK) { del_timer(&conn->idle_timer); if (conn->state == BT_CONNECTED) { timeo = conn->disc_timeout; @@ -622,20 +593,12 @@ static inline void hci_conn_put(struct hci_conn *conn) } else { timeo = msecs_to_jiffies(10); } - break; - - case AMP_LINK: - timeo = conn->disc_timeout; - break; - - default: + } else { timeo = msecs_to_jiffies(10); - break; } - cancel_delayed_work(&conn->disc_work); queue_delayed_work(conn->hdev->workqueue, - &conn->disc_work, timeo); + &conn->disc_work, timeo); } } @@ -687,7 +650,7 @@ static inline uint8_t __hci_num_ctrl(void) } struct hci_dev *hci_dev_get(int index); -struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); +struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); struct hci_dev *hci_alloc_dev(void); void hci_free_dev(struct hci_dev *hdev); @@ -736,8 +699,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, u8 *randomizer); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_update_ad(struct hci_dev *hdev); - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb); @@ -754,29 +715,18 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) /* ----- LMP capabilities ----- */ -#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) #define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) -#define lmp_hold_capable(dev) ((dev)->features[0] & LMP_HOLD) +#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) -#define lmp_park_capable(dev) ((dev)->features[1] & LMP_PARK) -#define lmp_inq_rssi_capable(dev) ((dev)->features[3] & LMP_RSSI_INQ) -#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) -#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) -#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) -#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) -#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) -#define lmp_le_br_capable(dev) ((dev)->features[6] & LMP_SIMUL_LE_BR) +#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) -#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) -#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR) -#define lmp_ext_feat_capable(dev) ((dev)->features[7] & LMP_EXTFEATURES) +#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) +#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) /* ----- Extended LMP capabilities ----- */ -#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) #define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) -#define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR) /* ----- HCI protocols ----- */ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, @@ -839,10 +789,6 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) sco_disconn_cfm(conn, reason); break; - /* L2CAP would be handled for BREDR chan */ - case AMP_LINK: - break; - default: BT_ERR("unknown link type %d", conn->type); break; @@ -895,7 +841,7 @@ struct hci_cb { static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) { - struct hci_cb *cb; + struct list_head *p; __u8 encrypt; hci_proto_auth_cfm(conn, status); @@ -906,7 +852,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } @@ -916,7 +863,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) { - struct hci_cb *cb; + struct list_head *p; if (conn->sec_level == BT_SECURITY_SDP) conn->sec_level = BT_SECURITY_LOW; @@ -927,7 +874,8 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, hci_proto_encrypt_cfm(conn, status, encrypt); read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } @@ -936,10 +884,11 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) { - struct hci_cb *cb; + struct list_head *p; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->key_change_cfm) cb->key_change_cfm(conn, status); } @@ -949,10 +898,11 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role) { - struct hci_cb *cb; + struct list_head *p; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->role_switch_cfm) cb->role_switch_cfm(conn, status, role); } diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index f57fab04e7c5..7ed8e356425a 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -32,14 +32,13 @@ /* L2CAP defaults */ #define L2CAP_DEFAULT_MTU 672 #define L2CAP_DEFAULT_MIN_MTU 48 -#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF -#define L2CAP_EFS_DEFAULT_FLUSH_TO 0xFFFFFFFF +#define L2CAP_DEFAULT_FLUSH_TO 0xffff #define L2CAP_DEFAULT_TX_WINDOW 63 #define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF #define L2CAP_DEFAULT_MAX_TX 3 #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ -#define L2CAP_DEFAULT_MAX_PDU_SIZE 1492 /* Sized for AMP packet */ +#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ #define L2CAP_DEFAULT_ACK_TO 200 #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF @@ -52,8 +51,6 @@ #define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000) #define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) #define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) -#define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000) -#define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000) #define L2CAP_A2MP_DEFAULT_MTU 670 @@ -436,8 +433,6 @@ struct l2cap_chan { struct sock *sk; struct l2cap_conn *conn; - struct hci_conn *hs_hcon; - struct hci_chan *hs_hchan; struct kref kref; __u8 state; @@ -481,12 +476,6 @@ struct l2cap_chan { unsigned long conn_state; unsigned long flags; - __u8 remote_amp_id; - __u8 local_amp_id; - __u8 move_id; - __u8 move_state; - __u8 move_role; - __u16 next_tx_seq; __u16 expected_ack_seq; __u16 expected_tx_seq; @@ -549,7 +538,6 @@ struct l2cap_ops { void (*state_change) (struct l2cap_chan *chan, int state); void (*ready) (struct l2cap_chan *chan); - void (*defer) (struct l2cap_chan *chan); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); }; @@ -652,9 +640,6 @@ enum { enum { L2CAP_RX_STATE_RECV, L2CAP_RX_STATE_SREJ_SENT, - L2CAP_RX_STATE_MOVE, - L2CAP_RX_STATE_WAIT_P, - L2CAP_RX_STATE_WAIT_F, }; enum { @@ -685,25 +670,6 @@ enum { L2CAP_EV_RECV_FRAME, }; -enum { - L2CAP_MOVE_ROLE_NONE, - L2CAP_MOVE_ROLE_INITIATOR, - L2CAP_MOVE_ROLE_RESPONDER, -}; - -enum { - L2CAP_MOVE_STABLE, - L2CAP_MOVE_WAIT_REQ, - L2CAP_MOVE_WAIT_RSP, - L2CAP_MOVE_WAIT_RSP_SUCCESS, - L2CAP_MOVE_WAIT_CONFIRM, - L2CAP_MOVE_WAIT_CONFIRM_RSP, - L2CAP_MOVE_WAIT_LOGICAL_COMP, - L2CAP_MOVE_WAIT_LOGICAL_CFM, - L2CAP_MOVE_WAIT_LOCAL_BUSY, - L2CAP_MOVE_WAIT_PREPARE, -}; - void l2cap_chan_hold(struct l2cap_chan *c); void l2cap_chan_put(struct l2cap_chan *c); @@ -779,10 +745,6 @@ static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) { } -static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) -{ -} - extern bool disable_ertm; int l2cap_init_sockets(void); @@ -805,12 +767,6 @@ int l2cap_chan_check_security(struct l2cap_chan *chan); void l2cap_chan_set_defaults(struct l2cap_chan *chan); int l2cap_ertm_init(struct l2cap_chan *chan); void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); -void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); void l2cap_chan_del(struct l2cap_chan *chan, int err); -void l2cap_send_conn_req(struct l2cap_chan *chan); -void l2cap_move_start(struct l2cap_chan *chan); -void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, - u8 status); -void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); #endif /* __L2CAP_H */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 81d725038f97..1b4989082244 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -498,7 +498,6 @@ enum station_parameters_apply_mask { * @plink_action: plink action to take * @plink_state: set the peer link state for a station * @ht_capa: HT capabilities of station - * @vht_capa: VHT capabilities of station * @uapsd_queues: bitmap of queues configured for uapsd. same format * as the AC bitmap in the QoS info field * @max_sp: max Service Period. same format as the MAX_SP in the @@ -518,7 +517,6 @@ struct station_parameters { u8 plink_action; u8 plink_state; struct ieee80211_ht_cap *ht_capa; - struct ieee80211_vht_cap *vht_capa; u8 uapsd_queues; u8 max_sp; }; @@ -1002,10 +1000,8 @@ struct cfg80211_ssid { * @n_channels: total number of channels to scan * @ie: optional information element(s) to add into Probe Request or %NULL * @ie_len: length of ie in octets - * @flags: bit field of flags controlling operation * @rates: bitmap of rates to advertise for each band * @wiphy: the wiphy this was for - * @scan_start: time (in jiffies) when the scan started * @wdev: the wireless device to scan for * @aborted: (internal) scan request was notified as aborted * @no_cck: used to send probe requests at non CCK rate in 2GHz band @@ -1016,7 +1012,6 @@ struct cfg80211_scan_request { u32 n_channels; const u8 *ie; size_t ie_len; - u32 flags; u32 rates[IEEE80211_NUM_BANDS]; @@ -1024,7 +1019,6 @@ struct cfg80211_scan_request { /* internal */ struct wiphy *wiphy; - unsigned long scan_start; bool aborted; bool no_cck; @@ -1050,7 +1044,6 @@ struct cfg80211_match_set { * @interval: interval between each scheduled scan cycle * @ie: optional information element(s) to add into Probe Request or %NULL * @ie_len: length of ie in octets - * @flags: bit field of flags controlling operation * @match_sets: sets of parameters to be matched for a scan result * entry to be considered valid and to be passed to the host * (others are filtered out). @@ -1068,7 +1061,6 @@ struct cfg80211_sched_scan_request { u32 interval; const u8 *ie; size_t ie_len; - u32 flags; struct cfg80211_match_set *match_sets; int n_match_sets; s32 rssi_thold; @@ -1076,7 +1068,6 @@ struct cfg80211_sched_scan_request { /* internal */ struct wiphy *wiphy; struct net_device *dev; - unsigned long scan_start; /* keep last */ struct ieee80211_channel *channels[0]; @@ -1161,9 +1152,6 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); * @key_len: length of WEP key for shared key authentication * @key_idx: index of WEP key for shared key authentication * @key: WEP key for shared key authentication - * @sae_data: Non-IE data to use with SAE or %NULL. This starts with - * Authentication transaction sequence number field. - * @sae_data_len: Length of sae_data buffer in octets */ struct cfg80211_auth_request { struct cfg80211_bss *bss; @@ -1172,8 +1160,6 @@ struct cfg80211_auth_request { enum nl80211_auth_type auth_type; const u8 *key; u8 key_len, key_idx; - const u8 *sae_data; - size_t sae_data_len; }; /** @@ -1232,7 +1218,6 @@ struct cfg80211_deauth_request { const u8 *ie; size_t ie_len; u16 reason_code; - bool local_state_change; }; /** @@ -1545,19 +1530,13 @@ struct cfg80211_gtk_rekey_data { * to a merge. * @leave_ibss: Leave the IBSS. * - * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or - * MESH mode) - * * @set_wiphy_params: Notify that wiphy parameters have changed; * @changed bitfield (see &enum wiphy_params_flags) describes which values * have changed. The actual parameter values are available in * struct wiphy. If returning an error, no value should be changed. * * @set_tx_power: set the transmit power according to the parameters, - * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The - * wdev may be %NULL if power was set for the wiphy, and will - * always be %NULL unless the driver supports per-vif TX power - * (as advertised by the nl80211 feature flag.) + * the power passed is in mBm, to get dBm use MBM_TO_DBM(). * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful * @@ -1752,15 +1731,11 @@ struct cfg80211_ops { struct cfg80211_ibss_params *params); int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); - int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev, - int rate[IEEE80211_NUM_BANDS]); - int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); - int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, + int (*set_tx_power)(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm); - int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, - int *dbm); + int (*get_tx_power)(struct wiphy *wiphy, int *dbm); int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, const u8 *addr); @@ -2675,15 +2650,6 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); -/** - * ieee80211_get_mesh_hdrlen - get mesh extension header length - * @meshhdr: the mesh extension header, only the flags field - * (first byte) will be accessed - * Returns the length of the extension header, which is always at - * least 6 bytes and at most 18 if address 5 and 6 are present. - */ -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); - /** * DOC: Data path helpers * @@ -3560,6 +3526,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, * @len: length of the frame * @freq: frequency the frame was received on * @sig_dbm: signal strength in mBm, or 0 if unknown + * @gfp: allocation flags * * Use this function to report to userspace when a beacon was * received. It is not useful to call this when there is no @@ -3567,7 +3534,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, */ void cfg80211_report_obss_beacon(struct wiphy *wiphy, const u8 *frame, size_t len, - int freq, int sig_dbm); + int freq, int sig_dbm, gfp_t gfp); /** * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used @@ -3617,25 +3584,6 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate); */ void cfg80211_unregister_wdev(struct wireless_dev *wdev); -/** - * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer - * @ies: the input IE buffer - * @len: the input length - * @attr: the attribute ID to find - * @buf: output buffer, can be %NULL if the data isn't needed, e.g. - * if the function is only called to get the needed buffer size - * @bufsize: size of the output buffer - * - * The function finds a given P2P attribute in the (vendor) IEs and - * copies its contents to the given buffer. - * - * The return value is a negative error code (-%EILSEQ or -%ENOENT) if - * the data is malformed or the attribute can't be found (respectively), - * or the length of the found attribute (which can be zero). - */ -unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, - u8 attr, u8 *buf, unsigned int bufsize); - /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index a789dd1d4c10..82558c8decf8 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -143,41 +143,6 @@ struct ieee80211_low_level_stats { unsigned int dot11RTSSuccessCount; }; -/** - * enum ieee80211_chanctx_change - change flag for channel context - * @IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE: The channel type was changed - * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed - */ -enum ieee80211_chanctx_change { - IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE = BIT(0), - IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), -}; - -/** - * struct ieee80211_chanctx_conf - channel context that vifs may be tuned to - * - * This is the driver-visible part. The ieee80211_chanctx - * that contains it is visible in mac80211 only. - * - * @channel: the channel to tune to - * @channel_type: the channel (HT) type - * @rx_chains_static: The number of RX chains that must always be - * active on the channel to receive MIMO transmissions - * @rx_chains_dynamic: The number of RX chains that must be enabled - * after RTS/CTS handshake to receive SMPS MIMO transmissions; - * this will always be >= @rx_chains_always. - * @drv_priv: data area for driver use, will always be aligned to - * sizeof(void *), size is determined in hw information. - */ -struct ieee80211_chanctx_conf { - struct ieee80211_channel *channel; - enum nl80211_channel_type channel_type; - - u8 rx_chains_static, rx_chains_dynamic; - - u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); -}; - /** * enum ieee80211_bss_change - BSS change notification flags * @@ -207,9 +172,6 @@ struct ieee80211_chanctx_conf { * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) * @BSS_CHANGED_PS: PS changed for this BSS (STA mode) - * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface - * @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS) - * changed (currently only in P2P client mode, GO mode will be later) */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -230,8 +192,6 @@ enum ieee80211_bss_change { BSS_CHANGED_SSID = 1<<15, BSS_CHANGED_AP_PROBE_RESP = 1<<16, BSS_CHANGED_PS = 1<<17, - BSS_CHANGED_TXPOWER = 1<<18, - BSS_CHANGED_P2P_PS = 1<<19, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -263,7 +223,6 @@ enum ieee80211_rssi_event { * @assoc: association status * @ibss_joined: indicates whether this station is part of an IBSS * or not - * @ibss_creator: indicates if a new IBSS network is being created * @aid: association ID number, valid only when @assoc is true * @use_cts_prot: use CTS protection * @use_short_preamble: use 802.11b short preamble; @@ -314,15 +273,11 @@ enum ieee80211_rssi_event { * @ssid: The SSID of the current vif. Only valid in AP-mode. * @ssid_len: Length of SSID given in @ssid. * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. - * @txpower: TX power in dBm - * @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces - * @p2p_oppps: P2P opportunistic PS is enabled */ struct ieee80211_bss_conf { const u8 *bssid; /* association related data */ bool assoc, ibss_joined; - bool ibss_creator; u16 aid; /* erp related data */ bool use_cts_prot; @@ -349,9 +304,6 @@ struct ieee80211_bss_conf { u8 ssid[IEEE80211_MAX_SSID_LEN]; size_t ssid_len; bool hidden_ssid; - int txpower; - u8 p2p_ctwindow; - bool p2p_oppps; }; /** @@ -842,8 +794,6 @@ enum ieee80211_conf_flags { * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed - * Note that this is only valid if channel contexts are not used, - * otherwise each channel context has the number of chains listed. */ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_SMPS = BIT(1), @@ -895,8 +845,7 @@ enum ieee80211_smps_mode { * powersave documentation below. This variable is valid only when * the CONF_PS flag is set. * - * @power_level: requested transmit power (in dBm), backward compatibility - * value only that is set to the minimum of all interfaces + * @power_level: requested transmit power (in dBm) * * @channel: the channel to tune to * @channel_type: the channel (HT) type @@ -910,9 +859,7 @@ enum ieee80211_smps_mode { * * @smps_mode: spatial multiplexing powersave mode; note that * %IEEE80211_SMPS_STATIC is used when the device is not - * configured for an HT channel. - * Note that this is only valid if channel contexts are not used, - * otherwise each channel context has the number of chains listed. + * configured for an HT channel */ struct ieee80211_conf { u32 flags; @@ -984,11 +931,6 @@ enum ieee80211_vif_flags { * at runtime, mac80211 will never touch this field * @hw_queue: hardware queue for each AC * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only - * @chanctx_conf: The channel context this interface is assigned to, or %NULL - * when it is not assigned. This pointer is RCU-protected due to the TX - * path needing to access it; even though the netdev carrier will always - * be off when it is %NULL there can still be races and packets could be - * processed after it switches back to %NULL. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -1001,8 +943,6 @@ struct ieee80211_vif { u8 cab_queue; u8 hw_queue[IEEE80211_NUM_ACS]; - struct ieee80211_chanctx_conf __rcu *chanctx_conf; - u32 driver_flags; /* must be last */ @@ -1136,8 +1076,6 @@ enum ieee80211_sta_state { * @aid: AID we assigned to the station if we're an AP * @supp_rates: Bitmap of supported rates (per band) * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities - * @vht_cap: VHT capabilities of this STA; Not restricting any capabilities - * of remote STA. Taking as is. * @wme: indicates whether the STA supports WME. Only valid during AP-mode. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *), size is determined in hw information. @@ -1150,7 +1088,6 @@ struct ieee80211_sta { u8 addr[ETH_ALEN]; u16 aid; struct ieee80211_sta_ht_cap ht_cap; - struct ieee80211_sta_vht_cap vht_cap; bool wme; u8 uapsd_queues; u8 max_sp; @@ -1388,8 +1325,6 @@ enum ieee80211_hw_flags { * within &struct ieee80211_vif. * @sta_data_size: size (in bytes) of the drv_priv data area * within &struct ieee80211_sta. - * @chanctx_data_size: size (in bytes) of the drv_priv data area - * within &struct ieee80211_chanctx_conf. * * @max_rates: maximum number of alternate rate retry stages the hw * can handle. @@ -1434,7 +1369,6 @@ struct ieee80211_hw { int channel_change_time; int vif_data_size; int sta_data_size; - int chanctx_data_size; int napi_weight; u16 queues; u16 max_listen_interval; @@ -2383,27 +2317,6 @@ enum ieee80211_rate_control_changed { * The callback will be called before each transmission and upon return * mac80211 will transmit the frame right away. * The callback is optional and can (should!) sleep. - * - * @add_chanctx: Notifies device driver about new channel context creation. - * @remove_chanctx: Notifies device driver about channel context destruction. - * @change_chanctx: Notifies device driver about channel context changes that - * may happen when combining different virtual interfaces on the same - * channel context with different settings - * @assign_vif_chanctx: Notifies device driver about channel context being bound - * to vif. Possible use is for hw queue remapping. - * @unassign_vif_chanctx: Notifies device driver about channel context being - * unbound from vif. - * @start_ap: Start operation on the AP interface, this is called after all the - * information in bss_conf is set and beacon can be retrieved. A channel - * context is bound before this is called. Note that if the driver uses - * software scan or ROC, this (and @stop_ap) isn't called when the AP is - * just "paused" for scanning/ROC, which is indicated by the beacon being - * disabled/enabled via @bss_info_changed. - * @stop_ap: Stop operation on the AP interface. - * - * @restart_complete: Called after a call to ieee80211_restart_hw(), when the - * reconfiguration has completed. This can help the driver implement the - * reconfiguration step. This callback may sleep. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -2429,9 +2342,6 @@ struct ieee80211_ops { struct ieee80211_bss_conf *info, u32 changed); - int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); - void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); - u64 (*prepare_multicast)(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list); void (*configure_filter)(struct ieee80211_hw *hw, @@ -2551,22 +2461,6 @@ struct ieee80211_ops { void (*mgd_prepare_tx)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); - - int (*add_chanctx)(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx); - void (*remove_chanctx)(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx); - void (*change_chanctx)(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *ctx, - u32 changed); - int (*assign_vif_chanctx)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_chanctx_conf *ctx); - void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_chanctx_conf *ctx); - - void (*restart_complete)(struct ieee80211_hw *hw); }; /** @@ -3250,19 +3144,6 @@ void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf, void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, struct sk_buff *skb, u8 *p2k); -/** - * ieee80211_aes_cmac_calculate_k1_k2 - calculate the AES-CMAC sub keys - * - * This function computes the two AES-CMAC sub-keys, based on the - * previously installed master key. - * - * @keyconf: the parameter passed with the set key - * @k1: a buffer to be filled with the 1st sub-key - * @k2: a buffer to be filled with the 2nd sub-key - */ -void ieee80211_aes_cmac_calculate_k1_k2(struct ieee80211_key_conf *keyconf, - u8 *k1, u8 *k2); - /** * struct ieee80211_key_seq - key sequence counter * @@ -3412,21 +3293,6 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw); */ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw); -/** - * enum ieee80211_interface_iteration_flags - interface iteration flags - * @IEEE80211_IFACE_ITER_NORMAL: Iterate over all interfaces that have - * been added to the driver; However, note that during hardware - * reconfiguration (after restart_hw) it will iterate over a new - * interface and over all the existing interfaces even if they - * haven't been re-added to the driver yet. - * @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all - * interfaces, even if they haven't been re-added to the driver yet. - */ -enum ieee80211_interface_iteration_flags { - IEEE80211_IFACE_ITER_NORMAL = 0, - IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0), -}; - /** * ieee80211_iterate_active_interfaces - iterate active interfaces * @@ -3435,15 +3301,13 @@ enum ieee80211_interface_iteration_flags { * This function allows the iterator function to sleep, when the iterator * function is atomic @ieee80211_iterate_active_interfaces_atomic can * be used. - * Does not iterate over a new interface during add_interface(). + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over - * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags * @iterator: the iterator function to call * @data: first argument of the iterator function */ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, - u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data); @@ -3455,15 +3319,13 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, * hardware that are currently active and calls the callback for them. * This function requires the iterator callback function to be atomic, * if that is not desired, use @ieee80211_iterate_active_interfaces instead. - * Does not iterate over a new interface during add_interface(). + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over - * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags * @iterator: the iterator function to call, cannot sleep * @data: first argument of the iterator function */ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, - u32 iter_flags, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), @@ -3661,27 +3523,6 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, void *data), void *iter_data); -/** - * ieee80211_iter_chan_contexts_atomic - iterate channel contexts - * @hw: pointre obtained from ieee80211_alloc_hw(). - * @iter: iterator function - * @iter_data: data passed to iterator function - * - * Iterate all active channel contexts. This function is atomic and - * doesn't acquire any locks internally that might be held in other - * places while calling into the driver. - * - * The iterator will not find a context that's being added (during - * the driver callback to add it) but will find it while it's being - * removed. - */ -void ieee80211_iter_chan_contexts_atomic( - struct ieee80211_hw *hw, - void (*iter)(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *chanctx_conf, - void *data), - void *iter_data); - /** * ieee80211_ap_probereq_get - retrieve a Probe Request template * @hw: pointer obtained from ieee80211_alloc_hw(). diff --git a/trunk/include/net/nfc/hci.h b/trunk/include/net/nfc/hci.h index 671953e11575..e900072950cb 100644 --- a/trunk/include/net/nfc/hci.h +++ b/trunk/include/net/nfc/hci.h @@ -24,12 +24,6 @@ #include -struct nfc_phy_ops { - int (*write)(void *dev_id, struct sk_buff *skb); - int (*enable)(void *dev_id); - void (*disable)(void *dev_id); -}; - struct nfc_hci_dev; struct nfc_hci_ops { @@ -44,21 +38,15 @@ struct nfc_hci_ops { int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll) (struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols); - int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target, - u8 comm_mode, u8 *gb, size_t gb_len); - int (*dep_link_down)(struct nfc_hci_dev *hdev); int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, struct nfc_target *target); - int (*im_transceive) (struct nfc_hci_dev *hdev, + int (*data_exchange) (struct nfc_hci_dev *hdev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); - int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*check_presence)(struct nfc_hci_dev *hdev, struct nfc_target *target); - void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, - struct sk_buff *skb); }; /* Pipes */ @@ -126,9 +114,6 @@ struct nfc_hci_dev { int async_cb_type; data_exchange_cb_t async_cb; void *async_cb_context; - - u8 *gb; - size_t gb_len; }; /* hci device allocation */ @@ -149,8 +134,6 @@ void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev); void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); -int nfc_hci_result_to_errno(u8 result); - /* Host IDs */ #define NFC_HCI_HOST_CONTROLLER_ID 0x00 #define NFC_HCI_TERMINAL_HOST_ID 0x01 @@ -236,7 +219,5 @@ int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, const u8 *param, size_t param_len); int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, const u8 *param, size_t param_len); -int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); -u32 nfc_hci_sak_to_protocol(u8 sak); #endif /* __NET_HCI_H */ diff --git a/trunk/include/net/nfc/nfc.h b/trunk/include/net/nfc/nfc.h index fce80b2f9be7..f05b10682c9d 100644 --- a/trunk/include/net/nfc/nfc.h +++ b/trunk/include/net/nfc/nfc.h @@ -95,7 +95,7 @@ struct nfc_genl_data { }; struct nfc_dev { - int idx; + unsigned int idx; u32 target_next_idx; struct nfc_target *targets; int n_targets; diff --git a/trunk/include/uapi/linux/nfc.h b/trunk/include/uapi/linux/nfc.h index 0e63cee8d810..d908d17da56d 100644 --- a/trunk/include/uapi/linux/nfc.h +++ b/trunk/include/uapi/linux/nfc.h @@ -60,13 +60,6 @@ * target mode. * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated * from target mode. - * @NFC_CMD_LLC_GET_PARAMS: request LTO, RW, and MIUX parameters for a device - * @NFC_CMD_LLC_SET_PARAMS: set one or more of LTO, RW, and MIUX parameters for - * a device. LTO must be set before the link is up otherwise -EINPROGRESS - * is returned. RW and MIUX can be set at anytime and will be passed in - * subsequent CONNECT and CC messages. - * If one of the passed parameters is wrong none is set and -EINVAL is - * returned. */ enum nfc_commands { NFC_CMD_UNSPEC, @@ -84,8 +77,6 @@ enum nfc_commands { NFC_EVENT_TARGET_LOST, NFC_EVENT_TM_ACTIVATED, NFC_EVENT_TM_DEACTIVATED, - NFC_CMD_LLC_GET_PARAMS, - NFC_CMD_LLC_SET_PARAMS, /* private: internal use only */ __NFC_CMD_AFTER_LAST }; @@ -111,9 +102,6 @@ enum nfc_commands { * @NFC_ATTR_RF_MODE: Initiator or target * @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for * @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for - * @NFC_ATTR_LLC_PARAM_LTO: Link TimeOut parameter - * @NFC_ATTR_LLC_PARAM_RW: Receive Window size parameter - * @NFC_ATTR_LLC_PARAM_MIUX: MIU eXtension parameter */ enum nfc_attrs { NFC_ATTR_UNSPEC, @@ -131,9 +119,6 @@ enum nfc_attrs { NFC_ATTR_DEVICE_POWERED, NFC_ATTR_IM_PROTOCOLS, NFC_ATTR_TM_PROTOCOLS, - NFC_ATTR_LLC_PARAM_LTO, - NFC_ATTR_LLC_PARAM_RW, - NFC_ATTR_LLC_PARAM_MIUX, /* private: internal use only */ __NFC_ATTR_AFTER_LAST }; diff --git a/trunk/include/uapi/linux/nl80211.h b/trunk/include/uapi/linux/nl80211.h index cbd2d6bb907a..7df9b500c804 100644 --- a/trunk/include/uapi/linux/nl80211.h +++ b/trunk/include/uapi/linux/nl80211.h @@ -578,9 +578,6 @@ * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON * is used for this. * - * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames - * for IBSS or MESH vif. - * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -729,8 +726,6 @@ enum nl80211_commands { NL80211_CMD_CONN_FAILED, - NL80211_CMD_SET_MCAST_RATE, - /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1278,14 +1273,6 @@ enum nl80211_commands { * the connection request from a station. nl80211_connect_failed_reason * enum has different reasons of connection failure. * - * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts - * with the Authentication transaction sequence number field. - * - * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from - * association request when used with NL80211_CMD_NEW_STATION) - * - * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) - * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1543,12 +1530,6 @@ enum nl80211_attrs { NL80211_ATTR_CONN_FAILED_REASON, - NL80211_ATTR_SAE_DATA, - - NL80211_ATTR_VHT_CAPABILITY, - - NL80211_ATTR_SCAN_FLAGS, - /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1592,7 +1573,6 @@ enum nl80211_attrs { #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 #define NL80211_HT_CAPABILITY_LEN 26 -#define NL80211_VHT_CAPABILITY_LEN 12 #define NL80211_MAX_NR_CIPHER_SUITES 5 #define NL80211_MAX_NR_AKM_SUITES 2 @@ -2509,7 +2489,6 @@ enum nl80211_bss_status { * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) - * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals * @__NL80211_AUTHTYPE_NUM: internal * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by @@ -2521,7 +2500,6 @@ enum nl80211_auth_type { NL80211_AUTHTYPE_SHARED_KEY, NL80211_AUTHTYPE_FT, NL80211_AUTHTYPE_NETWORK_EAP, - NL80211_AUTHTYPE_SAE, /* keep last */ __NL80211_AUTHTYPE_NUM, @@ -3050,13 +3028,6 @@ enum nl80211_ap_sme_features { * in the interface combinations, even when it's only used for scan * and remain-on-channel. This could be due to, for example, the * remain-on-channel implementation requiring a channel context. - * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of - * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station - * mode - * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan - * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported - * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif - * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting */ enum nl80211_feature_flags { NL80211_FEATURE_SK_TX_STATUS = 1 << 0, @@ -3064,11 +3035,6 @@ enum nl80211_feature_flags { NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, - NL80211_FEATURE_SAE = 1 << 5, - NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, - NL80211_FEATURE_SCAN_FLUSH = 1 << 7, - NL80211_FEATURE_AP_SCAN = 1 << 8, - NL80211_FEATURE_VIF_TXPOWER = 1 << 9, }; /** @@ -3103,25 +3069,4 @@ enum nl80211_connect_failed_reason { NL80211_CONN_FAIL_BLOCKED_CLIENT, }; -/** - * enum nl80211_scan_flags - scan request control flags - * - * Scan request control flags are used to control the handling - * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN - * requests. - * - * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority - * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning - * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured - * as AP and the beaconing has already been configured. This attribute is - * dangerous because will destroy stations performance as a lot of frames - * will be lost while scanning off-channel, therefore it must be used only - * when really needed - */ -enum nl80211_scan_flags { - NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, - NL80211_SCAN_FLAG_FLUSH = 1<<1, - NL80211_SCAN_FLAG_AP = 1<<2, -}; - #endif /* __LINUX_NL80211_H */ diff --git a/trunk/net/bluetooth/Kconfig b/trunk/net/bluetooth/Kconfig index d3f3f7b1d32c..3537d385035e 100644 --- a/trunk/net/bluetooth/Kconfig +++ b/trunk/net/bluetooth/Kconfig @@ -11,7 +11,6 @@ menuconfig BT select CRYPTO_BLKCIPHER select CRYPTO_AES select CRYPTO_ECB - select CRYPTO_SHA256 help Bluetooth is low-cost, low-power, short-range wireless technology. It was designed as a replacement for cables and other short-range @@ -48,3 +47,4 @@ source "net/bluetooth/cmtp/Kconfig" source "net/bluetooth/hidp/Kconfig" source "drivers/bluetooth/Kconfig" + diff --git a/trunk/net/bluetooth/Makefile b/trunk/net/bluetooth/Makefile index dea6a287daca..fa6d94a4602a 100644 --- a/trunk/net/bluetooth/Makefile +++ b/trunk/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_HIDP) += hidp/ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ - a2mp.o amp.o + a2mp.o diff --git a/trunk/net/bluetooth/a2mp.c b/trunk/net/bluetooth/a2mp.c index 2f67d5ecc907..0760d1fed6f0 100644 --- a/trunk/net/bluetooth/a2mp.c +++ b/trunk/net/bluetooth/a2mp.c @@ -16,11 +16,6 @@ #include #include #include -#include - -/* Global AMP Manager list */ -LIST_HEAD(amp_mgr_list); -DEFINE_MUTEX(amp_mgr_list_lock); /* A2MP build & send command helper functions */ static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) @@ -42,7 +37,8 @@ static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) return cmd; } -void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data) +static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, + void *data) { struct l2cap_chan *chan = mgr->a2mp_chan; struct a2mp_cmd *cmd; @@ -67,14 +63,6 @@ void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data) kfree(cmd); } -u8 __next_ident(struct amp_mgr *mgr) -{ - if (++mgr->ident == 0) - mgr->ident = 1; - - return mgr->ident; -} - static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) { cl->id = 0; @@ -173,83 +161,6 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } -static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_discov_rsp *rsp = (void *) skb->data; - u16 len = le16_to_cpu(hdr->len); - struct a2mp_cl *cl; - u16 ext_feat; - bool found = false; - - if (len < sizeof(*rsp)) - return -EINVAL; - - len -= sizeof(*rsp); - skb_pull(skb, sizeof(*rsp)); - - ext_feat = le16_to_cpu(rsp->ext_feat); - - BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(rsp->mtu), ext_feat); - - /* check that packet is not broken for now */ - while (ext_feat & A2MP_FEAT_EXT) { - if (len < sizeof(ext_feat)) - return -EINVAL; - - ext_feat = get_unaligned_le16(skb->data); - BT_DBG("efm 0x%4.4x", ext_feat); - len -= sizeof(ext_feat); - skb_pull(skb, sizeof(ext_feat)); - } - - cl = (void *) skb->data; - while (len >= sizeof(*cl)) { - BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type, - cl->status); - - if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { - struct a2mp_info_req req; - - found = true; - req.id = cl->id; - a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr), - sizeof(req), &req); - } - - len -= sizeof(*cl); - cl = (void *) skb_pull(skb, sizeof(*cl)); - } - - /* Fall back to L2CAP init sequence */ - if (!found) { - struct l2cap_conn *conn = mgr->l2cap_conn; - struct l2cap_chan *chan; - - mutex_lock(&conn->chan_lock); - - list_for_each_entry(chan, &conn->chan_l, list) { - - BT_DBG("chan %p state %s", chan, - state_to_string(chan->state)); - - if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) - continue; - - l2cap_chan_lock(chan); - - if (chan->state == BT_CONNECT) - l2cap_send_conn_req(chan); - - l2cap_chan_unlock(chan); - } - - mutex_unlock(&conn->chan_lock); - } - - return 0; -} - static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_cmd *hdr) { @@ -270,6 +181,7 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_cmd *hdr) { struct a2mp_info_req *req = (void *) skb->data; + struct a2mp_info_rsp rsp; struct hci_dev *hdev; if (le16_to_cpu(hdr->len) < sizeof(*req)) @@ -277,54 +189,25 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, BT_DBG("id %d", req->id); - hdev = hci_dev_get(req->id); - if (!hdev || hdev->dev_type != HCI_AMP) { - struct a2mp_info_rsp rsp; - - rsp.id = req->id; - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - - a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), - &rsp); + rsp.id = req->id; + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - goto done; + hdev = hci_dev_get(req->id); + if (hdev && hdev->amp_type != HCI_BREDR) { + rsp.status = 0; + rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); + rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); + rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); + rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); + rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); } - mgr->state = READ_LOC_AMP_INFO; - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); - -done: if (hdev) hci_dev_put(hdev); - skb_pull(skb, sizeof(*req)); - return 0; -} + a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp); -static int a2mp_getinfo_rsp(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_info_rsp *rsp = (struct a2mp_info_rsp *) skb->data; - struct a2mp_amp_assoc_req req; - struct amp_ctrl *ctrl; - - if (le16_to_cpu(hdr->len) < sizeof(*rsp)) - return -EINVAL; - - BT_DBG("id %d status 0x%2.2x", rsp->id, rsp->status); - - if (rsp->status) - return -EINVAL; - - ctrl = amp_ctrl_add(mgr, rsp->id); - if (!ctrl) - return -ENOMEM; - - req.id = rsp->id; - a2mp_send(mgr, A2MP_GETAMPASSOC_REQ, __next_ident(mgr), sizeof(req), - &req); - - skb_pull(skb, sizeof(*rsp)); + skb_pull(skb, sizeof(*req)); return 0; } @@ -333,37 +216,26 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, { struct a2mp_amp_assoc_req *req = (void *) skb->data; struct hci_dev *hdev; - struct amp_mgr *tmp; if (le16_to_cpu(hdr->len) < sizeof(*req)) return -EINVAL; BT_DBG("id %d", req->id); - /* Make sure that other request is not processed */ - tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); - hdev = hci_dev_get(req->id); - if (!hdev || hdev->amp_type == HCI_BREDR || tmp) { + if (!hdev || hdev->amp_type == HCI_BREDR) { struct a2mp_amp_assoc_rsp rsp; rsp.id = req->id; - - if (tmp) { - rsp.status = A2MP_STATUS_COLLISION_OCCURED; - amp_mgr_put(tmp); - } else { - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - } + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), &rsp); - - goto done; + goto clean; } - amp_read_loc_assoc(hdev, mgr); + /* Placeholder for HCI Read AMP Assoc */ -done: +clean: if (hdev) hci_dev_put(hdev); @@ -371,68 +243,6 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, return 0; } -static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_amp_assoc_rsp *rsp = (void *) skb->data; - u16 len = le16_to_cpu(hdr->len); - struct hci_dev *hdev; - struct amp_ctrl *ctrl; - struct hci_conn *hcon; - size_t assoc_len; - - if (len < sizeof(*rsp)) - return -EINVAL; - - assoc_len = len - sizeof(*rsp); - - BT_DBG("id %d status 0x%2.2x assoc len %zu", rsp->id, rsp->status, - assoc_len); - - if (rsp->status) - return -EINVAL; - - /* Save remote ASSOC data */ - ctrl = amp_ctrl_lookup(mgr, rsp->id); - if (ctrl) { - u8 *assoc; - - assoc = kzalloc(assoc_len, GFP_KERNEL); - if (!assoc) { - amp_ctrl_put(ctrl); - return -ENOMEM; - } - - memcpy(assoc, rsp->amp_assoc, assoc_len); - ctrl->assoc = assoc; - ctrl->assoc_len = assoc_len; - ctrl->assoc_rem_len = assoc_len; - ctrl->assoc_len_so_far = 0; - - amp_ctrl_put(ctrl); - } - - /* Create Phys Link */ - hdev = hci_dev_get(rsp->id); - if (!hdev) - return -EINVAL; - - hcon = phylink_add(hdev, mgr, rsp->id, true); - if (!hcon) - goto done; - - BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id); - - mgr->bredr_chan->remote_amp_id = rsp->id; - - amp_create_phylink(hdev, mgr, hcon); - -done: - hci_dev_put(hdev); - skb_pull(skb, len); - return 0; -} - static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_cmd *hdr) { @@ -440,8 +250,6 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_physlink_rsp rsp; struct hci_dev *hdev; - struct hci_conn *hcon; - struct amp_ctrl *ctrl; if (le16_to_cpu(hdr->len) < sizeof(*req)) return -EINVAL; @@ -457,43 +265,9 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, goto send_rsp; } - ctrl = amp_ctrl_lookup(mgr, rsp.remote_id); - if (!ctrl) { - ctrl = amp_ctrl_add(mgr, rsp.remote_id); - if (ctrl) { - amp_ctrl_get(ctrl); - } else { - rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; - goto send_rsp; - } - } - - if (ctrl) { - size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req); - u8 *assoc; + /* TODO process physlink create */ - assoc = kzalloc(assoc_len, GFP_KERNEL); - if (!assoc) { - amp_ctrl_put(ctrl); - return -ENOMEM; - } - - memcpy(assoc, req->amp_assoc, assoc_len); - ctrl->assoc = assoc; - ctrl->assoc_len = assoc_len; - ctrl->assoc_rem_len = assoc_len; - ctrl->assoc_len_so_far = 0; - - amp_ctrl_put(ctrl); - } - - hcon = phylink_add(hdev, mgr, req->local_id, false); - if (hcon) { - amp_accept_phylink(hdev, mgr, hcon); - rsp.status = A2MP_STATUS_SUCCESS; - } else { - rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; - } + rsp.status = A2MP_STATUS_SUCCESS; send_rsp: if (hdev) @@ -512,7 +286,6 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, struct a2mp_physlink_req *req = (void *) skb->data; struct a2mp_physlink_rsp rsp; struct hci_dev *hdev; - struct hci_conn *hcon; if (le16_to_cpu(hdr->len) < sizeof(*req)) return -EINVAL; @@ -523,22 +296,14 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, rsp.remote_id = req->local_id; rsp.status = A2MP_STATUS_SUCCESS; - hdev = hci_dev_get(req->remote_id); + hdev = hci_dev_get(req->local_id); if (!hdev) { rsp.status = A2MP_STATUS_INVALID_CTRL_ID; goto send_rsp; } - hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, mgr->l2cap_conn->dst); - if (!hcon) { - BT_ERR("No phys link exist"); - rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS; - goto clean; - } - /* TODO Disconnect Phys Link here */ -clean: hci_dev_put(hdev); send_rsp: @@ -612,19 +377,10 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) err = a2mp_discphyslink_req(mgr, skb, hdr); break; + case A2MP_CHANGE_RSP: case A2MP_DISCOVER_RSP: - err = a2mp_discover_rsp(mgr, skb, hdr); - break; - case A2MP_GETINFO_RSP: - err = a2mp_getinfo_rsp(mgr, skb, hdr); - break; - case A2MP_GETAMPASSOC_RSP: - err = a2mp_getampassoc_rsp(mgr, skb, hdr); - break; - - case A2MP_CHANGE_RSP: case A2MP_CREATEPHYSLINK_RSP: case A2MP_DISCONNPHYSLINK_RSP: err = a2mp_cmd_rsp(mgr, skb, hdr); @@ -699,10 +455,9 @@ static struct l2cap_ops a2mp_chan_ops = { .new_connection = l2cap_chan_no_new_connection, .teardown = l2cap_chan_no_teardown, .ready = l2cap_chan_no_ready, - .defer = l2cap_chan_no_defer, }; -static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) +static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) { struct l2cap_chan *chan; int err; @@ -737,10 +492,7 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) chan->conf_state = 0; - if (locked) - __l2cap_chan_add(conn, chan); - else - l2cap_chan_add(conn, chan); + l2cap_chan_add(conn, chan); chan->remote_mps = chan->omtu; chan->mps = chan->omtu; @@ -751,13 +503,11 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) } /* AMP Manager functions */ -struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr) +void amp_mgr_get(struct amp_mgr *mgr) { BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); kref_get(&mgr->kref); - - return mgr; } static void amp_mgr_destroy(struct kref *kref) @@ -766,11 +516,6 @@ static void amp_mgr_destroy(struct kref *kref) BT_DBG("mgr %p", mgr); - mutex_lock(&_mgr_list_lock); - list_del(&mgr->list); - mutex_unlock(&_mgr_list_lock); - - amp_ctrl_list_flush(mgr); kfree(mgr); } @@ -781,7 +526,7 @@ int amp_mgr_put(struct amp_mgr *mgr) return kref_put(&mgr->kref, &_mgr_destroy); } -static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked) +static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) { struct amp_mgr *mgr; struct l2cap_chan *chan; @@ -794,7 +539,7 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked) mgr->l2cap_conn = conn; - chan = a2mp_chan_open(conn, locked); + chan = a2mp_chan_open(conn); if (!chan) { kfree(mgr); return NULL; @@ -807,14 +552,6 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked) kref_init(&mgr->kref); - /* Remote AMP ctrl list initialization */ - INIT_LIST_HEAD(&mgr->amp_ctrls); - mutex_init(&mgr->amp_ctrls_lock); - - mutex_lock(&_mgr_list_lock); - list_add(&mgr->list, &_mgr_list); - mutex_unlock(&_mgr_list_lock); - return mgr; } @@ -823,7 +560,7 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, { struct amp_mgr *mgr; - mgr = amp_mgr_create(conn, false); + mgr = amp_mgr_create(conn); if (!mgr) { BT_ERR("Could not create AMP manager"); return NULL; @@ -833,139 +570,3 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, return mgr->a2mp_chan; } - -struct amp_mgr *amp_mgr_lookup_by_state(u8 state) -{ - struct amp_mgr *mgr; - - mutex_lock(&_mgr_list_lock); - list_for_each_entry(mgr, &_mgr_list, list) { - if (mgr->state == state) { - amp_mgr_get(mgr); - mutex_unlock(&_mgr_list_lock); - return mgr; - } - } - mutex_unlock(&_mgr_list_lock); - - return NULL; -} - -void a2mp_send_getinfo_rsp(struct hci_dev *hdev) -{ - struct amp_mgr *mgr; - struct a2mp_info_rsp rsp; - - mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO); - if (!mgr) - return; - - BT_DBG("%s mgr %p", hdev->name, mgr); - - rsp.id = hdev->id; - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - - if (hdev->amp_type != HCI_BREDR) { - rsp.status = 0; - rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); - rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); - rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); - rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); - rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); - } - - a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp); - amp_mgr_put(mgr); -} - -void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status) -{ - struct amp_mgr *mgr; - struct amp_assoc *loc_assoc = &hdev->loc_assoc; - struct a2mp_amp_assoc_rsp *rsp; - size_t len; - - mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); - if (!mgr) - return; - - BT_DBG("%s mgr %p", hdev->name, mgr); - - len = sizeof(struct a2mp_amp_assoc_rsp) + loc_assoc->len; - rsp = kzalloc(len, GFP_KERNEL); - if (!rsp) { - amp_mgr_put(mgr); - return; - } - - rsp->id = hdev->id; - - if (status) { - rsp->status = A2MP_STATUS_INVALID_CTRL_ID; - } else { - rsp->status = A2MP_STATUS_SUCCESS; - memcpy(rsp->amp_assoc, loc_assoc->data, loc_assoc->len); - } - - a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, mgr->ident, len, rsp); - amp_mgr_put(mgr); - kfree(rsp); -} - -void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status) -{ - struct amp_mgr *mgr; - struct amp_assoc *loc_assoc = &hdev->loc_assoc; - struct a2mp_physlink_req *req; - struct l2cap_chan *bredr_chan; - size_t len; - - mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC_FINAL); - if (!mgr) - return; - - len = sizeof(*req) + loc_assoc->len; - - BT_DBG("%s mgr %p assoc_len %zu", hdev->name, mgr, len); - - req = kzalloc(len, GFP_KERNEL); - if (!req) { - amp_mgr_put(mgr); - return; - } - - bredr_chan = mgr->bredr_chan; - if (!bredr_chan) - goto clean; - - req->local_id = hdev->id; - req->remote_id = bredr_chan->remote_amp_id; - memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len); - - a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req); - -clean: - amp_mgr_put(mgr); - kfree(req); -} - -void a2mp_discover_amp(struct l2cap_chan *chan) -{ - struct l2cap_conn *conn = chan->conn; - struct amp_mgr *mgr = conn->hcon->amp_mgr; - struct a2mp_discov_req req; - - BT_DBG("chan %p conn %p mgr %p", chan, conn, mgr); - - if (!mgr) { - mgr = amp_mgr_create(conn, true); - if (!mgr) - return; - } - - mgr->bredr_chan = chan; - - req.mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); - req.ext_feat = 0; - a2mp_send(mgr, A2MP_DISCOVER_REQ, 1, sizeof(req), &req); -} diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 5355df63d39b..ba033f09196e 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -569,6 +569,7 @@ static int bt_seq_show(struct seq_file *seq, void *v) { struct bt_seq_state *s = seq->private; struct bt_sock_list *l = s->l; + bdaddr_t src_baswapped, dst_baswapped; if (v == SEQ_START_TOKEN) { seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent"); @@ -582,17 +583,18 @@ static int bt_seq_show(struct seq_file *seq, void *v) } else { struct sock *sk = sk_entry(v); struct bt_sock *bt = bt_sk(sk); + baswap(&src_baswapped, &bt->src); + baswap(&dst_baswapped, &bt->dst); - seq_printf(seq, - "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu", + seq_printf(seq, "%pK %-6d %-6u %-6u %-6u %-6lu %pM %pM %-6lu", sk, atomic_read(&sk->sk_refcnt), sk_rmem_alloc_get(sk), sk_wmem_alloc_get(sk), from_kuid(seq_user_ns(seq), sock_i_uid(sk)), sock_i_ino(sk), - &bt->src, - &bt->dst, + &src_baswapped, + &dst_baswapped, bt->parent? sock_i_ino(bt->parent): 0LU); if (l->custom_seq_show) { diff --git a/trunk/net/bluetooth/amp.c b/trunk/net/bluetooth/amp.c deleted file mode 100644 index 1b0d92c0643a..000000000000 --- a/trunk/net/bluetooth/amp.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only version 2 as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ - -#include -#include -#include -#include -#include -#include - -/* Remote AMP Controllers interface */ -void amp_ctrl_get(struct amp_ctrl *ctrl) -{ - BT_DBG("ctrl %p orig refcnt %d", ctrl, - atomic_read(&ctrl->kref.refcount)); - - kref_get(&ctrl->kref); -} - -static void amp_ctrl_destroy(struct kref *kref) -{ - struct amp_ctrl *ctrl = container_of(kref, struct amp_ctrl, kref); - - BT_DBG("ctrl %p", ctrl); - - kfree(ctrl->assoc); - kfree(ctrl); -} - -int amp_ctrl_put(struct amp_ctrl *ctrl) -{ - BT_DBG("ctrl %p orig refcnt %d", ctrl, - atomic_read(&ctrl->kref.refcount)); - - return kref_put(&ctrl->kref, &_ctrl_destroy); -} - -struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id) -{ - struct amp_ctrl *ctrl; - - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); - if (!ctrl) - return NULL; - - kref_init(&ctrl->kref); - ctrl->id = id; - - mutex_lock(&mgr->amp_ctrls_lock); - list_add(&ctrl->list, &mgr->amp_ctrls); - mutex_unlock(&mgr->amp_ctrls_lock); - - BT_DBG("mgr %p ctrl %p", mgr, ctrl); - - return ctrl; -} - -void amp_ctrl_list_flush(struct amp_mgr *mgr) -{ - struct amp_ctrl *ctrl, *n; - - BT_DBG("mgr %p", mgr); - - mutex_lock(&mgr->amp_ctrls_lock); - list_for_each_entry_safe(ctrl, n, &mgr->amp_ctrls, list) { - list_del(&ctrl->list); - amp_ctrl_put(ctrl); - } - mutex_unlock(&mgr->amp_ctrls_lock); -} - -struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id) -{ - struct amp_ctrl *ctrl; - - BT_DBG("mgr %p id %d", mgr, id); - - mutex_lock(&mgr->amp_ctrls_lock); - list_for_each_entry(ctrl, &mgr->amp_ctrls, list) { - if (ctrl->id == id) { - amp_ctrl_get(ctrl); - mutex_unlock(&mgr->amp_ctrls_lock); - return ctrl; - } - } - mutex_unlock(&mgr->amp_ctrls_lock); - - return NULL; -} - -/* Physical Link interface */ -static u8 __next_handle(struct amp_mgr *mgr) -{ - if (++mgr->handle == 0) - mgr->handle = 1; - - return mgr->handle; -} - -struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, - u8 remote_id, bool out) -{ - bdaddr_t *dst = mgr->l2cap_conn->dst; - struct hci_conn *hcon; - - hcon = hci_conn_add(hdev, AMP_LINK, dst); - if (!hcon) - return NULL; - - BT_DBG("hcon %p dst %pMR", hcon, dst); - - hcon->state = BT_CONNECT; - hcon->attempt++; - hcon->handle = __next_handle(mgr); - hcon->remote_id = remote_id; - hcon->amp_mgr = amp_mgr_get(mgr); - hcon->out = out; - - return hcon; -} - -/* AMP crypto key generation interface */ -static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output) -{ - int ret = 0; - struct crypto_shash *tfm; - - if (!ksize) - return -EINVAL; - - tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); - if (IS_ERR(tfm)) { - BT_DBG("crypto_alloc_ahash failed: err %ld", PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - - ret = crypto_shash_setkey(tfm, key, ksize); - if (ret) { - BT_DBG("crypto_ahash_setkey failed: err %d", ret); - } else { - struct { - struct shash_desc shash; - char ctx[crypto_shash_descsize(tfm)]; - } desc; - - desc.shash.tfm = tfm; - desc.shash.flags = CRYPTO_TFM_REQ_MAY_SLEEP; - - ret = crypto_shash_digest(&desc.shash, plaintext, psize, - output); - } - - crypto_free_shash(tfm); - return ret; -} - -int phylink_gen_key(struct hci_conn *conn, u8 *data, u8 *len, u8 *type) -{ - struct hci_dev *hdev = conn->hdev; - struct link_key *key; - u8 keybuf[HCI_AMP_LINK_KEY_SIZE]; - u8 gamp_key[HCI_AMP_LINK_KEY_SIZE]; - int err; - - if (!hci_conn_check_link_mode(conn)) - return -EACCES; - - BT_DBG("conn %p key_type %d", conn, conn->key_type); - - /* Legacy key */ - if (conn->key_type < 3) { - BT_ERR("Legacy key type %d", conn->key_type); - return -EACCES; - } - - *type = conn->key_type; - *len = HCI_AMP_LINK_KEY_SIZE; - - key = hci_find_link_key(hdev, &conn->dst); - if (!key) { - BT_DBG("No Link key for conn %p dst %pMR", conn, &conn->dst); - return -EACCES; - } - - /* BR/EDR Link Key concatenated together with itself */ - memcpy(&keybuf[0], key->val, HCI_LINK_KEY_SIZE); - memcpy(&keybuf[HCI_LINK_KEY_SIZE], key->val, HCI_LINK_KEY_SIZE); - - /* Derive Generic AMP Link Key (gamp) */ - err = hmac_sha256(keybuf, HCI_AMP_LINK_KEY_SIZE, "gamp", 4, gamp_key); - if (err) { - BT_ERR("Could not derive Generic AMP Key: err %d", err); - return err; - } - - if (conn->key_type == HCI_LK_DEBUG_COMBINATION) { - BT_DBG("Use Generic AMP Key (gamp)"); - memcpy(data, gamp_key, HCI_AMP_LINK_KEY_SIZE); - return err; - } - - /* Derive Dedicated AMP Link Key: "802b" is 802.11 PAL keyID */ - return hmac_sha256(gamp_key, HCI_AMP_LINK_KEY_SIZE, "802b", 4, data); -} - -void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) -{ - struct hci_cp_read_local_amp_assoc cp; - struct amp_assoc *loc_assoc = &hdev->loc_assoc; - - BT_DBG("%s handle %d", hdev->name, phy_handle); - - cp.phy_handle = phy_handle; - cp.max_len = cpu_to_le16(hdev->amp_assoc_size); - cp.len_so_far = cpu_to_le16(loc_assoc->offset); - - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); -} - -void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr) -{ - struct hci_cp_read_local_amp_assoc cp; - - memset(&hdev->loc_assoc, 0, sizeof(struct amp_assoc)); - memset(&cp, 0, sizeof(cp)); - - cp.max_len = cpu_to_le16(hdev->amp_assoc_size); - - mgr->state = READ_LOC_AMP_ASSOC; - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); -} - -void amp_read_loc_assoc_final_data(struct hci_dev *hdev, - struct hci_conn *hcon) -{ - struct hci_cp_read_local_amp_assoc cp; - struct amp_mgr *mgr = hcon->amp_mgr; - - cp.phy_handle = hcon->handle; - cp.len_so_far = cpu_to_le16(0); - cp.max_len = cpu_to_le16(hdev->amp_assoc_size); - - mgr->state = READ_LOC_AMP_ASSOC_FINAL; - - /* Read Local AMP Assoc final link information data */ - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); -} - -/* Write AMP Assoc data fragments, returns true with last fragment written*/ -static bool amp_write_rem_assoc_frag(struct hci_dev *hdev, - struct hci_conn *hcon) -{ - struct hci_cp_write_remote_amp_assoc *cp; - struct amp_mgr *mgr = hcon->amp_mgr; - struct amp_ctrl *ctrl; - u16 frag_len, len; - - ctrl = amp_ctrl_lookup(mgr, hcon->remote_id); - if (!ctrl) - return false; - - if (!ctrl->assoc_rem_len) { - BT_DBG("all fragments are written"); - ctrl->assoc_rem_len = ctrl->assoc_len; - ctrl->assoc_len_so_far = 0; - - amp_ctrl_put(ctrl); - return true; - } - - frag_len = min_t(u16, 248, ctrl->assoc_rem_len); - len = frag_len + sizeof(*cp); - - cp = kzalloc(len, GFP_KERNEL); - if (!cp) { - amp_ctrl_put(ctrl); - return false; - } - - BT_DBG("hcon %p ctrl %p frag_len %u assoc_len %u rem_len %u", - hcon, ctrl, frag_len, ctrl->assoc_len, ctrl->assoc_rem_len); - - cp->phy_handle = hcon->handle; - cp->len_so_far = cpu_to_le16(ctrl->assoc_len_so_far); - cp->rem_len = cpu_to_le16(ctrl->assoc_rem_len); - memcpy(cp->frag, ctrl->assoc, frag_len); - - ctrl->assoc_len_so_far += frag_len; - ctrl->assoc_rem_len -= frag_len; - - amp_ctrl_put(ctrl); - - hci_send_cmd(hdev, HCI_OP_WRITE_REMOTE_AMP_ASSOC, len, cp); - - kfree(cp); - - return false; -} - -void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle) -{ - struct hci_conn *hcon; - - BT_DBG("%s phy handle 0x%2.2x", hdev->name, handle); - - hcon = hci_conn_hash_lookup_handle(hdev, handle); - if (!hcon) - return; - - amp_write_rem_assoc_frag(hdev, hcon); -} - -void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle) -{ - struct hci_conn *hcon; - - BT_DBG("%s phy handle 0x%2.2x", hdev->name, handle); - - hcon = hci_conn_hash_lookup_handle(hdev, handle); - if (!hcon) - return; - - BT_DBG("%s phy handle 0x%2.2x hcon %p", hdev->name, handle, hcon); - - amp_write_rem_assoc_frag(hdev, hcon); -} - -void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon) -{ - struct hci_cp_create_phy_link cp; - - cp.phy_handle = hcon->handle; - - BT_DBG("%s hcon %p phy handle 0x%2.2x", hdev->name, hcon, - hcon->handle); - - if (phylink_gen_key(mgr->l2cap_conn->hcon, cp.key, &cp.key_len, - &cp.key_type)) { - BT_DBG("Cannot create link key"); - return; - } - - hci_send_cmd(hdev, HCI_OP_CREATE_PHY_LINK, sizeof(cp), &cp); -} - -void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, - struct hci_conn *hcon) -{ - struct hci_cp_accept_phy_link cp; - - cp.phy_handle = hcon->handle; - - BT_DBG("%s hcon %p phy handle 0x%2.2x", hdev->name, hcon, - hcon->handle); - - if (phylink_gen_key(mgr->l2cap_conn->hcon, cp.key, &cp.key_len, - &cp.key_type)) { - BT_DBG("Cannot create link key"); - return; - } - - hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp); -} - -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon) -{ - struct hci_dev *bredr_hdev = hci_dev_hold(bredr_hcon->hdev); - struct amp_mgr *mgr = hs_hcon->amp_mgr; - struct l2cap_chan *bredr_chan; - - BT_DBG("bredr_hcon %p hs_hcon %p mgr %p", bredr_hcon, hs_hcon, mgr); - - if (!bredr_hdev || !mgr || !mgr->bredr_chan) - return; - - bredr_chan = mgr->bredr_chan; - - l2cap_chan_lock(bredr_chan); - - set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags); - bredr_chan->remote_amp_id = hs_hcon->remote_id; - bredr_chan->local_amp_id = hs_hcon->hdev->id; - bredr_chan->hs_hcon = hs_hcon; - bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu; - - __l2cap_physical_cfm(bredr_chan, 0); - - l2cap_chan_unlock(bredr_chan); - - hci_dev_put(bredr_hdev); -} - -void amp_create_logical_link(struct l2cap_chan *chan) -{ - struct hci_cp_create_accept_logical_link cp; - struct hci_conn *hcon; - struct hci_dev *hdev; - - BT_DBG("chan %p", chan); - - if (!chan->hs_hcon) - return; - - hdev = hci_dev_hold(chan->hs_hcon->hdev); - if (!hdev) - return; - - BT_DBG("chan %p dst %pMR", chan, chan->conn->dst); - - hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst); - if (!hcon) - goto done; - - cp.phy_handle = hcon->handle; - - cp.tx_flow_spec.id = chan->local_id; - cp.tx_flow_spec.stype = chan->local_stype; - cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu); - cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime); - cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat); - cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to); - - cp.rx_flow_spec.id = chan->remote_id; - cp.rx_flow_spec.stype = chan->remote_stype; - cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu); - cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime); - cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat); - cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to); - - if (hcon->out) - hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp), - &cp); - else - hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp), - &cp); - -done: - hci_dev_put(hdev); -} - -void amp_disconnect_logical_link(struct hci_chan *hchan) -{ - struct hci_conn *hcon = hchan->conn; - struct hci_cp_disconn_logical_link cp; - - if (hcon->state != BT_CONNECTED) { - BT_DBG("hchan %p not connected", hchan); - return; - } - - cp.log_handle = cpu_to_le16(hchan->handle); - hci_send_cmd(hcon->hdev, HCI_OP_DISCONN_LOGICAL_LINK, sizeof(cp), &cp); -} - -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason) -{ - BT_DBG("hchan %p", hchan); - - hci_chan_del(hchan); -} diff --git a/trunk/net/bluetooth/bnep/core.c b/trunk/net/bluetooth/bnep/core.c index a5b639702637..4a6620bc1570 100644 --- a/trunk/net/bluetooth/bnep/core.c +++ b/trunk/net/bluetooth/bnep/core.c @@ -182,7 +182,8 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) a2 = data; data += ETH_ALEN; - BT_DBG("mc filter %pMR -> %pMR", a1, a2); + BT_DBG("mc filter %s -> %s", + batostr((void *) a1), batostr((void *) a2)); /* Iterate from a1 to a2 */ set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); diff --git a/trunk/net/bluetooth/bnep/netdev.c b/trunk/net/bluetooth/bnep/netdev.c index e58c8b32589c..98f86f91d47c 100644 --- a/trunk/net/bluetooth/bnep/netdev.c +++ b/trunk/net/bluetooth/bnep/netdev.c @@ -25,6 +25,7 @@ SOFTWARE IS DISCLAIMED. */ +#include #include #include diff --git a/trunk/net/bluetooth/cmtp/capi.c b/trunk/net/bluetooth/cmtp/capi.c index a4a9d4b6816c..50f0d135eb8f 100644 --- a/trunk/net/bluetooth/cmtp/capi.c +++ b/trunk/net/bluetooth/cmtp/capi.c @@ -20,7 +20,7 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include #include #include #include diff --git a/trunk/net/bluetooth/cmtp/core.c b/trunk/net/bluetooth/cmtp/core.c index e0a6ebf2baa6..6c9c1fd601ca 100644 --- a/trunk/net/bluetooth/cmtp/core.c +++ b/trunk/net/bluetooth/cmtp/core.c @@ -353,7 +353,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) BT_DBG("mtu %d", session->mtu); - sprintf(session->name, "%pMR", &bt_sk(sock->sk)->dst); + sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst)); session->sock = sock; session->state = BT_CONFIG; diff --git a/trunk/net/bluetooth/cmtp/sock.c b/trunk/net/bluetooth/cmtp/sock.c index 1c57482112b6..aacb802d1ee4 100644 --- a/trunk/net/bluetooth/cmtp/sock.c +++ b/trunk/net/bluetooth/cmtp/sock.c @@ -20,7 +20,7 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include #include #include diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 25bfce0666eb..b9196a44f759 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -130,20 +130,6 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); } -static void hci_amp_disconn(struct hci_conn *conn, __u8 reason) -{ - struct hci_cp_disconn_phy_link cp; - - BT_DBG("hcon %p", conn); - - conn->state = BT_DISCONN; - - cp.phy_handle = HCI_PHY_HANDLE(conn->handle); - cp.reason = reason; - hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK, - sizeof(cp), &cp); -} - static void hci_add_sco(struct hci_conn *conn, __u16 handle) { struct hci_dev *hdev = conn->hdev; @@ -244,24 +230,11 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) } } -static void hci_conn_disconnect(struct hci_conn *conn) -{ - __u8 reason = hci_proto_disconn_ind(conn); - - switch (conn->type) { - case ACL_LINK: - hci_acl_disconn(conn, reason); - break; - case AMP_LINK: - hci_amp_disconn(conn, reason); - break; - } -} - static void hci_conn_timeout(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, disc_work.work); + __u8 reason; BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); @@ -280,7 +253,8 @@ static void hci_conn_timeout(struct work_struct *work) break; case BT_CONFIG: case BT_CONNECTED: - hci_conn_disconnect(conn); + reason = hci_proto_disconn_ind(conn); + hci_acl_disconn(conn, reason); break; default: conn->state = BT_CLOSED; @@ -346,7 +320,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) { struct hci_conn *conn; - BT_DBG("%s dst %pMR", hdev->name, dst); + BT_DBG("%s dst %s", hdev->name, batostr(dst)); conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL); if (!conn) @@ -463,7 +437,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) int use_src = bacmp(src, BDADDR_ANY); struct hci_dev *hdev = NULL, *d; - BT_DBG("%pMR -> %pMR", src, dst); + BT_DBG("%s -> %s", batostr(src), batostr(dst)); read_lock(&hci_dev_list_lock); @@ -502,9 +476,6 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, { struct hci_conn *le; - if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags)) - return ERR_PTR(-ENOTSUPP); - le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); if (!le) { le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); @@ -596,7 +567,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 dst_type, __u8 sec_level, __u8 auth_type) { - BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type); + BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type); switch (type) { case LE_LINK: @@ -962,7 +933,6 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) chan->conn = conn; skb_queue_head_init(&chan->data_q); - chan->state = BT_CONNECTED; list_add_rcu(&chan->list, &conn->chan_list); @@ -980,8 +950,6 @@ void hci_chan_del(struct hci_chan *chan) synchronize_rcu(); - hci_conn_put(conn); - skb_queue_purge(&chan->data_q); kfree(chan); } @@ -995,35 +963,3 @@ void hci_chan_list_flush(struct hci_conn *conn) list_for_each_entry_safe(chan, n, &conn->chan_list, list) hci_chan_del(chan); } - -static struct hci_chan *__hci_chan_lookup_handle(struct hci_conn *hcon, - __u16 handle) -{ - struct hci_chan *hchan; - - list_for_each_entry(hchan, &hcon->chan_list, list) { - if (hchan->handle == handle) - return hchan; - } - - return NULL; -} - -struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle) -{ - struct hci_conn_hash *h = &hdev->conn_hash; - struct hci_conn *hcon; - struct hci_chan *hchan = NULL; - - rcu_read_lock(); - - list_for_each_entry_rcu(hcon, &h->list, list) { - hchan = __hci_chan_lookup_handle(hcon, handle); - if (hchan) - break; - } - - rcu_read_unlock(); - - return hchan; -} diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 7140f83328a2..8a0ce706aebd 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -178,13 +178,48 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) static void bredr_init(struct hci_dev *hdev) { + struct hci_cp_delete_stored_link_key cp; + __le16 param; + __u8 flt_type; + hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; + /* Mandatory initialization */ + /* Read Local Supported Features */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); /* Read Local Version */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); + + /* Read Buffer Size (ACL mtu, max pkt, etc.) */ + hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); + + /* Read BD Address */ + hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); + + /* Read Class of Device */ + hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); + + /* Read Local Name */ + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); + + /* Read Voice Setting */ + hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); + + /* Optional initialization */ + + /* Clear Event Filters */ + flt_type = HCI_FLT_CLEAR_ALL; + hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); + + /* Connection accept timeout ~20 secs */ + param = __constant_cpu_to_le16(0x7d00); + hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); + + bacpy(&cp.bdaddr, BDADDR_ANY); + cp.delete_all = 1; + hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); } static void amp_init(struct hci_dev *hdev) @@ -238,6 +273,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) } } +static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) +{ + BT_DBG("%s", hdev->name); + + /* Read LE buffer size */ + hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); +} + static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) { __u8 scan = opt; @@ -362,7 +405,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %p, %s", cache, batostr(bdaddr)); list_for_each_entry(e, &cache->all, all) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -378,7 +421,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p, %pMR", cache, bdaddr); + BT_DBG("cache %p, %s", cache, batostr(bdaddr)); list_for_each_entry(e, &cache->unknown, list) { if (!bacmp(&e->data.bdaddr, bdaddr)) @@ -395,7 +438,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; - BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); + BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); list_for_each_entry(e, &cache->resolve, list) { if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) @@ -432,9 +475,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *ie; - BT_DBG("cache %p, %pMR", cache, &data->bdaddr); - - hci_remove_remote_oob_data(hdev, &data->bdaddr); + BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); if (ssp) *ssp = data->ssp_mode; @@ -596,99 +637,6 @@ int hci_inquiry(void __user *arg) return err; } -static u8 create_ad(struct hci_dev *hdev, u8 *ptr) -{ - u8 ad_len = 0, flags = 0; - size_t name_len; - - if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) - flags |= LE_AD_GENERAL; - - if (!lmp_bredr_capable(hdev)) - flags |= LE_AD_NO_BREDR; - - if (lmp_le_br_capable(hdev)) - flags |= LE_AD_SIM_LE_BREDR_CTRL; - - if (lmp_host_le_br_capable(hdev)) - flags |= LE_AD_SIM_LE_BREDR_HOST; - - if (flags) { - BT_DBG("adv flags 0x%02x", flags); - - ptr[0] = 2; - ptr[1] = EIR_FLAGS; - ptr[2] = flags; - - ad_len += 3; - ptr += 3; - } - - if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { - ptr[0] = 2; - ptr[1] = EIR_TX_POWER; - ptr[2] = (u8) hdev->adv_tx_power; - - ad_len += 3; - ptr += 3; - } - - name_len = strlen(hdev->dev_name); - if (name_len > 0) { - size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; - - if (name_len > max_len) { - name_len = max_len; - ptr[1] = EIR_NAME_SHORT; - } else - ptr[1] = EIR_NAME_COMPLETE; - - ptr[0] = name_len + 1; - - memcpy(ptr + 2, hdev->dev_name, name_len); - - ad_len += (name_len + 2); - ptr += (name_len + 2); - } - - return ad_len; -} - -int hci_update_ad(struct hci_dev *hdev) -{ - struct hci_cp_le_set_adv_data cp; - u8 len; - int err; - - hci_dev_lock(hdev); - - if (!lmp_le_capable(hdev)) { - err = -EINVAL; - goto unlock; - } - - memset(&cp, 0, sizeof(cp)); - - len = create_ad(hdev, cp.data); - - if (hdev->adv_data_len == len && - memcmp(cp.data, hdev->adv_data, len) == 0) { - err = 0; - goto unlock; - } - - memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); - hdev->adv_data_len = len; - - cp.length = len; - err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); - -unlock: - hci_dev_unlock(hdev); - - return err; -} - /* ---- HCI ioctl helpers ---- */ int hci_dev_open(__u16 dev) @@ -739,6 +687,10 @@ int hci_dev_open(__u16 dev) ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); + if (lmp_host_le_capable(hdev)) + ret = __hci_request(hdev, hci_le_init_req, 0, + HCI_INIT_TIMEOUT); + clear_bit(HCI_INIT, &hdev->flags); } @@ -746,7 +698,6 @@ int hci_dev_open(__u16 dev) hci_dev_hold(hdev); set_bit(HCI_UP, &hdev->flags); hci_notify(hdev, HCI_DEV_UP); - hci_update_ad(hdev); if (!test_bit(HCI_SETUP, &hdev->dev_flags) && mgmt_valid_hdev(hdev)) { hci_dev_lock(hdev); @@ -1088,17 +1039,10 @@ int hci_get_dev_info(void __user *arg) di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); di.flags = hdev->flags; di.pkt_type = hdev->pkt_type; - if (lmp_bredr_capable(hdev)) { - di.acl_mtu = hdev->acl_mtu; - di.acl_pkts = hdev->acl_pkts; - di.sco_mtu = hdev->sco_mtu; - di.sco_pkts = hdev->sco_pkts; - } else { - di.acl_mtu = hdev->le_mtu; - di.acl_pkts = hdev->le_pkts; - di.sco_mtu = 0; - di.sco_pkts = 0; - } + di.acl_mtu = hdev->acl_mtu; + di.acl_pkts = hdev->acl_pkts; + di.sco_mtu = hdev->sco_mtu; + di.sco_pkts = hdev->sco_pkts; di.link_policy = hdev->link_policy; di.link_mode = hdev->link_mode; @@ -1315,7 +1259,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, list_add(&key->list, &hdev->link_keys); } - BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); + BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); /* Some buggy controller combinations generate a changed * combination key for legacy pairing even when there's no @@ -1394,7 +1338,7 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) if (!key) return -ENOENT; - BT_DBG("%s removing %pMR", hdev->name, bdaddr); + BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); list_del(&key->list); kfree(key); @@ -1410,7 +1354,7 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) if (bacmp(bdaddr, &k->bdaddr)) continue; - BT_DBG("%s removing %pMR", hdev->name, bdaddr); + BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); list_del(&k->list); kfree(k); @@ -1457,7 +1401,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) if (!data) return -ENOENT; - BT_DBG("%s removing %pMR", hdev->name, bdaddr); + BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); list_del(&data->list); kfree(data); @@ -1496,7 +1440,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, memcpy(data->hash, hash, sizeof(data->hash)); memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); - BT_DBG("%s for %pMR", hdev->name, bdaddr); + BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); return 0; } @@ -1673,9 +1617,6 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, BT_DBG("%s", hdev->name); - if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) - return -ENOTSUPP; - if (work_busy(&hdev->le_scan)) return -EINPROGRESS; @@ -1702,8 +1643,6 @@ struct hci_dev *hci_alloc_dev(void) hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); hdev->io_capability = 0x03; /* No Input No Output */ - hdev->inq_tx_power = HCI_TX_POWER_INVALID; - hdev->adv_tx_power = HCI_TX_POWER_INVALID; hdev->sniff_max_interval = 800; hdev->sniff_min_interval = 80; @@ -1815,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); + schedule_work(&hdev->power_on); + hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); - schedule_work(&hdev->power_on); - return id; err_wqueue: @@ -2214,10 +2153,9 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) hdr->dlen = cpu_to_le16(len); } -static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, +static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, struct sk_buff *skb, __u16 flags) { - struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; struct sk_buff *list; @@ -2225,18 +2163,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, skb->data_len = 0; bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; - - switch (hdev->dev_type) { - case HCI_BREDR: - hci_add_acl_hdr(skb, conn->handle, flags); - break; - case HCI_AMP: - hci_add_acl_hdr(skb, chan->handle, flags); - break; - default: - BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); - return; - } + hci_add_acl_hdr(skb, conn->handle, flags); list = skb_shinfo(skb)->frag_list; if (!list) { @@ -2275,13 +2202,14 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) { - struct hci_dev *hdev = chan->conn->hdev; + struct hci_conn *conn = chan->conn; + struct hci_dev *hdev = conn->hdev; BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); skb->dev = (void *) hdev; - hci_queue_acl(chan, &chan->data_q, skb, flags); + hci_queue_acl(conn, &chan->data_q, skb, flags); queue_work(hdev->workqueue, &hdev->tx_work); } @@ -2383,8 +2311,8 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) /* Kill stalled connections */ list_for_each_entry_rcu(c, &h->list, list) { if (c->type == type && c->sent) { - BT_ERR("%s killing stalled connection %pMR", - hdev->name, &c->dst); + BT_ERR("%s killing stalled connection %s", + hdev->name, batostr(&c->dst)); hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); } } @@ -2453,9 +2381,6 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, case ACL_LINK: cnt = hdev->acl_cnt; break; - case AMP_LINK: - cnt = hdev->block_cnt; - break; case SCO_LINK: case ESCO_LINK: cnt = hdev->sco_cnt; @@ -2585,19 +2510,11 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) struct hci_chan *chan; struct sk_buff *skb; int quote; - u8 type; __check_timeout(hdev, cnt); - BT_DBG("%s", hdev->name); - - if (hdev->dev_type == HCI_AMP) - type = AMP_LINK; - else - type = ACL_LINK; - while (hdev->block_cnt > 0 && - (chan = hci_chan_sent(hdev, type, "e))) { + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; @@ -2630,19 +2547,14 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) } if (cnt != hdev->block_cnt) - hci_prio_recalculate(hdev, type); + hci_prio_recalculate(hdev, ACL_LINK); } static void hci_sched_acl(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); - /* No ACL link over BR/EDR controller */ - if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) - return; - - /* No AMP link over AMP controller */ - if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) + if (!hci_conn_num(hdev, ACL_LINK)) return; switch (hdev->flow_ctl_mode) { diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 9f5c5f244502..2022b43c7353 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -24,13 +24,12 @@ /* Bluetooth HCI event handling. */ +#include #include #include #include #include -#include -#include /* Handle HCI Event packets */ @@ -202,11 +201,6 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) BIT(HCI_PERIODIC_INQ)); hdev->discovery.state = DISCOVERY_STOPPED; - hdev->inq_tx_power = HCI_TX_POWER_INVALID; - hdev->adv_tx_power = HCI_TX_POWER_INVALID; - - memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); - hdev->adv_data_len = 0; } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) @@ -229,9 +223,6 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); - if (!status && !test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); } @@ -447,7 +438,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); - struct hci_cp_write_ssp_mode *sent; + void *sent; BT_DBG("%s status 0x%2.2x", hdev->name, status); @@ -455,17 +446,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; - if (!status) { - if (sent->mode) - hdev->host_features[0] |= LMP_HOST_SSP; - else - hdev->host_features[0] &= ~LMP_HOST_SSP; - } - if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_ssp_enable_complete(hdev, sent->mode, status); + mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); else if (!status) { - if (sent->mode) + if (*((u8 *) sent)) set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); else clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); @@ -474,10 +458,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) static u8 hci_get_inquiry_mode(struct hci_dev *hdev) { - if (lmp_ext_inq_capable(hdev)) + if (hdev->features[6] & LMP_EXT_INQ) return 2; - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) return 1; if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && @@ -521,30 +505,28 @@ static void hci_setup_event_mask(struct hci_dev *hdev) if (hdev->hci_ver < BLUETOOTH_VER_1_2) return; - if (lmp_bredr_capable(hdev)) { - events[4] |= 0x01; /* Flow Specification Complete */ - events[4] |= 0x02; /* Inquiry Result with RSSI */ - events[4] |= 0x04; /* Read Remote Extended Features Complete */ - events[5] |= 0x08; /* Synchronous Connection Complete */ - events[5] |= 0x10; /* Synchronous Connection Changed */ - } + events[4] |= 0x01; /* Flow Specification Complete */ + events[4] |= 0x02; /* Inquiry Result with RSSI */ + events[4] |= 0x04; /* Read Remote Extended Features Complete */ + events[5] |= 0x08; /* Synchronous Connection Complete */ + events[5] |= 0x10; /* Synchronous Connection Changed */ - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) events[4] |= 0x02; /* Inquiry Result with RSSI */ if (lmp_sniffsubr_capable(hdev)) events[5] |= 0x20; /* Sniff Subrating */ - if (lmp_pause_enc_capable(hdev)) + if (hdev->features[5] & LMP_PAUSE_ENC) events[5] |= 0x80; /* Encryption Key Refresh Complete */ - if (lmp_ext_inq_capable(hdev)) + if (hdev->features[6] & LMP_EXT_INQ) events[5] |= 0x40; /* Extended Inquiry Result */ if (lmp_no_flush_capable(hdev)) events[7] |= 0x01; /* Enhanced Flush Complete */ - if (lmp_lsto_capable(hdev)) + if (hdev->features[7] & LMP_LSTO) events[6] |= 0x80; /* Link Supervision Timeout Changed */ if (lmp_ssp_capable(hdev)) { @@ -564,53 +546,6 @@ static void hci_setup_event_mask(struct hci_dev *hdev) events[7] |= 0x20; /* LE Meta-Event */ hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); - - if (lmp_le_capable(hdev)) { - memset(events, 0, sizeof(events)); - events[0] = 0x1f; - hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK, - sizeof(events), events); - } -} - -static void bredr_setup(struct hci_dev *hdev) -{ - struct hci_cp_delete_stored_link_key cp; - __le16 param; - __u8 flt_type; - - /* Read Buffer Size (ACL mtu, max pkt, etc.) */ - hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); - - /* Read Class of Device */ - hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); - - /* Read Local Name */ - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); - - /* Read Voice Setting */ - hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); - - /* Clear Event Filters */ - flt_type = HCI_FLT_CLEAR_ALL; - hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); - - /* Connection accept timeout ~20 secs */ - param = __constant_cpu_to_le16(0x7d00); - hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); - - bacpy(&cp.bdaddr, BDADDR_ANY); - cp.delete_all = 1; - hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); -} - -static void le_setup(struct hci_dev *hdev) -{ - /* Read LE Buffer Size */ - hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); - - /* Read LE Advertising Channel TX Power */ - hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); } static void hci_setup(struct hci_dev *hdev) @@ -618,15 +553,6 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->dev_type != HCI_BREDR) return; - /* Read BD Address */ - hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); - - if (lmp_bredr_capable(hdev)) - bredr_setup(hdev); - - if (lmp_le_capable(hdev)) - le_setup(hdev); - hci_setup_event_mask(hdev); if (hdev->hci_ver > BLUETOOTH_VER_1_1) @@ -647,13 +573,13 @@ static void hci_setup(struct hci_dev *hdev) } } - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) hci_setup_inquiry_mode(hdev); - if (lmp_inq_tx_pwr_capable(hdev)) + if (hdev->features[7] & LMP_INQ_TX_PWR) hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); - if (lmp_ext_feat_capable(hdev)) { + if (hdev->features[7] & LMP_EXTFEATURES) { struct hci_cp_read_local_ext_features cp; cp.page = 0x01; @@ -700,11 +626,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev) if (lmp_rswitch_capable(hdev)) link_policy |= HCI_LP_RSWITCH; - if (lmp_hold_capable(hdev)) + if (hdev->features[0] & LMP_HOLD) link_policy |= HCI_LP_HOLD; if (lmp_sniff_capable(hdev)) link_policy |= HCI_LP_SNIFF; - if (lmp_park_capable(hdev)) + if (hdev->features[1] & LMP_PARK) link_policy |= HCI_LP_PARK; cp.policy = cpu_to_le16(link_policy); @@ -794,10 +720,10 @@ static void hci_set_le_support(struct hci_dev *hdev) if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { cp.le = 1; - cp.simul = !!lmp_le_br_capable(hdev); + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); } - if (cp.le != !!lmp_host_le_capable(hdev)) + if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); } @@ -920,7 +846,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); if (rp->status) - goto a2mp_rsp; + return; hdev->amp_status = rp->amp_status; hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); @@ -934,46 +860,6 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); - -a2mp_rsp: - a2mp_send_getinfo_rsp(hdev); -} - -static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; - struct amp_assoc *assoc = &hdev->loc_assoc; - size_t rem_len, frag_len; - - BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); - - if (rp->status) - goto a2mp_rsp; - - frag_len = skb->len - sizeof(*rp); - rem_len = __le16_to_cpu(rp->rem_len); - - if (rem_len > frag_len) { - BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); - - memcpy(assoc->data + assoc->offset, rp->frag, frag_len); - assoc->offset += frag_len; - - /* Read other fragments */ - amp_read_loc_assoc_frag(hdev, rp->phy_handle); - - return; - } - - memcpy(assoc->data + assoc->offset, rp->frag, rem_len); - assoc->len = assoc->offset + rem_len; - assoc->offset = 0; - -a2mp_rsp: - /* Send A2MP Rsp when all fragments are received */ - a2mp_send_getampassoc_rsp(hdev, rp->status); - a2mp_send_create_phy_link_req(hdev, rp->status); } static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, @@ -1090,31 +976,6 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); } -static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; - - BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); - - if (!rp->status) { - hdev->adv_tx_power = rp->tx_power; - if (!test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - } - - hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status); -} - -static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 status = *((__u8 *) skb->data); - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status); -} - static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1190,33 +1051,6 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 *sent, status = *((__u8 *) skb->data); - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); - if (!sent) - return; - - hci_dev_lock(hdev); - - if (!status) { - if (*sent) - set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); - else - clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); - } - - hci_dev_unlock(hdev); - - if (!test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - - hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status); -} - static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -1331,11 +1165,6 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, hdev->host_features[0] |= LMP_HOST_LE; else hdev->host_features[0] &= ~LMP_HOST_LE; - - if (sent->simul) - hdev->host_features[0] |= LMP_HOST_LE_BREDR; - else - hdev->host_features[0] &= ~LMP_HOST_LE_BREDR; } if (test_bit(HCI_MGMT, &hdev->dev_flags) && @@ -1345,20 +1174,6 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); } -static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; - - BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", - hdev->name, rp->status, rp->phy_handle); - - if (rp->status) - return; - - amp_write_rem_assoc_continue(hdev, rp->phy_handle); -} - static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%2.2x", hdev->name, status); @@ -1395,7 +1210,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); - BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); + BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1824,7 +1639,8 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) return; } - BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); + BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst), + conn); conn->state = BT_CLOSED; mgmt_connect_failed(hdev, &conn->dst, conn->type, @@ -1841,52 +1657,6 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) BT_DBG("%s status 0x%2.2x", hdev->name, status); } -static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) -{ - struct hci_cp_create_phy_link *cp; - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); - if (!cp) - return; - - hci_dev_lock(hdev); - - if (status) { - struct hci_conn *hcon; - - hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); - if (hcon) - hci_conn_del(hcon); - } else { - amp_write_remote_assoc(hdev, cp->phy_handle); - } - - hci_dev_unlock(hdev); -} - -static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) -{ - struct hci_cp_accept_phy_link *cp; - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - if (status) - return; - - cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); - if (!cp) - return; - - amp_write_remote_assoc(hdev, cp->phy_handle); -} - -static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status) -{ - BT_DBG("%s status 0x%2.2x", hdev->name, status); -} - static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -2052,7 +1822,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) struct hci_ev_conn_request *ev = (void *) skb->data; int mask = hdev->link_mode; - BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, + BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); @@ -2544,10 +2314,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_read_local_amp_info(hdev, skb); break; - case HCI_OP_READ_LOCAL_AMP_ASSOC: - hci_cc_read_local_amp_assoc(hdev, skb); - break; - case HCI_OP_DELETE_STORED_LINK_KEY: hci_cc_delete_stored_link_key(hdev, skb); break; @@ -2584,14 +2350,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_read_buffer_size(hdev, skb); break; - case HCI_OP_LE_READ_ADV_TX_POWER: - hci_cc_le_read_adv_tx_power(hdev, skb); - break; - - case HCI_OP_LE_SET_EVENT_MASK: - hci_cc_le_set_event_mask(hdev, skb); - break; - case HCI_OP_USER_CONFIRM_REPLY: hci_cc_user_confirm_reply(hdev, skb); break; @@ -2612,10 +2370,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_set_scan_param(hdev, skb); break; - case HCI_OP_LE_SET_ADV_ENABLE: - hci_cc_le_set_adv_enable(hdev, skb); - break; - case HCI_OP_LE_SET_SCAN_ENABLE: hci_cc_le_set_scan_enable(hdev, skb); break; @@ -2632,10 +2386,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_write_le_host_supported(hdev, skb); break; - case HCI_OP_WRITE_REMOTE_AMP_ASSOC: - hci_cc_write_remote_amp_assoc(hdev, skb); - break; - default: BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); break; @@ -2717,18 +2467,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cs_le_start_enc(hdev, ev->status); break; - case HCI_OP_CREATE_PHY_LINK: - hci_cs_create_phylink(hdev, ev->status); - break; - - case HCI_OP_ACCEPT_PHY_LINK: - hci_cs_accept_phylink(hdev, ev->status); - break; - - case HCI_OP_CREATE_LOGICAL_LINK: - hci_cs_create_logical_link(hdev, ev->status); - break; - default: BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); break; @@ -2836,27 +2574,6 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) queue_work(hdev->workqueue, &hdev->tx_work); } -static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, - __u16 handle) -{ - struct hci_chan *chan; - - switch (hdev->dev_type) { - case HCI_BREDR: - return hci_conn_hash_lookup_handle(hdev, handle); - case HCI_AMP: - chan = hci_chan_lookup_handle(hdev, handle); - if (chan) - return chan->conn; - break; - default: - BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); - break; - } - - return NULL; -} - static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_num_comp_blocks *ev = (void *) skb->data; @@ -2878,13 +2595,13 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) for (i = 0; i < ev->num_hndl; i++) { struct hci_comp_blocks_info *info = &ev->handles[i]; - struct hci_conn *conn = NULL; + struct hci_conn *conn; __u16 handle, block_count; handle = __le16_to_cpu(info->handle); block_count = __le16_to_cpu(info->blocks); - conn = __hci_conn_lookup_handle(hdev, handle); + conn = hci_conn_hash_lookup_handle(hdev, handle); if (!conn) continue; @@ -2892,7 +2609,6 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) switch (conn->type) { case ACL_LINK: - case AMP_LINK: hdev->block_cnt += block_count; if (hdev->block_cnt > hdev->num_blocks) hdev->block_cnt = hdev->num_blocks; @@ -2989,13 +2705,13 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) key = hci_find_link_key(hdev, &ev->bdaddr); if (!key) { - BT_DBG("%s link key not found for %pMR", hdev->name, - &ev->bdaddr); + BT_DBG("%s link key not found for %s", hdev->name, + batostr(&ev->bdaddr)); goto not_found; } - BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, - &ev->bdaddr); + BT_DBG("%s found key type %u for %s", hdev->name, key->type, + batostr(&ev->bdaddr)); if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && key->type == HCI_LK_DEBUG_COMBINATION) { @@ -3703,130 +3419,6 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_phy_link_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_phy_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon, *bredr_hcon; - - BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, - ev->status); - - hci_dev_lock(hdev); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (!hcon) { - hci_dev_unlock(hdev); - return; - } - - if (ev->status) { - hci_conn_del(hcon); - hci_dev_unlock(hdev); - return; - } - - bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; - - hcon->state = BT_CONNECTED; - bacpy(&hcon->dst, &bredr_hcon->dst); - - hci_conn_hold(hcon); - hcon->disc_timeout = HCI_DISCONN_TIMEOUT; - hci_conn_put(hcon); - - hci_conn_hold_device(hcon); - hci_conn_add_sysfs(hcon); - - amp_physical_cfm(bredr_hcon, hcon); - - hci_dev_unlock(hdev); -} - -static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_logical_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon; - struct hci_chan *hchan; - struct amp_mgr *mgr; - - BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", - hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, - ev->status); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (!hcon) - return; - - /* Create AMP hchan */ - hchan = hci_chan_create(hcon); - if (!hchan) - return; - - hchan->handle = le16_to_cpu(ev->handle); - - BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); - - mgr = hcon->amp_mgr; - if (mgr && mgr->bredr_chan) { - struct l2cap_chan *bredr_chan = mgr->bredr_chan; - - l2cap_chan_lock(bredr_chan); - - bredr_chan->conn->mtu = hdev->block_mtu; - l2cap_logical_cfm(bredr_chan, hchan, 0); - hci_conn_hold(hcon); - - l2cap_chan_unlock(bredr_chan); - } -} - -static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; - struct hci_chan *hchan; - - BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, - le16_to_cpu(ev->handle), ev->status); - - if (ev->status) - return; - - hci_dev_lock(hdev); - - hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); - if (!hchan) - goto unlock; - - amp_destroy_logical_link(hchan, ev->reason); - -unlock: - hci_dev_unlock(hdev); -} - -static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon; - - BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); - - if (ev->status) - return; - - hci_dev_lock(hdev); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (hcon) { - hcon->state = BT_CLOSED; - hci_conn_del(hcon); - } - - hci_dev_unlock(hdev); -} - static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; @@ -3966,22 +3558,6 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_channel_selected *ev = (void *) skb->data; - struct hci_conn *hcon; - - BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); - - skb_pull(skb, sizeof(*ev)); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (!hcon) - return; - - amp_read_loc_assoc_final_data(hdev, hcon); -} - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; @@ -4146,30 +3722,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_le_meta_evt(hdev, skb); break; - case HCI_EV_CHANNEL_SELECTED: - hci_chan_selected_evt(hdev, skb); - break; - case HCI_EV_REMOTE_OOB_DATA_REQUEST: hci_remote_oob_data_request_evt(hdev, skb); break; - case HCI_EV_PHY_LINK_COMPLETE: - hci_phy_link_complete_evt(hdev, skb); - break; - - case HCI_EV_LOGICAL_LINK_COMPLETE: - hci_loglink_complete_evt(hdev, skb); - break; - - case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: - hci_disconn_loglink_complete_evt(hdev, skb); - break; - - case HCI_EV_DISCONN_PHY_LINK_COMPLETE: - hci_disconn_phylink_complete_evt(hdev, skb); - break; - case HCI_EV_NUM_COMP_BLOCKS: hci_num_comp_blocks_evt(hdev, skb); break; diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index 55cceee02a84..a20e61c3653d 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -38,7 +38,7 @@ static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); - return sprintf(buf, "%pMR\n", &conn->dst); + return sprintf(buf, "%s\n", batostr(&conn->dst)); } static ssize_t show_link_features(struct device *dev, @@ -224,7 +224,7 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); - return sprintf(buf, "%pMR\n", &hdev->bdaddr); + return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); } static ssize_t show_features(struct device *dev, @@ -406,8 +406,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p) list_for_each_entry(e, &cache->all, all) { struct inquiry_data *data = &e->data; - seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", - &data->bdaddr, + seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", + batostr(&data->bdaddr), data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode, data->dev_class[2], data->dev_class[1], data->dev_class[0], @@ -440,7 +440,7 @@ static int blacklist_show(struct seq_file *f, void *p) hci_dev_lock(hdev); list_for_each_entry(b, &hdev->blacklist, list) - seq_printf(f, "%pMR\n", &b->bdaddr); + seq_printf(f, "%s\n", batostr(&b->bdaddr)); hci_dev_unlock(hdev); diff --git a/trunk/net/bluetooth/hidp/core.c b/trunk/net/bluetooth/hidp/core.c index 0c0028463fa3..ccd985da6518 100644 --- a/trunk/net/bluetooth/hidp/core.c +++ b/trunk/net/bluetooth/hidp/core.c @@ -932,12 +932,8 @@ static int hidp_setup_hid(struct hidp_session *session, hid->country = req->country; strncpy(hid->name, req->name, 128); - - snprintf(hid->phys, sizeof(hid->phys), "%pMR", - &bt_sk(session->ctrl_sock->sk)->src); - - snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", - &bt_sk(session->ctrl_sock->sk)->dst); + strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); + strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); hid->dev.parent = &session->conn->dev; hid->ll_driver = &hidp_hid_driver; diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index b52f66d22437..a91239dcda41 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -38,7 +38,6 @@ #include #include #include -#include bool disable_ertm; @@ -49,20 +48,19 @@ static LIST_HEAD(chan_list); static DEFINE_RWLOCK(chan_list_lock); static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, - u8 code, u8 ident, u16 dlen, void *data); + u8 code, u8 ident, u16 dlen, void *data); static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, - void *data); + void *data); static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event); + struct sk_buff_head *skbs, u8 event); /* ---- L2CAP channels ---- */ -static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, - u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; @@ -73,8 +71,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, return NULL; } -static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, - u16 cid) +static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; @@ -87,8 +84,7 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, /* Find channel with given SCID. * Returns locked channel. */ -static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, - u16 cid) +static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) { struct l2cap_chan *c; @@ -101,25 +97,7 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, return c; } -/* Find channel with given DCID. - * Returns locked channel. - */ -static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, - u16 cid) -{ - struct l2cap_chan *c; - - mutex_lock(&conn->chan_lock); - c = __l2cap_get_chan_by_dcid(conn, cid); - if (c) - l2cap_chan_lock(c); - mutex_unlock(&conn->chan_lock); - - return c; -} - -static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, - u8 ident) +static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) { struct l2cap_chan *c; @@ -130,20 +108,6 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, return NULL; } -static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, - u8 ident) -{ - struct l2cap_chan *c; - - mutex_lock(&conn->chan_lock); - c = __l2cap_get_chan_by_ident(conn, ident); - if (c) - l2cap_chan_lock(c); - mutex_unlock(&conn->chan_lock); - - return c; -} - static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) { struct l2cap_chan *c; @@ -214,7 +178,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) static void __l2cap_state_change(struct l2cap_chan *chan, int state) { BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), - state_to_string(state)); + state_to_string(state)); chan->state = state; chan->ops->state_change(chan, state); @@ -397,7 +361,7 @@ static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq) static void l2cap_chan_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - chan_timer.work); + chan_timer.work); struct l2cap_conn *conn = chan->conn; int reason; @@ -409,7 +373,7 @@ static void l2cap_chan_timeout(struct work_struct *work) if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) reason = ECONNREFUSED; else if (chan->state == BT_CONNECT && - chan->sec_level != BT_SECURITY_SDP) + chan->sec_level != BT_SECURITY_SDP) reason = ECONNREFUSED; else reason = ETIMEDOUT; @@ -491,7 +455,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) set_bit(FLAG_FORCE_ACTIVE, &chan->flags); } -void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, __le16_to_cpu(chan->psm), chan->dcid); @@ -540,7 +504,7 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE; chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME; chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; - chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO; + chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; l2cap_chan_hold(chan); @@ -563,7 +527,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) BT_DBG("chan %p, conn %p, err %d", chan, conn, err); if (conn) { - struct amp_mgr *mgr = conn->hcon->amp_mgr; /* Delete from channel list */ list_del(&chan->list); @@ -573,19 +536,10 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) hci_conn_put(conn->hcon); - - if (mgr && mgr->bredr_chan == chan) - mgr->bredr_chan = NULL; } - if (chan->hs_hchan) { - struct hci_chan *hs_hchan = chan->hs_hchan; - - BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); - amp_disconnect_logical_link(hs_hchan); - } - - chan->ops->teardown(chan, err); + if (chan->ops->teardown) + chan->ops->teardown(chan, err); if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; @@ -619,18 +573,19 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) struct l2cap_conn *conn = chan->conn; struct sock *sk = chan->sk; - BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), - sk); + BT_DBG("chan %p state %s sk %p", chan, + state_to_string(chan->state), sk); switch (chan->state) { case BT_LISTEN: - chan->ops->teardown(chan, 0); + if (chan->ops->teardown) + chan->ops->teardown(chan, 0); break; case BT_CONNECTED: case BT_CONFIG: if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && - conn->hcon->type == ACL_LINK) { + conn->hcon->type == ACL_LINK) { __set_chan_timer(chan, sk->sk_sndtimeo); l2cap_send_disconn_req(conn, chan, reason); } else @@ -639,7 +594,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) case BT_CONNECT2: if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && - conn->hcon->type == ACL_LINK) { + conn->hcon->type == ACL_LINK) { struct l2cap_conn_rsp rsp; __u16 result; @@ -654,7 +609,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) rsp.result = cpu_to_le16(result); rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, - sizeof(rsp), &rsp); + sizeof(rsp), &rsp); } l2cap_chan_del(chan, reason); @@ -666,7 +621,8 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) break; default: - chan->ops->teardown(chan, 0); + if (chan->ops->teardown) + chan->ops->teardown(chan, 0); break; } } @@ -735,8 +691,7 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn) return id; } -static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, - void *data) +static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) { struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); u8 flags; @@ -757,31 +712,16 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, hci_send_acl(conn->hchan, skb, flags); } -static bool __chan_is_moving(struct l2cap_chan *chan) -{ - return chan->move_state != L2CAP_MOVE_STABLE && - chan->move_state != L2CAP_MOVE_WAIT_PREPARE; -} - static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) { struct hci_conn *hcon = chan->conn->hcon; u16 flags; BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, - skb->priority); - - if (chan->hs_hcon && !__chan_is_moving(chan)) { - if (chan->hs_hchan) - hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE); - else - kfree_skb(skb); - - return; - } + skb->priority); if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && - lmp_no_flush_capable(hcon->hdev)) + lmp_no_flush_capable(hcon->hdev)) flags = ACL_START_NO_FLUSH; else flags = ACL_START; @@ -955,9 +895,6 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, if (!control->sframe) return; - if (__chan_is_moving(chan)) - return; - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) && !control->poll) control->final = 1; @@ -1009,25 +946,7 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); } -static bool __amp_capable(struct l2cap_chan *chan) -{ - struct l2cap_conn *conn = chan->conn; - - if (enable_hs && - chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && - conn->fixed_chan_mask & L2CAP_FC_A2MP) - return true; - else - return false; -} - -static bool l2cap_check_efs(struct l2cap_chan *chan) -{ - /* Check EFS parameters */ - return true; -} - -void l2cap_send_conn_req(struct l2cap_chan *chan) +static void l2cap_send_conn_req(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; struct l2cap_conn_req req; @@ -1042,76 +961,6 @@ void l2cap_send_conn_req(struct l2cap_chan *chan) l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req); } -static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id) -{ - struct l2cap_create_chan_req req; - req.scid = cpu_to_le16(chan->scid); - req.psm = chan->psm; - req.amp_id = amp_id; - - chan->ident = l2cap_get_ident(chan->conn); - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ, - sizeof(req), &req); -} - -static void l2cap_move_setup(struct l2cap_chan *chan) -{ - struct sk_buff *skb; - - BT_DBG("chan %p", chan); - - if (chan->mode != L2CAP_MODE_ERTM) - return; - - __clear_retrans_timer(chan); - __clear_monitor_timer(chan); - __clear_ack_timer(chan); - - chan->retry_count = 0; - skb_queue_walk(&chan->tx_q, skb) { - if (bt_cb(skb)->control.retries) - bt_cb(skb)->control.retries = 1; - else - break; - } - - chan->expected_tx_seq = chan->buffer_seq; - - clear_bit(CONN_REJ_ACT, &chan->conn_state); - clear_bit(CONN_SREJ_ACT, &chan->conn_state); - l2cap_seq_list_clear(&chan->retrans_list); - l2cap_seq_list_clear(&chan->srej_list); - skb_queue_purge(&chan->srej_q); - - chan->tx_state = L2CAP_TX_STATE_XMIT; - chan->rx_state = L2CAP_RX_STATE_MOVE; - - set_bit(CONN_REMOTE_BUSY, &chan->conn_state); -} - -static void l2cap_move_done(struct l2cap_chan *chan) -{ - u8 move_role = chan->move_role; - BT_DBG("chan %p", chan); - - chan->move_state = L2CAP_MOVE_STABLE; - chan->move_role = L2CAP_MOVE_ROLE_NONE; - - if (chan->mode != L2CAP_MODE_ERTM) - return; - - switch (move_role) { - case L2CAP_MOVE_ROLE_INITIATOR: - l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL); - chan->rx_state = L2CAP_RX_STATE_WAIT_F; - break; - case L2CAP_MOVE_ROLE_RESPONDER: - chan->rx_state = L2CAP_RX_STATE_WAIT_P; - break; - } -} - static void l2cap_chan_ready(struct l2cap_chan *chan) { /* This clears all conf flags, including CONF_NOT_COMPLETE */ @@ -1123,16 +972,6 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) chan->ops->ready(chan); } -static void l2cap_start_connection(struct l2cap_chan *chan) -{ - if (__amp_capable(chan)) { - BT_DBG("chan %p AMP capable: discover AMPs", chan); - a2mp_discover_amp(chan); - } else { - l2cap_send_conn_req(chan); - } -} - static void l2cap_do_start(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1147,9 +986,8 @@ static void l2cap_do_start(struct l2cap_chan *chan) return; if (l2cap_chan_check_security(chan) && - __l2cap_no_conn_pending(chan)) { - l2cap_start_connection(chan); - } + __l2cap_no_conn_pending(chan)) + l2cap_send_conn_req(chan); } else { struct l2cap_info_req req; req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); @@ -1159,8 +997,8 @@ static void l2cap_do_start(struct l2cap_chan *chan) schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); - l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, - sizeof(req), &req); + l2cap_send_cmd(conn, conn->info_ident, + L2CAP_INFO_REQ, sizeof(req), &req); } } @@ -1180,8 +1018,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) } } -static void l2cap_send_disconn_req(struct l2cap_conn *conn, - struct l2cap_chan *chan, int err) +static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) { struct sock *sk = chan->sk; struct l2cap_disconn_req req; @@ -1196,14 +1033,14 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, } if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { - l2cap_state_change(chan, BT_DISCONN); + __l2cap_state_change(chan, BT_DISCONN); return; } req.dcid = cpu_to_le16(chan->dcid); req.scid = cpu_to_le16(chan->scid); - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, - sizeof(req), &req); + l2cap_send_cmd(conn, l2cap_get_ident(conn), + L2CAP_DISCONN_REQ, sizeof(req), &req); lock_sock(sk); __l2cap_state_change(chan, BT_DISCONN); @@ -1232,20 +1069,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn) if (chan->state == BT_CONNECT) { if (!l2cap_chan_check_security(chan) || - !__l2cap_no_conn_pending(chan)) { + !__l2cap_no_conn_pending(chan)) { l2cap_chan_unlock(chan); continue; } if (!l2cap_mode_supported(chan->mode, conn->feat_mask) - && test_bit(CONF_STATE2_DEVICE, + && test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) { l2cap_chan_close(chan, ECONNRESET); l2cap_chan_unlock(chan); continue; } - l2cap_start_connection(chan); + l2cap_send_conn_req(chan); } else if (chan->state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; @@ -1257,9 +1094,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn) lock_sock(sk); if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { + struct sock *parent = bt_sk(sk)->parent; rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); - chan->ops->defer(chan); + if (parent) + parent->sk_data_ready(parent, 0); } else { __l2cap_state_change(chan, BT_CONFIG); @@ -1273,17 +1112,17 @@ static void l2cap_conn_start(struct l2cap_conn *conn) } l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, - sizeof(rsp), &rsp); + sizeof(rsp), &rsp); if (test_bit(CONF_REQ_SENT, &chan->conf_state) || - rsp.result != L2CAP_CR_SUCCESS) { + rsp.result != L2CAP_CR_SUCCESS) { l2cap_chan_unlock(chan); continue; } set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf), buf); chan->num_conf_req++; } @@ -1365,6 +1204,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) bacpy(&bt_sk(sk)->src, conn->src); bacpy(&bt_sk(sk)->dst, conn->dst); + bt_accept_enqueue(parent, sk); + l2cap_chan_add(conn, chan); l2cap_chan_ready(chan); @@ -1429,7 +1270,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) list_for_each_entry(chan, &conn->chan_l, list) { if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) - l2cap_chan_set_err(chan, err); + __l2cap_chan_set_err(chan, err); } mutex_unlock(&conn->chan_lock); @@ -1438,7 +1279,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) static void l2cap_info_timeout(struct work_struct *work) { struct l2cap_conn *conn = container_of(work, struct l2cap_conn, - info_timer.work); + info_timer.work); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; conn->info_ident = 0; @@ -1492,7 +1333,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) static void security_timeout(struct work_struct *work) { struct l2cap_conn *conn = container_of(work, struct l2cap_conn, - security_timer.work); + security_timer.work); BT_DBG("conn %p", conn); @@ -1514,7 +1355,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) if (!hchan) return NULL; - conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL); + conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); if (!conn) { hci_chan_del(hchan); return NULL; @@ -1526,22 +1367,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); - switch (hcon->type) { - case AMP_LINK: - conn->mtu = hcon->hdev->block_mtu; - break; - - case LE_LINK: - if (hcon->hdev->le_mtu) { - conn->mtu = hcon->hdev->le_mtu; - break; - } - /* fall through */ - - default: + if (hcon->hdev->le_mtu && hcon->type == LE_LINK) + conn->mtu = hcon->hdev->le_mtu; + else conn->mtu = hcon->hdev->acl_mtu; - break; - } conn->src = &hcon->hdev->bdaddr; conn->dst = &hcon->dst; @@ -1619,7 +1448,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, __u8 auth_type; int err; - BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst, + BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst), dst_type, __le16_to_cpu(psm)); hdev = hci_get_route(dst, src); @@ -1632,7 +1461,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, /* PSM must be odd and lsb of upper byte must be 0 */ if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid && - chan->chan_type != L2CAP_CHAN_RAW) { + chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; goto done; } @@ -1828,9 +1657,6 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, BT_DBG("chan %p, skbs %p", chan, skbs); - if (__chan_is_moving(chan)) - return; - skb_queue_splice_tail_init(skbs, &chan->tx_q); while (!skb_queue_empty(&chan->tx_q)) { @@ -1873,9 +1699,6 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return 0; - if (__chan_is_moving(chan)) - return 0; - while (chan->tx_send_head && chan->unacked_frames < chan->remote_tx_win && chan->tx_state == L2CAP_TX_STATE_XMIT) { @@ -1941,16 +1764,13 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return; - if (__chan_is_moving(chan)) - return; - while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) { seq = l2cap_seq_list_pop(&chan->retrans_list); skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq); if (!skb) { BT_DBG("Error: Can't retransmit seq %d, frame missing", - seq); + seq); continue; } @@ -1975,9 +1795,9 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) /* Cloned sk_buffs are read-only, so we need a * writeable copy */ - tx_skb = skb_copy(skb, GFP_KERNEL); + tx_skb = skb_copy(skb, GFP_ATOMIC); } else { - tx_skb = skb_clone(skb, GFP_KERNEL); + tx_skb = skb_clone(skb, GFP_ATOMIC); } if (!tx_skb) { @@ -2035,7 +1855,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, if (chan->unacked_frames) { skb_queue_walk(&chan->tx_q, skb) { if (bt_cb(skb)->control.txseq == control->reqseq || - skb == chan->tx_send_head) + skb == chan->tx_send_head) break; } @@ -2286,9 +2106,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, /* PDU size is derived from the HCI MTU */ pdu_len = chan->conn->mtu; - /* Constrain PDU size for BR/EDR connections */ - if (!chan->hs_hcon) - pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); + pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); /* Adjust for largest possible L2CAP overhead. */ if (chan->fcs) @@ -2338,7 +2156,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, } int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, - u32 priority) + u32 priority) { struct sk_buff *skb; int err; @@ -2725,7 +2543,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) /* Don't send frame to the socket it came from */ if (skb->sk == sk) continue; - nskb = skb_clone(skb, GFP_KERNEL); + nskb = skb_clone(skb, GFP_ATOMIC); if (!nskb) continue; @@ -2751,7 +2569,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; count = min_t(unsigned int, conn->mtu, len); - skb = bt_skb_alloc(count, GFP_KERNEL); + skb = bt_skb_alloc(count, GFP_ATOMIC); if (!skb) return NULL; @@ -2781,7 +2599,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, while (len) { count = min_t(unsigned int, conn->mtu, len); - *frag = bt_skb_alloc(count, GFP_KERNEL); + *frag = bt_skb_alloc(count, GFP_ATOMIC); if (!*frag) goto fail; @@ -2800,8 +2618,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, return NULL; } -static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, - unsigned long *val) +static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val) { struct l2cap_conf_opt *opt = *ptr; int len; @@ -2875,7 +2692,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) efs.msdu = cpu_to_le16(chan->local_msdu); efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); - efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO); + efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); break; case L2CAP_MODE_STREAMING: @@ -2892,7 +2709,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) } l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + (unsigned long) &efs); } static void l2cap_ack_timeout(struct work_struct *work) @@ -2932,11 +2749,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->tx_q); - chan->local_amp_id = 0; - chan->move_id = 0; - chan->move_state = L2CAP_MOVE_STABLE; - chan->move_role = L2CAP_MOVE_ROLE_NONE; - if (chan->mode != L2CAP_MODE_ERTM) return 0; @@ -2983,54 +2795,16 @@ static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; } -static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, - struct l2cap_conf_rfc *rfc) -{ - if (chan->local_amp_id && chan->hs_hcon) { - u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to; - - /* Class 1 devices have must have ERTM timeouts - * exceeding the Link Supervision Timeout. The - * default Link Supervision Timeout for AMP - * controllers is 10 seconds. - * - * Class 1 devices use 0xffffffff for their - * best-effort flush timeout, so the clamping logic - * will result in a timeout that meets the above - * requirement. ERTM timeouts are 16-bit values, so - * the maximum timeout is 65.535 seconds. - */ - - /* Convert timeout to milliseconds and round */ - ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000); - - /* This is the recommended formula for class 2 devices - * that start ERTM timers when packets are sent to the - * controller. - */ - ertm_to = 3 * ertm_to + 500; - - if (ertm_to > 0xffff) - ertm_to = 0xffff; - - rfc->retrans_timeout = cpu_to_le16((u16) ertm_to); - rfc->monitor_timeout = rfc->retrans_timeout; - } else { - rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); - rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); - } -} - static inline void l2cap_txwin_setup(struct l2cap_chan *chan) { if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && - __l2cap_ews_supported(chan)) { + __l2cap_ews_supported(chan)) { /* use extended control field */ set_bit(FLAG_EXT_CTRL, &chan->flags); chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; } else { chan->tx_win = min_t(u16, chan->tx_win, - L2CAP_DEFAULT_TX_WINDOW); + L2CAP_DEFAULT_TX_WINDOW); chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; } chan->ack_win = chan->tx_win; @@ -3070,7 +2844,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) switch (chan->mode) { case L2CAP_MODE_BASIC: if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) && - !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING)) + !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING)) break; rfc.mode = L2CAP_MODE_BASIC; @@ -3081,27 +2855,28 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) rfc.max_pdu_size = 0; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc); break; case L2CAP_MODE_ERTM: rfc.mode = L2CAP_MODE_ERTM; rfc.max_transmit = chan->max_tx; - - __l2cap_set_ertm_timeouts(chan, &rfc); + rfc.retrans_timeout = 0; + rfc.monitor_timeout = 0; size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - - L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - - L2CAP_FCS_SIZE); + L2CAP_EXT_HDR_SIZE - + L2CAP_SDULEN_SIZE - + L2CAP_FCS_SIZE); rfc.max_pdu_size = cpu_to_le16(size); l2cap_txwin_setup(chan); rfc.txwin_size = min_t(u16, chan->tx_win, - L2CAP_DEFAULT_TX_WINDOW); + L2CAP_DEFAULT_TX_WINDOW); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) l2cap_add_opt_efs(&ptr, chan); @@ -3110,14 +2885,14 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) break; if (chan->fcs == L2CAP_FCS_NONE || - test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { chan->fcs = L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); } if (test_bit(FLAG_EXT_CTRL, &chan->flags)) l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, - chan->tx_win); + chan->tx_win); break; case L2CAP_MODE_STREAMING: @@ -3129,12 +2904,13 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) rfc.monitor_timeout = 0; size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - - L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - - L2CAP_FCS_SIZE); + L2CAP_EXT_HDR_SIZE - + L2CAP_SDULEN_SIZE - + L2CAP_FCS_SIZE); rfc.max_pdu_size = cpu_to_le16(size); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + (unsigned long) &rfc); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) l2cap_add_opt_efs(&ptr, chan); @@ -3143,7 +2919,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) break; if (chan->fcs == L2CAP_FCS_NONE || - test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { chan->fcs = L2CAP_FCS_NONE; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); } @@ -3235,7 +3011,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) case L2CAP_MODE_ERTM: if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) { chan->mode = l2cap_select_mode(rfc.mode, - chan->conn->feat_mask); + chan->conn->feat_mask); break; } @@ -3260,8 +3036,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) if (chan->num_conf_rsp == 1) return -ECONNREFUSED; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, + sizeof(rfc), (unsigned long) &rfc); } if (result == L2CAP_CONF_SUCCESS) { @@ -3278,8 +3054,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) if (remote_efs) { if (chan->local_stype != L2CAP_SERV_NOTRAFIC && - efs.stype != L2CAP_SERV_NOTRAFIC && - efs.stype != chan->local_stype) { + efs.stype != L2CAP_SERV_NOTRAFIC && + efs.stype != chan->local_stype) { result = L2CAP_CONF_UNACCEPT; @@ -3287,8 +3063,8 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) return -ECONNREFUSED; l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, - sizeof(efs), - (unsigned long) &efs); + sizeof(efs), + (unsigned long) &efs); } else { /* Send PENDING Conf Rsp */ result = L2CAP_CONF_PENDING; @@ -3311,45 +3087,51 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) chan->remote_max_tx = rfc.max_transmit; size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), - chan->conn->mtu - L2CAP_EXT_HDR_SIZE - - L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE); + chan->conn->mtu - + L2CAP_EXT_HDR_SIZE - + L2CAP_SDULEN_SIZE - + L2CAP_FCS_SIZE); rfc.max_pdu_size = cpu_to_le16(size); chan->remote_mps = size; - __l2cap_set_ertm_timeouts(chan, &rfc); + rfc.retrans_timeout = + __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc.monitor_timeout = + __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); set_bit(CONF_MODE_DONE, &chan->conf_state); l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc); if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->remote_id = efs.id; chan->remote_stype = efs.stype; chan->remote_msdu = le16_to_cpu(efs.msdu); chan->remote_flush_to = - le32_to_cpu(efs.flush_to); + le32_to_cpu(efs.flush_to); chan->remote_acc_lat = - le32_to_cpu(efs.acc_lat); + le32_to_cpu(efs.acc_lat); chan->remote_sdu_itime = le32_to_cpu(efs.sdu_itime); l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, - sizeof(efs), - (unsigned long) &efs); + sizeof(efs), (unsigned long) &efs); } break; case L2CAP_MODE_STREAMING: size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), - chan->conn->mtu - L2CAP_EXT_HDR_SIZE - - L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE); + chan->conn->mtu - + L2CAP_EXT_HDR_SIZE - + L2CAP_SDULEN_SIZE - + L2CAP_FCS_SIZE); rfc.max_pdu_size = cpu_to_le16(size); chan->remote_mps = size; set_bit(CONF_MODE_DONE, &chan->conf_state); - l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), - (unsigned long) &rfc); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, + sizeof(rfc), (unsigned long) &rfc); break; @@ -3370,8 +3152,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) return ptr - data; } -static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, - void *data, u16 *result) +static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result) { struct l2cap_conf_req *req = data; void *ptr = req->data; @@ -3398,7 +3179,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, case L2CAP_CONF_FLUSH_TO: chan->flush_to = val; l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, - 2, chan->flush_to); + 2, chan->flush_to); break; case L2CAP_CONF_RFC: @@ -3406,13 +3187,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, memcpy(&rfc, (void *)val, olen); if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) && - rfc.mode != chan->mode) + rfc.mode != chan->mode) return -ECONNREFUSED; chan->fcs = 0; l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, - sizeof(rfc), (unsigned long) &rfc); + sizeof(rfc), (unsigned long) &rfc); break; case L2CAP_CONF_EWS: @@ -3426,12 +3207,12 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, memcpy(&efs, (void *)val, olen); if (chan->local_stype != L2CAP_SERV_NOTRAFIC && - efs.stype != L2CAP_SERV_NOTRAFIC && - efs.stype != chan->local_stype) + efs.stype != L2CAP_SERV_NOTRAFIC && + efs.stype != chan->local_stype) return -ECONNREFUSED; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), - (unsigned long) &efs); + l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, + sizeof(efs), (unsigned long) &efs); break; } } @@ -3454,10 +3235,10 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { chan->local_msdu = le16_to_cpu(efs.msdu); chan->local_sdu_itime = - le32_to_cpu(efs.sdu_itime); + le32_to_cpu(efs.sdu_itime); chan->local_acc_lat = le32_to_cpu(efs.acc_lat); chan->local_flush_to = - le32_to_cpu(efs.flush_to); + le32_to_cpu(efs.flush_to); } break; @@ -3472,8 +3253,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, return ptr - data; } -static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, - u16 result, u16 flags) +static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags) { struct l2cap_conf_rsp *rsp = data; void *ptr = rsp->data; @@ -3492,27 +3272,19 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) struct l2cap_conn_rsp rsp; struct l2cap_conn *conn = chan->conn; u8 buf[128]; - u8 rsp_code; rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - - if (chan->hs_hcon) - rsp_code = L2CAP_CREATE_CHAN_RSP; - else - rsp_code = L2CAP_CONN_RSP; - - BT_DBG("chan %p rsp_code %u", chan, rsp_code); - - l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, chan->ident, + L2CAP_CONN_RSP, sizeof(rsp), &rsp); if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) return; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf), buf); chan->num_conf_req++; } @@ -3567,8 +3339,7 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) } } -static inline int l2cap_command_rej(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; @@ -3576,7 +3347,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, return 0; if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && - cmd->ident == conn->info_ident) { + cmd->ident == conn->info_ident) { cancel_delayed_work(&conn->info_timer); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; @@ -3588,9 +3359,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, return 0; } -static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u8 *data, u8 rsp_code, u8 amp_id) +static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; @@ -3617,7 +3386,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, /* Check if the ACL is secure enough (if not SDP) */ if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && - !hci_conn_check_link_mode(conn->hcon)) { + !hci_conn_check_link_mode(conn->hcon)) { conn->disc_reason = HCI_ERROR_AUTH_FAILURE; result = L2CAP_CR_SEC_BLOCK; goto response; @@ -3641,7 +3410,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, bacpy(&bt_sk(sk)->dst, conn->dst); chan->psm = psm; chan->dcid = scid; - chan->local_amp_id = amp_id; + + bt_accept_enqueue(parent, sk); __l2cap_chan_add(conn, chan); @@ -3657,19 +3427,10 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, __l2cap_state_change(chan, BT_CONNECT2); result = L2CAP_CR_PEND; status = L2CAP_CS_AUTHOR_PEND; - chan->ops->defer(chan); + parent->sk_data_ready(parent, 0); } else { - /* Force pending result for AMP controllers. - * The connection will succeed after the - * physical link is up. - */ - if (amp_id) { - __l2cap_state_change(chan, BT_CONNECT2); - result = L2CAP_CR_PEND; - } else { - __l2cap_state_change(chan, BT_CONFIG); - result = L2CAP_CR_SUCCESS; - } + __l2cap_state_change(chan, BT_CONFIG); + result = L2CAP_CR_SUCCESS; status = L2CAP_CS_NO_INFO; } } else { @@ -3692,7 +3453,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, rsp.dcid = cpu_to_le16(dcid); rsp.result = cpu_to_le16(result); rsp.status = cpu_to_le16(status); - l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { struct l2cap_info_req info; @@ -3703,31 +3464,23 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); - l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, - sizeof(info), &info); + l2cap_send_cmd(conn, conn->info_ident, + L2CAP_INFO_REQ, sizeof(info), &info); } if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) && - result == L2CAP_CR_SUCCESS) { + result == L2CAP_CR_SUCCESS) { u8 buf[128]; set_bit(CONF_REQ_SENT, &chan->conf_state); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf), buf); chan->num_conf_req++; } - return chan; -} - -static int l2cap_connect_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) -{ - l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); return 0; } -static int l2cap_connect_create_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; u16 scid, dcid, result, status; @@ -3741,7 +3494,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, status = __le16_to_cpu(rsp->status); BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", - dcid, scid, result, status); + dcid, scid, result, status); mutex_lock(&conn->chan_lock); @@ -3774,7 +3527,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, break; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, req), req); + l2cap_build_conf_req(chan, req), req); chan->num_conf_req++; break; @@ -3806,25 +3559,7 @@ static inline void set_default_fcs(struct l2cap_chan *chan) chan->fcs = L2CAP_FCS_CRC16; } -static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, - u8 ident, u16 flags) -{ - struct l2cap_conn *conn = chan->conn; - - BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident, - flags); - - clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); - set_bit(CONF_OUTPUT_DONE, &chan->conf_state); - - l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP, - l2cap_build_conf_rsp(chan, data, - L2CAP_CONF_SUCCESS, flags), data); -} - -static inline int l2cap_config_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u16 cmd_len, - u8 *data) +static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; u16 dcid, flags; @@ -3849,7 +3584,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, rej.dcid = cpu_to_le16(chan->dcid); l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, - sizeof(rej), &rej); + sizeof(rej), &rej); goto unlock; } @@ -3857,8 +3592,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, len = cmd_len - sizeof(*req); if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, - l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_REJECT, flags), rsp); + l2cap_build_conf_rsp(chan, rsp, + L2CAP_CONF_REJECT, flags), rsp); goto unlock; } @@ -3869,8 +3604,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, if (flags & L2CAP_CONF_FLAG_CONTINUATION) { /* Incomplete config. Send empty response. */ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, - l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_SUCCESS, flags), rsp); + l2cap_build_conf_rsp(chan, rsp, + L2CAP_CONF_SUCCESS, flags), rsp); goto unlock; } @@ -3881,7 +3616,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, goto unlock; } - chan->ident = cmd->ident; l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); chan->num_conf_rsp++; @@ -3909,22 +3643,23 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { u8 buf[64]; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); + l2cap_build_conf_req(chan, buf), buf); chan->num_conf_req++; } /* Got Conf Rsp PENDING from remote side and asume we sent Conf Rsp PENDING in the code above */ if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && - test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { + test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { /* check compatibility */ - /* Send rsp for BR/EDR channel */ - if (!chan->hs_hcon) - l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags); - else - chan->ident = cmd->ident; + clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); + set_bit(CONF_OUTPUT_DONE, &chan->conf_state); + + l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, + l2cap_build_conf_rsp(chan, rsp, + L2CAP_CONF_SUCCESS, flags), rsp); } unlock: @@ -3932,8 +3667,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, return err; } -static inline int l2cap_config_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; u16 scid, flags, result; @@ -3965,21 +3699,20 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, char buf[64]; len = l2cap_parse_conf_rsp(chan, rsp->data, len, - buf, &result); + buf, &result); if (len < 0) { l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } - if (!chan->hs_hcon) { - l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, - 0); - } else { - if (l2cap_check_efs(chan)) { - amp_create_logical_link(chan); - chan->ident = cmd->ident; - } - } + /* check compatibility */ + + clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); + set_bit(CONF_OUTPUT_DONE, &chan->conf_state); + + l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, + l2cap_build_conf_rsp(chan, buf, + L2CAP_CONF_SUCCESS, 0x0000), buf); } goto done; @@ -3995,14 +3728,14 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, /* throw out any old stored conf requests */ result = L2CAP_CONF_SUCCESS; len = l2cap_parse_conf_rsp(chan, rsp->data, len, - req, &result); + req, &result); if (len < 0) { l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } l2cap_send_cmd(conn, l2cap_get_ident(conn), - L2CAP_CONF_REQ, len, req); + L2CAP_CONF_REQ, len, req); chan->num_conf_req++; if (result != L2CAP_CONF_SUCCESS) goto done; @@ -4040,8 +3773,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, return err; } -static inline int l2cap_disconnect_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; struct l2cap_disconn_rsp rsp; @@ -4087,8 +3819,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, return 0; } -static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; u16 dcid, scid; @@ -4122,8 +3853,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, return 0; } -static inline int l2cap_information_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_info_req *req = (struct l2cap_info_req *) data; u16 type; @@ -4140,14 +3870,14 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); if (!disable_ertm) feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING - | L2CAP_FEAT_FCS; + | L2CAP_FEAT_FCS; if (enable_hs) feat_mask |= L2CAP_FEAT_EXT_FLOW - | L2CAP_FEAT_EXT_WINDOW; + | L2CAP_FEAT_EXT_WINDOW; put_unaligned_le32(feat_mask, rsp->data); - l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), - buf); + l2cap_send_cmd(conn, cmd->ident, + L2CAP_INFO_RSP, sizeof(buf), buf); } else if (type == L2CAP_IT_FIXED_CHAN) { u8 buf[12]; struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; @@ -4160,21 +3890,20 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); - l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), - buf); + l2cap_send_cmd(conn, cmd->ident, + L2CAP_INFO_RSP, sizeof(buf), buf); } else { struct l2cap_info_rsp rsp; rsp.type = cpu_to_le16(type); rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); - l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), - &rsp); + l2cap_send_cmd(conn, cmd->ident, + L2CAP_INFO_RSP, sizeof(rsp), &rsp); } return 0; } -static inline int l2cap_information_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) +static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; u16 type, result; @@ -4186,7 +3915,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, /* L2CAP Info req/rsp are unbound to channels, add extra checks */ if (cmd->ident != conn->info_ident || - conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) + conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) return 0; cancel_delayed_work(&conn->info_timer); @@ -4211,7 +3940,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, conn->info_ident = l2cap_get_ident(conn); l2cap_send_cmd(conn, conn->info_ident, - L2CAP_INFO_REQ, sizeof(req), &req); + L2CAP_INFO_REQ, sizeof(req), &req); } else { conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; conn->info_ident = 0; @@ -4232,14 +3961,12 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, return 0; } -static int l2cap_create_channel_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) +static inline int l2cap_create_channel_req(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, u16 cmd_len, + void *data) { struct l2cap_create_chan_req *req = data; struct l2cap_create_chan_rsp rsp; - struct l2cap_chan *chan; - struct hci_dev *hdev; u16 psm, scid; if (cmd_len != sizeof(*req)) @@ -4253,119 +3980,56 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); - /* For controller id 0 make BR/EDR connection */ - if (req->amp_id == HCI_BREDR_ID) { - l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, - req->amp_id); - return 0; - } - - /* Validate AMP controller id */ - hdev = hci_dev_get(req->amp_id); - if (!hdev) - goto error; - - if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) { - hci_dev_put(hdev); - goto error; - } - - chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, - req->amp_id); - if (chan) { - struct amp_mgr *mgr = conn->hcon->amp_mgr; - struct hci_conn *hs_hcon; - - hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst); - if (!hs_hcon) { - hci_dev_put(hdev); - return -EFAULT; - } - - BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); - - mgr->bredr_chan = chan; - chan->hs_hcon = hs_hcon; - chan->fcs = L2CAP_FCS_NONE; - conn->mtu = hdev->block_mtu; - } - - hci_dev_put(hdev); - - return 0; - -error: + /* Placeholder: Always reject */ rsp.dcid = 0; rsp.scid = cpu_to_le16(scid); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, sizeof(rsp), &rsp); - return -EFAULT; + return 0; } -static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) +static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, void *data) { - struct l2cap_move_chan_req req; - u8 ident; - - BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); - - ident = l2cap_get_ident(chan->conn); - chan->ident = ident; - - req.icid = cpu_to_le16(chan->scid); - req.dest_amp_id = dest_amp_id; - - l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req), - &req); + BT_DBG("conn %p", conn); - __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); + return l2cap_connect_rsp(conn, cmd, data); } -static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) +static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, + u16 icid, u16 result) { struct l2cap_move_chan_rsp rsp; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - rsp.icid = cpu_to_le16(chan->dcid); + rsp.icid = cpu_to_le16(icid); rsp.result = cpu_to_le16(result); - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP, - sizeof(rsp), &rsp); + l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); } -static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) +static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, + struct l2cap_chan *chan, + u16 icid, u16 result) { struct l2cap_move_chan_cfm cfm; + u8 ident; - BT_DBG("chan %p, result 0x%4.4x", chan, result); - - chan->ident = l2cap_get_ident(chan->conn); - - cfm.icid = cpu_to_le16(chan->scid); - cfm.result = cpu_to_le16(result); - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM, - sizeof(cfm), &cfm); - - __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); -} - -static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) -{ - struct l2cap_move_chan_cfm cfm; + BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - BT_DBG("conn %p, icid 0x%4.4x", conn, icid); + ident = l2cap_get_ident(conn); + if (chan) + chan->ident = ident; cfm.icid = cpu_to_le16(icid); - cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); + cfm.result = cpu_to_le16(result); - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM, - sizeof(cfm), &cfm); + l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); } static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, @@ -4379,528 +4043,56 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); } -static void __release_logical_link(struct l2cap_chan *chan) +static inline int l2cap_move_channel_req(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { - chan->hs_hchan = NULL; - chan->hs_hcon = NULL; + struct l2cap_move_chan_req *req = data; + u16 icid = 0; + u16 result = L2CAP_MR_NOT_ALLOWED; - /* Placeholder - release the logical link */ -} + if (cmd_len != sizeof(*req)) + return -EPROTO; -static void l2cap_logical_fail(struct l2cap_chan *chan) -{ - /* Logical link setup failed */ - if (chan->state != BT_CONNECTED) { - /* Create channel failure, disconnect */ - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - return; - } + icid = le16_to_cpu(req->icid); - switch (chan->move_role) { - case L2CAP_MOVE_ROLE_RESPONDER: - l2cap_move_done(chan); - l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP); - break; - case L2CAP_MOVE_ROLE_INITIATOR: - if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP || - chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) { - /* Remote has only sent pending or - * success responses, clean up - */ - l2cap_move_done(chan); - } + BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); - /* Other amp move states imply that the move - * has already aborted - */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - break; - } + if (!enable_hs) + return -EINVAL; + + /* Placeholder: Always refuse */ + l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result); + + return 0; } -static void l2cap_logical_finish_create(struct l2cap_chan *chan, - struct hci_chan *hchan) +static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { - struct l2cap_conf_rsp rsp; + struct l2cap_move_chan_rsp *rsp = data; + u16 icid, result; - chan->hs_hchan = hchan; - chan->hs_hcon->l2cap_data = chan->conn; + if (cmd_len != sizeof(*rsp)) + return -EPROTO; - l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0); + icid = le16_to_cpu(rsp->icid); + result = le16_to_cpu(rsp->result); - if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { - int err; + BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - set_default_fcs(chan); + /* Placeholder: Always unconfirmed */ + l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); - err = l2cap_ertm_init(chan); - if (err < 0) - l2cap_send_disconn_req(chan->conn, chan, -err); - else - l2cap_chan_ready(chan); - } + return 0; } -static void l2cap_logical_finish_move(struct l2cap_chan *chan, - struct hci_chan *hchan) -{ - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - - BT_DBG("move_state %d", chan->move_state); - - switch (chan->move_state) { - case L2CAP_MOVE_WAIT_LOGICAL_COMP: - /* Move confirm will be sent after a success - * response is received - */ - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - break; - case L2CAP_MOVE_WAIT_LOGICAL_CFM: - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); - } - break; - default: - /* Move was not in expected state, free the channel */ - __release_logical_link(chan); - - chan->move_state = L2CAP_MOVE_STABLE; - } -} - -/* Call with chan locked */ -void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, - u8 status) -{ - BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); - - if (status) { - l2cap_logical_fail(chan); - __release_logical_link(chan); - return; - } - - if (chan->state != BT_CONNECTED) { - /* Ignore logical link if channel is on BR/EDR */ - if (chan->local_amp_id) - l2cap_logical_finish_create(chan, hchan); - } else { - l2cap_logical_finish_move(chan, hchan); - } -} - -void l2cap_move_start(struct l2cap_chan *chan) -{ - BT_DBG("chan %p", chan); - - if (chan->local_amp_id == HCI_BREDR_ID) { - if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) - return; - chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; - chan->move_state = L2CAP_MOVE_WAIT_PREPARE; - /* Placeholder - start physical link setup */ - } else { - chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - chan->move_id = 0; - l2cap_move_setup(chan); - l2cap_send_move_chan_req(chan, 0); - } -} - -static void l2cap_do_create(struct l2cap_chan *chan, int result, - u8 local_amp_id, u8 remote_amp_id) -{ - BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), - local_amp_id, remote_amp_id); - - chan->fcs = L2CAP_FCS_NONE; - - /* Outgoing channel on AMP */ - if (chan->state == BT_CONNECT) { - if (result == L2CAP_CR_SUCCESS) { - chan->local_amp_id = local_amp_id; - l2cap_send_create_chan_req(chan, remote_amp_id); - } else { - /* Revert to BR/EDR connect */ - l2cap_send_conn_req(chan); - } - - return; - } - - /* Incoming channel on AMP */ - if (__l2cap_no_conn_pending(chan)) { - struct l2cap_conn_rsp rsp; - char buf[128]; - rsp.scid = cpu_to_le16(chan->dcid); - rsp.dcid = cpu_to_le16(chan->scid); - - if (result == L2CAP_CR_SUCCESS) { - /* Send successful response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - } else { - /* Send negative response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - } - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP, - sizeof(rsp), &rsp); - - if (result == L2CAP_CR_SUCCESS) { - __l2cap_state_change(chan, BT_CONFIG); - set_bit(CONF_REQ_SENT, &chan->conf_state); - l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), - L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); - chan->num_conf_req++; - } - } -} - -static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id, - u8 remote_amp_id) -{ - l2cap_move_setup(chan); - chan->move_id = local_amp_id; - chan->move_state = L2CAP_MOVE_WAIT_RSP; - - l2cap_send_move_chan_req(chan, remote_amp_id); -} - -static void l2cap_do_move_respond(struct l2cap_chan *chan, int result) -{ - struct hci_chan *hchan = NULL; - - /* Placeholder - get hci_chan for logical link */ - - if (hchan) { - if (hchan->state == BT_CONNECTED) { - /* Logical link is ready to go */ - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); - - l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); - } else { - /* Wait for logical link to be ready */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - } - } else { - /* Logical link not available */ - l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED); - } -} - -static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result) -{ - if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { - u8 rsp_result; - if (result == -EINVAL) - rsp_result = L2CAP_MR_BAD_ID; - else - rsp_result = L2CAP_MR_NOT_ALLOWED; - - l2cap_send_move_chan_rsp(chan, rsp_result); - } - - chan->move_role = L2CAP_MOVE_ROLE_NONE; - chan->move_state = L2CAP_MOVE_STABLE; - - /* Restart data transmission */ - l2cap_ertm_send(chan); -} - -/* Invoke with locked chan */ -void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) -{ - u8 local_amp_id = chan->local_amp_id; - u8 remote_amp_id = chan->remote_amp_id; - - BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", - chan, result, local_amp_id, remote_amp_id); - - if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { - l2cap_chan_unlock(chan); - return; - } - - if (chan->state != BT_CONNECTED) { - l2cap_do_create(chan, result, local_amp_id, remote_amp_id); - } else if (result != L2CAP_MR_SUCCESS) { - l2cap_do_move_cancel(chan, result); - } else { - switch (chan->move_role) { - case L2CAP_MOVE_ROLE_INITIATOR: - l2cap_do_move_initiate(chan, local_amp_id, - remote_amp_id); - break; - case L2CAP_MOVE_ROLE_RESPONDER: - l2cap_do_move_respond(chan, result); - break; - default: - l2cap_do_move_cancel(chan, result); - break; - } - } -} - -static inline int l2cap_move_channel_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) -{ - struct l2cap_move_chan_req *req = data; - struct l2cap_move_chan_rsp rsp; - struct l2cap_chan *chan; - u16 icid = 0; - u16 result = L2CAP_MR_NOT_ALLOWED; - - if (cmd_len != sizeof(*req)) - return -EPROTO; - - icid = le16_to_cpu(req->icid); - - BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); - - if (!enable_hs) - return -EINVAL; - - chan = l2cap_get_chan_by_dcid(conn, icid); - if (!chan) { - rsp.icid = cpu_to_le16(icid); - rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED); - l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP, - sizeof(rsp), &rsp); - return 0; - } - - chan->ident = cmd->ident; - - if (chan->scid < L2CAP_CID_DYN_START || - chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY || - (chan->mode != L2CAP_MODE_ERTM && - chan->mode != L2CAP_MODE_STREAMING)) { - result = L2CAP_MR_NOT_ALLOWED; - goto send_move_response; - } - - if (chan->local_amp_id == req->dest_amp_id) { - result = L2CAP_MR_SAME_ID; - goto send_move_response; - } - - if (req->dest_amp_id) { - struct hci_dev *hdev; - hdev = hci_dev_get(req->dest_amp_id); - if (!hdev || hdev->dev_type != HCI_AMP || - !test_bit(HCI_UP, &hdev->flags)) { - if (hdev) - hci_dev_put(hdev); - - result = L2CAP_MR_BAD_ID; - goto send_move_response; - } - hci_dev_put(hdev); - } - - /* Detect a move collision. Only send a collision response - * if this side has "lost", otherwise proceed with the move. - * The winner has the larger bd_addr. - */ - if ((__chan_is_moving(chan) || - chan->move_role != L2CAP_MOVE_ROLE_NONE) && - bacmp(conn->src, conn->dst) > 0) { - result = L2CAP_MR_COLLISION; - goto send_move_response; - } - - chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; - l2cap_move_setup(chan); - chan->move_id = req->dest_amp_id; - icid = chan->dcid; - - if (!req->dest_amp_id) { - /* Moving to BR/EDR */ - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - result = L2CAP_MR_PEND; - } else { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - result = L2CAP_MR_SUCCESS; - } - } else { - chan->move_state = L2CAP_MOVE_WAIT_PREPARE; - /* Placeholder - uncomment when amp functions are available */ - /*amp_accept_physical(chan, req->dest_amp_id);*/ - result = L2CAP_MR_PEND; - } - -send_move_response: - l2cap_send_move_chan_rsp(chan, result); - - l2cap_chan_unlock(chan); - - return 0; -} - -static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result) -{ - struct l2cap_chan *chan; - struct hci_chan *hchan = NULL; - - chan = l2cap_get_chan_by_scid(conn, icid); - if (!chan) { - l2cap_send_move_chan_cfm_icid(conn, icid); - return; - } - - __clear_chan_timer(chan); - if (result == L2CAP_MR_PEND) - __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT); - - switch (chan->move_state) { - case L2CAP_MOVE_WAIT_LOGICAL_COMP: - /* Move confirm will be sent when logical link - * is complete. - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - break; - case L2CAP_MOVE_WAIT_RSP_SUCCESS: - if (result == L2CAP_MR_PEND) { - break; - } else if (test_bit(CONN_LOCAL_BUSY, - &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - } else { - /* Logical link is up or moving to BR/EDR, - * proceed with move - */ - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } - break; - case L2CAP_MOVE_WAIT_RSP: - /* Moving to AMP */ - if (result == L2CAP_MR_SUCCESS) { - /* Remote is ready, send confirm immediately - * after logical link is ready - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - } else { - /* Both logical link and move success - * are required to confirm - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP; - } - - /* Placeholder - get hci_chan for logical link */ - if (!hchan) { - /* Logical link not available */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - break; - } - - /* If the logical link is not yet connected, do not - * send confirmation. - */ - if (hchan->state != BT_CONNECTED) - break; - - /* Logical link is already ready to go */ - - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - - if (result == L2CAP_MR_SUCCESS) { - /* Can confirm now */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } else { - /* Now only need move success - * to confirm - */ - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - } - - l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); - break; - default: - /* Any other amp move state means the move failed. */ - chan->move_id = chan->local_amp_id; - l2cap_move_done(chan); - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - } - - l2cap_chan_unlock(chan); -} - -static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, - u16 result) -{ - struct l2cap_chan *chan; - - chan = l2cap_get_chan_by_ident(conn, ident); - if (!chan) { - /* Could not locate channel, icid is best guess */ - l2cap_send_move_chan_cfm_icid(conn, icid); - return; - } - - __clear_chan_timer(chan); - - if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { - if (result == L2CAP_MR_COLLISION) { - chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; - } else { - /* Cleanup - cancel move */ - chan->move_id = chan->local_amp_id; - l2cap_move_done(chan); - } - } - - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - - l2cap_chan_unlock(chan); -} - -static int l2cap_move_channel_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) -{ - struct l2cap_move_chan_rsp *rsp = data; - u16 icid, result; - - if (cmd_len != sizeof(*rsp)) - return -EPROTO; - - icid = le16_to_cpu(rsp->icid); - result = le16_to_cpu(rsp->result); - - BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - - if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND) - l2cap_move_continue(conn, icid, result); - else - l2cap_move_fail(conn, cmd->ident, icid, result); - - return 0; -} - -static int l2cap_move_channel_confirm(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) +static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { struct l2cap_move_chan_cfm *cfm = data; - struct l2cap_chan *chan; u16 icid, result; if (cmd_len != sizeof(*cfm)) @@ -4911,29 +4103,8 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn, BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - chan = l2cap_get_chan_by_dcid(conn, icid); - if (!chan) { - /* Spec requires a response even if the icid was not found */ - l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); - return 0; - } - - if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) { - if (result == L2CAP_MC_CONFIRMED) { - chan->local_amp_id = chan->move_id; - if (!chan->local_amp_id) - __release_logical_link(chan); - } else { - chan->move_id = chan->local_amp_id; - } - - l2cap_move_done(chan); - } - l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); - l2cap_chan_unlock(chan); - return 0; } @@ -4942,7 +4113,6 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, u16 cmd_len, void *data) { struct l2cap_move_chan_cfm_rsp *rsp = data; - struct l2cap_chan *chan; u16 icid; if (cmd_len != sizeof(*rsp)) @@ -4952,28 +4122,11 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, BT_DBG("icid 0x%4.4x", icid); - chan = l2cap_get_chan_by_scid(conn, icid); - if (!chan) - return 0; - - __clear_chan_timer(chan); - - if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) { - chan->local_amp_id = chan->move_id; - - if (!chan->local_amp_id && chan->hs_hchan) - __release_logical_link(chan); - - l2cap_move_done(chan); - } - - l2cap_chan_unlock(chan); - return 0; } static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, - u16 to_multiplier) + u16 to_multiplier) { u16 max_latency; @@ -4994,8 +4147,7 @@ static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, } static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u8 *data) + struct l2cap_cmd_hdr *cmd, u8 *data) { struct hci_conn *hcon = conn->hcon; struct l2cap_conn_param_update_req *req; @@ -5017,7 +4169,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, to_multiplier = __le16_to_cpu(req->to_multiplier); BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x", - min, max, latency, to_multiplier); + min, max, latency, to_multiplier); memset(&rsp, 0, sizeof(rsp)); @@ -5028,7 +4180,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, - sizeof(rsp), &rsp); + sizeof(rsp), &rsp); if (!err) hci_le_conn_update(hcon, min, max, latency, to_multiplier); @@ -5037,8 +4189,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, } static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u16 cmd_len, - u8 *data) + struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { int err = 0; @@ -5052,8 +4203,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, break; case L2CAP_CONN_RSP: - case L2CAP_CREATE_CHAN_RSP: - err = l2cap_connect_create_rsp(conn, cmd, data); + err = l2cap_connect_rsp(conn, cmd, data); break; case L2CAP_CONF_REQ: @@ -5091,6 +4241,10 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, err = l2cap_create_channel_req(conn, cmd, cmd_len, data); break; + case L2CAP_CREATE_CHAN_RSP: + err = l2cap_create_channel_rsp(conn, cmd, data); + break; + case L2CAP_MOVE_CHAN_REQ: err = l2cap_move_channel_req(conn, cmd, cmd_len, data); break; @@ -5117,7 +4271,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, } static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, u8 *data) + struct l2cap_cmd_hdr *cmd, u8 *data) { switch (cmd->code) { case L2CAP_COMMAND_REJ: @@ -5136,7 +4290,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, } static inline void l2cap_sig_channel(struct l2cap_conn *conn, - struct sk_buff *skb) + struct sk_buff *skb) { u8 *data = skb->data; int len = skb->len; @@ -5153,8 +4307,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, cmd_len = le16_to_cpu(cmd.len); - BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, - cmd.ident); + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident); if (cmd_len > len || !cmd.ident) { BT_DBG("corrupted command"); @@ -5173,8 +4326,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, /* FIXME: Map err to a valid reason */ rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); - l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, - sizeof(rej), &rej); + l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } data += cmd_len; @@ -5239,8 +4391,8 @@ static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) } } -static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag, - struct sk_buff **last_frag) +static void append_skb_frag(struct sk_buff *skb, + struct sk_buff *new_frag, struct sk_buff **last_frag) { /* skb->len reflects data in skb as well as all fragments * skb->data_len reflects only data in fragments @@ -5340,12 +4492,6 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, return err; } -static int l2cap_resegment(struct l2cap_chan *chan) -{ - /* Placeholder */ - return 0; -} - void l2cap_chan_busy(struct l2cap_chan *chan, int busy) { u8 event; @@ -5495,7 +4641,7 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { if (__seq_offset(chan, txseq, chan->last_acked_seq) >= - chan->tx_win) { + chan->tx_win) { /* See notes below regarding "double poll" and * invalid packets. */ @@ -5536,7 +4682,8 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) } if (__seq_offset(chan, txseq, chan->last_acked_seq) < - __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) { + __seq_offset(chan, chan->expected_tx_seq, + chan->last_acked_seq)){ BT_DBG("Duplicate - expected_tx_seq later than txseq"); return L2CAP_TXSEQ_DUPLICATE; } @@ -5661,8 +4808,8 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, if (control->final) { clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) && - !__chan_is_moving(chan)) { + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { control->final = 0; l2cap_retransmit_all(chan, control); } @@ -5851,96 +4998,6 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, return err; } -static int l2cap_finish_move(struct l2cap_chan *chan) -{ - BT_DBG("chan %p", chan); - - chan->rx_state = L2CAP_RX_STATE_RECV; - - if (chan->hs_hcon) - chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; - else - chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; - - return l2cap_resegment(chan); -} - -static int l2cap_rx_state_wait_p(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err; - - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, - event); - - if (!control->poll) - return -EPROTO; - - l2cap_process_reqseq(chan, control->reqseq); - - if (!skb_queue_empty(&chan->tx_q)) - chan->tx_send_head = skb_peek(&chan->tx_q); - else - chan->tx_send_head = NULL; - - /* Rewind next_tx_seq to the point expected - * by the receiver. - */ - chan->next_tx_seq = control->reqseq; - chan->unacked_frames = 0; - - err = l2cap_finish_move(chan); - if (err) - return err; - - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_send_i_or_rr_or_rnr(chan); - - if (event == L2CAP_EV_RECV_IFRAME) - return -EPROTO; - - return l2cap_rx_state_recv(chan, control, NULL, event); -} - -static int l2cap_rx_state_wait_f(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err; - - if (!control->final) - return -EPROTO; - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - chan->rx_state = L2CAP_RX_STATE_RECV; - l2cap_process_reqseq(chan, control->reqseq); - - if (!skb_queue_empty(&chan->tx_q)) - chan->tx_send_head = skb_peek(&chan->tx_q); - else - chan->tx_send_head = NULL; - - /* Rewind next_tx_seq to the point expected - * by the receiver. - */ - chan->next_tx_seq = control->reqseq; - chan->unacked_frames = 0; - - if (chan->hs_hcon) - chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; - else - chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; - - err = l2cap_resegment(chan); - - if (!err) - err = l2cap_rx_state_recv(chan, control, skb, event); - - return err; -} - static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq) { /* Make sure reqseq is for a packet that has been sent but not acked */ @@ -5967,12 +5024,6 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, err = l2cap_rx_state_srej_sent(chan, control, skb, event); break; - case L2CAP_RX_STATE_WAIT_P: - err = l2cap_rx_state_wait_p(chan, control, skb, event); - break; - case L2CAP_RX_STATE_WAIT_F: - err = l2cap_rx_state_wait_f(chan, control, skb, event); - break; default: /* shut it down */ break; @@ -6092,7 +5143,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) control->super); if (len != 0) { - BT_ERR("Trailing bytes: %d in sframe", len); + BT_ERR("%d", len); l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; } @@ -6272,7 +5323,7 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) int exact = 0, lm1 = 0, lm2 = 0; struct l2cap_chan *c; - BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); /* Find listening sockets and check their link_mode */ read_lock(&chan_list_lock); @@ -6302,15 +5353,15 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_conn *conn; - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); if (!status) { conn = l2cap_conn_add(hcon, status); if (conn) l2cap_conn_ready(conn); - } else { + } else l2cap_conn_del(hcon, bt_to_errno(status)); - } + } int l2cap_disconn_ind(struct hci_conn *hcon) @@ -6386,13 +5437,13 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) continue; } - if (!__l2cap_no_conn_pending(chan)) { + if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { l2cap_chan_unlock(chan); continue; } if (!status && (chan->state == BT_CONNECTED || - chan->state == BT_CONFIG)) { + chan->state == BT_CONFIG)) { struct sock *sk = chan->sk; clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); @@ -6405,7 +5456,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (chan->state == BT_CONNECT) { if (!status) { - l2cap_start_connection(chan); + l2cap_send_conn_req(chan); } else { __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); } @@ -6419,9 +5470,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) if (!status) { if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { + struct sock *parent = bt_sk(sk)->parent; res = L2CAP_CR_PEND; stat = L2CAP_CS_AUTHOR_PEND; - chan->ops->defer(chan); + if (parent) + parent->sk_data_ready(parent, 0); } else { __l2cap_state_change(chan, BT_CONFIG); res = L2CAP_CR_SUCCESS; @@ -6441,7 +5494,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) rsp.result = cpu_to_le16(res); rsp.status = cpu_to_le16(stat); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, - sizeof(rsp), &rsp); + sizeof(rsp), &rsp); if (!test_bit(CONF_REQ_SENT, &chan->conf_state) && res == L2CAP_CR_SUCCESS) { @@ -6466,12 +5519,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) { struct l2cap_conn *conn = hcon->l2cap_data; - struct l2cap_hdr *hdr; - int len; - - /* For AMP controller do not create l2cap conn */ - if (!conn && hcon->hdev->dev_type != HCI_BREDR) - goto drop; if (!conn) conn = l2cap_conn_add(hcon, 0); @@ -6481,10 +5528,10 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); - switch (flags) { - case ACL_START: - case ACL_START_NO_FLUSH: - case ACL_COMPLETE: + if (!(flags & ACL_CONT)) { + struct l2cap_hdr *hdr; + int len; + if (conn->rx_len) { BT_ERR("Unexpected start frame (len %d)", skb->len); kfree_skb(conn->rx_skb); @@ -6513,22 +5560,20 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (skb->len > len) { BT_ERR("Frame is too long (len %d, expected len %d)", - skb->len, len); + skb->len, len); l2cap_conn_unreliable(conn, ECOMM); goto drop; } /* Allocate skb for the complete frame (with header) */ - conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL); + conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); if (!conn->rx_skb) goto drop; skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), - skb->len); + skb->len); conn->rx_len = len - skb->len; - break; - - case ACL_CONT: + } else { BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len); if (!conn->rx_len) { @@ -6539,7 +5584,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (skb->len > conn->rx_len) { BT_ERR("Fragment is too long (len %d, expected %d)", - skb->len, conn->rx_len); + skb->len, conn->rx_len); kfree_skb(conn->rx_skb); conn->rx_skb = NULL; conn->rx_len = 0; @@ -6548,7 +5593,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) } skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), - skb->len); + skb->len); conn->rx_len -= skb->len; if (!conn->rx_len) { @@ -6556,7 +5601,6 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) l2cap_recv_frame(conn, conn->rx_skb); conn->rx_skb = NULL; } - break; } drop: @@ -6573,11 +5617,12 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) list_for_each_entry(c, &chan_list, global_l) { struct sock *sk = c->sk; - seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", - &bt_sk(sk)->src, &bt_sk(sk)->dst, - c->state, __le16_to_cpu(c->psm), - c->scid, c->dcid, c->imtu, c->omtu, - c->sec_level, c->mode); + seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), + c->state, __le16_to_cpu(c->psm), + c->scid, c->dcid, c->imtu, c->omtu, + c->sec_level, c->mode); } read_unlock(&chan_list_lock); @@ -6608,8 +5653,8 @@ int __init l2cap_init(void) return err; if (bt_debugfs) { - l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, - NULL, &l2cap_debugfs_fops); + l2cap_debugfs = debugfs_create_file("l2cap", 0444, + bt_debugfs, NULL, &l2cap_debugfs_fops); if (!l2cap_debugfs) BT_ERR("Failed to create L2CAP debug file"); } diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index 1bcfb8422fdc..083f2bf065d4 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -40,8 +40,7 @@ static struct bt_sock_list l2cap_sk_list = { static const struct proto_ops l2cap_sock_ops; static void l2cap_sock_init(struct sock *sk, struct sock *parent); -static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, - int proto, gfp_t prio); +static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) { @@ -107,8 +106,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) return err; } -static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, - int alen, int flags) +static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -136,7 +134,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, lock_sock(sk); err = bt_sock_wait_state(sk, BT_CONNECTED, - sock_sndtimeo(sk, flags & O_NONBLOCK)); + sock_sndtimeo(sk, flags & O_NONBLOCK)); release_sock(sk); @@ -187,8 +185,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) return err; } -static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, - int flags) +static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) { DECLARE_WAITQUEUE(wait, current); struct sock *sk = sock->sk, *nsk; @@ -244,8 +241,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, return err; } -static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, - int *len, int peer) +static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) { struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; struct sock *sk = sock->sk; @@ -270,8 +266,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, return 0; } -static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, - char __user *optval, int __user *optlen) +static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -314,7 +309,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, break; case BT_SECURITY_HIGH: opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | - L2CAP_LM_SECURE; + L2CAP_LM_SECURE; break; default: opt = 0; @@ -358,8 +353,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, return err; } -static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) +static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -383,20 +377,19 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, switch (optname) { case BT_SECURITY: if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && - chan->chan_type != L2CAP_CHAN_RAW) { + chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; break; } memset(&sec, 0, sizeof(sec)); - if (chan->conn) { + if (chan->conn) sec.level = chan->conn->hcon->sec_level; - - if (sk->sk_state == BT_CONNECTED) - sec.key_size = chan->conn->hcon->enc_key_size; - } else { + else sec.level = chan->sec_level; - } + + if (sk->sk_state == BT_CONNECTED) + sec.key_size = chan->conn->hcon->enc_key_size; len = min_t(unsigned int, len, sizeof(sec)); if (copy_to_user(optval, (char *) &sec, len)) @@ -418,14 +411,14 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, case BT_FLUSHABLE: if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), - (u32 __user *) optval)) + (u32 __user *) optval)) err = -EFAULT; break; case BT_POWER: if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM - && sk->sk_type != SOCK_RAW) { + && sk->sk_type != SOCK_RAW) { err = -EINVAL; break; } @@ -473,8 +466,7 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) return true; } -static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, - char __user *optval, unsigned int optlen) +static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -537,7 +529,6 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, chan->fcs = opts.fcs; chan->max_tx = opts.max_tx; chan->tx_win = opts.txwin_size; - chan->flush_to = opts.flush_to; break; case L2CAP_LM: @@ -573,8 +564,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, return err; } -static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, unsigned int optlen) +static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -597,7 +587,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, switch (optname) { case BT_SECURITY: if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && - chan->chan_type != L2CAP_CHAN_RAW) { + chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; break; } @@ -611,7 +601,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, } if (sec.level < BT_SECURITY_LOW || - sec.level > BT_SECURITY_HIGH) { + sec.level > BT_SECURITY_HIGH) { err = -EINVAL; break; } @@ -637,7 +627,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, /* or for ACL link */ } else if ((sk->sk_state == BT_CONNECT2 && - test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) || + test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) || sk->sk_state == BT_CONNECTED) { if (!l2cap_chan_check_security(chan)) set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); @@ -694,7 +684,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, case BT_POWER: if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && - chan->chan_type != L2CAP_CHAN_RAW) { + chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; break; } @@ -730,17 +720,12 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, } if (chan->mode != L2CAP_MODE_ERTM && - chan->mode != L2CAP_MODE_STREAMING) { + chan->mode != L2CAP_MODE_STREAMING) { err = -EOPNOTSUPP; break; } chan->chan_policy = (u8) opt; - - if (sk->sk_state == BT_CONNECTED && - chan->move_role == L2CAP_MOVE_ROLE_NONE) - l2cap_move_start(chan); - break; default: @@ -752,8 +737,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, return err; } -static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) +static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; struct l2cap_chan *chan = l2cap_pi(sk)->chan; @@ -778,8 +762,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, return err; } -static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) +static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) { struct sock *sk = sock->sk; struct l2cap_pinfo *pi = l2cap_pi(sk); @@ -883,7 +866,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) err = bt_sock_wait_state(sk, BT_CLOSED, - sk->sk_lingertime); + sk->sk_lingertime); } if (!err && sk->sk_err) @@ -947,7 +930,7 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) } sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, - GFP_ATOMIC); + GFP_ATOMIC); if (!sk) return NULL; @@ -955,8 +938,6 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) l2cap_sock_init(sk, parent); - bt_accept_enqueue(parent, sk); - return l2cap_pi(sk)->chan; } @@ -1087,15 +1068,6 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) release_sock(sk); } -static void l2cap_sock_defer_cb(struct l2cap_chan *chan) -{ - struct sock *sk = chan->data; - struct sock *parent = bt_sk(sk)->parent; - - if (parent) - parent->sk_data_ready(parent, 0); -} - static struct l2cap_ops l2cap_chan_ops = { .name = "L2CAP Socket Interface", .new_connection = l2cap_sock_new_connection_cb, @@ -1104,7 +1076,6 @@ static struct l2cap_ops l2cap_chan_ops = { .teardown = l2cap_sock_teardown_cb, .state_change = l2cap_sock_state_change_cb, .ready = l2cap_sock_ready_cb, - .defer = l2cap_sock_defer_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, }; @@ -1112,8 +1083,7 @@ static void l2cap_sock_destruct(struct sock *sk) { BT_DBG("sk %p", sk); - if (l2cap_pi(sk)->chan) - l2cap_chan_put(l2cap_pi(sk)->chan); + l2cap_chan_put(l2cap_pi(sk)->chan); if (l2cap_pi(sk)->rx_busy_skb) { kfree_skb(l2cap_pi(sk)->rx_busy_skb); l2cap_pi(sk)->rx_busy_skb = NULL; @@ -1189,8 +1159,7 @@ static struct proto l2cap_proto = { .obj_size = sizeof(struct l2cap_pinfo) }; -static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, - int proto, gfp_t prio) +static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) { struct sock *sk; struct l2cap_chan *chan; @@ -1235,7 +1204,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, sock->state = SS_UNCONNECTED; if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && - sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) + sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) @@ -1292,8 +1261,7 @@ int __init l2cap_init_sockets(void) goto error; } - err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, - NULL); + err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, NULL); if (err < 0) { BT_ERR("Failed to create L2CAP proc file"); bt_sock_unregister(BTPROTO_L2CAP); diff --git a/trunk/net/bluetooth/lib.c b/trunk/net/bluetooth/lib.c index b3fbc73516c4..e1c97527e16c 100644 --- a/trunk/net/bluetooth/lib.c +++ b/trunk/net/bluetooth/lib.c @@ -41,6 +41,20 @@ void baswap(bdaddr_t *dst, bdaddr_t *src) } EXPORT_SYMBOL(baswap); +char *batostr(bdaddr_t *ba) +{ + static char str[2][18]; + static int i = 1; + + i ^= 1; + sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", + ba->b[5], ba->b[4], ba->b[3], + ba->b[2], ba->b[1], ba->b[0]); + + return str[i]; +} +EXPORT_SYMBOL(batostr); + /* Bluetooth error codes to Unix errno mapping */ int bt_to_errno(__u16 code) { diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index 142764aec2af..aa2ea0a8142c 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -222,7 +222,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev)); @@ -253,7 +253,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int err; + int i, err; BT_DBG("sock %p", sk); @@ -347,7 +347,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - count = 0; + rp->num_controllers = cpu_to_le16(count); + + i = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -355,13 +357,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[count++] = cpu_to_le16(d->id); + rp->index[i++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } - rp->num_controllers = cpu_to_le16(count); - rp_len = sizeof(*rp) + (2 * count); - read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, @@ -377,15 +376,15 @@ static u32 get_supported_settings(struct hci_dev *hdev) u32 settings = 0; settings |= MGMT_SETTING_POWERED; + settings |= MGMT_SETTING_CONNECTABLE; + settings |= MGMT_SETTING_FAST_CONNECTABLE; + settings |= MGMT_SETTING_DISCOVERABLE; settings |= MGMT_SETTING_PAIRABLE; if (lmp_ssp_capable(hdev)) settings |= MGMT_SETTING_SSP; if (lmp_bredr_capable(hdev)) { - settings |= MGMT_SETTING_CONNECTABLE; - settings |= MGMT_SETTING_FAST_CONNECTABLE; - settings |= MGMT_SETTING_DISCOVERABLE; settings |= MGMT_SETTING_BREDR; settings |= MGMT_SETTING_LINK_SECURITY; } @@ -485,7 +484,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) ptr += (name_len + 2); } - if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) { + if (hdev->inq_tx_power) { ptr[0] = 2; ptr[1] = EIR_TX_POWER; ptr[2] = (u8) hdev->inq_tx_power; @@ -566,7 +565,7 @@ static int update_eir(struct hci_dev *hdev) if (!hdev_is_powered(hdev)) return 0; - if (!lmp_ext_inq_capable(hdev)) + if (!(hdev->features[6] & LMP_EXT_INQ)) return 0; if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) @@ -833,7 +832,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, if (hdev) hdr->index = cpu_to_le16(hdev->id); else - hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE); + hdr->index = cpu_to_le16(MGMT_INDEX_NONE); hdr->len = cpu_to_le16(data_len); if (data) @@ -868,10 +867,6 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_NOT_SUPPORTED); - timeout = __le16_to_cpu(cp->timeout); if (!cp->val && timeout > 0) return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, @@ -967,10 +962,6 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, - MGMT_STATUS_NOT_SUPPORTED); - hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { @@ -1069,10 +1060,6 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, - MGMT_STATUS_NOT_SUPPORTED); - hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { @@ -1226,7 +1213,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) } val = !!cp->val; - enabled = !!lmp_host_le_capable(hdev); + enabled = !!(hdev->host_features[0] & LMP_HOST_LE); if (!hdev_is_powered(hdev) || val == enabled) { bool changed = false; @@ -1262,7 +1249,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) if (val) { hci_cp.le = val; - hci_cp.simul = !!lmp_le_br_capable(hdev); + hci_cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); } err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), @@ -1379,7 +1366,6 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); - kfree(match); found++; } @@ -2608,10 +2594,6 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_NOT_SUPPORTED); - if (!hdev_is_powered(hdev)) return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, MGMT_STATUS_NOT_POWERED); @@ -2889,21 +2871,6 @@ static void settings_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_free(cmd); } -static int set_bredr_scan(struct hci_dev *hdev) -{ - u8 scan = 0; - - if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) - scan |= SCAN_PAGE; - if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) - scan |= SCAN_INQUIRY; - - if (!scan) - return 0; - - return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); -} - int mgmt_powered(struct hci_dev *hdev, u8 powered) { struct cmd_lookup match = { NULL, hdev }; @@ -2915,8 +2882,17 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); if (powered) { - if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - !lmp_host_ssp_capable(hdev)) { + u8 scan = 0; + + if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) + scan |= SCAN_PAGE; + if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) + scan |= SCAN_INQUIRY; + + if (scan) + hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + + if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 ssp = 1; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); @@ -2926,24 +2902,15 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) struct hci_cp_write_le_host_supported cp; cp.le = 1; - cp.simul = !!lmp_le_br_capable(hdev); - - /* Check first if we already have the right - * host state (host features set) - */ - if (cp.le != !!lmp_host_le_capable(hdev) || - cp.simul != !!lmp_host_le_br_capable(hdev)) - hci_send_cmd(hdev, - HCI_OP_WRITE_LE_HOST_SUPPORTED, - sizeof(cp), &cp); - } + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); - if (lmp_bredr_capable(hdev)) { - set_bredr_scan(hdev); - update_class(hdev); - update_name(hdev, hdev->dev_name); - update_eir(hdev); + hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, + sizeof(cp), &cp); } + + update_class(hdev); + update_name(hdev, hdev->dev_name); + update_eir(hdev); } else { u8 status = MGMT_STATUS_NOT_POWERED; mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); @@ -3158,9 +3125,6 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, struct pending_cmd *cmd; int err; - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, - hdev); - cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); if (!cmd) return -ENOENT; @@ -3173,6 +3137,8 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, mgmt_pending_remove(cmd); + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, + hdev); return err; } @@ -3392,7 +3358,7 @@ static int clear_eir(struct hci_dev *hdev) { struct hci_cp_write_eir cp; - if (!lmp_ext_inq_capable(hdev)) + if (!(hdev->features[6] & LMP_EXT_INQ)) return 0; memset(hdev->eir, 0, sizeof(hdev->eir)); @@ -3524,12 +3490,7 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), cmd ? cmd->sk : NULL); - /* EIR is taken care of separately when powering on the - * adapter so only update them here if this is a name change - * unrelated to power on. - */ - if (!test_bit(HCI_INIT, &hdev->flags)) - update_eir(hdev); + update_eir(hdev); failed: if (cmd) @@ -3624,9 +3585,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->rssi = rssi; if (cfm_name) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); if (!ssp) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); if (eir_len > 0) memcpy(ev->eir, eir, eir_len); diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index 201fdf737209..c75107ef8920 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -377,8 +377,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, int err = 0; u8 dlci; - BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", - d, d->state, src, dst, channel); + BT_DBG("dlc %p state %ld %s %s channel %d", + d, d->state, batostr(src), batostr(dst), channel); if (channel < 1 || channel > 30) return -EINVAL; @@ -676,7 +676,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, struct socket *sock; struct sock *sk; - BT_DBG("%pMR -> %pMR", src, dst); + BT_DBG("%s %s", batostr(src), batostr(dst)); *err = rfcomm_l2sock_create(&sock); if (*err < 0) @@ -709,7 +709,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bacpy(&addr.l2_bdaddr, dst); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = cpu_to_le16(RFCOMM_PSM); addr.l2_cid = 0; *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); if (*err == 0 || *err == -EINPROGRESS) @@ -1987,7 +1987,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) /* Bind socket */ bacpy(&addr.l2_bdaddr, ba); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = cpu_to_le16(RFCOMM_PSM); addr.l2_cid = 0; err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0) { @@ -2125,10 +2125,11 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) list_for_each_entry(d, &s->dlcs, list) { struct sock *sk = s->sock->sk; - seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n", - &bt_sk(sk)->src, &bt_sk(sk)->dst, - d->state, d->dlci, d->mtu, - d->rx_credits, d->tx_credits); + seq_printf(f, "%s %s %ld %d %d %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), + d->state, d->dlci, d->mtu, + d->rx_credits, d->tx_credits); } } diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 4ddef57d03a7..b3226f3658cf 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -334,7 +334,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); + BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr)); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -975,9 +975,10 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) read_lock(&rfcomm_sk_list.lock); sk_for_each(sk, node, &rfcomm_sk_list.head) { - seq_printf(f, "%pMR %pMR %d %d\n", - &bt_sk(sk)->src, &bt_sk(sk)->dst, - sk->sk_state, rfcomm_pi(sk)->channel); + seq_printf(f, "%s %s %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), + sk->sk_state, rfcomm_pi(sk)->channel); } read_unlock(&rfcomm_sk_list.lock); diff --git a/trunk/net/bluetooth/rfcomm/tty.c b/trunk/net/bluetooth/rfcomm/tty.c index bd6fd0f43d2b..ccc248791d50 100644 --- a/trunk/net/bluetooth/rfcomm/tty.c +++ b/trunk/net/bluetooth/rfcomm/tty.c @@ -166,7 +166,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) { struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); - return sprintf(buf, "%pMR\n", &dev->dst); + return sprintf(buf, "%s\n", batostr(&dev->dst)); } static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf) @@ -663,8 +663,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) if (!dev) return -ENODEV; - BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, - dev->channel, dev->port.count); + BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), + dev->channel, dev->port.count); spin_lock_irqsave(&dev->port.lock, flags); if (++dev->port.count > 1) { diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 450cdcd88e5c..dc42b917aaaf 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -172,7 +172,7 @@ static int sco_connect(struct sock *sk) struct hci_dev *hdev; int err, type; - BT_DBG("%pMR -> %pMR", src, dst); + BT_DBG("%s -> %s", batostr(src), batostr(dst)); hdev = hci_get_route(dst, src); if (!hdev) @@ -460,7 +460,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le struct sock *sk = sock->sk; int err = 0; - BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr); + BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr)); if (!addr || addr->sa_family != AF_BLUETOOTH) return -EINVAL; @@ -893,7 +893,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) struct hlist_node *node; int lm = 0; - BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); /* Find listening sockets */ read_lock(&sco_sk_list.lock); @@ -914,7 +914,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) void sco_connect_cfm(struct hci_conn *hcon, __u8 status) { - BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); if (!status) { struct sco_conn *conn; @@ -959,8 +959,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p) read_lock(&sco_sk_list.lock); sk_for_each(sk, node, &sco_sk_list.head) { - seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, - &bt_sk(sk)->dst, sk->sk_state); + seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), sk->sk_state); } read_unlock(&sco_sk_list.lock); diff --git a/trunk/net/bluetooth/smp.c b/trunk/net/bluetooth/smp.c index 68a9587c9694..8c225ef349cd 100644 --- a/trunk/net/bluetooth/smp.c +++ b/trunk/net/bluetooth/smp.c @@ -32,8 +32,6 @@ #define SMP_TIMEOUT msecs_to_jiffies(30000) -#define AUTH_REQ_MASK 0x07 - static inline void swap128(u8 src[16], u8 dst[16]) { int i; @@ -167,7 +165,7 @@ static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(sizeof(code) + dlen); - lh->cid = __constant_cpu_to_le16(L2CAP_CID_SMP); + lh->cid = cpu_to_le16(L2CAP_CID_SMP); memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); @@ -232,7 +230,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, req->max_key_size = SMP_MAX_ENC_KEY_SIZE; req->init_key_dist = 0; req->resp_key_dist = dist_keys; - req->auth_req = (authreq & AUTH_REQ_MASK); + req->auth_req = authreq; return; } @@ -241,7 +239,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; rsp->init_key_dist = 0; rsp->resp_key_dist = req->resp_key_dist & dist_keys; - rsp->auth_req = (authreq & AUTH_REQ_MASK); + rsp->auth_req = authreq; } static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) @@ -267,7 +265,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, HCI_ERROR_AUTH_FAILURE); + hcon->dst_type, reason); cancel_delayed_work_sync(&conn->security_timer); diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 017a8bacfb27..bcf02f608cbf 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -429,17 +429,6 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) -static struct attribute *wireless_attrs[] = { - NULL -}; - -static struct attribute_group wireless_group = { - .name = "wireless", - .attrs = wireless_attrs, -}; -#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1420,15 +1409,6 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) - if (net->ieee80211_ptr) - *groups++ = &wireless_group; -#if IS_ENABLED(CONFIG_WIRELESS_EXT) - else if (net->wireless_handlers) - *groups++ = &wireless_group; -#endif -#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); diff --git a/trunk/net/mac80211/Kconfig b/trunk/net/mac80211/Kconfig index b4ecf267a34b..63af25458fda 100644 --- a/trunk/net/mac80211/Kconfig +++ b/trunk/net/mac80211/Kconfig @@ -248,7 +248,7 @@ config MAC80211_MHWMP_DEBUG Do not select this option. config MAC80211_MESH_SYNC_DEBUG - bool "Verbose mesh synchronization debugging" + bool "Verbose mesh mesh synchronization debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH ---help--- diff --git a/trunk/net/mac80211/Makefile b/trunk/net/mac80211/Makefile index 4911202334d9..a7dd110faafa 100644 --- a/trunk/net/mac80211/Makefile +++ b/trunk/net/mac80211/Makefile @@ -8,7 +8,6 @@ mac80211-y := \ wpa.o \ scan.o offchannel.o \ ht.o agg-tx.o agg-rx.o \ - vht.o \ ibss.o \ iface.o \ rate.o \ diff --git a/trunk/net/mac80211/aes_cmac.c b/trunk/net/mac80211/aes_cmac.c index 537488cbf941..a04752e91023 100644 --- a/trunk/net/mac80211/aes_cmac.c +++ b/trunk/net/mac80211/aes_cmac.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -127,20 +126,3 @@ void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) { crypto_free_cipher(tfm); } - -void ieee80211_aes_cmac_calculate_k1_k2(struct ieee80211_key_conf *keyconf, - u8 *k1, u8 *k2) -{ - u8 l[AES_BLOCK_SIZE] = {}; - struct ieee80211_key *key = - container_of(keyconf, struct ieee80211_key, conf); - - crypto_cipher_encrypt_one(key->u.aes_cmac.tfm, l, l); - - memcpy(k1, l, AES_BLOCK_SIZE); - gf_mulx(k1); - - memcpy(k2, k1, AES_BLOCK_SIZE); - gf_mulx(k2); -} -EXPORT_SYMBOL(ieee80211_aes_cmac_calculate_k1_k2); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index c46d4ee1c298..05f3a313db88 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -372,11 +372,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx) { - enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata); - if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { struct ieee80211_supported_band *sband; - sband = sta->local->hw.wiphy->bands[band]; + sband = sta->local->hw.wiphy->bands[ + sta->local->oper_channel->band]; rate->legacy = sband->bitrates[idx].bitrate; } else rate->mcs = idx; @@ -533,8 +532,6 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, u64 *data) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *channel; struct sta_info *sta; struct ieee80211_local *local = sdata->local; struct station_info sinfo; @@ -610,26 +607,19 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, do_survey: i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; /* Get survey stats for current channel */ - survey.filled = 0; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (chanctx_conf) - channel = chanctx_conf->channel; - else - channel = NULL; - rcu_read_unlock(); - - if (channel) { - q = 0; - do { + q = 0; + while (true) { + survey.filled = 0; + if (drv_get_survey(local, q, &survey) != 0) { survey.filled = 0; - if (drv_get_survey(local, q, &survey) != 0) { - survey.filled = 0; - break; - } - q++; - } while (channel != survey.channel); + break; + } + + if (survey.channel && + (local->oper_channel->center_freq == + survey.channel->center_freq)) + break; + q++; } if (survey.filled) @@ -734,42 +724,47 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, return ret; } -static int ieee80211_set_monitor_channel(struct wiphy *wiphy, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) +static int ieee80211_set_channel(struct wiphy *wiphy, + struct net_device *netdev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) { struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata; - int ret = 0; + struct ieee80211_sub_if_data *sdata = NULL; + + if (netdev) + sdata = IEEE80211_DEV_TO_SUB_IF(netdev); + + switch (ieee80211_get_channel_mode(local, NULL)) { + case CHAN_MODE_HOPPING: + return -EBUSY; + case CHAN_MODE_FIXED: + if (local->oper_channel != chan || + (!sdata && local->_oper_channel_type != channel_type)) + return -EBUSY; + if (!sdata && local->_oper_channel_type == channel_type) + return 0; + break; + case CHAN_MODE_UNDEFINED: + break; + } - if (local->monitor_channel == chan && - local->monitor_channel_type == channel_type) - return 0; + if (!ieee80211_set_channel_type(local, sdata, channel_type)) + return -EBUSY; - mutex_lock(&local->iflist_mtx); - if (local->use_chanctx) { - sdata = rcu_dereference_protected( - local->monitor_sdata, - lockdep_is_held(&local->iflist_mtx)); - if (sdata) { - ieee80211_vif_release_channel(sdata); - ret = ieee80211_vif_use_channel( - sdata, chan, channel_type, - IEEE80211_CHANCTX_EXCLUSIVE); - } - } else if (local->open_count == local->monitors) { - local->_oper_channel = chan; - local->_oper_channel_type = channel_type; - ieee80211_hw_config(local, 0); - } + local->oper_channel = chan; - if (ret == 0) { - local->monitor_channel = chan; - local->monitor_channel_type = channel_type; - } - mutex_unlock(&local->iflist_mtx); + /* auto-detects changes */ + ieee80211_hw_config(local, 0); - return ret; + return 0; +} + +static int ieee80211_set_monitor_channel(struct wiphy *wiphy, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type) +{ + return ieee80211_set_channel(wiphy, NULL, chan, channel_type); } static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, @@ -884,13 +879,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, if (old) return -EALREADY; - /* TODO: make hostapd tell us what it wants */ - sdata->smps_mode = IEEE80211_SMPS_OFF; - sdata->needed_rx_chains = sdata->local->rx_chains; - - err = ieee80211_vif_use_channel(sdata, params->channel, - params->channel_type, - IEEE80211_CHANCTX_SHARED); + err = ieee80211_set_channel(wiphy, dev, params->channel, + params->channel_type); if (err) return err; @@ -922,15 +912,6 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, return err; changed |= err; - err = drv_start_ap(sdata->local, sdata); - if (err) { - old = rtnl_dereference(sdata->u.ap.beacon); - if (old) - kfree_rcu(old, rcu_head); - RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); - return err; - } - ieee80211_bss_info_change_notify(sdata, changed); netif_carrier_on(dev); @@ -962,39 +943,25 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_sub_if_data *vlan; - struct ieee80211_local *local = sdata->local; - struct beacon_data *old_beacon; - struct probe_resp *old_probe_resp; + struct ieee80211_sub_if_data *sdata, *vlan; + struct beacon_data *old; + + sdata = IEEE80211_DEV_TO_SUB_IF(dev); - old_beacon = rtnl_dereference(sdata->u.ap.beacon); - if (!old_beacon) + old = rtnl_dereference(sdata->u.ap.beacon); + if (!old) return -ENOENT; - old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); - /* turn off carrier for this interface and dependent VLANs */ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) netif_carrier_off(vlan->dev); netif_carrier_off(dev); - /* remove beacon and probe response */ RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); - RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); - kfree_rcu(old_beacon, rcu_head); - if (old_probe_resp) - kfree_rcu(old_probe_resp, rcu_head); - - sta_info_flush(local, sdata); - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - drv_stop_ap(sdata->local, sdata); + kfree_rcu(old, rcu_head); - /* free all potentially still buffered bcast frames */ - local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); - skb_queue_purge(&sdata->u.ap.ps.bc_buf); - - ieee80211_vif_release_channel(sdata); + sta_info_flush(sdata->local, sdata); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); return 0; } @@ -1052,10 +1019,9 @@ static int sta_apply_parameters(struct ieee80211_local *local, int i, j; struct ieee80211_supported_band *sband; struct ieee80211_sub_if_data *sdata = sta->sdata; - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); u32 mask, set; - sband = local->hw.wiphy->bands[band]; + sband = local->hw.wiphy->bands[local->oper_channel->band]; mask = params->sta_flags_mask; set = params->sta_flags_set; @@ -1170,7 +1136,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, rates |= BIT(j); } } - sta->sta.supp_rates[band] = rates; + sta->sta.supp_rates[local->oper_channel->band] = rates; } if (params->ht_capa) @@ -1178,11 +1144,6 @@ static int sta_apply_parameters(struct ieee80211_local *local, params->ht_capa, &sta->sta.ht_cap); - if (params->vht_capa) - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, - params->vht_capa, - &sta->sta.vht_cap); - if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) @@ -1703,13 +1664,8 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, if (err) return err; - /* can mesh use other SMPS modes? */ - sdata->smps_mode = IEEE80211_SMPS_OFF; - sdata->needed_rx_chains = sdata->local->rx_chains; - - err = ieee80211_vif_use_channel(sdata, setup->channel, - setup->channel_type, - IEEE80211_CHANCTX_SHARED); + err = ieee80211_set_channel(wiphy, dev, setup->channel, + setup->channel_type); if (err) return err; @@ -1723,7 +1679,6 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ieee80211_stop_mesh(sdata); - ieee80211_vif_release_channel(sdata); return 0; } @@ -1733,14 +1688,10 @@ static int ieee80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - enum ieee80211_band band; + struct ieee80211_sub_if_data *sdata; u32 changed = 0; - if (!rtnl_dereference(sdata->u.ap.beacon)) - return -ENOENT; - - band = ieee80211_get_sdata_band(sdata); + sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (params->use_cts_prot >= 0) { sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; @@ -1753,7 +1704,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, } if (!sdata->vif.bss_conf.use_short_slot && - band == IEEE80211_BAND_5GHZ) { + sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) { sdata->vif.bss_conf.use_short_slot = true; changed |= BSS_CHANGED_ERP_SLOT; } @@ -1767,7 +1718,9 @@ static int ieee80211_change_bss(struct wiphy *wiphy, if (params->basic_rates) { int i, j; u32 rates = 0; - struct ieee80211_supported_band *sband = wiphy->bands[band]; + struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_supported_band *sband = + wiphy->bands[local->oper_channel->band]; for (i = 0; i < params->basic_rates_len; i++) { int rate = (params->basic_rates[i] & 0x7f) * 5; @@ -1876,16 +1829,7 @@ static int ieee80211_scan(struct wiphy *wiphy, * beaconing hasn't been configured yet */ case NL80211_IFTYPE_AP: - /* - * If the scan has been forced (and the driver supports - * forcing), don't care about being beaconing already. - * This will create problems to the attached stations (e.g. all - * the frames sent while scanning on other channel will be - * lost) - */ - if (sdata->u.ap.beacon && - (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || - !(req->flags & NL80211_SCAN_FLAG_AP))) + if (sdata->u.ap.beacon) return -EOPNOTSUPP; break; default: @@ -1928,6 +1872,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_assoc_request *req) { + struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + switch (ieee80211_get_channel_mode(local, sdata)) { + case CHAN_MODE_HOPPING: + return -EBUSY; + case CHAN_MODE_FIXED: + if (local->oper_channel == req->bss->channel) + break; + return -EBUSY; + case CHAN_MODE_UNDEFINED: + break; + } + return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); } @@ -1946,22 +1904,30 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - return ieee80211_ibss_join(IEEE80211_DEV_TO_SUB_IF(dev), params); -} + struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -{ - return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); + switch (ieee80211_get_channel_mode(local, sdata)) { + case CHAN_MODE_HOPPING: + return -EBUSY; + case CHAN_MODE_FIXED: + if (!params->channel_fixed) + return -EBUSY; + if (local->oper_channel == params->channel) + break; + return -EBUSY; + case CHAN_MODE_UNDEFINED: + break; + } + + return ieee80211_ibss_join(sdata, params); } -static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, - int rate[IEEE80211_NUM_BANDS]) +static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - memcpy(sdata->vif.bss_conf.mcast_rate, rate, sizeof(rate)); - - return 0; + return ieee80211_ibss_leave(sdata); } static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) @@ -2002,65 +1968,41 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) } static int ieee80211_set_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm) { struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata; - - if (wdev) { - sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - - switch (type) { - case NL80211_TX_POWER_AUTOMATIC: - sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL; - break; - case NL80211_TX_POWER_LIMITED: - case NL80211_TX_POWER_FIXED: - if (mbm < 0 || (mbm % 100)) - return -EOPNOTSUPP; - sdata->user_power_level = MBM_TO_DBM(mbm); - break; - } - - ieee80211_recalc_txpower(sdata); - - return 0; - } + struct ieee80211_channel *chan = local->oper_channel; + u32 changes = 0; switch (type) { case NL80211_TX_POWER_AUTOMATIC: - local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; + local->user_power_level = -1; break; case NL80211_TX_POWER_LIMITED: + if (mbm < 0 || (mbm % 100)) + return -EOPNOTSUPP; + local->user_power_level = MBM_TO_DBM(mbm); + break; case NL80211_TX_POWER_FIXED: if (mbm < 0 || (mbm % 100)) return -EOPNOTSUPP; + /* TODO: move to cfg80211 when it knows the channel */ + if (MBM_TO_DBM(mbm) > chan->max_power) + return -EINVAL; local->user_power_level = MBM_TO_DBM(mbm); break; } - mutex_lock(&local->iflist_mtx); - list_for_each_entry(sdata, &local->interfaces, list) - sdata->user_power_level = local->user_power_level; - list_for_each_entry(sdata, &local->interfaces, list) - ieee80211_recalc_txpower(sdata); - mutex_unlock(&local->iflist_mtx); + ieee80211_hw_config(local, changes); return 0; } -static int ieee80211_get_tx_power(struct wiphy *wiphy, - struct wireless_dev *wdev, - int *dbm) +static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) { struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - if (!local->use_chanctx) - *dbm = local->hw.conf.power_level; - else - *dbm = sdata->vif.bss_conf.txpower; + *dbm = local->hw.conf.power_level; return 0; } @@ -2125,12 +2067,13 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, /* * If not associated, or current association is not an HT - * association, there's no need to do anything, just store - * the new value until we associate. + * association, there's no need to send an action frame. */ if (!sdata->u.mgd.associated || - sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) + sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { + ieee80211_recalc_smps(sdata->local); return 0; + } ap = sdata->u.mgd.associated->bssid; @@ -2246,9 +2189,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, lockdep_assert_held(&local->mtx); - if (local->use_chanctx && !local->ops->remain_on_channel) - return -EOPNOTSUPP; - roc = kzalloc(sizeof(*roc), GFP_KERNEL); if (!roc) return -ENOMEM; @@ -2392,22 +2332,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, list_add_tail(&roc->list, &local->roc_list); /* - * cookie is either the roc cookie (for normal roc) + * cookie is either the roc (for normal roc) * or the SKB (for mgmt TX) */ - if (!txskb) { - /* local->mtx protects this */ - local->roc_cookie_counter++; - roc->cookie = local->roc_cookie_counter; - /* wow, you wrapped 64 bits ... more likely a bug */ - if (WARN_ON(roc->cookie == 0)) { - roc->cookie = 1; - local->roc_cookie_counter++; - } - *cookie = roc->cookie; - } else { + if (txskb) *cookie = (unsigned long)txskb; - } + else + *cookie = (unsigned long)roc; return 0; } @@ -2442,7 +2373,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, struct ieee80211_roc_work *dep, *tmp2; list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { - if (!mgmt_tx && dep->cookie != cookie) + if (!mgmt_tx && (unsigned long)dep != cookie) continue; else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) continue; @@ -2454,7 +2385,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, return 0; } - if (!mgmt_tx && roc->cookie != cookie) + if (!mgmt_tx && (unsigned long)roc != cookie) continue; else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) continue; @@ -2584,20 +2515,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, /* Check if the operating channel is the requested channel */ if (!need_offchan) { - struct ieee80211_chanctx_conf *chanctx_conf; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - - if (chanctx_conf) { - need_offchan = chan != chanctx_conf->channel; - if (channel_type_valid && - channel_type != chanctx_conf->channel_type) - need_offchan = true; - } else { + need_offchan = chan != local->oper_channel; + if (channel_type_valid && + channel_type != local->_oper_channel_type) need_offchan = true; - } - rcu_read_unlock(); } if (need_offchan && !offchan) { @@ -2673,9 +2594,6 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; - if (!local->open_count) - break; - ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: @@ -2749,7 +2667,7 @@ static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) u16 capab; capab = 0; - if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) + if (local->oper_channel->band != IEEE80211_BAND_2GHZ) return capab; if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) @@ -2781,7 +2699,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, u16 status_code, struct sk_buff *skb) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); + struct ieee80211_local *local = sdata->local; struct ieee80211_tdls_data *tf; tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); @@ -2801,8 +2719,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_req.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, band); - ieee80211_add_ext_srates_ie(sdata, skb, false, band); + ieee80211_add_srates_ie(sdata, skb, false, + local->oper_channel->band); + ieee80211_add_ext_srates_ie(sdata, skb, false, + local->oper_channel->band); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_RESPONSE: @@ -2815,8 +2735,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, band); - ieee80211_add_ext_srates_ie(sdata, skb, false, band); + ieee80211_add_srates_ie(sdata, skb, false, + local->oper_channel->band); + ieee80211_add_ext_srates_ie(sdata, skb, false, + local->oper_channel->band); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_CONFIRM: @@ -2854,7 +2776,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, u16 status_code, struct sk_buff *skb) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); + struct ieee80211_local *local = sdata->local; struct ieee80211_mgmt *mgmt; mgmt = (void *)skb_put(skb, 24); @@ -2877,8 +2799,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, band); - ieee80211_add_ext_srates_ie(sdata, skb, false, band); + ieee80211_add_srates_ie(sdata, skb, false, + local->oper_channel->band); + ieee80211_add_ext_srates_ie(sdata, skb, false, + local->oper_channel->band); ieee80211_tdls_add_ext_capab(skb); break; default: @@ -2895,6 +2819,7 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; + struct ieee80211_tx_info *info; struct sk_buff *skb = NULL; bool send_direct; int ret; @@ -2920,6 +2845,7 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, if (!skb) return -ENOMEM; + info = IEEE80211_SKB_CB(skb); skb_reserve(skb, local->hw.extra_tx_headroom); switch (action_code) { @@ -3056,19 +2982,12 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, bool qos; struct ieee80211_tx_info *info; struct sta_info *sta; - struct ieee80211_chanctx_conf *chanctx_conf; - enum ieee80211_band band; rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return -EINVAL; - } - band = chanctx_conf->channel->band; sta = sta_info_get(sdata, peer); if (sta) { qos = test_sta_flag(sta, WLAN_STA_WME); + rcu_read_unlock(); } else { rcu_read_unlock(); return -ENOLINK; @@ -3086,10 +3005,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, } skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); - if (!skb) { - rcu_read_unlock(); + if (!skb) return -ENOMEM; - } skb->dev = dev; @@ -3114,9 +3031,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, nullfunc->qos_ctrl = cpu_to_le16(7); local_bh_disable(); - ieee80211_xmit(sdata, skb, band); + ieee80211_xmit(sdata, skb); local_bh_enable(); - rcu_read_unlock(); *cookie = (unsigned long) skb; return 0; @@ -3126,19 +3042,10 @@ static struct ieee80211_channel * ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, enum nl80211_channel_type *type) { - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan = NULL; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (chanctx_conf) { - *type = chanctx_conf->channel_type; - chan = chanctx_conf->channel; - } - rcu_read_unlock(); + struct ieee80211_local *local = wiphy_priv(wiphy); - return chan; + *type = local->_oper_channel_type; + return local->oper_channel; } #ifdef CONFIG_PM @@ -3193,7 +3100,6 @@ struct cfg80211_ops mac80211_config_ops = { .disassoc = ieee80211_disassoc, .join_ibss = ieee80211_join_ibss, .leave_ibss = ieee80211_leave_ibss, - .set_mcast_rate = ieee80211_set_mcast_rate, .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, diff --git a/trunk/net/mac80211/chan.c b/trunk/net/mac80211/chan.c index a2b06d40aebf..0bfc914ddd15 100644 --- a/trunk/net/mac80211/chan.c +++ b/trunk/net/mac80211/chan.c @@ -3,10 +3,108 @@ */ #include -#include #include #include "ieee80211_i.h" -#include "driver-ops.h" + +static enum ieee80211_chan_mode +__ieee80211_get_channel_mode(struct ieee80211_local *local, + struct ieee80211_sub_if_data *ignore) +{ + struct ieee80211_sub_if_data *sdata; + + lockdep_assert_held(&local->iflist_mtx); + + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata == ignore) + continue; + + if (!ieee80211_sdata_running(sdata)) + continue; + + switch (sdata->vif.type) { + case NL80211_IFTYPE_MONITOR: + continue; + case NL80211_IFTYPE_STATION: + if (!sdata->u.mgd.associated) + continue; + break; + case NL80211_IFTYPE_ADHOC: + if (!sdata->u.ibss.ssid_len) + continue; + if (!sdata->u.ibss.fixed_channel) + return CHAN_MODE_HOPPING; + break; + case NL80211_IFTYPE_AP_VLAN: + /* will also have _AP interface */ + continue; + case NL80211_IFTYPE_AP: + if (!sdata->u.ap.beacon) + continue; + break; + case NL80211_IFTYPE_MESH_POINT: + if (!sdata->wdev.mesh_id_len) + continue; + break; + default: + break; + } + + return CHAN_MODE_FIXED; + } + + return CHAN_MODE_UNDEFINED; +} + +enum ieee80211_chan_mode +ieee80211_get_channel_mode(struct ieee80211_local *local, + struct ieee80211_sub_if_data *ignore) +{ + enum ieee80211_chan_mode mode; + + mutex_lock(&local->iflist_mtx); + mode = __ieee80211_get_channel_mode(local, ignore); + mutex_unlock(&local->iflist_mtx); + + return mode; +} + +static enum nl80211_channel_type +ieee80211_get_superchan(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT; + struct ieee80211_sub_if_data *tmp; + + mutex_lock(&local->iflist_mtx); + list_for_each_entry(tmp, &local->interfaces, list) { + if (tmp == sdata) + continue; + + if (!ieee80211_sdata_running(tmp)) + continue; + + switch (tmp->vif.bss_conf.channel_type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + if (superchan > tmp->vif.bss_conf.channel_type) + break; + + superchan = tmp->vif.bss_conf.channel_type; + break; + case NL80211_CHAN_HT40PLUS: + WARN_ON(superchan == NL80211_CHAN_HT40MINUS); + superchan = NL80211_CHAN_HT40PLUS; + break; + case NL80211_CHAN_HT40MINUS: + WARN_ON(superchan == NL80211_CHAN_HT40PLUS); + superchan = NL80211_CHAN_HT40MINUS; + break; + } + } + mutex_unlock(&local->iflist_mtx); + + return superchan; +} static bool ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, @@ -50,352 +148,23 @@ ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, return true; } -static void ieee80211_change_chantype(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx, - enum nl80211_channel_type chantype) -{ - if (chantype == ctx->conf.channel_type) - return; - - ctx->conf.channel_type = chantype; - drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE); - - if (!local->use_chanctx) { - local->_oper_channel_type = chantype; - ieee80211_hw_config(local, 0); - } -} - -static struct ieee80211_chanctx * -ieee80211_find_chanctx(struct ieee80211_local *local, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type, - enum ieee80211_chanctx_mode mode) -{ - struct ieee80211_chanctx *ctx; - enum nl80211_channel_type compat_type; - - lockdep_assert_held(&local->chanctx_mtx); - - if (mode == IEEE80211_CHANCTX_EXCLUSIVE) - return NULL; - if (WARN_ON(!channel)) - return NULL; - - list_for_each_entry(ctx, &local->chanctx_list, list) { - compat_type = ctx->conf.channel_type; - - if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) - continue; - if (ctx->conf.channel != channel) - continue; - if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type, - channel_type, - &compat_type)) - continue; - - ieee80211_change_chantype(local, ctx, compat_type); - - return ctx; - } - - return NULL; -} - -static struct ieee80211_chanctx * -ieee80211_new_chanctx(struct ieee80211_local *local, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type, - enum ieee80211_chanctx_mode mode) -{ - struct ieee80211_chanctx *ctx; - int err; - - lockdep_assert_held(&local->chanctx_mtx); - - ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); - if (!ctx) - return ERR_PTR(-ENOMEM); - - ctx->conf.channel = channel; - ctx->conf.channel_type = channel_type; - ctx->conf.rx_chains_static = 1; - ctx->conf.rx_chains_dynamic = 1; - ctx->mode = mode; - - if (!local->use_chanctx) { - local->_oper_channel_type = channel_type; - local->_oper_channel = channel; - ieee80211_hw_config(local, 0); - } else { - err = drv_add_chanctx(local, ctx); - if (err) { - kfree(ctx); - return ERR_PTR(err); - } - } - - list_add_rcu(&ctx->list, &local->chanctx_list); - - return ctx; -} - -static void ieee80211_free_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx) -{ - lockdep_assert_held(&local->chanctx_mtx); - - WARN_ON_ONCE(ctx->refcount != 0); - - if (!local->use_chanctx) { - local->_oper_channel_type = NL80211_CHAN_NO_HT; - ieee80211_hw_config(local, 0); - } else { - drv_remove_chanctx(local, ctx); - } - - list_del_rcu(&ctx->list); - kfree_rcu(ctx, rcu_head); -} - -static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx) +bool ieee80211_set_channel_type(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_channel_type chantype) { - struct ieee80211_local *local = sdata->local; - int ret; + enum nl80211_channel_type superchan; + enum nl80211_channel_type compatchan; - lockdep_assert_held(&local->chanctx_mtx); - - ret = drv_assign_vif_chanctx(local, sdata, ctx); - if (ret) - return ret; - - rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); - ctx->refcount++; - - ieee80211_recalc_txpower(sdata); - - return 0; -} - -static enum nl80211_channel_type -ieee80211_calc_chantype(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx) -{ - struct ieee80211_chanctx_conf *conf = &ctx->conf; - struct ieee80211_sub_if_data *sdata; - enum nl80211_channel_type result = NL80211_CHAN_NO_HT; - - lockdep_assert_held(&local->chanctx_mtx); - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) - continue; - if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) - continue; - - WARN_ON_ONCE(!ieee80211_channel_types_are_compatible( - sdata->vif.bss_conf.channel_type, - result, &result)); - } - rcu_read_unlock(); - - return result; -} - -static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx) -{ - enum nl80211_channel_type chantype; - - lockdep_assert_held(&local->chanctx_mtx); - - chantype = ieee80211_calc_chantype(local, ctx); - ieee80211_change_chantype(local, ctx, chantype); -} - -static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx) -{ - struct ieee80211_local *local = sdata->local; - - lockdep_assert_held(&local->chanctx_mtx); - - ctx->refcount--; - rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); - - drv_unassign_vif_chanctx(local, sdata, ctx); - - if (ctx->refcount > 0) { - ieee80211_recalc_chanctx_chantype(sdata->local, ctx); - ieee80211_recalc_smps_chanctx(local, ctx); - } -} - -static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx_conf *conf; - struct ieee80211_chanctx *ctx; - - lockdep_assert_held(&local->chanctx_mtx); - - conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); - if (!conf) - return; - - ctx = container_of(conf, struct ieee80211_chanctx, conf); - - ieee80211_unassign_vif_chanctx(sdata, ctx); - if (ctx->refcount == 0) - ieee80211_free_chanctx(local, ctx); -} - -void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *chanctx) -{ - struct ieee80211_sub_if_data *sdata; - u8 rx_chains_static, rx_chains_dynamic; - - lockdep_assert_held(&local->chanctx_mtx); - - rx_chains_static = 1; - rx_chains_dynamic = 1; - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - u8 needed_static, needed_dynamic; - - if (!ieee80211_sdata_running(sdata)) - continue; - - if (rcu_access_pointer(sdata->vif.chanctx_conf) != - &chanctx->conf) - continue; - - switch (sdata->vif.type) { - case NL80211_IFTYPE_P2P_DEVICE: - continue; - case NL80211_IFTYPE_STATION: - if (!sdata->u.mgd.associated) - continue; - break; - case NL80211_IFTYPE_AP_VLAN: - continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: - break; - default: - WARN_ON_ONCE(1); - } - - switch (sdata->smps_mode) { - default: - WARN_ONCE(1, "Invalid SMPS mode %d\n", - sdata->smps_mode); - /* fall through */ - case IEEE80211_SMPS_OFF: - needed_static = sdata->needed_rx_chains; - needed_dynamic = sdata->needed_rx_chains; - break; - case IEEE80211_SMPS_DYNAMIC: - needed_static = 1; - needed_dynamic = sdata->needed_rx_chains; - break; - case IEEE80211_SMPS_STATIC: - needed_static = 1; - needed_dynamic = 1; - break; - } - - rx_chains_static = max(rx_chains_static, needed_static); - rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); - } - rcu_read_unlock(); - - if (!local->use_chanctx) { - if (rx_chains_static > 1) - local->smps_mode = IEEE80211_SMPS_OFF; - else if (rx_chains_dynamic > 1) - local->smps_mode = IEEE80211_SMPS_DYNAMIC; - else - local->smps_mode = IEEE80211_SMPS_STATIC; - ieee80211_hw_config(local, 0); - } - - if (rx_chains_static == chanctx->conf.rx_chains_static && - rx_chains_dynamic == chanctx->conf.rx_chains_dynamic) - return; - - chanctx->conf.rx_chains_static = rx_chains_static; - chanctx->conf.rx_chains_dynamic = rx_chains_dynamic; - drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); -} - -int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type, - enum ieee80211_chanctx_mode mode) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx *ctx; - int ret; - - WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); - - mutex_lock(&local->chanctx_mtx); - __ieee80211_vif_release_channel(sdata); - - ctx = ieee80211_find_chanctx(local, channel, channel_type, mode); - if (!ctx) - ctx = ieee80211_new_chanctx(local, channel, channel_type, mode); - if (IS_ERR(ctx)) { - ret = PTR_ERR(ctx); - goto out; - } - - sdata->vif.bss_conf.channel_type = channel_type; - - ret = ieee80211_assign_vif_chanctx(sdata, ctx); - if (ret) { - /* if assign fails refcount stays the same */ - if (ctx->refcount == 0) - ieee80211_free_chanctx(local, ctx); - goto out; - } - - ieee80211_recalc_smps_chanctx(local, ctx); - out: - mutex_unlock(&local->chanctx_mtx); - return ret; -} + superchan = ieee80211_get_superchan(local, sdata); + if (!ieee80211_channel_types_are_compatible(superchan, chantype, + &compatchan)) + return false; -void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) -{ - WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); + local->_oper_channel_type = compatchan; - mutex_lock(&sdata->local->chanctx_mtx); - __ieee80211_vif_release_channel(sdata); - mutex_unlock(&sdata->local->chanctx_mtx); -} + if (sdata) + sdata->vif.bss_conf.channel_type = chantype; -void ieee80211_iter_chan_contexts_atomic( - struct ieee80211_hw *hw, - void (*iter)(struct ieee80211_hw *hw, - struct ieee80211_chanctx_conf *chanctx_conf, - void *data), - void *iter_data) -{ - struct ieee80211_local *local = hw_to_local(hw); - struct ieee80211_chanctx *ctx; + return true; - rcu_read_lock(); - list_for_each_entry_rcu(ctx, &local->chanctx_list, list) - iter(hw, &ctx->conf, iter_data); - rcu_read_unlock(); } -EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic); diff --git a/trunk/net/mac80211/debugfs.h b/trunk/net/mac80211/debugfs.h index 214ed4ecd739..9be4e6d71d00 100644 --- a/trunk/net/mac80211/debugfs.h +++ b/trunk/net/mac80211/debugfs.h @@ -2,9 +2,9 @@ #define __MAC80211_DEBUGFS_H #ifdef CONFIG_MAC80211_DEBUGFS -void debugfs_hw_add(struct ieee80211_local *local); -int __printf(4, 5) mac80211_format_buffer(char __user *userbuf, size_t count, - loff_t *ppos, char *fmt, ...); +extern void debugfs_hw_add(struct ieee80211_local *local); +extern int mac80211_format_buffer(char __user *userbuf, size_t count, + loff_t *ppos, char *fmt, ...); #else static inline void debugfs_hw_add(struct ieee80211_local *local) { diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c index ba9bd0ef119a..6d5aec9418ee 100644 --- a/trunk/net/mac80211/debugfs_netdev.c +++ b/trunk/net/mac80211/debugfs_netdev.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -169,29 +168,6 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz, IEEE80211_IF_FILE(flags, flags, HEX); IEEE80211_IF_FILE(state, state, LHEX); IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC); -IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC); -IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC); -IEEE80211_IF_FILE(user_power_level, user_power_level, DEC); - -static ssize_t -ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata, - char *buf, int buflen) -{ - int len; - - len = scnprintf(buf, buflen, "AC queues: VO:%d VI:%d BE:%d BK:%d\n", - sdata->vif.hw_queue[IEEE80211_AC_VO], - sdata->vif.hw_queue[IEEE80211_AC_VI], - sdata->vif.hw_queue[IEEE80211_AC_BE], - sdata->vif.hw_queue[IEEE80211_AC_BK]); - - if (sdata->vif.type == NL80211_IFTYPE_AP) - len += scnprintf(buf + len, buflen - len, "cab queue: %d\n", - sdata->vif.cab_queue); - - return len; -} -__IEEE80211_IF_FILE(hw_queues, NULL); /* STA attributes */ IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); @@ -241,7 +217,7 @@ static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata, return snprintf(buf, buflen, "request: %s\nused: %s\n", smps_modes[sdata->u.mgd.req_smps], - smps_modes[sdata->smps_mode]); + smps_modes[sdata->u.mgd.ap_smps]); } static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, @@ -269,6 +245,27 @@ static ssize_t ieee80211_if_fmt_tkip_mic_test( return -EOPNOTSUPP; } +static int hwaddr_aton(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < ETH_ALEN; i++) { + int a, b; + + a = hex_to_bin(*txt++); + if (a < 0) + return -1; + b = hex_to_bin(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + static ssize_t ieee80211_if_parse_tkip_mic_test( struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) { @@ -278,7 +275,13 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( struct ieee80211_hdr *hdr; __le16 fc; - if (!mac_pton(buf, addr)) + /* + * Assume colon-delimited MAC address with possible white space + * following. + */ + if (buflen < 3 * ETH_ALEN - 1) + return -EINVAL; + if (hwaddr_aton(buf, addr) < 0) return -EINVAL; if (!ieee80211_sdata_running(sdata)) @@ -304,16 +307,13 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( case NL80211_IFTYPE_STATION: fc |= cpu_to_le16(IEEE80211_FCTL_TODS); /* BSSID SA DA */ - mutex_lock(&sdata->u.mgd.mtx); - if (!sdata->u.mgd.associated) { - mutex_unlock(&sdata->u.mgd.mtx); + if (sdata->vif.bss_conf.bssid == NULL) { dev_kfree_skb(skb); return -ENOTCONN; } - memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN); + memcpy(hdr->addr1, sdata->vif.bss_conf.bssid, ETH_ALEN); memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); memcpy(hdr->addr3, addr, ETH_ALEN); - mutex_unlock(&sdata->u.mgd.mtx); break; default: dev_kfree_skb(skb); @@ -395,14 +395,14 @@ __IEEE80211_IF_FILE_W(uapsd_max_sp_len); /* AP attributes */ IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC); -IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC); -IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC); +IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); +IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); static ssize_t ieee80211_if_fmt_num_buffered_multicast( const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) { return scnprintf(buf, buflen, "%u\n", - skb_queue_len(&sdata->u.ap.ps.bc_buf)); + skb_queue_len(&sdata->u.ap.ps_bc_buf)); } __IEEE80211_IF_FILE(num_buffered_multicast, NULL); @@ -443,7 +443,7 @@ static ssize_t ieee80211_if_parse_tsf( } ret = kstrtoull(buf, 10, &tsf); if (ret < 0) - return ret; + return -EINVAL; if (tsf_is_delta) tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf; if (local->ops->set_tsf) { @@ -471,7 +471,7 @@ IEEE80211_IF_FILE(dropped_frames_congestion, u.mesh.mshstats.dropped_frames_congestion, DEC); IEEE80211_IF_FILE(dropped_frames_no_route, u.mesh.mshstats.dropped_frames_no_route, DEC); -IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC); +IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); /* Mesh parameters */ IEEE80211_IF_FILE(dot11MeshMaxRetries, @@ -531,7 +531,6 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD(rc_rateidx_mask_5ghz); DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz); DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz); - DEBUGFS_ADD(hw_queues); } static void add_sta_files(struct ieee80211_sub_if_data *sdata) @@ -633,9 +632,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD(flags); DEBUGFS_ADD(state); DEBUGFS_ADD(channel_type); - DEBUGFS_ADD(txpower); - DEBUGFS_ADD(user_power_level); - DEBUGFS_ADD(ap_power_level); if (sdata->vif.type != NL80211_IFTYPE_MONITOR) add_common_files(sdata); diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index 4dc2577886ff..da9003b20004 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -871,104 +871,4 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); trace_drv_return_void(local); } - -static inline int drv_add_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx) -{ - int ret = -EOPNOTSUPP; - - trace_drv_add_chanctx(local, ctx); - if (local->ops->add_chanctx) - ret = local->ops->add_chanctx(&local->hw, &ctx->conf); - trace_drv_return_int(local, ret); - - return ret; -} - -static inline void drv_remove_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx) -{ - trace_drv_remove_chanctx(local, ctx); - if (local->ops->remove_chanctx) - local->ops->remove_chanctx(&local->hw, &ctx->conf); - trace_drv_return_void(local); -} - -static inline void drv_change_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx, - u32 changed) -{ - trace_drv_change_chanctx(local, ctx, changed); - if (local->ops->change_chanctx) - local->ops->change_chanctx(&local->hw, &ctx->conf, changed); - trace_drv_return_void(local); -} - -static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx) -{ - int ret = 0; - - check_sdata_in_driver(sdata); - - trace_drv_assign_vif_chanctx(local, sdata, ctx); - if (local->ops->assign_vif_chanctx) - ret = local->ops->assign_vif_chanctx(&local->hw, - &sdata->vif, - &ctx->conf); - trace_drv_return_int(local, ret); - - return ret; -} - -static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx) -{ - check_sdata_in_driver(sdata); - - trace_drv_unassign_vif_chanctx(local, sdata, ctx); - if (local->ops->unassign_vif_chanctx) - local->ops->unassign_vif_chanctx(&local->hw, - &sdata->vif, - &ctx->conf); - trace_drv_return_void(local); -} - -static inline int drv_start_ap(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) -{ - int ret = 0; - - check_sdata_in_driver(sdata); - - trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); - if (local->ops->start_ap) - ret = local->ops->start_ap(&local->hw, &sdata->vif); - trace_drv_return_int(local, ret); - return ret; -} - -static inline void drv_stop_ap(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) -{ - check_sdata_in_driver(sdata); - - trace_drv_stop_ap(local, sdata); - if (local->ops->stop_ap) - local->ops->stop_ap(&local->hw, &sdata->vif); - trace_drv_return_void(local); -} - -static inline void drv_restart_complete(struct ieee80211_local *local) -{ - might_sleep(); - - trace_drv_restart_complete(local); - if (local->ops->restart_complete) - local->ops->restart_complete(&local->hw); - trace_drv_return_void(local); -} - #endif /* __MAC80211_DRIVER_OPS */ diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 67774b053535..5f3620f0bc0a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -26,6 +26,7 @@ #include "rate.h" #define IEEE80211_SCAN_INTERVAL (2 * HZ) +#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) @@ -38,8 +39,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, const u8 *bssid, const int beacon_int, struct ieee80211_channel *chan, const u32 basic_rates, - const u16 capability, u64 tsf, - bool creator) + const u16 capability, u64 tsf) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; @@ -72,27 +72,25 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, /* if merging, indicate to driver that we leave the old IBSS */ if (sdata->vif.bss_conf.ibss_joined) { sdata->vif.bss_conf.ibss_joined = false; - sdata->vif.bss_conf.ibss_creator = false; netif_carrier_off(sdata->dev); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); } + memcpy(ifibss->bssid, bssid, ETH_ALEN); + sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; + local->oper_channel = chan; channel_type = ifibss->channel_type; if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) channel_type = NL80211_CHAN_HT20; - - ieee80211_vif_release_channel(sdata); - if (ieee80211_vif_use_channel(sdata, chan, channel_type, - ifibss->fixed_channel ? - IEEE80211_CHANCTX_SHARED : - IEEE80211_CHANCTX_EXCLUSIVE)) { - sdata_info(sdata, "Failed to join IBSS, no channel context\n"); - return; + if (!ieee80211_set_channel_type(local, sdata, channel_type)) { + /* can only fail due to HT40+/- mismatch */ + channel_type = NL80211_CHAN_HT20; + WARN_ON(!ieee80211_set_channel_type(local, sdata, + NL80211_CHAN_HT20)); } - - memcpy(ifibss->bssid, bssid, ETH_ALEN); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); sband = local->hw.wiphy->bands[chan->band]; @@ -199,7 +197,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, bss_change |= BSS_CHANGED_HT; bss_change |= BSS_CHANGED_IBSS; sdata->vif.bss_conf.ibss_joined = true; - sdata->vif.bss_conf.ibss_creator = creator; ieee80211_bss_info_change_notify(sdata, bss_change); ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); @@ -252,8 +249,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, cbss->channel, basic_rates, cbss->capability, - cbss->tsf, - false); + cbss->tsf); } static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, @@ -283,7 +279,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, ibss_dbg(sdata, "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", sdata->vif.addr, addr, sdata->u.ibss.bssid); - ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, + ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, addr, sdata->u.ibss.bssid, NULL, 0, 0); } return sta; @@ -298,8 +294,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - struct ieee80211_chanctx_conf *chanctx_conf; - int band; + int band = local->oper_channel->band; /* * XXX: Consider removing the least recently used entry and @@ -322,13 +317,6 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, return NULL; } - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON_ONCE(!chanctx_conf)) - return NULL; - band = chanctx_conf->channel->band; - rcu_read_unlock(); - sta = sta_info_alloc(sdata, addr, GFP_KERNEL); if (!sta) { rcu_read_lock(); @@ -401,7 +389,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, * However, try to reply to authentication attempts if someone * has actually implemented this. */ - ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, 0, NULL, 0, + ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); } @@ -529,8 +517,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, goto put_bss; /* different channel */ - if (sdata->u.ibss.fixed_channel && - sdata->u.ibss.channel != cbss->channel) + if (cbss->channel != local->oper_channel) goto put_bss; /* different SSID */ @@ -605,8 +592,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - struct ieee80211_chanctx_conf *chanctx_conf; - int band; + int band = local->oper_channel->band; /* * XXX: Consider removing the least recently used entry and @@ -624,15 +610,6 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) return; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON_ONCE(!chanctx_conf)) { - rcu_read_unlock(); - return; - } - band = chanctx_conf->channel->band; - rcu_read_unlock(); - sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); if (!sta) return; @@ -738,7 +715,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, ifibss->channel, ifibss->basic_rates, - capability, 0, true); + capability, 0); } /* @@ -807,8 +784,18 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) int interval = IEEE80211_SCAN_INTERVAL; if (time_after(jiffies, ifibss->ibss_join_req + - IEEE80211_IBSS_JOIN_TIMEOUT)) - ieee80211_sta_create_ibss(sdata); + IEEE80211_IBSS_JOIN_TIMEOUT)) { + if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) { + ieee80211_sta_create_ibss(sdata); + return; + } + sdata_info(sdata, "IBSS not allowed on %d MHz\n", + local->oper_channel->center_freq); + + /* No IBSS found - decrease scan interval and continue + * scanning. */ + interval = IEEE80211_SCAN_INTERVAL_SLOW; + } mod_timer(&ifibss->timer, round_jiffies(jiffies + interval)); @@ -1099,6 +1086,17 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.channel_type = params->channel_type; sdata->u.ibss.fixed_channel = params->channel_fixed; + /* fix ourselves to that channel now already */ + if (params->channel_fixed) { + sdata->local->oper_channel = params->channel; + if (!ieee80211_set_channel_type(sdata->local, sdata, + params->channel_type)) { + mutex_unlock(&sdata->u.ibss.mtx); + kfree_skb(skb); + return -EINVAL; + } + } + if (params->ie) { sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, GFP_KERNEL); @@ -1110,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; - memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); @@ -1136,9 +1134,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); - sdata->smps_mode = IEEE80211_SMPS_OFF; - sdata->needed_rx_chains = sdata->local->rx_chains; - ieee80211_queue_work(&sdata->local->hw, &sdata->work); return 0; @@ -1156,6 +1151,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + memset(sdata->u.ibss.bssid, 0, ETH_ALEN); + sdata->u.ibss.ssid_len = 0; + active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1176,10 +1175,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } - ifibss->state = IEEE80211_IBSS_MLME_SEARCH; - memset(ifibss->bssid, 0, ETH_ALEN); - ifibss->ssid_len = 0; - sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); @@ -1202,7 +1197,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) lockdep_is_held(&sdata->u.ibss.mtx)); RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); sdata->vif.bss_conf.ibss_joined = false; - sdata->vif.bss_conf.ibss_creator = false; ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_IBSS); synchronize_rcu(); diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 74748896d77b..8c804550465b 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -56,9 +56,6 @@ struct ieee80211_local; #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) -/* power level hasn't been configured (or set to automatic) */ -#define IEEE80211_UNSET_POWER_LEVEL INT_MIN - /* * Some APs experience problems when working with U-APSD. Decrease the * probability of that happening by using legacy mode for all ACs but VO. @@ -283,25 +280,21 @@ struct probe_resp { u8 data[0]; }; -struct ps_data { - /* yes, this looks ugly, but guarantees that we can later use - * bitmap_empty :) - * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ - u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; - struct sk_buff_head bc_buf; - atomic_t num_sta_ps; /* number of stations in PS mode */ - int dtim_count; - bool dtim_bc_mc; -}; - struct ieee80211_if_ap { struct beacon_data __rcu *beacon; struct probe_resp __rcu *probe_resp; struct list_head vlans; - struct ps_data ps; + /* yes, this looks ugly, but guarantees that we can later use + * bitmap_empty :) + * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ + u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; + struct sk_buff_head ps_bc_buf; + atomic_t num_sta_ps; /* number of stations in PS mode */ atomic_t num_mcast_sta; /* number of stations receiving multicast */ + int dtim_count; + bool dtim_bc_mc; }; struct ieee80211_if_wds { @@ -323,6 +316,7 @@ struct mesh_stats { __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ __u32 dropped_frames_no_route; /* Not transmitted, no route found */ __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ + atomic_t estab_plinks; }; #define PREQ_Q_F_START 0x1 @@ -356,7 +350,7 @@ struct ieee80211_roc_work { u32 duration, req_duration; struct sk_buff *frame; - u64 cookie, mgmt_tx_cookie; + u64 mgmt_tx_cookie; }; /* flags used in struct ieee80211_if_managed.flags */ @@ -384,9 +378,8 @@ struct ieee80211_mgd_auth_data { u8 key_len, key_idx; bool done; - u16 sae_trans, sae_status; - size_t data_len; - u8 data[]; + size_t ie_len; + u8 ie[]; }; struct ieee80211_mgd_assoc_data { @@ -440,6 +433,7 @@ struct ieee80211_if_managed { bool powersave; /* powersave requested for this iface */ bool broken_ap; /* AP is broken -- turn off powersave */ enum ieee80211_smps_mode req_smps, /* requested smps mode */ + ap_smps, /* smps mode AP thinks we're in */ driver_smps_mode; /* smps mode request */ struct work_struct request_smps_work; @@ -473,8 +467,6 @@ struct ieee80211_if_managed { u8 use_4addr; - u8 p2p_noa_index; - /* Signal strength from the last Beacon frame in the current BSS. */ int last_beacon_signal; @@ -607,7 +599,6 @@ struct ieee80211_if_mesh { int preq_queue_len; struct mesh_stats mshstats; struct mesh_config mshcfg; - atomic_t estab_plinks; u32 mesh_seqnum; bool accepting_plinks; int num_gates; @@ -619,7 +610,7 @@ struct ieee80211_if_mesh { IEEE80211_MESH_SEC_SECURED = 0x2, } security; /* Extensible Synchronization Framework */ - const struct ieee80211_mesh_sync_ops *sync_ops; + struct ieee80211_mesh_sync_ops *sync_ops; s64 sync_offset_clockdrift_max; spinlock_t sync_offset_lock; bool adjusting_tbtt; @@ -667,30 +658,6 @@ enum ieee80211_sdata_state_bits { SDATA_STATE_OFFCHANNEL, }; -/** - * enum ieee80211_chanctx_mode - channel context configuration mode - * - * @IEEE80211_CHANCTX_SHARED: channel context may be used by - * multiple interfaces - * @IEEE80211_CHANCTX_EXCLUSIVE: channel context can be used - * only by a single interface. This can be used for example for - * non-fixed channel IBSS. - */ -enum ieee80211_chanctx_mode { - IEEE80211_CHANCTX_SHARED, - IEEE80211_CHANCTX_EXCLUSIVE -}; - -struct ieee80211_chanctx { - struct list_head list; - struct rcu_head rcu_head; - - enum ieee80211_chanctx_mode mode; - int refcount; - - struct ieee80211_chanctx_conf conf; -}; - struct ieee80211_sub_if_data { struct list_head list; @@ -737,20 +704,11 @@ struct ieee80211_sub_if_data { struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; - /* used to reconfigure hardware SM PS */ - struct work_struct recalc_smps; - struct work_struct work; struct sk_buff_head skb_queue; bool arp_filter_state; - u8 needed_rx_chains; - enum ieee80211_smps_mode smps_mode; - - int user_power_level; /* in dBm */ - int ap_power_level; /* in dBm */ - /* * AP this belongs to: self in AP mode and * corresponding AP in VLAN mode, NULL for @@ -791,21 +749,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) return container_of(p, struct ieee80211_sub_if_data, vif); } -static inline enum ieee80211_band -ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) -{ - enum ieee80211_band band = IEEE80211_BAND_2GHZ; - struct ieee80211_chanctx_conf *chanctx_conf; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!WARN_ON(!chanctx_conf)) - band = chanctx_conf->channel->band; - rcu_read_unlock(); - - return band; -} - enum sdata_queue_type { IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, IEEE80211_SDATA_QUEUE_AGG_START = 1, @@ -878,7 +821,6 @@ enum { * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to * send out data * @SCAN_RESUME: Resume the scan and scan the next channel - * @SCAN_ABORT: Abort the scan and go back to operating channel */ enum mac80211_scan_state { SCAN_DECISION, @@ -886,7 +828,6 @@ enum mac80211_scan_state { SCAN_SEND_PROBE, SCAN_SUSPEND, SCAN_RESUME, - SCAN_ABORT, }; struct ieee80211_local { @@ -917,14 +858,15 @@ struct ieee80211_local { bool wiphy_ciphers_allocated; - bool use_chanctx; - /* protects the aggregated multicast list and filter calls */ spinlock_t filter_lock; /* used for uploading changed mc list */ struct work_struct reconfig_filter; + /* used to reconfigure hardware SM PS */ + struct work_struct recalc_smps; + /* aggregated multicast list */ struct netdev_hw_addr_list mc_list; @@ -961,9 +903,6 @@ struct ieee80211_local { /* wowlan is enabled -- don't reconfig on resume */ bool wowlan; - /* number of RX chains the hardware has */ - u8 rx_chains; - int tx_headroom; /* required headroom for hardware/radiotap */ /* Tasklet and skb queue to process calls from IRQ mode. All frames @@ -1041,19 +980,13 @@ struct ieee80211_local { enum mac80211_scan_state next_scan_state; struct delayed_work scan_work; struct ieee80211_sub_if_data __rcu *scan_sdata; - struct ieee80211_channel *csa_channel; - /* For backward compatibility only -- do not use */ - struct ieee80211_channel *_oper_channel; enum nl80211_channel_type _oper_channel_type; + struct ieee80211_channel *oper_channel, *csa_channel; /* Temporary remain-on-channel for off-channel operations */ struct ieee80211_channel *tmp_channel; enum nl80211_channel_type tmp_channel_type; - /* channel contexts */ - struct list_head chanctx_list; - struct mutex chanctx_mtx; - /* SNMP counters */ /* dot11CountersTable */ u32 dot11TransmittedFragmentCount; @@ -1125,7 +1058,8 @@ struct ieee80211_local { int dynamic_ps_user_timeout; bool disable_dynamic_ps; - int user_power_level; /* in dBm, for all interfaces */ + int user_power_level; /* in dBm */ + int ap_power_level; /* in dBm */ enum ieee80211_smps_mode smps_mode; @@ -1144,7 +1078,6 @@ struct ieee80211_local { struct list_head roc_list; struct work_struct hw_roc_start, hw_roc_done; unsigned long hw_roc_start_time; - u64 roc_cookie_counter; struct idr ack_status_frames; spinlock_t ack_status_lock; @@ -1158,8 +1091,6 @@ struct ieee80211_local { /* virtual monitor interface */ struct ieee80211_sub_if_data __rcu *monitor_sdata; - struct ieee80211_channel *monitor_channel; - enum nl80211_channel_type monitor_channel_type; }; static inline struct ieee80211_sub_if_data * @@ -1202,8 +1133,6 @@ struct ieee802_11_elems { u8 *wmm_param; struct ieee80211_ht_cap *ht_cap_elem; struct ieee80211_ht_operation *ht_operation; - struct ieee80211_vht_cap *vht_cap_elem; - struct ieee80211_vht_operation *vht_operation; struct ieee80211_meshconf_ie *mesh_config; u8 *mesh_id; u8 *peering; @@ -1373,9 +1302,6 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); -bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); -void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata); - static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) { return test_bit(SDATA_STATE_RUNNING, &sdata->state); @@ -1388,8 +1314,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, @@ -1435,13 +1359,6 @@ void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); -u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs); - -/* VHT */ -void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, - struct ieee80211_supported_band *sband, - struct ieee80211_vht_cap *vht_cap_ie, - struct ieee80211_sta_vht_cap *vht_cap); /* Spectrum management */ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, @@ -1476,42 +1393,11 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke gfp_t gfp); void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, bool bss_notify); -void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, - enum ieee80211_band band); - -void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, int tid, - enum ieee80211_band band); - -static inline void -ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, int tid, - enum ieee80211_band band) -{ - rcu_read_lock(); - __ieee80211_tx_skb_tid_band(sdata, skb, tid, band); - rcu_read_unlock(); -} +void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); -static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, int tid) -{ - struct ieee80211_chanctx_conf *chanctx_conf; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - kfree_skb(skb); - return; - } - - __ieee80211_tx_skb_tid_band(sdata, skb, tid, - chanctx_conf->channel->band); - rcu_read_unlock(); -} - -static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, +void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, int tid); +static void inline ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ @@ -1558,7 +1444,7 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, } void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, - u16 transaction, u16 auth_alg, u16 status, + u16 transaction, u16 auth_alg, u8 *extra, size_t extra_len, const u8 *bssid, const u8 *da, const u8 *key, u8 key_len, u8 key_idx); void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, @@ -1578,7 +1464,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u32 ratemask, bool directed, bool no_cck, - struct ieee80211_channel *channel, bool scan); + struct ieee80211_channel *channel); void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, const size_t supp_rates_len, @@ -1588,7 +1474,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, enum ieee80211_band band, u32 *basic_rates); int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps_mode); -void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); +void ieee80211_recalc_smps(struct ieee80211_local *local); size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset); @@ -1609,19 +1495,21 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, enum ieee80211_band band); /* channel management */ +enum ieee80211_chan_mode { + CHAN_MODE_UNDEFINED, + CHAN_MODE_HOPPING, + CHAN_MODE_FIXED, +}; + +enum ieee80211_chan_mode +ieee80211_get_channel_mode(struct ieee80211_local *local, + struct ieee80211_sub_if_data *ignore); +bool ieee80211_set_channel_type(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_channel_type chantype); enum nl80211_channel_type ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); -int __must_check -ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type, - enum ieee80211_chanctx_mode mode); -void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); - -void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *chanctx); - #ifdef CONFIG_MAC80211_NOINLINE #define debug_noinline noinline #else diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 80ce90b29d9d..6f8a73c64fb3 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -42,41 +42,6 @@ * by either the RTNL, the iflist_mtx or RCU. */ -bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_chanctx_conf *chanctx_conf; - int power; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) { - rcu_read_unlock(); - return false; - } - - power = chanctx_conf->channel->max_power; - rcu_read_unlock(); - - if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL) - power = min(power, sdata->user_power_level); - - if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL) - power = min(power, sdata->ap_power_level); - - if (power != sdata->vif.bss_conf.txpower) { - sdata->vif.bss_conf.txpower = power; - ieee80211_hw_config(sdata->local, 0); - return true; - } - - return false; -} - -void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) -{ - if (__ieee80211_recalc_txpower(sdata)) - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); -} static u32 ieee80211_idle_off(struct ieee80211_local *local, const char *reason) @@ -415,15 +380,6 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) goto out_unlock; } - ret = ieee80211_vif_use_channel(sdata, local->monitor_channel, - local->monitor_channel_type, - IEEE80211_CHANCTX_EXCLUSIVE); - if (ret) { - drv_remove_interface(local, sdata); - kfree(sdata); - goto out_unlock; - } - rcu_assign_pointer(local->monitor_sdata, sdata); out_unlock: mutex_unlock(&local->iflist_mtx); @@ -447,8 +403,6 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) rcu_assign_pointer(local->monitor_sdata, NULL); synchronize_net(); - ieee80211_vif_release_channel(sdata); - drv_remove_interface(local, sdata); kfree(sdata); @@ -711,6 +665,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, *tmp; u32 hw_reconf_flags = 0; int i; + enum nl80211_channel_type orig_ct; clear_bit(SDATA_STATE_RUNNING, &sdata->state); @@ -774,17 +729,34 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, del_timer_sync(&local->dynamic_ps_timer); cancel_work_sync(&local->dynamic_ps_enable_work); - cancel_work_sync(&sdata->recalc_smps); - /* APs need special treatment */ if (sdata->vif.type == NL80211_IFTYPE_AP) { struct ieee80211_sub_if_data *vlan, *tmpsdata; + struct beacon_data *old_beacon = + rtnl_dereference(sdata->u.ap.beacon); + struct probe_resp *old_probe_resp = + rtnl_dereference(sdata->u.ap.probe_resp); + + /* sdata_running will return false, so this will disable */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BEACON_ENABLED); + + /* remove beacon and probe response */ + RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); + RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); + synchronize_rcu(); + kfree(old_beacon); + kfree(old_probe_resp); /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, u.vlan.list) dev_close(vlan->dev); WARN_ON(!list_empty(&sdata->u.ap.vlans)); + + /* free all potentially still buffered bcast frames */ + local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); + skb_queue_purge(&sdata->u.ap.ps_bc_buf); } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { ieee80211_mgd_stop(sdata); } @@ -865,8 +837,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, hw_reconf_flags = 0; } + /* Re-calculate channel-type, in case there are multiple vifs + * on different channel types. + */ + orig_ct = local->_oper_channel_type; + ieee80211_set_channel_type(local, NULL, NL80211_CHAN_NO_HT); + /* do after stop to avoid reconfiguring when we stop anyway */ - if (hw_reconf_flags) + if (hw_reconf_flags || (orig_ct != local->_oper_channel_type)) ieee80211_hw_config(local, hw_reconf_flags); spin_lock_irqsave(&local->queue_stop_reason_lock, flags); @@ -875,7 +853,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (info->control.vif == &sdata->vif) { __skb_unlink(skb, &local->pending[i]); - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb_irq(skb); } } } @@ -1143,13 +1121,6 @@ static void ieee80211_iface_work(struct work_struct *work) } } -static void ieee80211_recalc_smps_work(struct work_struct *work) -{ - struct ieee80211_sub_if_data *sdata = - container_of(work, struct ieee80211_sub_if_data, recalc_smps); - - ieee80211_recalc_smps(sdata); -} /* * Helper function to initialise an interface to a specific type. @@ -1178,7 +1149,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&sdata->skb_queue); INIT_WORK(&sdata->work, ieee80211_iface_work); - INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); switch (type) { case NL80211_IFTYPE_P2P_GO: @@ -1187,7 +1157,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->vif.p2p = true; /* fall through */ case NL80211_IFTYPE_AP: - skb_queue_head_init(&sdata->u.ap.ps.bc_buf); + skb_queue_head_init(&sdata->u.ap.ps_bc_buf); INIT_LIST_HEAD(&sdata->u.ap.vlans); break; case NL80211_IFTYPE_P2P_CLIENT: @@ -1312,6 +1282,11 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, if (type == ieee80211_vif_type_p2p(&sdata->vif)) return 0; + /* Setting ad-hoc mode on non-IBSS channel is not supported. */ + if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS && + type == NL80211_IFTYPE_ADHOC) + return -EOPNOTSUPP; + if (ieee80211_sdata_running(sdata)) { ret = ieee80211_runtime_change_iftype(sdata, type); if (ret) @@ -1323,6 +1298,9 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, } /* reset some values that shouldn't be kept across type changes */ + sdata->vif.bss_conf.basic_rates = + ieee80211_mandatory_rates(sdata->local, + sdata->local->oper_channel->band); sdata->drop_unencrypted = 0; if (type == NL80211_IFTYPE_STATION) sdata->u.mgd.use_4addr = false; @@ -1545,9 +1523,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ieee80211_set_default_queues(sdata); - sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; - sdata->user_power_level = local->user_power_level; - /* setup type-dependent data */ ieee80211_setup_sdata(sdata, type); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index da2f41610125..c80c4490351c 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -93,15 +93,15 @@ static void ieee80211_reconfig_filter(struct work_struct *work) ieee80211_configure_filter(local); } -static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) +int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) { - struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *chan; - u32 changed = 0; + int ret = 0; int power; enum nl80211_channel_type channel_type; u32 offchannel_flag; - bool scanning = false; + + might_sleep(); offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; if (local->scan_channel) { @@ -109,7 +109,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) /* If scanning on oper channel, use whatever channel-type * is currently in use. */ - if (chan == local->_oper_channel) + if (chan == local->oper_channel) channel_type = local->_oper_channel_type; else channel_type = NL80211_CHAN_NO_HT; @@ -117,11 +117,11 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) chan = local->tmp_channel; channel_type = local->tmp_channel_type; } else { - chan = local->_oper_channel; + chan = local->oper_channel; channel_type = local->_oper_channel_type; } - if (chan != local->_oper_channel || + if (chan != local->oper_channel || channel_type != local->_oper_channel_type) local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; else @@ -148,39 +148,22 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) changed |= IEEE80211_CONF_CHANGE_SMPS; } - scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || - test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || - test_bit(SCAN_HW_SCANNING, &local->scanning); - power = chan->max_power; + if (test_bit(SCAN_SW_SCANNING, &local->scanning) || + test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || + test_bit(SCAN_HW_SCANNING, &local->scanning) || + !local->ap_power_level) + power = chan->max_power; + else + power = min(chan->max_power, local->ap_power_level); - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (!rcu_access_pointer(sdata->vif.chanctx_conf)) - continue; - power = min(power, sdata->vif.bss_conf.txpower); - } - rcu_read_unlock(); + if (local->user_power_level >= 0) + power = min(power, local->user_power_level); if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; } - return changed; -} - -int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) -{ - int ret = 0; - - might_sleep(); - - if (!local->use_chanctx) - changed |= ieee80211_hw_conf_chan(local); - else - changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL | - IEEE80211_CONF_CHANGE_POWER); - if (changed && local->open_count) { ret = drv_config(local, changed); /* @@ -376,6 +359,14 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) } EXPORT_SYMBOL(ieee80211_restart_hw); +static void ieee80211_recalc_smps_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, recalc_smps); + + ieee80211_recalc_smps(local); +} + #ifdef CONFIG_INET static int ieee80211_ifa_changed(struct notifier_block *nb, unsigned long data, void *arg) @@ -549,7 +540,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, struct ieee80211_local *local; int priv_size, i; struct wiphy *wiphy; - bool use_chanctx; if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || !ops->add_interface || !ops->remove_interface || @@ -559,14 +549,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) return NULL; - /* check all or no channel context operations exist */ - i = !!ops->add_chanctx + !!ops->remove_chanctx + - !!ops->change_chanctx + !!ops->assign_vif_chanctx + - !!ops->unassign_vif_chanctx; - if (WARN_ON(i != 0 && i != 5)) - return NULL; - use_chanctx = i == 5; - /* Ensure 32-byte alignment of our private data and hw private data. * We use the wiphy priv data for both our ieee80211_local and for * the driver's private data @@ -602,15 +584,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, if (ops->remain_on_channel) wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | - NL80211_FEATURE_SAE | - NL80211_FEATURE_HT_IBSS | - NL80211_FEATURE_VIF_TXPOWER; - - if (!ops->hw_scan) - wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | - NL80211_FEATURE_AP_SCAN; - + wiphy->features = NL80211_FEATURE_SK_TX_STATUS | + NL80211_FEATURE_HT_IBSS; if (!ops->set_key) wiphy->flags |= WIPHY_FLAG_IBSS_RSN; @@ -624,7 +599,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); local->ops = ops; - local->use_chanctx = use_chanctx; /* set up some defaults */ local->hw.queues = 1; @@ -638,7 +612,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | IEEE80211_RADIOTAP_MCS_HAVE_GI | IEEE80211_RADIOTAP_MCS_HAVE_BW; - local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; + local->user_power_level = -1; wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; INIT_LIST_HEAD(&local->interfaces); @@ -652,9 +626,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, spin_lock_init(&local->filter_lock); spin_lock_init(&local->queue_stop_reason_lock); - INIT_LIST_HEAD(&local->chanctx_list); - mutex_init(&local->chanctx_mtx); - /* * The rx_skb_queue is only accessed from tasklets, * but other SKB queues are used from within IRQ @@ -670,6 +641,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, INIT_WORK(&local->restart_work, ieee80211_restart_work); INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); + INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work); local->smps_mode = IEEE80211_SMPS_OFF; INIT_WORK(&local->dynamic_ps_enable_work, @@ -747,25 +719,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) return -EINVAL; - if (!local->use_chanctx) { - for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { - const struct ieee80211_iface_combination *comb; - - comb = &local->hw.wiphy->iface_combinations[i]; - - if (comb->num_different_channels > 1) - return -EINVAL; - } - } else { - /* - * WDS is currently prohibited when channel contexts are used - * because there's no clear definition of which channel WDS - * type interfaces use - */ - if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) - return -EINVAL; - } - /* Only HW csum features are currently compatible with mac80211 */ feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM; @@ -775,8 +728,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (hw->max_report_rates == 0) hw->max_report_rates = hw->max_rates; - local->rx_chains = 1; - /* * generic code guarantees at least one band, * set this very early because much code assumes @@ -792,29 +743,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) sband = local->hw.wiphy->bands[band]; if (!sband) continue; - if (!local->use_chanctx && !local->_oper_channel) { + if (!local->oper_channel) { /* init channel we're on */ local->hw.conf.channel = - local->_oper_channel = &sband->channels[0]; + local->oper_channel = &sband->channels[0]; local->hw.conf.channel_type = NL80211_CHAN_NO_HT; } - if (!local->monitor_channel) { - local->monitor_channel = &sband->channels[0]; - local->monitor_channel_type = NL80211_CHAN_NO_HT; - } channels += sband->n_channels; if (max_bitrates < sband->n_bitrates) max_bitrates = sband->n_bitrates; supp_ht = supp_ht || sband->ht_cap.ht_supported; supp_vht = supp_vht || sband->vht_cap.vht_supported; - - if (sband->ht_cap.ht_supported) - local->rx_chains = - max(ieee80211_mcs_to_chains(&sband->ht_cap.mcs), - local->rx_chains); - - /* TODO: consider VHT for RX chains, hopefully it's the same */ } local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + @@ -838,13 +778,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); - /* mac80211 doesn't support more than one IBSS interface right now */ + /* + * mac80211 doesn't support more than 1 channel, and also not more + * than one IBSS interface + */ for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { const struct ieee80211_iface_combination *c; int j; c = &hw->wiphy->iface_combinations[i]; + if (c->num_different_channels > 1) + return -EINVAL; + for (j = 0; j < c->n_limits; j++) if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && c->limits[j].max > 1) @@ -886,7 +832,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (supp_vht) local->scan_ies_len += - 2 + sizeof(struct ieee80211_vht_cap); + 2 + sizeof(struct ieee80211_vht_capabilities); if (!local->ops->hw_scan) { /* For hw_scan, driver needs to set these up. */ @@ -925,10 +871,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) { - result = -ENOMEM; - goto fail_wiphy_register; - } + if (!suites) + return -ENOMEM; for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index a350cab4b339..ff0296c7bab8 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -97,7 +97,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, (ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth))) goto mismatch; - ieee80211_sta_get_rates(local, ie, ieee80211_get_sdata_band(sdata), + ieee80211_sta_get_rates(local, ie, local->oper_channel->band, &basic_rates); if (sdata->vif.bss_conf.basic_rates != basic_rates) @@ -264,7 +264,7 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) /* Authentication Protocol identifier */ *pos++ = ifmsh->mesh_auth_id; /* Mesh Formation Info - number of neighbors */ - neighbors = atomic_read(&ifmsh->estab_plinks); + neighbors = atomic_read(&ifmsh->mshstats.estab_plinks); /* Number of neighbor mesh STAs or 15 whichever is smaller */ neighbors = (neighbors > 15) ? 15 : neighbors; *pos++ = neighbors << 1; @@ -355,22 +355,12 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan; + struct ieee80211_channel *chan = local->oper_channel; u8 *pos; if (skb_tailroom(skb) < 3) return -ENOMEM; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return -EINVAL; - } - chan = chanctx_conf->channel; - rcu_read_unlock(); - sband = local->hw.wiphy->bands[chan->band]; if (sband->band == IEEE80211_BAND_2GHZ) { pos = skb_put(skb, 2 + 1); @@ -386,11 +376,10 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); struct ieee80211_supported_band *sband; u8 *pos; - sband = local->hw.wiphy->bands[band]; + sband = local->hw.wiphy->bands[local->oper_channel->band]; if (!sband->ht_cap.ht_supported || sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) return 0; @@ -408,26 +397,14 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *channel; + struct ieee80211_channel *channel = local->oper_channel; enum nl80211_channel_type channel_type = - sdata->vif.bss_conf.channel_type; - struct ieee80211_supported_band *sband; - struct ieee80211_sta_ht_cap *ht_cap; + sdata->vif.bss_conf.channel_type; + struct ieee80211_supported_band *sband = + local->hw.wiphy->bands[channel->band]; + struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; u8 *pos; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return -EINVAL; - } - channel = chanctx_conf->channel; - rcu_read_unlock(); - - sband = local->hw.wiphy->bands[channel->band]; - ht_cap = &sband->ht_cap; - if (!ht_cap->ht_supported || channel_type == NL80211_CHAN_NO_HT) return 0; @@ -633,7 +610,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sdata->local, - ieee80211_get_sdata_band(sdata)); + sdata->local->oper_channel->band); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_HT | @@ -703,10 +680,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, &elems); - /* ignore non-mesh or secure / unsecure mismatch */ - if ((!elems.mesh_id || !elems.mesh_config) || - (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || - (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) + /* ignore beacons from secure mesh peers if our security is off */ + if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) return; if (elems.ds_params && elems.ds_params_len == 1) @@ -719,7 +694,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) return; - if (mesh_matches_local(sdata, &elems)) + if (elems.mesh_id && elems.mesh_config && + mesh_matches_local(sdata, &elems)) mesh_neighbour_update(sdata, mgmt->sa, &elems); if (ifmsh->sync_ops) diff --git a/trunk/net/mac80211/mesh.h b/trunk/net/mac80211/mesh.h index 9285f3f67e66..25d0f17dec71 100644 --- a/trunk/net/mac80211/mesh.h +++ b/trunk/net/mac80211/mesh.h @@ -256,7 +256,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); -const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); +struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); /* Mesh paths */ int mesh_nexthop_lookup(struct sk_buff *skb, @@ -324,7 +324,7 @@ extern int mesh_allocated; static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) { return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks - - atomic_read(&sdata->u.mesh.estab_plinks); + atomic_read(&sdata->u.mesh.mshstats.estab_plinks); } static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c index 234fe755968b..3ab34d816897 100644 --- a/trunk/net/mac80211/mesh_plink.c +++ b/trunk/net/mac80211/mesh_plink.c @@ -50,14 +50,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, static inline u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) { - atomic_inc(&sdata->u.mesh.estab_plinks); + atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); return mesh_accept_plinks_update(sdata); } static inline u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) { - atomic_dec(&sdata->u.mesh.estab_plinks); + atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); return mesh_accept_plinks_update(sdata); } @@ -252,8 +252,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, mgmt->u.action.u.self_prot.action_code = action; if (action != WLAN_SP_MESH_PEERING_CLOSE) { - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); - /* capability info */ pos = skb_put(skb, 2); memset(pos, 0, 2); @@ -262,8 +260,10 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, 2); memcpy(pos + 2, &plid, 2); } - if (ieee80211_add_srates_ie(sdata, skb, true, band) || - ieee80211_add_ext_srates_ie(sdata, skb, true, band) || + if (ieee80211_add_srates_ie(sdata, skb, true, + local->oper_channel->band) || + ieee80211_add_ext_srates_ie(sdata, skb, true, + local->oper_channel->band) || mesh_add_rsn_ie(skb, sdata) || mesh_add_meshid_ie(skb, sdata) || mesh_add_meshconf_ie(skb, sdata)) @@ -343,7 +343,7 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems) { struct ieee80211_local *local = sdata->local; - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); + enum ieee80211_band band = local->oper_channel->band; struct ieee80211_supported_band *sband; u32 rates, basic_rates = 0; struct sta_info *sta; diff --git a/trunk/net/mac80211/mesh_sync.c b/trunk/net/mac80211/mesh_sync.c index 407c8705e10d..a16b7b4b1e02 100644 --- a/trunk/net/mac80211/mesh_sync.c +++ b/trunk/net/mac80211/mesh_sync.c @@ -234,7 +234,49 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) spin_unlock_bh(&ifmsh->sync_offset_lock); } -static const struct sync_method sync_methods[] = { +static const u8 *mesh_get_vendor_oui(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + u8 offset; + + if (!ifmsh->ie || !ifmsh->ie_len) + return NULL; + + offset = ieee80211_ie_split_vendor(ifmsh->ie, + ifmsh->ie_len, 0); + + if (!offset) + return NULL; + + return ifmsh->ie + offset + 2; +} + +static void mesh_sync_vendor_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, + u16 stype, + struct ieee80211_mgmt *mgmt, + struct ieee802_11_elems *elems, + struct ieee80211_rx_status *rx_status) +{ + const u8 *oui; + + WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); + msync_dbg(sdata, "called mesh_sync_vendor_rx_bcn_presp\n"); + oui = mesh_get_vendor_oui(sdata); + /* here you would implement the vendor offset tracking for this oui */ +} + +static void mesh_sync_vendor_adjust_tbtt(struct ieee80211_sub_if_data *sdata) +{ + const u8 *oui; + + WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); + msync_dbg(sdata, "called mesh_sync_vendor_adjust_tbtt\n"); + oui = mesh_get_vendor_oui(sdata); + /* here you would implement the vendor tsf adjustment for this oui */ +} + +/* global variable */ +static struct sync_method sync_methods[] = { { .method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, .ops = { @@ -242,11 +284,18 @@ static const struct sync_method sync_methods[] = { .adjust_tbtt = &mesh_sync_offset_adjust_tbtt, } }, + { + .method = IEEE80211_SYNC_METHOD_VENDOR, + .ops = { + .rx_bcn_presp = &mesh_sync_vendor_rx_bcn_presp, + .adjust_tbtt = &mesh_sync_vendor_adjust_tbtt, + } + }, }; -const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) +struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method) { - const struct ieee80211_mesh_sync_ops *ops = NULL; + struct ieee80211_mesh_sync_ops *ops = NULL; u8 i; for (i = 0 ; i < ARRAY_SIZE(sync_methods); ++i) { diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 61614461e089..e714ed8bb198 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -178,30 +178,20 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan; struct sta_info *sta; u32 changed = 0; u16 ht_opmode; bool disable_40 = false; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return 0; - } - chan = chanctx_conf->channel; - rcu_read_unlock(); - sband = local->hw.wiphy->bands[chan->band]; + sband = local->hw.wiphy->bands[local->oper_channel->band]; switch (sdata->vif.bss_conf.channel_type) { case NL80211_CHAN_HT40PLUS: - if (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) + if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40PLUS) disable_40 = true; break; case NL80211_CHAN_HT40MINUS: - if (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) + if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40MINUS) disable_40 = true; break; default: @@ -353,7 +343,7 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, cap = vht_cap.cap; /* reserve and fill IE */ - pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); + pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2); ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); } @@ -369,21 +359,11 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) int i, count, rates_len, supp_rates_len; u16 capab; struct ieee80211_supported_band *sband; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan; u32 rates = 0; lockdep_assert_held(&ifmgd->mtx); - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return; - } - chan = chanctx_conf->channel; - rcu_read_unlock(); - sband = local->hw.wiphy->bands[chan->band]; + sband = local->hw.wiphy->bands[local->oper_channel->band]; if (assoc_data->supp_rates_len) { /* @@ -412,7 +392,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 4 + /* power capability */ 2 + 2 * sband->n_channels + /* supported channels */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ - 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ + 2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */ assoc_data->ie_len + /* extra IEs */ 9, /* WMM */ GFP_KERNEL); @@ -505,7 +485,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) *pos++ = WLAN_EID_PWR_CAPABILITY; *pos++ = 2; *pos++ = 0; /* min tx power */ - *pos++ = chan->max_power; /* max tx power */ + *pos++ = local->oper_channel->max_power; /* max tx power */ /* 2. supported channels */ /* TODO: get this in reg domain format */ @@ -543,7 +523,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, - sband, chan, sdata->smps_mode); + sband, local->oper_channel, ifmgd->ap_smps); if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) ieee80211_add_vht_ie(sdata, skb, sband); @@ -677,18 +657,18 @@ static void ieee80211_chswitch_work(struct work_struct *work) if (!ifmgd->associated) goto out; - sdata->local->_oper_channel = sdata->local->csa_channel; + sdata->local->oper_channel = sdata->local->csa_channel; if (!sdata->local->ops->channel_switch) { /* call "hw_config" only if doing sw channel switch */ ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL); } else { /* update the device channel directly */ - sdata->local->hw.conf.channel = sdata->local->_oper_channel; + sdata->local->hw.conf.channel = sdata->local->oper_channel; } /* XXX: shouldn't really modify cfg80211-owned data! */ - ifmgd->associated->channel = sdata->local->_oper_channel; + ifmgd->associated->channel = sdata->local->oper_channel; /* XXX: wait for a beacon first? */ ieee80211_wake_queues_by_reason(&sdata->local->hw, @@ -700,8 +680,11 @@ static void ieee80211_chswitch_work(struct work_struct *work) void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_if_managed *ifmgd; + + sdata = vif_to_sdata(vif); + ifmgd = &sdata->u.mgd; trace_api_chswitch_done(sdata, success); if (!success) { @@ -740,7 +723,6 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, cbss->channel->band); - struct ieee80211_chanctx *chanctx; ASSERT_MGD_MTX(ifmgd); @@ -766,34 +748,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, return; } - ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; - - if (sdata->local->use_chanctx) { - sdata_info(sdata, - "not handling channel switch with channel contexts\n"); - ieee80211_queue_work(&sdata->local->hw, - &ifmgd->csa_connection_drop_work); - } - - mutex_lock(&sdata->local->chanctx_mtx); - if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { - mutex_unlock(&sdata->local->chanctx_mtx); - return; - } - chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf), - struct ieee80211_chanctx, conf); - if (chanctx->refcount > 1) { - sdata_info(sdata, - "channel switch with multiple interfaces on the same channel, disconnecting\n"); - ieee80211_queue_work(&sdata->local->hw, - &ifmgd->csa_connection_drop_work); - mutex_unlock(&sdata->local->chanctx_mtx); - return; - } - mutex_unlock(&sdata->local->chanctx_mtx); - sdata->local->csa_channel = new_ch; + ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; + if (sw_elem->mode) ieee80211_stop_queues_by_reason(&sdata->local->hw, IEEE80211_QUEUE_STOP_REASON_CSA); @@ -820,10 +778,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, cbss->beacon_interval)); } -static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel *channel, - const u8 *country_ie, u8 country_ie_len, - const u8 *pwr_constr_elem) +static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, + struct ieee80211_channel *channel, + const u8 *country_ie, u8 country_ie_len, + const u8 *pwr_constr_elem) { struct ieee80211_country_ie_triplet *triplet; int chan = ieee80211_frequency_to_channel(channel->center_freq); @@ -832,7 +790,7 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, /* Invalid IE */ if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) - return 0; + return; triplet = (void *)(country_ie + 3); country_ie_len -= 3; @@ -873,21 +831,19 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, } if (!have_chan_pwr) - return 0; + return; new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem); - if (sdata->ap_power_level == new_ap_level) - return 0; + if (sdata->local->ap_power_level == new_ap_level) + return; sdata_info(sdata, "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", new_ap_level, chan_pwr, *pwr_constr_elem, sdata->u.mgd.bssid); - sdata->ap_power_level = new_ap_level; - if (__ieee80211_recalc_txpower(sdata)) - return BSS_CHANGED_TXPOWER; - return 0; + sdata->local->ap_power_level = new_ap_level; + ieee80211_hw_config(sdata->local, 0); } void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif) @@ -1324,7 +1280,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, } use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); - if (ieee80211_get_sdata_band(sdata) == IEEE80211_BAND_5GHZ) + if (sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) use_short_slot = true; if (use_protection != bss_conf->use_cts_prot) { @@ -1365,22 +1321,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; - if (sdata->vif.p2p) { - u8 noa[2]; - int ret; - - ret = cfg80211_get_p2p_attr(cbss->information_elements, - cbss->len_information_elements, - IEEE80211_P2P_ATTR_ABSENCE_NOTICE, - noa, sizeof(noa)); - if (ret >= 2) { - bss_conf->p2p_oppps = noa[1] & 0x80; - bss_conf->p2p_ctwindow = noa[1] & 0x7f; - bss_info_changed |= BSS_CHANGED_P2P_PS; - sdata->u.mgd.p2p_noa_index = noa[0]; - } - } - /* just to be sure */ ieee80211_stop_poll(sdata); @@ -1410,7 +1350,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ieee80211_recalc_ps(local, -1); mutex_unlock(&local->iflist_mtx); - ieee80211_recalc_smps(sdata); + ieee80211_recalc_smps(local); ieee80211_recalc_ps_vif(sdata); netif_tx_start_all_queues(sdata->dev); @@ -1503,14 +1443,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ASSOC; sdata->vif.bss_conf.assoc = false; - sdata->vif.bss_conf.p2p_ctwindow = 0; - sdata->vif.bss_conf.p2p_oppps = false; - /* on the next assoc, re-program HT parameters */ memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask)); - sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; + local->ap_power_level = 0; del_timer_sync(&local->dynamic_ps_timer); cancel_work_sync(&local->dynamic_ps_enable_work); @@ -1528,7 +1465,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); - ieee80211_vif_release_channel(sdata); + /* channel(_type) changes are handled by ieee80211_hw_config */ + WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); + ieee80211_hw_config(local, 0); /* disassociated - set to defaults now */ ieee80211_set_wmm_default(sdata, false); @@ -1650,7 +1589,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, 0, (u32) -1, true, false, - ifmgd->associated->channel, false); + ifmgd->associated->channel); } ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); @@ -1753,7 +1692,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, ssid_len = ssid[1]; skb = ieee80211_build_probe_req(sdata, cbss->bssid, - (u32) -1, cbss->channel, + (u32) -1, + sdata->local->oper_channel, ssid + 2, ssid_len, NULL, 0, true); @@ -1864,7 +1804,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, memset(sdata->u.mgd.bssid, 0, ETH_ALEN); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - ieee80211_vif_release_channel(sdata); } cfg80211_put_bss(auth_data->bss); @@ -1885,7 +1824,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, return; auth_data->expected_transaction = 4; drv_mgd_prepare_tx(sdata->local, sdata); - ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, + ieee80211_send_auth(sdata, 3, auth_data->algorithm, elems.challenge - 2, elems.challenge_len + 2, auth_data->bss->bssid, auth_data->bss->bssid, auth_data->key, auth_data->key_len, @@ -1919,13 +1858,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, status_code = le16_to_cpu(mgmt->u.auth.status_code); if (auth_alg != ifmgd->auth_data->algorithm || - auth_transaction != ifmgd->auth_data->expected_transaction) { - sdata_info(sdata, "%pM unexpected authentication state: alg %d (expected %d) transact %d (expected %d)\n", - mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, - auth_transaction, - ifmgd->auth_data->expected_transaction); + auth_transaction != ifmgd->auth_data->expected_transaction) return RX_MGMT_NONE; - } if (status_code != WLAN_STATUS_SUCCESS) { sdata_info(sdata, "%pM denied authentication (status %d)\n", @@ -1938,7 +1872,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, case WLAN_AUTH_OPEN: case WLAN_AUTH_LEAP: case WLAN_AUTH_FT: - case WLAN_AUTH_SAE: break; case WLAN_AUTH_SHARED_KEY: if (ifmgd->auth_data->expected_transaction != 4) { @@ -1958,15 +1891,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); - if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && - ifmgd->auth_data->expected_transaction != 2) { - /* - * Report auth frame to user space for processing since another - * round of Authentication frames is still needed. - */ - return RX_MGMT_CFG80211_RX_AUTH; - } - /* move station state to auth */ mutex_lock(&sdata->local->sta_mtx); sta = sta_info_get(sdata, bssid); @@ -2106,7 +2030,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, memset(sdata->u.mgd.bssid, 0, ETH_ALEN); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); - ieee80211_vif_release_channel(sdata); } kfree(assoc_data); @@ -2168,7 +2091,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, return false; } - sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)]; + sband = local->hw.wiphy->bands[local->oper_channel->band]; if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, @@ -2177,11 +2100,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, sta->supports_40mhz = sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; - if (elems.vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) - ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, - elems.vht_cap_elem, - &sta->sta.vht_cap); - rate_control_rate_init(sta); if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) @@ -2451,10 +2369,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, size_t baselen; struct ieee802_11_elems elems; struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan; u32 changed = 0; - bool erp_valid; + bool erp_valid, directed_tim = false; u8 erp_value = 0; u32 ncrc; u8 *bssid; @@ -2466,19 +2382,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (baselen > len) return; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) { - rcu_read_unlock(); + if (rx_status->freq != local->oper_channel->center_freq) return; - } - - if (rx_status->freq != chanctx_conf->channel->center_freq) { - rcu_read_unlock(); - return; - } - chan = chanctx_conf->channel; - rcu_read_unlock(); if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) { @@ -2585,10 +2490,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, len - baselen, &elems, care_about_ies, ncrc); + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) + directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, + ifmgd->aid); + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { - bool directed_tim = ieee80211_check_tim(elems.tim, - elems.tim_len, - ifmgd->aid); if (directed_tim) { if (local->hw.conf.dynamic_ps_timeout > 0) { if (local->hw.conf.flags & IEEE80211_CONF_PS) { @@ -2613,27 +2519,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } - if (sdata->vif.p2p) { - u8 noa[2]; - int ret; - - ret = cfg80211_get_p2p_attr(mgmt->u.beacon.variable, - len - baselen, - IEEE80211_P2P_ATTR_ABSENCE_NOTICE, - noa, sizeof(noa)); - if (ret >= 2 && sdata->u.mgd.p2p_noa_index != noa[0]) { - bss_conf->p2p_oppps = noa[1] & 0x80; - bss_conf->p2p_ctwindow = noa[1] & 0x7f; - changed |= BSS_CHANGED_P2P_PS; - sdata->u.mgd.p2p_noa_index = noa[0]; - /* - * make sure we update all information, the CRC - * mechanism doesn't look at P2P attributes. - */ - ifmgd->beacon_crc_valid = false; - } - } - if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) return; ifmgd->beacon_crc = ncrc; @@ -2658,17 +2543,22 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && - !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) + !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) { + struct ieee80211_supported_band *sband; + + sband = local->hw.wiphy->bands[local->oper_channel->band]; + changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, bssid, true); + } if (elems.country_elem && elems.pwr_constr_elem && mgmt->u.probe_resp.capab_info & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) - changed |= ieee80211_handle_pwr_constr(sdata, chan, - elems.country_elem, - elems.country_elem_len, - elems.pwr_constr_elem); + ieee80211_handle_pwr_constr(sdata, local->oper_channel, + elems.country_elem, + elems.country_elem_len, + elems.pwr_constr_elem); ieee80211_bss_info_change_notify(sdata, changed); } @@ -2813,23 +2703,13 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) drv_mgd_prepare_tx(local, sdata); if (auth_data->bss->proberesp_ies) { - u16 trans = 1; - u16 status = 0; - sdata_info(sdata, "send auth to %pM (try %d/%d)\n", auth_data->bss->bssid, auth_data->tries, IEEE80211_AUTH_MAX_TRIES); auth_data->expected_transaction = 2; - - if (auth_data->algorithm == WLAN_AUTH_SAE) { - trans = auth_data->sae_trans; - status = auth_data->sae_status; - auth_data->expected_transaction = trans; - } - - ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, - auth_data->data, auth_data->data_len, + ieee80211_send_auth(sdata, 1, auth_data->algorithm, + auth_data->ie, auth_data->ie_len, auth_data->bss->bssid, auth_data->bss->bssid, NULL, 0, 0); } else { @@ -2848,7 +2728,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) */ ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], NULL, 0, (u32) -1, true, false, - auth_data->bss->channel, false); + auth_data->bss->channel); } auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; @@ -3219,57 +3099,39 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, ht_cfreq, ht_oper->primary_chan, cbss->channel->band); ht_oper = NULL; - } else { - channel_type = NL80211_CHAN_HT20; } } - if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { - /* - * cfg80211 already verified that the channel itself can - * be used, but it didn't check that we can do the right - * HT type, so do that here as well. If HT40 isn't allowed - * on this channel, disable 40 MHz operation. - */ - const u8 *ht_cap_ie; - const struct ieee80211_ht_cap *ht_cap; - u8 chains = 1; - + if (ht_oper) { channel_type = NL80211_CHAN_HT20; - switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { - case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) - ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; - else + if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { + switch (ht_oper->ht_param & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: channel_type = NL80211_CHAN_HT40PLUS; - break; - case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) - ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; - else + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: channel_type = NL80211_CHAN_HT40MINUS; - break; + break; + } } + } - ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, - cbss->information_elements, - cbss->len_information_elements); - if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) { - ht_cap = (void *)(ht_cap_ie + 2); - chains = ieee80211_mcs_to_chains(&ht_cap->mcs); - } - sdata->needed_rx_chains = min(chains, local->rx_chains); - } else { - sdata->needed_rx_chains = 1; + if (!ieee80211_set_channel_type(local, sdata, channel_type)) { + /* can only fail due to HT40+/- mismatch */ + channel_type = NL80211_CHAN_HT20; + sdata_info(sdata, + "disabling 40 MHz due to multi-vif mismatch\n"); + ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; + WARN_ON(!ieee80211_set_channel_type(local, sdata, + channel_type)); } - /* will change later if needed */ - sdata->smps_mode = IEEE80211_SMPS_OFF; + local->oper_channel = cbss->channel; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - ieee80211_vif_release_channel(sdata); - return ieee80211_vif_use_channel(sdata, cbss->channel, channel_type, - IEEE80211_CHANCTX_SHARED); + return 0; } static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, @@ -3339,7 +3201,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.basic_rates = basic_rates; /* cf. IEEE 802.11 9.2.12 */ - if (cbss->channel->band == IEEE80211_BAND_2GHZ && + if (local->oper_channel->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit) sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; else @@ -3401,33 +3263,19 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, case NL80211_AUTHTYPE_NETWORK_EAP: auth_alg = WLAN_AUTH_LEAP; break; - case NL80211_AUTHTYPE_SAE: - auth_alg = WLAN_AUTH_SAE; - break; default: return -EOPNOTSUPP; } - auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len + - req->ie_len, GFP_KERNEL); + auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL); if (!auth_data) return -ENOMEM; auth_data->bss = req->bss; - if (req->sae_data_len >= 4) { - __le16 *pos = (__le16 *) req->sae_data; - auth_data->sae_trans = le16_to_cpu(pos[0]); - auth_data->sae_status = le16_to_cpu(pos[1]); - memcpy(auth_data->data, req->sae_data + 4, - req->sae_data_len - 4); - auth_data->data_len += req->sae_data_len - 4; - } - if (req->ie && req->ie_len) { - memcpy(&auth_data->data[auth_data->data_len], - req->ie, req->ie_len); - auth_data->data_len += req->ie_len; + memcpy(auth_data->ie, req->ie, req->ie_len); + auth_data->ie_len = req->ie_len; } if (req->key && req->key_len) { @@ -3594,11 +3442,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) { if (ifmgd->powersave) - sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; + ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC; else - sdata->smps_mode = IEEE80211_SMPS_OFF; + ifmgd->ap_smps = IEEE80211_SMPS_OFF; } else - sdata->smps_mode = ifmgd->req_smps; + ifmgd->ap_smps = ifmgd->req_smps; assoc_data->capability = req->bss->capability; assoc_data->wmm = bss->wmm_used && @@ -3701,45 +3549,40 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; - bool tx = !req->local_state_change; - bool sent_frame = false; mutex_lock(&ifmgd->mtx); + if (ifmgd->auth_data) { + ieee80211_destroy_auth_data(sdata, false); + mutex_unlock(&ifmgd->mtx); + return 0; + } + sdata_info(sdata, "deauthenticating from %pM by local choice (reason=%d)\n", req->bssid, req->reason_code); - if (ifmgd->auth_data) { + if (ifmgd->associated && + ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { + ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, + req->reason_code, true, frame_buf); + } else { drv_mgd_prepare_tx(sdata->local, sdata); ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH, - req->reason_code, tx, + req->reason_code, true, frame_buf); - ieee80211_destroy_auth_data(sdata, false); - mutex_unlock(&ifmgd->mtx); - - sent_frame = tx; - goto out; } - if (ifmgd->associated && - ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { - ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, - req->reason_code, tx, frame_buf); - sent_frame = tx; - } mutex_unlock(&ifmgd->mtx); - out: + __cfg80211_send_deauth(sdata->dev, frame_buf, + IEEE80211_DEAUTH_FRAME_LEN); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); mutex_unlock(&sdata->local->mtx); - if (sent_frame) - __cfg80211_send_deauth(sdata->dev, frame_buf, - IEEE80211_DEAUTH_FRAME_LEN); - return 0; } diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 0cd42d52880c..83608ac16780 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -107,9 +107,6 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, { struct ieee80211_sub_if_data *sdata; - if (WARN_ON(local->use_chanctx)) - return; - /* * notify the AP about us leaving the channel and stop all * STA interfaces. @@ -148,9 +145,6 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, { struct ieee80211_sub_if_data *sdata; - if (WARN_ON(local->use_chanctx)) - return; - mutex_lock(&local->iflist_mtx); list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) @@ -199,12 +193,11 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) if (roc->mgmt_tx_cookie) { if (!WARN_ON(!roc->frame)) { - ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7, - roc->chan->band); + ieee80211_tx_skb(roc->sdata, roc->frame); roc->frame = NULL; } } else { - cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie, + cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, roc->chan, roc->chan_type, roc->req_duration, GFP_KERNEL); } @@ -320,8 +313,9 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) if (!roc->mgmt_tx_cookie) cfg80211_remain_on_channel_expired(&roc->sdata->wdev, - roc->cookie, roc->chan, - roc->chan_type, GFP_KERNEL); + (unsigned long)roc, + roc->chan, roc->chan_type, + GFP_KERNEL); list_for_each_entry_safe(dep, tmp, &roc->dependents, list) ieee80211_roc_notify_destroy(dep); diff --git a/trunk/net/mac80211/pm.c b/trunk/net/mac80211/pm.c index 0f1c434638bc..5c572e7a1a71 100644 --- a/trunk/net/mac80211/pm.c +++ b/trunk/net/mac80211/pm.c @@ -135,12 +135,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - if (sdata->vif.type == NL80211_IFTYPE_AP && - rcu_access_pointer(sdata->u.ap.beacon)) - drv_stop_ap(local, sdata); - - /* the interface is leaving the channel and is removed */ - ieee80211_vif_release_channel(sdata); drv_remove_interface(local, sdata); } diff --git a/trunk/net/mac80211/rate.h b/trunk/net/mac80211/rate.h index ec198ef6aa8a..10de668eb9f6 100644 --- a/trunk/net/mac80211/rate.h +++ b/trunk/net/mac80211/rate.h @@ -52,21 +52,11 @@ static inline void rate_control_rate_init(struct sta_info *sta) struct ieee80211_sta *ista = &sta->sta; void *priv_sta = sta->rate_ctrl_priv; struct ieee80211_supported_band *sband; - struct ieee80211_chanctx_conf *chanctx_conf; if (!ref) return; - rcu_read_lock(); - - chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - return; - } - - sband = local->hw.wiphy->bands[chanctx_conf->channel->band]; - rcu_read_unlock(); + sband = local->hw.wiphy->bands[local->oper_channel->band]; ref->ops->rate_init(ref->priv, sband, ista, priv_sta); set_sta_flag(sta, WLAN_STA_RATE_CONTROL); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 6ad330341b71..61c621e9273f 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -54,7 +54,8 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, return skb; } -static inline int should_drop_frame(struct sk_buff *skb, int present_fcs_len) +static inline int should_drop_frame(struct sk_buff *skb, + int present_fcs_len) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -129,14 +130,15 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, (1 << IEEE80211_RADIOTAP_RX_FLAGS)); rthdr->it_len = cpu_to_le16(rtap_len); - pos = (unsigned char *)(rthdr + 1); + pos = (unsigned char *)(rthdr+1); /* the order of the following fields is important */ /* IEEE80211_RADIOTAP_TSFT */ if (status->flag & RX_FLAG_MACTIME_MPDU) { put_unaligned_le64(status->mactime, pos); - rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); + rthdr->it_present |= + cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); pos += 8; } @@ -372,6 +374,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, return origskb; } + static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; @@ -478,7 +481,8 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb) struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data; struct ieee80211_mmie *mmie; - if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da)) + if (skb->len < 24 + sizeof(*mmie) || + !is_multicast_ether_addr(hdr->da)) return -1; if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr)) @@ -493,7 +497,9 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb) return le16_to_cpu(mmie->key_id); } -static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) + +static ieee80211_rx_result +ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; char *dev_addr = rx->sdata->vif.addr; @@ -501,7 +507,7 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_data(hdr->frame_control)) { if (is_multicast_ether_addr(hdr->addr1)) { if (ieee80211_has_tods(hdr->frame_control) || - !ieee80211_has_fromds(hdr->frame_control)) + !ieee80211_has_fromds(hdr->frame_control)) return RX_DROP_MONITOR; if (ether_addr_equal(hdr->addr3, dev_addr)) return RX_DROP_MONITOR; @@ -525,15 +531,10 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; - - /* make sure category field is present */ - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) - return RX_DROP_MONITOR; - mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && - category != WLAN_CATEGORY_SELF_PROTECTED) + category != WLAN_CATEGORY_SELF_PROTECTED) return RX_DROP_MONITOR; return RX_CONTINUE; } @@ -545,6 +546,7 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) return RX_CONTINUE; return RX_DROP_MONITOR; + } return RX_CONTINUE; @@ -568,6 +570,7 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) return (sq1 - sq2) & SEQ_MASK; } + static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, struct tid_ampdu_rx *tid_agg_rx, int index) @@ -880,16 +883,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { - unsigned int hdrlen; - __be16 ethertype; - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - if (rx->skb->len < hdrlen + 8) - return RX_DROP_MONITOR; - - skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); - if (ethertype == rx->sdata->control_port_protocol) + u16 ethertype; + u8 *payload; + + payload = rx->skb->data + + ieee80211_hdrlen(hdr->frame_control); + ethertype = (payload[6] << 8) | payload[7]; + if (cpu_to_be16(ethertype) == + rx->sdata->control_port_protocol) return RX_CONTINUE; } @@ -1140,19 +1141,12 @@ ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) return RX_CONTINUE; } -static void sta_ps_start(struct sta_info *sta) +static void ap_sta_ps_start(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - struct ps_data *ps; - if (sta->sdata->vif.type == NL80211_IFTYPE_AP || - sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - ps = &sdata->bss->ps; - else - return; - - atomic_inc(&ps->num_sta_ps); + atomic_inc(&sdata->bss->num_sta_ps); set_sta_flag(sta, WLAN_STA_PS_STA); if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); @@ -1160,7 +1154,7 @@ static void sta_ps_start(struct sta_info *sta) sta->sta.addr, sta->sta.aid); } -static void sta_ps_end(struct sta_info *sta) +static void ap_sta_ps_end(struct sta_info *sta) { ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", sta->sta.addr, sta->sta.aid); @@ -1187,9 +1181,9 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start) return -EINVAL; if (start) - sta_ps_start(sta_inf); + ap_sta_ps_start(sta_inf); else - sta_ps_end(sta_inf); + ap_sta_ps_end(sta_inf); return 0; } @@ -1341,10 +1335,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) */ if (ieee80211_is_data(hdr->frame_control) && !ieee80211_has_pm(hdr->frame_control)) - sta_ps_end(sta); + ap_sta_ps_end(sta); } else { if (ieee80211_has_pm(hdr->frame_control)) - sta_ps_start(sta); + ap_sta_ps_start(sta); } } @@ -1390,7 +1384,9 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, struct sk_buff **skb) { struct ieee80211_fragment_entry *entry; + int idx; + idx = sdata->fragment_next; entry = &sdata->fragments[sdata->fragment_next++]; if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) sdata->fragment_next = 0; @@ -1466,14 +1462,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; - - if (ieee80211_is_ctl(fc)) - return RX_CONTINUE; - sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || + (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; @@ -1577,15 +1570,18 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) return RX_CONTINUE; } -static int ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) +static int +ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) { - if (unlikely(!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED))) + if (unlikely(!rx->sta || + !test_sta_flag(rx->sta, WLAN_STA_AUTHORIZED))) return -EACCES; return 0; } -static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) +static int +ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) { struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); @@ -1607,7 +1603,8 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) return 0; } -static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) +static int +ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); @@ -1892,20 +1889,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); - - /* make sure fixed part of mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, hdrlen + 6)) - return RX_DROP_MONITOR; - - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* make sure full mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, - hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) - return RX_DROP_MONITOR; - - /* reload pointers */ - hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ @@ -1914,8 +1897,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; - if (!ieee80211_is_data(hdr->frame_control) || - !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!ieee80211_is_data(hdr->frame_control)) return RX_CONTINUE; if (!mesh_hdr->ttl) @@ -1929,12 +1911,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; - } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { - /* has_a4 already checked in ieee80211_rx_mesh_check */ + } else { mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; - } else { - return RX_DROP_MONITOR; } rcu_read_lock(); @@ -1962,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) + goto out; + if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); - goto out; + return RX_DROP_MONITOR; } if (!ifmsh->mshcfg.dot11MeshForwarding) @@ -1991,7 +1973,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } else { /* unable to resolve next hop */ mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, - 0, reason, fwd_hdr->addr2, sdata); + 0, reason, fwd_hdr->addr2, sdata); IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); kfree_skb(fwd_skb); return RX_DROP_MONITOR; @@ -2200,7 +2182,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) cfg80211_report_obss_beacon(rx->local->hw.wiphy, rx->skb->data, rx->skb->len, - status->freq, sig); + status->freq, sig, GFP_ATOMIC); rx->flags |= IEEE80211_RX_BEACON_REPORTED; } @@ -2371,10 +2353,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.self_prot.action_code))) - break; - switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: @@ -2393,14 +2371,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.mesh_action.action_code))) - break; - if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && - !mesh_path_sel_is_hwmp(sdata)) + (!mesh_path_sel_is_hwmp(sdata))) break; goto queue; } @@ -2456,6 +2430,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) return RX_QUEUED; } + return RX_CONTINUE; } @@ -2938,15 +2913,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; - if (ieee80211_is_mgmt(fc)) { - /* drop frame if too short for header */ - if (skb->len < ieee80211_hdrlen(fc)) - err = -ENOBUFS; - else - err = skb_linearize(skb); - } else { + if (ieee80211_is_mgmt(fc)) + err = skb_linearize(skb); + else err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); - } if (err) { dev_kfree_skb(skb); @@ -3040,7 +3010,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) WARN_ON_ONCE(softirq_count() == 0); - if (WARN_ON(status->band >= IEEE80211_NUM_BANDS)) + if (WARN_ON(status->band < 0 || + status->band >= IEEE80211_NUM_BANDS)) goto drop; sband = local->hw.wiphy->bands[status->band]; @@ -3085,7 +3056,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) * hardware error. The driver should catch hardware * errors. */ - if (WARN(status->rate_idx > 76, + if (WARN((status->rate_idx < 0 || + status->rate_idx > 76), "Rate marked as an HT rate but passed " "status->rate_idx is not " "an MCS index [0-76]: %d (0x%02x)\n", @@ -3093,7 +3065,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) status->rate_idx)) goto drop; } else { - if (WARN_ON(status->rate_idx >= sband->n_bitrates)) + if (WARN_ON(status->rate_idx < 0 || + status->rate_idx >= sband->n_bitrates)) goto drop; rate = &sband->bitrates[status->rate_idx]; } diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 8e9bb168b73b..c4cdbde24fd3 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -336,10 +336,6 @@ EXPORT_SYMBOL(ieee80211_scan_completed); static int ieee80211_start_sw_scan(struct ieee80211_local *local) { - /* Software scan is not supported in multi-channel cases */ - if (local->use_chanctx) - return -EOPNOTSUPP; - /* * Hardware/driver doesn't support hw_scan, so use software * scanning instead. First send a nullfunc frame with power save @@ -421,7 +417,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, local->scan_req->ie, local->scan_req->ie_len, local->scan_req->rates[band], false, local->scan_req->no_cck, - local->hw.conf.channel, true); + local->hw.conf.channel); /* * After sending probe requests, wait for probe responses @@ -466,7 +462,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, sizeof(*local->hw_scan_req) + req->n_channels * sizeof(req->channels[0]); local->hw_scan_req->ie = ies; - local->hw_scan_req->flags = req->flags; local->hw_scan_band = 0; @@ -485,7 +480,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if (local->ops->hw_scan) { __set_bit(SCAN_HW_SCANNING, &local->scanning); } else if ((req->n_channels == 1) && - (req->channels[0] == local->_oper_channel)) { + (req->channels[0] == local->oper_channel)) { /* * If we are scanning only on the operating channel * then we do not need to stop normal activities @@ -567,7 +562,6 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, unsigned long min_beacon_int = 0; struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *next_chan; - enum mac80211_scan_state next_scan_state; /* * check if at least one STA interface is associated, @@ -626,18 +620,10 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, usecs_to_jiffies(min_beacon_int * 1024) * local->hw.conf.listen_interval); - if (associated && !tx_empty) { - if (local->scan_req->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) - next_scan_state = SCAN_ABORT; - else - next_scan_state = SCAN_SUSPEND; - } else if (associated && (bad_latency || listen_int_exceeded)) { - next_scan_state = SCAN_SUSPEND; - } else { - next_scan_state = SCAN_SET_CHANNEL; - } - - local->next_scan_state = next_scan_state; + if (associated && (!tx_empty || bad_latency || listen_int_exceeded)) + local->next_scan_state = SCAN_SUSPEND; + else + local->next_scan_state = SCAN_SET_CHANNEL; *next_delay = 0; } @@ -808,9 +794,6 @@ void ieee80211_scan_work(struct work_struct *work) case SCAN_RESUME: ieee80211_scan_state_resume(local, &next_delay); break; - case SCAN_ABORT: - aborted = true; - goto out_complete; } } while (next_delay == 0); @@ -934,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies = {}; + struct ieee80211_sched_scan_ies sched_scan_ies; int ret, i; mutex_lock(&local->mtx); diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index e9d57689c05f..797dd36a220d 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -98,7 +98,6 @@ static void free_sta_work(struct work_struct *wk) struct tid_ampdu_tx *tid_tx; struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - struct ps_data *ps; /* * At this point, when being called as call_rcu callback, @@ -108,22 +107,18 @@ static void free_sta_work(struct work_struct *wk) */ if (test_sta_flag(sta, WLAN_STA_PS_STA)) { - if (sta->sdata->vif.type == NL80211_IFTYPE_AP || - sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - ps = &sdata->bss->ps; - else - return; + BUG_ON(!sdata->bss); clear_sta_flag(sta, WLAN_STA_PS_STA); - atomic_dec(&ps->num_sta_ps); + atomic_dec(&sdata->bss->num_sta_ps); sta_info_recalc_tim(sta); } for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); + __skb_queue_purge(&sta->ps_tx_buf[ac]); + __skb_queue_purge(&sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -146,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); + __skb_queue_purge(&tid_tx->pending); kfree(tid_tx); } @@ -507,22 +502,22 @@ int sta_info_insert(struct sta_info *sta) return err; } -static inline void __bss_tim_set(u8 *tim, u16 id) +static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __set_bit() format. */ - tim[id / 8] |= (1 << (id % 8)); + bss->tim[aid / 8] |= (1 << (aid % 8)); } -static inline void __bss_tim_clear(u8 *tim, u16 id) +static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) { /* * This format has been mandated by the IEEE specifications, * so this line may not be changed to use the __clear_bit() format. */ - tim[id / 8] &= ~(1 << (id % 8)); + bss->tim[aid / 8] &= ~(1 << (aid % 8)); } static unsigned long ieee80211_tids_for_ac(int ac) @@ -546,23 +541,14 @@ static unsigned long ieee80211_tids_for_ac(int ac) void sta_info_recalc_tim(struct sta_info *sta) { struct ieee80211_local *local = sta->local; - struct ps_data *ps; + struct ieee80211_if_ap *bss = sta->sdata->bss; unsigned long flags; bool indicate_tim = false; u8 ignore_for_tim = sta->sta.uapsd_queues; int ac; - u16 id; - - if (sta->sdata->vif.type == NL80211_IFTYPE_AP || - sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - if (WARN_ON_ONCE(!sta->sdata->bss)) - return; - ps = &sta->sdata->bss->ps; - id = sta->sta.aid; - } else { + if (WARN_ON_ONCE(!sta->sdata->bss)) return; - } /* No need to do anything if the driver does all */ if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) @@ -601,9 +587,9 @@ void sta_info_recalc_tim(struct sta_info *sta) spin_lock_irqsave(&local->tim_lock, flags); if (indicate_tim) - __bss_tim_set(ps->tim, id); + __bss_tim_set(bss, sta->sta.aid); else - __bss_tim_clear(ps->tim, id); + __bss_tim_clear(bss, sta->sta.aid); if (local->ops->set_tim) { local->tim_in_locked_section = true; @@ -664,7 +650,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, */ if (!skb) break; - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb(skb); } /* @@ -693,7 +679,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, local->total_ps_buffered--; ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", sta->sta.addr); - ieee80211_free_txskb(&local->hw, skb); + dev_kfree_skb(skb); } /* @@ -907,8 +893,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, continue; if (time_after(jiffies, sta->last_rx + exp_time)) { - sta_dbg(sta->sdata, "expiring inactive STA %pM\n", - sta->sta.addr); + ibss_dbg(sdata, "expiring inactive STA %pM\n", + sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); } } @@ -962,17 +948,10 @@ static void clear_sta_ps_flags(void *_sta) { struct sta_info *sta = _sta; struct ieee80211_sub_if_data *sdata = sta->sdata; - struct ps_data *ps; - - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - ps = &sdata->bss->ps; - else - return; clear_sta_flag(sta, WLAN_STA_PS_DRIVER); if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) - atomic_dec(&ps->num_sta_ps); + atomic_dec(&sdata->bss->num_sta_ps); } /* powersave support code */ @@ -982,7 +961,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; - unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -998,16 +976,12 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; - spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); - spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; - spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); - spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } @@ -1034,7 +1008,6 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, __le16 fc; bool qos = test_sta_flag(sta, WLAN_STA_WME); struct ieee80211_tx_info *info; - struct ieee80211_chanctx_conf *chanctx_conf; if (qos) { fc = cpu_to_le16(IEEE80211_FTYPE_DATA | @@ -1084,16 +1057,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (WARN_ON(!chanctx_conf)) { - rcu_read_unlock(); - kfree_skb(skb); - return; - } - - ieee80211_xmit(sdata, skb, chanctx_conf->channel->band); - rcu_read_unlock(); + ieee80211_xmit(sdata, skb); } static void diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index ab63237107c8..3af0cc4130f1 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -189,31 +189,30 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) } if (ieee80211_is_action(mgmt->frame_control) && - mgmt->u.action.category == WLAN_CATEGORY_HT && - mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS && sdata->vif.type == NL80211_IFTYPE_STATION && - ieee80211_sdata_running(sdata)) { + mgmt->u.action.category == WLAN_CATEGORY_HT && + mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS) { /* * This update looks racy, but isn't -- if we come * here we've definitely got a station that we're * talking to, and on a managed interface that can * only be the AP. And the only other place updating - * this variable in managed mode is before association. + * this variable is before we're associated. */ switch (mgmt->u.action.u.ht_smps.smps_control) { case WLAN_HT_SMPS_CONTROL_DYNAMIC: - sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; + sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_DYNAMIC; break; case WLAN_HT_SMPS_CONTROL_STATIC: - sdata->smps_mode = IEEE80211_SMPS_STATIC; + sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_STATIC; break; case WLAN_HT_SMPS_CONTROL_DISABLED: default: /* shouldn't happen since we don't send that */ - sdata->smps_mode = IEEE80211_SMPS_OFF; + sta->sdata->u.mgd.ap_smps = IEEE80211_SMPS_OFF; break; } - ieee80211_queue_work(&local->hw, &sdata->recalc_smps); + ieee80211_queue_work(&local->hw, &local->recalc_smps); } } @@ -325,75 +324,6 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band } -static void ieee80211_report_used_skb(struct ieee80211_local *local, - struct sk_buff *skb, bool dropped) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (void *)skb->data; - bool acked = info->flags & IEEE80211_TX_STAT_ACK; - - if (dropped) - acked = false; - - if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { - struct ieee80211_sub_if_data *sdata = NULL; - struct ieee80211_sub_if_data *iter_sdata; - u64 cookie = (unsigned long)skb; - - rcu_read_lock(); - - if (skb->dev) { - list_for_each_entry_rcu(iter_sdata, &local->interfaces, - list) { - if (!iter_sdata->dev) - continue; - - if (skb->dev == iter_sdata->dev) { - sdata = iter_sdata; - break; - } - } - } else { - sdata = rcu_dereference(local->p2p_sdata); - } - - if (!sdata) - skb->dev = NULL; - else if (ieee80211_is_nullfunc(hdr->frame_control) || - ieee80211_is_qos_nullfunc(hdr->frame_control)) { - cfg80211_probe_status(sdata->dev, hdr->addr1, - cookie, acked, GFP_ATOMIC); - } else { - cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data, - skb->len, acked, GFP_ATOMIC); - } - - rcu_read_unlock(); - } - - if (unlikely(info->ack_frame_id)) { - struct sk_buff *ack_skb; - unsigned long flags; - - spin_lock_irqsave(&local->ack_status_lock, flags); - ack_skb = idr_find(&local->ack_status_frames, - info->ack_frame_id); - if (ack_skb) - idr_remove(&local->ack_status_frames, - info->ack_frame_id); - spin_unlock_irqrestore(&local->ack_status_lock, flags); - - if (ack_skb) { - if (!dropped) { - /* consumes ack_skb */ - skb_complete_wifi_ack(ack_skb, acked); - } else { - dev_kfree_skb_any(ack_skb); - } - } - } -} - /* * Use a static threshold for now, best value to be determined * by testing ... @@ -585,7 +515,62 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) msecs_to_jiffies(10)); } - ieee80211_report_used_skb(local, skb, false); + if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { + u64 cookie = (unsigned long)skb; + bool found = false; + + acked = info->flags & IEEE80211_TX_STAT_ACK; + + rcu_read_lock(); + + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!sdata->dev) + continue; + + if (skb->dev != sdata->dev) + continue; + + found = true; + break; + } + + if (!skb->dev) { + sdata = rcu_dereference(local->p2p_sdata); + if (sdata) + found = true; + } + + if (!found) + skb->dev = NULL; + else if (ieee80211_is_nullfunc(hdr->frame_control) || + ieee80211_is_qos_nullfunc(hdr->frame_control)) { + cfg80211_probe_status(sdata->dev, hdr->addr1, + cookie, acked, GFP_ATOMIC); + } else { + cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data, + skb->len, acked, GFP_ATOMIC); + } + + rcu_read_unlock(); + } + + if (unlikely(info->ack_frame_id)) { + struct sk_buff *ack_skb; + unsigned long flags; + + spin_lock_irqsave(&local->ack_status_lock, flags); + ack_skb = idr_find(&local->ack_status_frames, + info->ack_frame_id); + if (ack_skb) + idr_remove(&local->ack_status_frames, + info->ack_frame_id); + spin_unlock_irqrestore(&local->ack_status_lock, flags); + + /* consumes ack_skb */ + if (ack_skb) + skb_complete_wifi_ack(ack_skb, + info->flags & IEEE80211_TX_STAT_ACK); + } /* this was a transmitted frame, but now we want to reuse it */ skb_orphan(skb); @@ -661,17 +646,25 @@ EXPORT_SYMBOL(ieee80211_report_low_ack); void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ieee80211_local *local = hw_to_local(hw); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - ieee80211_report_used_skb(local, skb, true); - dev_kfree_skb_any(skb); -} -EXPORT_SYMBOL(ieee80211_free_txskb); + if (unlikely(info->ack_frame_id)) { + struct sk_buff *ack_skb; + unsigned long flags; -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs) -{ - struct sk_buff *skb; + spin_lock_irqsave(&local->ack_status_lock, flags); + ack_skb = idr_find(&local->ack_status_frames, + info->ack_frame_id); + if (ack_skb) + idr_remove(&local->ack_status_frames, + info->ack_frame_id); + spin_unlock_irqrestore(&local->ack_status_lock, flags); - while ((skb = __skb_dequeue(skbs))) - ieee80211_free_txskb(hw, skb); + /* consumes ack_skb */ + if (ack_skb) + dev_kfree_skb_any(ack_skb); + } + + dev_kfree_skb_any(skb); } +EXPORT_SYMBOL(ieee80211_free_txskb); diff --git a/trunk/net/mac80211/trace.h b/trunk/net/mac80211/trace.h index 758836c85a80..18d9c8a52e9e 100644 --- a/trunk/net/mac80211/trace.h +++ b/trunk/net/mac80211/trace.h @@ -28,20 +28,6 @@ #define VIF_PR_FMT " vif:%s(%d%s)" #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" -#define CHANCTX_ENTRY __field(int, freq) \ - __field(int, chantype) \ - __field(u8, rx_chains_static) \ - __field(u8, rx_chains_dynamic) -#define CHANCTX_ASSIGN __entry->freq = ctx->conf.channel->center_freq; \ - __entry->chantype = ctx->conf.channel_type; \ - __entry->rx_chains_static = ctx->conf.rx_chains_static; \ - __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic -#define CHANCTX_PR_FMT " freq:%d MHz chantype:%d chains:%d/%d" -#define CHANCTX_PR_ARG __entry->freq, __entry->chantype, \ - __entry->rx_chains_static, __entry->rx_chains_dynamic - - - /* * Tracing for driver callbacks. */ @@ -315,36 +301,20 @@ TRACE_EVENT(drv_bss_info_changed, TP_STRUCT__entry( LOCAL_ENTRY VIF_ENTRY - __field(u32, changed) __field(bool, assoc) - __field(bool, ibss_joined) - __field(bool, ibss_creator) __field(u16, aid) __field(bool, cts) __field(bool, shortpre) __field(bool, shortslot) - __field(bool, enable_beacon) __field(u8, dtimper) __field(u16, bcnint) __field(u16, assoc_cap) __field(u64, sync_tsf) __field(u32, sync_device_ts) __field(u32, basic_rates) - __array(int, mcast_rate, IEEE80211_NUM_BANDS) + __field(u32, changed) + __field(bool, enable_beacon) __field(u16, ht_operation_mode) - __field(s32, cqm_rssi_thold); - __field(s32, cqm_rssi_hyst); - __field(u32, channel_type); - __dynamic_array(u32, arp_addr_list, info->arp_addr_cnt); - __field(bool, arp_filter_enabled); - __field(bool, qos); - __field(bool, idle); - __field(bool, ps); - __dynamic_array(u8, ssid, info->ssid_len); - __field(bool, hidden_ssid); - __field(int, txpower) - __field(u8, p2p_ctwindow) - __field(bool, p2p_oppps) ), TP_fast_assign( @@ -353,35 +323,17 @@ TRACE_EVENT(drv_bss_info_changed, __entry->changed = changed; __entry->aid = info->aid; __entry->assoc = info->assoc; - __entry->ibss_joined = info->ibss_joined; - __entry->ibss_creator = info->ibss_creator; __entry->shortpre = info->use_short_preamble; __entry->cts = info->use_cts_prot; __entry->shortslot = info->use_short_slot; - __entry->enable_beacon = info->enable_beacon; __entry->dtimper = info->dtim_period; __entry->bcnint = info->beacon_int; __entry->assoc_cap = info->assoc_capability; __entry->sync_tsf = info->sync_tsf; __entry->sync_device_ts = info->sync_device_ts; __entry->basic_rates = info->basic_rates; - memcpy(__entry->mcast_rate, info->mcast_rate, - sizeof(__entry->mcast_rate)); + __entry->enable_beacon = info->enable_beacon; __entry->ht_operation_mode = info->ht_operation_mode; - __entry->cqm_rssi_thold = info->cqm_rssi_thold; - __entry->cqm_rssi_hyst = info->cqm_rssi_hyst; - __entry->channel_type = info->channel_type; - memcpy(__get_dynamic_array(arp_addr_list), info->arp_addr_list, - sizeof(u32) * info->arp_addr_cnt); - __entry->arp_filter_enabled = info->arp_filter_enabled; - __entry->qos = info->qos; - __entry->idle = info->idle; - __entry->ps = info->ps; - memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); - __entry->hidden_ssid = info->hidden_ssid; - __entry->txpower = info->txpower; - __entry->p2p_ctwindow = info->p2p_ctwindow; - __entry->p2p_oppps = info->p2p_oppps; ), TP_printk( @@ -1049,6 +1001,34 @@ DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel, TP_ARGS(local) ); +TRACE_EVENT(drv_offchannel_tx, + TP_PROTO(struct ieee80211_local *local, struct sk_buff *skb, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + unsigned int wait), + + TP_ARGS(local, skb, chan, channel_type, wait), + + TP_STRUCT__entry( + LOCAL_ENTRY + __field(int, center_freq) + __field(int, channel_type) + __field(unsigned int, wait) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + __entry->center_freq = chan->center_freq; + __entry->channel_type = channel_type; + __entry->wait = wait; + ), + + TP_printk( + LOCAL_PR_FMT " freq:%dMHz, wait:%dms", + LOCAL_PR_ARG, __entry->center_freq, __entry->wait + ) +); + TRACE_EVENT(drv_set_ringparam, TP_PROTO(struct ieee80211_local *local, u32 tx, u32 rx), @@ -1276,146 +1256,6 @@ DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, TP_ARGS(local, sdata) ); -DECLARE_EVENT_CLASS(local_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx), - - TP_ARGS(local, ctx), - - TP_STRUCT__entry( - LOCAL_ENTRY - CHANCTX_ENTRY - ), - - TP_fast_assign( - LOCAL_ASSIGN; - CHANCTX_ASSIGN; - ), - - TP_printk( - LOCAL_PR_FMT CHANCTX_PR_FMT, - LOCAL_PR_ARG, CHANCTX_PR_ARG - ) -); - -DEFINE_EVENT(local_chanctx, drv_add_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx), - TP_ARGS(local, ctx) -); - -DEFINE_EVENT(local_chanctx, drv_remove_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx), - TP_ARGS(local, ctx) -); - -TRACE_EVENT(drv_change_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx, - u32 changed), - - TP_ARGS(local, ctx, changed), - - TP_STRUCT__entry( - LOCAL_ENTRY - CHANCTX_ENTRY - __field(u32, changed) - ), - - TP_fast_assign( - LOCAL_ASSIGN; - CHANCTX_ASSIGN; - __entry->changed = changed; - ), - - TP_printk( - LOCAL_PR_FMT CHANCTX_PR_FMT " changed:%#x", - LOCAL_PR_ARG, CHANCTX_PR_ARG, __entry->changed - ) -); - -DECLARE_EVENT_CLASS(local_sdata_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx), - - TP_ARGS(local, sdata, ctx), - - TP_STRUCT__entry( - LOCAL_ENTRY - VIF_ENTRY - CHANCTX_ENTRY - ), - - TP_fast_assign( - LOCAL_ASSIGN; - VIF_ASSIGN; - CHANCTX_ASSIGN; - ), - - TP_printk( - LOCAL_PR_FMT VIF_PR_FMT CHANCTX_PR_FMT, - LOCAL_PR_ARG, VIF_PR_ARG, CHANCTX_PR_ARG - ) -); - -DEFINE_EVENT(local_sdata_chanctx, drv_assign_vif_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx), - TP_ARGS(local, sdata, ctx) -); - -DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_chanctx *ctx), - TP_ARGS(local, sdata, ctx) -); - -TRACE_EVENT(drv_start_ap, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_bss_conf *info), - - TP_ARGS(local, sdata, info), - - TP_STRUCT__entry( - LOCAL_ENTRY - VIF_ENTRY - __field(u8, dtimper) - __field(u16, bcnint) - __dynamic_array(u8, ssid, info->ssid_len); - __field(bool, hidden_ssid); - ), - - TP_fast_assign( - LOCAL_ASSIGN; - VIF_ASSIGN; - __entry->dtimper = info->dtim_period; - __entry->bcnint = info->beacon_int; - memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len); - __entry->hidden_ssid = info->hidden_ssid; - ), - - TP_printk( - LOCAL_PR_FMT VIF_PR_FMT, - LOCAL_PR_ARG, VIF_PR_ARG - ) -); - -DEFINE_EVENT(local_sdata_evt, drv_stop_ap, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata), - TP_ARGS(local, sdata) -); - -DEFINE_EVENT(local_only_evt, drv_restart_complete, - TP_PROTO(struct ieee80211_local *local), - TP_ARGS(local) -); - /* * Tracing for API calls that drivers call. */ diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 04076250264b..c9bf83f36657 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -324,20 +324,22 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) struct ieee80211_sub_if_data *sdata; struct sta_info *sta; - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - struct ps_data *ps; + /* + * virtual interfaces are protected by RCU + */ + rcu_read_lock(); - if (sdata->vif.type == NL80211_IFTYPE_AP) - ps = &sdata->u.ap.ps; - else + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + struct ieee80211_if_ap *ap; + if (sdata->vif.type != NL80211_IFTYPE_AP) continue; - - skb = skb_dequeue(&ps->bc_buf); + ap = &sdata->u.ap; + skb = skb_dequeue(&ap->ps_bc_buf); if (skb) { purged++; dev_kfree_skb(skb); } - total += skb_queue_len(&ps->bc_buf); + total += skb_queue_len(&ap->ps_bc_buf); } /* @@ -358,6 +360,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) } } + rcu_read_unlock(); + local->total_ps_buffered = total; ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); } @@ -367,7 +371,6 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; - struct ps_data *ps; /* * broadcast/multicast frame @@ -377,24 +380,16 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) * This is done either by the hardware or us. */ - /* powersaving STAs currently only in AP/VLAN mode */ - if (tx->sdata->vif.type == NL80211_IFTYPE_AP || - tx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - if (!tx->sdata->bss) - return TX_CONTINUE; - - ps = &tx->sdata->bss->ps; - } else { + /* powersaving STAs only in AP/VLAN mode */ + if (!tx->sdata->bss) return TX_CONTINUE; - } - /* no buffering for ordered frames */ if (ieee80211_has_order(hdr->frame_control)) return TX_CONTINUE; /* no stations in PS mode */ - if (!atomic_read(&ps->num_sta_ps)) + if (!atomic_read(&tx->sdata->bss->num_sta_ps)) return TX_CONTINUE; info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; @@ -409,14 +404,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) purge_old_ps_buffers(tx->local); - if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) { + if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { ps_dbg(tx->sdata, "BC TX buffer full - dropping the oldest frame\n"); - dev_kfree_skb(skb_dequeue(&ps->bc_buf)); + dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); } else tx->local->total_ps_buffered++; - skb_queue_tail(&ps->bc_buf, tx->skb); + skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); return TX_QUEUED; } @@ -956,6 +951,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) fragnum = 0; skb_queue_walk(&tx->skbs, skb) { + int next_len; const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); hdr = (void *)skb->data; @@ -974,6 +970,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { hdr->frame_control &= ~morefrags; + next_len = 0; } hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG); fragnum++; @@ -1361,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); + __skb_queue_purge(&tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -1375,8 +1372,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) * Returns false if the frame couldn't be transmitted but was queued instead. */ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool txpending, - enum ieee80211_band band) + struct sk_buff *skb, bool txpending) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_data tx; @@ -1390,18 +1386,20 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, return true; } + rcu_read_lock(); + /* initialises tx */ led_len = skb->len; res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); if (unlikely(res_prepare == TX_DROP)) { ieee80211_free_txskb(&local->hw, skb); - return true; + goto out; } else if (unlikely(res_prepare == TX_QUEUED)) { - return true; + goto out; } - info->band = band; + info->band = local->hw.conf.channel->band; /* set up hw_queue value early */ if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || @@ -1412,7 +1410,8 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, if (!invoke_tx_handlers(&tx)) result = __ieee80211_tx(local, &tx.skbs, led_len, tx.sta, txpending); - + out: + rcu_read_unlock(); return result; } @@ -1447,8 +1446,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, return 0; } -void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, - enum ieee80211_band band) +void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1456,6 +1454,8 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, int headroom; bool may_encrypt; + rcu_read_lock(); + may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT); headroom = local->tx_headroom; @@ -1466,6 +1466,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { ieee80211_free_txskb(&local->hw, skb); + rcu_read_unlock(); return; } @@ -1477,11 +1478,13 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, !is_multicast_ether_addr(hdr->addr1) && mesh_nexthop_resolve(skb, sdata)) { /* skb queued: don't free */ + rcu_read_unlock(); return; } ieee80211_set_qos_hdr(sdata, skb); - ieee80211_tx(sdata, skb, false, band); + ieee80211_tx(sdata, skb, false); + rcu_read_unlock(); } static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) @@ -1571,8 +1574,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_channel *chan; + struct ieee80211_channel *chan = local->hw.conf.channel; struct ieee80211_radiotap_header *prthdr = (struct ieee80211_radiotap_header *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1581,6 +1583,26 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, u16 len_rthdr; int hdrlen; + /* + * Frame injection is not allowed if beaconing is not allowed + * or if we need radar detection. Beaconing is usually not allowed when + * the mode or operation (Adhoc, AP, Mesh) does not support DFS. + * Passive scan is also used in world regulatory domains where + * your country is not known and as such it should be treated as + * NO TX unless the channel is explicitly allowed in which case + * your current regulatory domain would not have the passive scan + * flag. + * + * Since AP mode uses monitor interfaces to inject/TX management + * frames we can make AP mode the exception to this rule once it + * supports radar detection as its implementation can deal with + * radar detection by itself. We can do that later by adding a + * monitor flag interfaces used for AP support. + */ + if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_PASSIVE_SCAN))) + goto fail; + /* check for not even having the fixed radiotap header part */ if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) goto fail; /* too short to be possibly valid */ @@ -1666,45 +1688,11 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, } } - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) { - tmp_sdata = rcu_dereference(local->monitor_sdata); - if (tmp_sdata) - chanctx_conf = - rcu_dereference(tmp_sdata->vif.chanctx_conf); - } - if (!chanctx_conf) - goto fail_rcu; - - chan = chanctx_conf->channel; - - /* - * Frame injection is not allowed if beaconing is not allowed - * or if we need radar detection. Beaconing is usually not allowed when - * the mode or operation (Adhoc, AP, Mesh) does not support DFS. - * Passive scan is also used in world regulatory domains where - * your country is not known and as such it should be treated as - * NO TX unless the channel is explicitly allowed in which case - * your current regulatory domain would not have the passive scan - * flag. - * - * Since AP mode uses monitor interfaces to inject/TX management - * frames we can make AP mode the exception to this rule once it - * supports radar detection as its implementation can deal with - * radar detection by itself. We can do that later by adding a - * monitor flag interfaces used for AP support. - */ - if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_PASSIVE_SCAN))) - goto fail_rcu; - - ieee80211_xmit(sdata, skb, chan->band); + ieee80211_xmit(sdata, skb); rcu_read_unlock(); return NETDEV_TX_OK; -fail_rcu: - rcu_read_unlock(); fail: dev_kfree_skb(skb); return NETDEV_TX_OK; /* meaning, we dealt with the skb */ @@ -1746,9 +1734,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, bool multicast; u32 info_flags = 0; u16 info_id = 0; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_sub_if_data *ap_sdata; - enum ieee80211_band band; if (unlikely(skb->len < ETH_HLEN)) goto fail; @@ -1758,10 +1743,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, ethertype = (skb->data[12] << 8) | skb->data[13]; fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); - rcu_read_lock(); - switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: + rcu_read_lock(); sta = rcu_dereference(sdata->u.vlan.sta); if (sta) { fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); @@ -1774,12 +1758,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); wme_sta = test_sta_flag(sta, WLAN_STA_WME); } - ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, - u.ap); - chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; - band = chanctx_conf->channel->band; + rcu_read_unlock(); if (sta) break; /* fall through */ @@ -1790,11 +1769,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); hdrlen = 24; - if (sdata->vif.type == NL80211_IFTYPE_AP) - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; - band = chanctx_conf->channel->band; break; case NL80211_IFTYPE_WDS: fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); @@ -1804,20 +1778,15 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr3, skb->data, ETH_ALEN); memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); hdrlen = 30; - /* - * This is the exception! WDS style interfaces are prohibited - * when channel contexts are in used so this must be valid - */ - band = local->hw.conf.channel->band; break; #ifdef CONFIG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { /* Do not send frames with mesh_ttl == 0 */ sdata->u.mesh.mshstats.dropped_frames_ttl++; - goto fail_rcu; + goto fail; } - + rcu_read_lock(); if (!is_multicast_ether_addr(skb->data)) { mpath = mesh_path_lookup(skb->data, sdata); if (!mpath) @@ -1834,6 +1803,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) { hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, skb->data, skb->data + ETH_ALEN); + rcu_read_unlock(); meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, NULL, NULL); } else { @@ -1849,6 +1819,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, mesh_da = mppath->mpp; else if (mpath) mesh_da = mpath->dst; + rcu_read_unlock(); hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, mesh_da, sdata->vif.addr); @@ -1868,16 +1839,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, skb->data + ETH_ALEN); } - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; - band = chanctx_conf->channel->band; break; #endif case NL80211_IFTYPE_STATION: if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { bool tdls_peer = false; + rcu_read_lock(); sta = sta_info_get(sdata, skb->data); if (sta) { authorized = test_sta_flag(sta, @@ -1888,6 +1856,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, tdls_auth = test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); } + rcu_read_unlock(); /* * If the TDLS link is enabled, send everything @@ -1902,7 +1871,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (tdls_direct) { /* link during setup - throw out frames to peer */ if (!tdls_auth) - goto fail_rcu; + goto fail; /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -1927,10 +1896,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr3, skb->data, ETH_ALEN); hdrlen = 24; } - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; - band = chanctx_conf->channel->band; break; case NL80211_IFTYPE_ADHOC: /* DA SA BSSID */ @@ -1938,13 +1903,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN); hdrlen = 24; - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!chanctx_conf) - goto fail_rcu; - band = chanctx_conf->channel->band; break; default: - goto fail_rcu; + goto fail; } /* @@ -1954,11 +1915,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ multicast = is_multicast_ether_addr(hdr.addr1); if (!multicast) { + rcu_read_lock(); sta = sta_info_get(sdata, hdr.addr1); if (sta) { authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); wme_sta = test_sta_flag(sta, WLAN_STA_WME); } + rcu_read_unlock(); } /* For mesh, the use of the QoS header is mandatory */ @@ -1986,7 +1949,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); - goto fail_rcu; + goto fail; } if (unlikely(!multicast && skb->sk && @@ -2041,7 +2004,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, kfree_skb(tmp_skb); if (!skb) - goto fail_rcu; + goto fail; } hdr.frame_control = fc; @@ -2089,8 +2052,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, head_need = max_t(int, 0, head_need); if (ieee80211_skb_resize(sdata, skb, head_need, true)) { ieee80211_free_txskb(&local->hw, skb); - skb = NULL; - goto fail_rcu; + return NETDEV_TX_OK; } } @@ -2142,13 +2104,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, info->flags = info_flags; info->ack_frame_id = info_id; - ieee80211_xmit(sdata, skb, band); - rcu_read_unlock(); + ieee80211_xmit(sdata, skb); return NETDEV_TX_OK; - fail_rcu: - rcu_read_unlock(); fail: dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -2161,13 +2120,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { - struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) { - while ((skb = skb_dequeue(&local->pending[i])) != NULL) - ieee80211_free_txskb(&local->hw, skb); - } + for (i = 0; i < local->hw.queues; i++) + skb_queue_purge(&local->pending[i]); } /* @@ -2183,18 +2139,11 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, struct sta_info *sta; struct ieee80211_hdr *hdr; bool result; - struct ieee80211_chanctx_conf *chanctx_conf; sdata = vif_to_sdata(info->control.vif); if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (unlikely(!chanctx_conf)) { - dev_kfree_skb(skb); - return true; - } - result = ieee80211_tx(sdata, skb, true, - chanctx_conf->channel->band); + result = ieee80211_tx(sdata, skb, true); } else { struct sk_buff_head skbs; @@ -2262,8 +2211,9 @@ void ieee80211_tx_pending(unsigned long data) /* functions for drivers to get certain frames */ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, - struct ps_data *ps, - struct sk_buff *skb) + struct ieee80211_if_ap *bss, + struct sk_buff *skb, + struct beacon_data *beacon) { u8 *pos, *tim; int aid0 = 0; @@ -2271,27 +2221,27 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, /* Generate bitmap for TIM only if there are any STAs in power save * mode. */ - if (atomic_read(&ps->num_sta_ps) > 0) + if (atomic_read(&bss->num_sta_ps) > 0) /* in the hope that this is faster than * checking byte-for-byte */ - have_bits = !bitmap_empty((unsigned long*)ps->tim, + have_bits = !bitmap_empty((unsigned long*)bss->tim, IEEE80211_MAX_AID+1); - if (ps->dtim_count == 0) - ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1; + if (bss->dtim_count == 0) + bss->dtim_count = sdata->vif.bss_conf.dtim_period - 1; else - ps->dtim_count--; + bss->dtim_count--; tim = pos = (u8 *) skb_put(skb, 6); *pos++ = WLAN_EID_TIM; *pos++ = 4; - *pos++ = ps->dtim_count; + *pos++ = bss->dtim_count; *pos++ = sdata->vif.bss_conf.dtim_period; - if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf)) + if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) aid0 = 1; - ps->dtim_bc_mc = aid0 == 1; + bss->dtim_bc_mc = aid0 == 1; if (have_bits) { /* Find largest even number N1 so that bits numbered 1 through @@ -2299,14 +2249,14 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, * (N2 + 1) x 8 through 2007 are 0. */ n1 = 0; for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) { - if (ps->tim[i]) { + if (bss->tim[i]) { n1 = i & 0xfe; break; } } n2 = n1; for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) { - if (ps->tim[i]) { + if (bss->tim[i]) { n2 = i; break; } @@ -2316,7 +2266,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, *pos++ = n1 | aid0; /* Part Virt Bitmap */ skb_put(skb, n2 - n1); - memcpy(pos, ps->tim + n1, n2 - n1 + 1); + memcpy(pos, bss->tim + n1, n2 - n1 + 1); tim[1] = n2 - n1 + 4; } else { @@ -2333,16 +2283,16 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, struct sk_buff *skb = NULL; struct ieee80211_tx_info *info; struct ieee80211_sub_if_data *sdata = NULL; - enum ieee80211_band band; + struct ieee80211_if_ap *ap = NULL; + struct beacon_data *beacon; + enum ieee80211_band band = local->oper_channel->band; struct ieee80211_tx_rate_control txrc; - struct ieee80211_chanctx_conf *chanctx_conf; rcu_read_lock(); sdata = vif_to_sdata(vif); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - if (!ieee80211_sdata_running(sdata) || !chanctx_conf) + if (!ieee80211_sdata_running(sdata)) goto out; if (tim_offset) @@ -2351,9 +2301,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, *tim_length = 0; if (sdata->vif.type == NL80211_IFTYPE_AP) { - struct ieee80211_if_ap *ap = &sdata->u.ap; - struct beacon_data *beacon = rcu_dereference(ap->beacon); - + ap = &sdata->u.ap; + beacon = rcu_dereference(ap->beacon); if (beacon) { /* * headroom, head length, @@ -2377,12 +2326,14 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, * of the tim bitmap in mac80211 and the driver. */ if (local->tim_in_locked_section) { - ieee80211_beacon_add_tim(sdata, &ap->ps, skb); + ieee80211_beacon_add_tim(sdata, ap, skb, + beacon); } else { unsigned long flags; spin_lock_irqsave(&local->tim_lock, flags); - ieee80211_beacon_add_tim(sdata, &ap->ps, skb); + ieee80211_beacon_add_tim(sdata, ap, skb, + beacon); spin_unlock_irqrestore(&local->tim_lock, flags); } @@ -2458,8 +2409,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, *pos++ = WLAN_EID_SSID; *pos++ = 0x0; - band = chanctx_conf->channel->band; - if (ieee80211_add_srates_ie(sdata, skb, true, band) || mesh_add_ds_params_ie(skb, sdata) || ieee80211_add_ext_srates_ie(sdata, skb, true, band) || @@ -2477,8 +2426,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, goto out; } - band = chanctx_conf->channel->band; - info = IEEE80211_SKB_CB(skb); info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; @@ -2706,40 +2653,29 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct sk_buff *skb = NULL; struct ieee80211_tx_data tx; struct ieee80211_sub_if_data *sdata; - struct ps_data *ps; + struct ieee80211_if_ap *bss = NULL; + struct beacon_data *beacon; struct ieee80211_tx_info *info; - struct ieee80211_chanctx_conf *chanctx_conf; sdata = vif_to_sdata(vif); + bss = &sdata->u.ap; rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - - if (!chanctx_conf) - goto out; + beacon = rcu_dereference(bss->beacon); - if (sdata->vif.type == NL80211_IFTYPE_AP) { - struct beacon_data *beacon = - rcu_dereference(sdata->u.ap.beacon); - - if (!beacon || !beacon->head) - goto out; - - ps = &sdata->u.ap.ps; - } else { + if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head) goto out; - } - if (ps->dtim_count != 0 || !ps->dtim_bc_mc) + if (bss->dtim_count != 0 || !bss->dtim_bc_mc) goto out; /* send buffered bc/mc only after DTIM beacon */ while (1) { - skb = skb_dequeue(&ps->bc_buf); + skb = skb_dequeue(&bss->ps_bc_buf); if (!skb) goto out; local->total_ps_buffered--; - if (!skb_queue_empty(&ps->bc_buf) && skb->len >= 2) { + if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; /* more buffered multicast/broadcast frames ==> set @@ -2757,7 +2693,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, info = IEEE80211_SKB_CB(skb); tx.flags |= IEEE80211_TX_PS_BUFFERED; - info->band = chanctx_conf->channel->band; + info->band = local->oper_channel->band; if (invoke_tx_handlers(&tx)) skb = NULL; @@ -2768,9 +2704,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ieee80211_get_buffered_bc); -void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, int tid, - enum ieee80211_band band) +void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, int tid) { int ac = ieee802_1d_to_ac[tid & 7]; @@ -2787,6 +2722,6 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, * requirements are that we do not come into tx with bhs on. */ local_bh_disable(); - ieee80211_xmit(sdata, skb, band); + ieee80211_xmit(sdata, skb); local_bh_enable(); } diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index c4a60bfb9f14..22ca35054dd0 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -406,7 +406,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, int queue = info->hw_queue; if (WARN_ON(!info->control.vif)) { - ieee80211_free_txskb(&local->hw, skb); + kfree_skb(skb); return; } @@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (WARN_ON(!info->control.vif)) { - ieee80211_free_txskb(&local->hw, skb); + kfree_skb(skb); continue; } @@ -512,7 +512,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw) EXPORT_SYMBOL(ieee80211_wake_queues); void ieee80211_iterate_active_interfaces( - struct ieee80211_hw *hw, u32 iter_flags, + struct ieee80211_hw *hw, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data) @@ -530,9 +530,6 @@ void ieee80211_iterate_active_interfaces( default: break; } - if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && - !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) - continue; if (ieee80211_sdata_running(sdata)) iterator(data, sdata->vif.addr, &sdata->vif); @@ -540,9 +537,7 @@ void ieee80211_iterate_active_interfaces( sdata = rcu_dereference_protected(local->monitor_sdata, lockdep_is_held(&local->iflist_mtx)); - if (sdata && - (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || - sdata->flags & IEEE80211_SDATA_IN_DRIVER)) + if (sdata) iterator(data, sdata->vif.addr, &sdata->vif); mutex_unlock(&local->iflist_mtx); @@ -550,7 +545,7 @@ void ieee80211_iterate_active_interfaces( EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); void ieee80211_iterate_active_interfaces_atomic( - struct ieee80211_hw *hw, u32 iter_flags, + struct ieee80211_hw *hw, void (*iterator)(void *data, u8 *mac, struct ieee80211_vif *vif), void *data) @@ -568,18 +563,13 @@ void ieee80211_iterate_active_interfaces_atomic( default: break; } - if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && - !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) - continue; if (ieee80211_sdata_running(sdata)) iterator(data, sdata->vif.addr, &sdata->vif); } sdata = rcu_dereference(local->monitor_sdata); - if (sdata && - (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || - sdata->flags & IEEE80211_SDATA_IN_DRIVER)) + if (sdata) iterator(data, sdata->vif.addr, &sdata->vif); rcu_read_unlock(); @@ -653,41 +643,13 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, break; } - switch (id) { - case WLAN_EID_SSID: - case WLAN_EID_SUPP_RATES: - case WLAN_EID_FH_PARAMS: - case WLAN_EID_DS_PARAMS: - case WLAN_EID_CF_PARAMS: - case WLAN_EID_TIM: - case WLAN_EID_IBSS_PARAMS: - case WLAN_EID_CHALLENGE: - case WLAN_EID_RSN: - case WLAN_EID_ERP_INFO: - case WLAN_EID_EXT_SUPP_RATES: - case WLAN_EID_HT_CAPABILITY: - case WLAN_EID_HT_OPERATION: - case WLAN_EID_VHT_CAPABILITY: - case WLAN_EID_VHT_OPERATION: - case WLAN_EID_MESH_ID: - case WLAN_EID_MESH_CONFIG: - case WLAN_EID_PEER_MGMT: - case WLAN_EID_PREQ: - case WLAN_EID_PREP: - case WLAN_EID_PERR: - case WLAN_EID_RANN: - case WLAN_EID_CHANNEL_SWITCH: - case WLAN_EID_EXT_CHANSWITCH_ANN: - case WLAN_EID_COUNTRY: - case WLAN_EID_PWR_CONSTRAINT: - case WLAN_EID_TIMEOUT_INTERVAL: - if (test_bit(id, seen_elems)) { - elems->parse_error = true; - left -= elen; - pos += elen; - continue; - } - break; + if (id != WLAN_EID_VENDOR_SPECIFIC && + id != WLAN_EID_QUIET && + test_bit(id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; + continue; } if (calc_crc && id < 64 && (filter & (1ULL << id))) @@ -779,18 +741,6 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, else elem_parse_failed = true; break; - case WLAN_EID_VHT_CAPABILITY: - if (elen >= sizeof(struct ieee80211_vht_cap)) - elems->vht_cap_elem = (void *)pos; - else - elem_parse_failed = true; - break; - case WLAN_EID_VHT_OPERATION: - if (elen >= sizeof(struct ieee80211_vht_operation)) - elems->vht_operation = (void *)pos; - else - elem_parse_failed = true; - break; case WLAN_EID_MESH_ID: elems->mesh_id = pos; elems->mesh_id_len = elen; @@ -859,7 +809,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, if (elem_parse_failed) elems->parse_error = true; else - __set_bit(id, seen_elems); + set_bit(id, seen_elems); left -= elen; pos += elen; @@ -882,7 +832,6 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_queue_params qparam; - struct ieee80211_chanctx_conf *chanctx_conf; int ac; bool use_11b, enable_qos; int aCWmin, aCWmax; @@ -895,12 +844,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, memset(&qparam, 0, sizeof(qparam)); - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - use_11b = (chanctx_conf && - chanctx_conf->channel->band == IEEE80211_BAND_2GHZ) && + use_11b = (local->oper_channel->band == IEEE80211_BAND_2GHZ) && !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); - rcu_read_unlock(); /* * By default disable QoS in STA mode for old access points, which do @@ -979,7 +924,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, const size_t supp_rates_len, const u8 *supp_rates) { - struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_local *local = sdata->local; int i, have_higher_than_11mbit = 0; /* cf. IEEE 802.11 9.2.12 */ @@ -987,16 +932,11 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, if ((supp_rates[i] & 0x7f) * 5 > 110) have_higher_than_11mbit = 1; - rcu_read_lock(); - chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); - - if (chanctx_conf && - chanctx_conf->channel->band == IEEE80211_BAND_2GHZ && + if (local->oper_channel->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit) sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; else sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; - rcu_read_unlock(); ieee80211_set_wmm_default(sdata, true); } @@ -1028,7 +968,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local, } void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, - u16 transaction, u16 auth_alg, u16 status, + u16 transaction, u16 auth_alg, u8 *extra, size_t extra_len, const u8 *da, const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx) { @@ -1053,7 +993,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, memcpy(mgmt->bssid, bssid, ETH_ALEN); mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg); mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); - mgmt->u.auth.status_code = cpu_to_le16(status); + mgmt->u.auth.status_code = cpu_to_le16(0); if (extra) memcpy(skb_put(skb, extra_len), extra, extra_len); @@ -1266,7 +1206,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u32 ratemask, bool directed, bool no_cck, - struct ieee80211_channel *channel, bool scan) + struct ieee80211_channel *channel) { struct sk_buff *skb; @@ -1277,10 +1217,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, if (no_cck) IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_CCK_RATE; - if (scan) - ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band); - else - ieee80211_tx_skb(sdata, skb); + ieee80211_tx_skb(sdata, skb); } } @@ -1343,7 +1280,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) { struct ieee80211_hw *hw = &local->hw; struct ieee80211_sub_if_data *sdata; - struct ieee80211_chanctx *ctx; struct sta_info *sta; int res, i; @@ -1416,29 +1352,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) res = drv_add_interface(local, sdata); } - /* add channel contexts */ - mutex_lock(&local->chanctx_mtx); - list_for_each_entry(ctx, &local->chanctx_list, list) - WARN_ON(drv_add_chanctx(local, ctx)); - mutex_unlock(&local->chanctx_mtx); - - list_for_each_entry(sdata, &local->interfaces, list) { - struct ieee80211_chanctx_conf *ctx_conf; - - if (!ieee80211_sdata_running(sdata)) - continue; - - mutex_lock(&local->chanctx_mtx); - ctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); - if (ctx_conf) { - ctx = container_of(ctx_conf, struct ieee80211_chanctx, - conf); - drv_assign_vif_chanctx(local, sdata, ctx); - } - mutex_unlock(&local->chanctx_mtx); - } - /* add STAs back */ mutex_lock(&local->sta_mtx); list_for_each_entry(sta, &local->sta_list, list) { @@ -1494,8 +1407,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) BSS_CHANGED_BSSID | BSS_CHANGED_CQM | BSS_CHANGED_QOS | - BSS_CHANGED_IDLE | - BSS_CHANGED_TXPOWER; + BSS_CHANGED_IDLE; switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: @@ -1512,13 +1424,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) case NL80211_IFTYPE_AP: changed |= BSS_CHANGED_SSID; - if (sdata->vif.type == NL80211_IFTYPE_AP) { + if (sdata->vif.type == NL80211_IFTYPE_AP) changed |= BSS_CHANGED_AP_PROBE_RESP; - if (rcu_access_pointer(sdata->u.ap.beacon)) - drv_start_ap(local, sdata); - } - /* fall through */ case NL80211_IFTYPE_MESH_POINT: changed |= BSS_CHANGED_BEACON | @@ -1555,8 +1463,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; - if (!sdata->u.mgd.associated) - continue; ieee80211_send_nullfunc(local, sdata, 0); } @@ -1617,10 +1523,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) * If this is for hw restart things are still running. * We may want to change that later, however. */ - if (!local->suspended) { - drv_restart_complete(local); + if (!local->suspended) return 0; - } #ifdef CONFIG_PM /* first set suspended false, then resuming */ @@ -1683,24 +1587,68 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif) } EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); -void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata) +static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, + enum ieee80211_smps_mode *smps_mode) { - struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_chanctx *chanctx; + if (ifmgd->associated) { + *smps_mode = ifmgd->ap_smps; + + if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) { + if (ifmgd->powersave) + *smps_mode = IEEE80211_SMPS_DYNAMIC; + else + *smps_mode = IEEE80211_SMPS_OFF; + } + + return 1; + } + + return 0; +} - mutex_lock(&local->chanctx_mtx); +void ieee80211_recalc_smps(struct ieee80211_local *local) +{ + struct ieee80211_sub_if_data *sdata; + enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; + int count = 0; + + mutex_lock(&local->iflist_mtx); + + /* + * This function could be improved to handle multiple + * interfaces better, but right now it makes any + * non-station interfaces force SM PS to be turned + * off. If there are multiple station interfaces it + * could also use the best possible mode, e.g. if + * one is in static and the other in dynamic then + * dynamic is ok. + */ + + list_for_each_entry(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) + continue; + if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) + continue; + if (sdata->vif.type != NL80211_IFTYPE_STATION) + goto set; - chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, - lockdep_is_held(&local->chanctx_mtx)); + count += check_mgd_smps(&sdata->u.mgd, &smps_mode); - if (WARN_ON_ONCE(!chanctx_conf)) + if (count > 1) { + smps_mode = IEEE80211_SMPS_OFF; + break; + } + } + + if (smps_mode == local->smps_mode) goto unlock; - chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf); - ieee80211_recalc_smps_chanctx(local, chanctx); + set: + local->smps_mode = smps_mode; + /* changed flag is auto-detected for this */ + ieee80211_hw_config(local, 0); unlock: - mutex_unlock(&local->chanctx_mtx); + mutex_unlock(&local->iflist_mtx); } static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) @@ -1840,8 +1788,8 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, __le32 tmp; *pos++ = WLAN_EID_VHT_CAPABILITY; - *pos++ = sizeof(struct ieee80211_vht_cap); - memset(pos, 0, sizeof(struct ieee80211_vht_cap)); + *pos++ = sizeof(struct ieee80211_vht_capabilities); + memset(pos, 0, sizeof(struct ieee80211_vht_capabilities)); /* capability flags */ tmp = cpu_to_le32(cap); @@ -1999,19 +1947,3 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif) return ifmgd->ave_beacon_signal; } EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); - -u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs) -{ - if (!mcs) - return 1; - - /* TODO: consider rx_highest */ - - if (mcs->rx_mask[3]) - return 4; - if (mcs->rx_mask[2]) - return 3; - if (mcs->rx_mask[1]) - return 2; - return 1; -} diff --git a/trunk/net/mac80211/vht.c b/trunk/net/mac80211/vht.c deleted file mode 100644 index f311388aeedf..000000000000 --- a/trunk/net/mac80211/vht.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * VHT handling - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include "ieee80211_i.h" - - -void ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, - struct ieee80211_supported_band *sband, - struct ieee80211_vht_cap *vht_cap_ie, - struct ieee80211_sta_vht_cap *vht_cap) -{ - if (WARN_ON_ONCE(!vht_cap)) - return; - - memset(vht_cap, 0, sizeof(*vht_cap)); - - if (!vht_cap_ie || !sband->vht_cap.vht_supported) - return; - - vht_cap->vht_supported = true; - - vht_cap->cap = le32_to_cpu(vht_cap_ie->vht_cap_info); - - /* Copy peer MCS info, the driver might need them. */ - memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs, - sizeof(struct ieee80211_vht_mcs_info)); -} diff --git a/trunk/net/mac80211/wpa.c b/trunk/net/mac80211/wpa.c index 8bd2f5c6a56e..bdb53aba888e 100644 --- a/trunk/net/mac80211/wpa.c +++ b/trunk/net/mac80211/wpa.c @@ -106,8 +106,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_MMIC_ERROR) goto mic_fail; - if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && - rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) + if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) goto update_iv; return RX_CONTINUE; @@ -546,19 +545,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) static void bip_aad(struct sk_buff *skb, u8 *aad) { - __le16 mask_fc; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - /* BIP AAD: FC(masked) || A1 || A2 || A3 */ /* FC type/subtype */ + aad[0] = skb->data[0]; /* Mask FC Retry, PwrMgt, MoreData flags to zero */ - mask_fc = hdr->frame_control; - mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM | - IEEE80211_FCTL_MOREDATA); - put_unaligned(mask_fc, (__le16 *) &aad[0]); + aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); /* A1 || A2 || A3 */ - memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN); + memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); } diff --git a/trunk/net/nfc/Kconfig b/trunk/net/nfc/Kconfig index 60c3bbb63e8e..8d8d9bc4b6ff 100644 --- a/trunk/net/nfc/Kconfig +++ b/trunk/net/nfc/Kconfig @@ -3,8 +3,8 @@ # menuconfig NFC - depends on NET - tristate "NFC subsystem support" + depends on NET && EXPERIMENTAL + tristate "NFC subsystem support (EXPERIMENTAL)" default n help Say Y here if you want to build support for NFC (Near field diff --git a/trunk/net/nfc/core.c b/trunk/net/nfc/core.c index aa64ea441676..479bee36dc3e 100644 --- a/trunk/net/nfc/core.c +++ b/trunk/net/nfc/core.c @@ -40,9 +40,6 @@ int nfc_devlist_generation; DEFINE_MUTEX(nfc_devlist_mutex); -/* NFC device ID bitmap */ -static DEFINE_IDA(nfc_index_ida); - /** * nfc_dev_up - turn on the NFC device * @@ -184,7 +181,6 @@ int nfc_stop_poll(struct nfc_dev *dev) dev->ops->stop_poll(dev); dev->polling = false; - dev->rf_mode = NFC_RF_NONE; error: device_unlock(&dev->dev); @@ -198,7 +194,7 @@ static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx) if (dev->n_targets == 0) return NULL; - for (i = 0; i < dev->n_targets; i++) { + for (i = 0; i < dev->n_targets ; i++) { if (dev->targets[i].idx == target_idx) return &dev->targets[i]; } @@ -278,14 +274,12 @@ int nfc_dep_link_down(struct nfc_dev *dev) if (!rc) { dev->dep_link_up = false; dev->active_target = NULL; - dev->rf_mode = NFC_RF_NONE; nfc_llcp_mac_is_down(dev); nfc_genl_dep_link_down_event(dev); } error: device_unlock(&dev->dev); - return rc; } @@ -509,7 +503,6 @@ EXPORT_SYMBOL(nfc_tm_activated); int nfc_tm_deactivated(struct nfc_dev *dev) { dev->dep_link_up = false; - dev->rf_mode = NFC_RF_NONE; return nfc_genl_tm_deactivated(dev); } @@ -704,8 +697,6 @@ static void nfc_check_pres_work(struct work_struct *work) if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) { rc = dev->ops->check_presence(dev, dev->active_target); - if (rc == -EOPNOTSUPP) - goto exit; if (!rc) { mod_timer(&dev->check_pres_timer, jiffies + msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); @@ -717,7 +708,6 @@ static void nfc_check_pres_work(struct work_struct *work) } } -exit: device_unlock(&dev->dev); } @@ -763,6 +753,7 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, u32 supported_protocols, int tx_headroom, int tx_tailroom) { + static atomic_t dev_no = ATOMIC_INIT(0); struct nfc_dev *dev; if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || @@ -776,6 +767,11 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, if (!dev) return NULL; + dev->dev.class = &nfc_class; + dev->idx = atomic_inc_return(&dev_no) - 1; + dev_set_name(&dev->dev, "nfc%d", dev->idx); + device_initialize(&dev->dev); + dev->ops = ops; dev->supported_protocols = supported_protocols; dev->tx_headroom = tx_headroom; @@ -783,7 +779,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, nfc_genl_data_init(&dev->genl_data); - dev->rf_mode = NFC_RF_NONE; /* first generation must not be 0 */ dev->targets_generation = 1; @@ -811,14 +806,6 @@ int nfc_register_device(struct nfc_dev *dev) pr_debug("dev_name=%s\n", dev_name(&dev->dev)); - dev->idx = ida_simple_get(&nfc_index_ida, 0, 0, GFP_KERNEL); - if (dev->idx < 0) - return dev->idx; - - dev->dev.class = &nfc_class; - dev_set_name(&dev->dev, "nfc%d", dev->idx); - device_initialize(&dev->dev); - mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; rc = device_add(&dev->dev); @@ -847,12 +834,10 @@ EXPORT_SYMBOL(nfc_register_device); */ void nfc_unregister_device(struct nfc_dev *dev) { - int rc, id; + int rc; pr_debug("dev_name=%s\n", dev_name(&dev->dev)); - id = dev->idx; - mutex_lock(&nfc_devlist_mutex); nfc_devlist_generation++; @@ -871,8 +856,6 @@ void nfc_unregister_device(struct nfc_dev *dev) pr_debug("The userspace won't be notified that the device %s was removed\n", dev_name(&dev->dev)); - ida_simple_remove(&nfc_index_ida, id); - } EXPORT_SYMBOL(nfc_unregister_device); diff --git a/trunk/net/nfc/hci/command.c b/trunk/net/nfc/hci/command.c index 7d99410e6c1a..71c6a7086b8f 100644 --- a/trunk/net/nfc/hci/command.c +++ b/trunk/net/nfc/hci/command.c @@ -257,16 +257,16 @@ static u8 nfc_hci_create_pipe(struct nfc_hci_dev *hdev, u8 dest_host, *result = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, NFC_HCI_ADM_CREATE_PIPE, (u8 *) ¶ms, sizeof(params), &skb); - if (*result < 0) - return NFC_HCI_INVALID_PIPE; - - resp = (struct hci_create_pipe_resp *)skb->data; - pipe = resp->pipe; - kfree_skb(skb); + if (*result == 0) { + resp = (struct hci_create_pipe_resp *)skb->data; + pipe = resp->pipe; + kfree_skb(skb); - pr_debug("pipe created=%d\n", pipe); + pr_debug("pipe created=%d\n", pipe); - return pipe; + return pipe; + } else + return NFC_HCI_INVALID_PIPE; } static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) @@ -279,6 +279,8 @@ static int nfc_hci_delete_pipe(struct nfc_hci_dev *hdev, u8 pipe) static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) { + int r; + u8 param[2]; /* TODO: Find out what the identity reference data is @@ -286,8 +288,10 @@ static int nfc_hci_clear_all_pipes(struct nfc_hci_dev *hdev) pr_debug("\n"); - return nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, - NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); + r = nfc_hci_execute_cmd(hdev, NFC_HCI_ADMIN_PIPE, + NFC_HCI_ADM_CLEAR_ALL_PIPE, param, 2, NULL); + + return 0; } int nfc_hci_disconnect_gate(struct nfc_hci_dev *hdev, u8 gate) @@ -344,7 +348,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return -EADDRINUSE; if (pipe != NFC_HCI_INVALID_PIPE) - goto open_pipe; + goto pipe_is_open; switch (dest_gate) { case NFC_HCI_LINK_MGMT_GATE: @@ -361,7 +365,6 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, break; } -open_pipe: r = nfc_hci_open_pipe(hdev, pipe); if (r < 0) { if (pipe_created) @@ -372,6 +375,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return r; } +pipe_is_open: hdev->gate2pipe[dest_gate] = pipe; return 0; diff --git a/trunk/net/nfc/hci/core.c b/trunk/net/nfc/hci/core.c index 7bea574d5934..5fbb6e40793e 100644 --- a/trunk/net/nfc/hci/core.c +++ b/trunk/net/nfc/hci/core.c @@ -33,20 +33,17 @@ /* Largest headroom needed for outgoing HCI commands */ #define HCI_CMDS_HEADROOM 1 -int nfc_hci_result_to_errno(u8 result) +static int nfc_hci_result_to_errno(u8 result) { switch (result) { case NFC_HCI_ANY_OK: return 0; - case NFC_HCI_ANY_E_REG_PAR_UNKNOWN: - return -EOPNOTSUPP; case NFC_HCI_ANY_E_TIMEOUT: return -ETIME; default: return -1; } } -EXPORT_SYMBOL(nfc_hci_result_to_errno); static void nfc_hci_msg_tx_work(struct work_struct *work) { @@ -68,9 +65,8 @@ static void nfc_hci_msg_tx_work(struct work_struct *work) -ETIME); kfree(hdev->cmd_pending_msg); hdev->cmd_pending_msg = NULL; - } else { + } else goto exit; - } } next_msg: @@ -170,7 +166,7 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, kfree_skb(skb); } -u32 nfc_hci_sak_to_protocol(u8 sak) +static u32 nfc_hci_sak_to_protocol(u8 sak) { switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) { case NFC_HCI_TYPE_A_SEL_PROT_MIFARE: @@ -185,9 +181,8 @@ u32 nfc_hci_sak_to_protocol(u8 sak) return 0xffffffff; } } -EXPORT_SYMBOL(nfc_hci_sak_to_protocol); -int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) +static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) { struct nfc_target *targets; struct sk_buff *atqa_skb = NULL; @@ -268,9 +263,7 @@ int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) break; } - /* if driver set the new gate, we will skip the old one */ - if (targets->hci_reader_gate == 0x00) - targets->hci_reader_gate = gate; + targets->hci_reader_gate = gate; r = nfc_targets_found(hdev->ndev, targets, 1); @@ -282,18 +275,11 @@ int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) return r; } -EXPORT_SYMBOL(nfc_hci_target_discovered); void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, struct sk_buff *skb) { int r = 0; - u8 gate = nfc_hci_pipe2gate(hdev, pipe); - - if (gate == 0xff) { - pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); - goto exit; - } switch (event) { case NFC_HCI_EVT_TARGET_DISCOVERED: @@ -317,14 +303,12 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, goto exit; } - r = nfc_hci_target_discovered(hdev, gate); + r = nfc_hci_target_discovered(hdev, + nfc_hci_pipe2gate(hdev, pipe)); break; default: - if (hdev->ops->event_received) { - hdev->ops->event_received(hdev, gate, event, skb); - return; - } - + /* TODO: Unknown events are hardware specific + * pass them to the driver (needs a new hci_ops) */ break; } @@ -426,10 +410,6 @@ static int hci_dev_version(struct nfc_hci_dev *hdev) r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, NFC_HCI_ID_MGMT_VERSION_SW, &skb); - if (r == -EOPNOTSUPP) { - pr_info("Software/Hardware info not available\n"); - return 0; - } if (r < 0) return r; @@ -547,8 +527,7 @@ static int hci_start_poll(struct nfc_dev *nfc_dev, return hdev->ops->start_poll(hdev, im_protocols, tm_protocols); else return nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, - NFC_HCI_EVT_READER_REQUESTED, - NULL, 0); + NFC_HCI_EVT_READER_REQUESTED, NULL, 0); } static void hci_stop_poll(struct nfc_dev *nfc_dev) @@ -559,28 +538,6 @@ static void hci_stop_poll(struct nfc_dev *nfc_dev) NFC_HCI_EVT_END_OPERATION, NULL, 0); } -static int hci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, - __u8 comm_mode, __u8 *gb, size_t gb_len) -{ - struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); - - if (hdev->ops->dep_link_up) - return hdev->ops->dep_link_up(hdev, target, comm_mode, - gb, gb_len); - - return 0; -} - -static int hci_dep_link_down(struct nfc_dev *nfc_dev) -{ - struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); - - if (hdev->ops->dep_link_down) - return hdev->ops->dep_link_down(hdev); - - return 0; -} - static int hci_activate_target(struct nfc_dev *nfc_dev, struct nfc_target *target, u32 protocol) { @@ -629,8 +586,8 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, switch (target->hci_reader_gate) { case NFC_HCI_RF_READER_A_GATE: case NFC_HCI_RF_READER_B_GATE: - if (hdev->ops->im_transceive) { - r = hdev->ops->im_transceive(hdev, target, skb, cb, + if (hdev->ops->data_exchange) { + r = hdev->ops->data_exchange(hdev, target, skb, cb, cb_context); if (r <= 0) /* handled */ break; @@ -647,14 +604,14 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, skb->len, hci_transceive_cb, hdev); break; default: - if (hdev->ops->im_transceive) { - r = hdev->ops->im_transceive(hdev, target, skb, cb, + if (hdev->ops->data_exchange) { + r = hdev->ops->data_exchange(hdev, target, skb, cb, cb_context); if (r == 1) r = -ENOTSUPP; - } else { - r = -ENOTSUPP; } + else + r = -ENOTSUPP; break; } @@ -663,16 +620,6 @@ static int hci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, return r; } -static int hci_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) -{ - struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev); - - if (hdev->ops->tm_send) - return hdev->ops->tm_send(hdev, skb); - else - return -ENOTSUPP; -} - static int hci_check_presence(struct nfc_dev *nfc_dev, struct nfc_target *target) { @@ -776,12 +723,9 @@ static struct nfc_ops hci_nfc_ops = { .dev_down = hci_dev_down, .start_poll = hci_start_poll, .stop_poll = hci_stop_poll, - .dep_link_up = hci_dep_link_up, - .dep_link_down = hci_dep_link_down, .activate_target = hci_activate_target, .deactivate_target = hci_deactivate_target, .im_transceive = hci_transceive, - .tm_send = hci_tm_send, .check_presence = hci_check_presence, }; @@ -904,7 +848,7 @@ void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err) } EXPORT_SYMBOL(nfc_hci_driver_failure); -void nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) +void inline nfc_hci_recv_frame(struct nfc_hci_dev *hdev, struct sk_buff *skb) { nfc_llc_rcv_from_drv(hdev->llc, skb); } diff --git a/trunk/net/nfc/hci/llc.c b/trunk/net/nfc/hci/llc.c index fe5e966e5b88..ae1205ded87f 100644 --- a/trunk/net/nfc/hci/llc.c +++ b/trunk/net/nfc/hci/llc.c @@ -72,7 +72,7 @@ int nfc_llc_register(const char *name, struct nfc_llc_ops *ops) llc_engine->ops = ops; INIT_LIST_HEAD(&llc_engine->entry); - list_add_tail(&llc_engine->entry, &llc_engines); + list_add_tail (&llc_engine->entry, &llc_engines); return 0; } diff --git a/trunk/net/nfc/hci/llc_shdlc.c b/trunk/net/nfc/hci/llc_shdlc.c index 27b313befc35..01cbc72943cd 100644 --- a/trunk/net/nfc/hci/llc_shdlc.c +++ b/trunk/net/nfc/hci/llc_shdlc.c @@ -634,9 +634,9 @@ static void llc_shdlc_sm_work(struct work_struct *work) r = llc_shdlc_connect_initiate(shdlc); else r = -ETIME; - if (r < 0) { + if (r < 0) llc_shdlc_connect_complete(shdlc, r); - } else { + else { mod_timer(&shdlc->connect_timer, jiffies + msecs_to_jiffies(SHDLC_CONNECT_VALUE_MS)); @@ -682,8 +682,9 @@ static void llc_shdlc_sm_work(struct work_struct *work) llc_shdlc_handle_send_queue(shdlc); } - if (shdlc->hard_fault) + if (shdlc->hard_fault) { shdlc->llc_failure(shdlc->hdev, shdlc->hard_fault); + } break; default: break; diff --git a/trunk/net/nfc/llcp/Kconfig b/trunk/net/nfc/llcp/Kconfig index a1a41cd68255..fbf5e8150908 100644 --- a/trunk/net/nfc/llcp/Kconfig +++ b/trunk/net/nfc/llcp/Kconfig @@ -1,6 +1,6 @@ config NFC_LLCP - depends on NFC - bool "NFC LLCP support" + depends on NFC && EXPERIMENTAL + bool "NFC LLCP support (EXPERIMENTAL)" default n help Say Y here if you want to build support for a kernel NFC LLCP diff --git a/trunk/net/nfc/llcp/commands.c b/trunk/net/nfc/llcp/commands.c index df24be48d4da..c45ccd6c094c 100644 --- a/trunk/net/nfc/llcp/commands.c +++ b/trunk/net/nfc/llcp/commands.c @@ -261,6 +261,7 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock) struct sk_buff *skb; struct nfc_dev *dev; struct nfc_llcp_local *local; + u16 size = 0; pr_debug("Sending DISC\n"); @@ -272,10 +273,17 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock) if (dev == NULL) return -ENODEV; - skb = llcp_allocate_pdu(sock, LLCP_PDU_DISC, 0); + size += LLCP_HEADER_SIZE; + size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; + + skb = alloc_skb(size, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; + skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); + + skb = llcp_add_header(skb, sock->dsap, sock->ssap, LLCP_PDU_DISC); + skb_queue_tail(&local->tx_queue, skb); return 0; @@ -316,7 +324,8 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) struct sk_buff *skb; u8 *service_name_tlv = NULL, service_name_tlv_length; u8 *miux_tlv = NULL, miux_tlv_length; - u8 *rw_tlv = NULL, rw_tlv_length; + u8 *rw_tlv = NULL, rw_tlv_length, rw; + __be16 miux; int err; u16 size = 0; @@ -334,11 +343,13 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) size += service_name_tlv_length; } - miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, + miux = cpu_to_be16(LLCP_MAX_MIUX); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); size += miux_tlv_length; - rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); + rw = LLCP_MAX_RW; + rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); size += rw_tlv_length; pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); @@ -375,7 +386,8 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) struct nfc_llcp_local *local; struct sk_buff *skb; u8 *miux_tlv = NULL, miux_tlv_length; - u8 *rw_tlv = NULL, rw_tlv_length; + u8 *rw_tlv = NULL, rw_tlv_length, rw; + __be16 miux; int err; u16 size = 0; @@ -385,11 +397,13 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) if (local == NULL) return -ENODEV; - miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, + miux = cpu_to_be16(LLCP_MAX_MIUX); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_tlv_length); size += miux_tlv_length; - rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); + rw = LLCP_MAX_RW; + rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); size += rw_tlv_length; skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); @@ -414,52 +428,6 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) return err; } -int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap) -{ - struct sk_buff *skb; - struct nfc_dev *dev; - u8 *sdres_tlv = NULL, sdres_tlv_length, sdres[2]; - u16 size = 0; - - pr_debug("Sending SNL tid 0x%x sap 0x%x\n", tid, sap); - - if (local == NULL) - return -ENODEV; - - dev = local->dev; - if (dev == NULL) - return -ENODEV; - - sdres[0] = tid; - sdres[1] = sap; - sdres_tlv = nfc_llcp_build_tlv(LLCP_TLV_SDRES, sdres, 0, - &sdres_tlv_length); - if (sdres_tlv == NULL) - return -ENOMEM; - - size += LLCP_HEADER_SIZE; - size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE; - size += sdres_tlv_length; - - skb = alloc_skb(size, GFP_KERNEL); - if (skb == NULL) { - kfree(sdres_tlv); - return -ENOMEM; - } - - skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); - - skb = llcp_add_header(skb, LLCP_SAP_SDP, LLCP_SAP_SDP, LLCP_PDU_SNL); - - memcpy(skb_put(skb, sdres_tlv_length), sdres_tlv, sdres_tlv_length); - - skb_queue_tail(&local->tx_queue, skb); - - kfree(sdres_tlv); - - return 0; -} - int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) { struct sk_buff *skb; @@ -528,23 +496,6 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, if (local == NULL) return -ENODEV; - /* Remote is ready but has not acknowledged our frames */ - if((sock->remote_ready && - skb_queue_len(&sock->tx_pending_queue) >= sock->rw && - skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { - pr_err("Pending queue is full %d frames\n", - skb_queue_len(&sock->tx_pending_queue)); - return -ENOBUFS; - } - - /* Remote is not ready and we've been queueing enough frames */ - if ((!sock->remote_ready && - skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { - pr_err("Tx queue is full %d frames\n", - skb_queue_len(&sock->tx_queue)); - return -ENOBUFS; - } - msg_data = kzalloc(len, GFP_KERNEL); if (msg_data == NULL) return -ENOMEM; @@ -590,63 +541,6 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, return len; } -int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, - struct msghdr *msg, size_t len) -{ - struct sk_buff *pdu; - struct nfc_llcp_local *local; - size_t frag_len = 0, remaining_len; - u8 *msg_ptr, *msg_data; - int err; - - pr_debug("Send UI frame len %zd\n", len); - - local = sock->local; - if (local == NULL) - return -ENODEV; - - msg_data = kzalloc(len, GFP_KERNEL); - if (msg_data == NULL) - return -ENOMEM; - - if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { - kfree(msg_data); - return -EFAULT; - } - - remaining_len = len; - msg_ptr = msg_data; - - while (remaining_len > 0) { - - frag_len = min_t(size_t, sock->miu, remaining_len); - - pr_debug("Fragment %zd bytes remaining %zd", - frag_len, remaining_len); - - pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, - frag_len + LLCP_HEADER_SIZE, &err); - if (pdu == NULL) { - pr_err("Could not allocate PDU\n"); - continue; - } - - pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); - - memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); - - /* No need to check for the peer RW for UI frames */ - skb_queue_tail(&local->tx_queue, pdu); - - remaining_len -= frag_len; - msg_ptr += frag_len; - } - - kfree(msg_data); - - return len; -} - int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) { struct sk_buff *skb; diff --git a/trunk/net/nfc/llcp/llcp.c b/trunk/net/nfc/llcp/llcp.c index 2df87056c6df..cc10d073c338 100644 --- a/trunk/net/nfc/llcp/llcp.c +++ b/trunk/net/nfc/llcp/llcp.c @@ -45,38 +45,12 @@ void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *sk) write_unlock(&l->lock); } -static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) -{ - struct nfc_llcp_local *local = sock->local; - struct sk_buff *s, *tmp; - - pr_debug("%p\n", &sock->sk); - - skb_queue_purge(&sock->tx_queue); - skb_queue_purge(&sock->tx_pending_queue); - skb_queue_purge(&sock->tx_backlog_queue); - - if (local == NULL) - return; - - /* Search for local pending SKBs that are related to this socket */ - skb_queue_walk_safe(&local->tx_queue, s, tmp) { - if (s->sk != &sock->sk) - continue; - - skb_unlink(s, &local->tx_queue); - kfree_skb(s); - } -} - static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) { struct sock *sk; struct hlist_node *node, *tmp; struct nfc_llcp_sock *llcp_sock; - skb_queue_purge(&local->tx_queue); - write_lock(&local->sockets.lock); sk_for_each_safe(sk, node, tmp, &local->sockets.head) { @@ -84,8 +58,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) bh_lock_sock(sk); - nfc_llcp_socket_purge(llcp_sock); - if (sk->sk_state == LLCP_CONNECTED) nfc_put_device(llcp_sock->dev); @@ -93,8 +65,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) struct nfc_llcp_sock *lsk, *n; struct sock *accept_sk; - list_for_each_entry_safe(lsk, n, - &llcp_sock->accept_queue, + list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, accept_queue) { accept_sk = &lsk->sk; bh_lock_sock(accept_sk); @@ -114,16 +85,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) } } - /* - * If we have a connection less socket bound, we keep it alive - * if the device is still present. - */ - if (sk->sk_state == LLCP_BOUND && sk->sk_type == SOCK_DGRAM && - listen == true) { - bh_unlock_sock(sk); - continue; - } - sk->sk_state = LLCP_CLOSED; bh_unlock_sock(sk); @@ -173,7 +134,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, { struct sock *sk; struct hlist_node *node; - struct nfc_llcp_sock *llcp_sock, *tmp_sock; + struct nfc_llcp_sock *llcp_sock; pr_debug("ssap dsap %d %d\n", ssap, dsap); @@ -185,12 +146,10 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, llcp_sock = NULL; sk_for_each(sk, node, &local->sockets.head) { - tmp_sock = nfc_llcp_sock(sk); + llcp_sock = nfc_llcp_sock(sk); - if (tmp_sock->ssap == ssap && tmp_sock->dsap == dsap) { - llcp_sock = tmp_sock; + if (llcp_sock->ssap == ssap && llcp_sock->dsap == dsap) break; - } } read_unlock(&local->sockets.lock); @@ -290,12 +249,7 @@ struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local, pr_debug("llcp sock %p\n", tmp_sock); - if (tmp_sock->sk.sk_type == SOCK_STREAM && - tmp_sock->sk.sk_state != LLCP_LISTEN) - continue; - - if (tmp_sock->sk.sk_type == SOCK_DGRAM && - tmp_sock->sk.sk_state != LLCP_BOUND) + if (tmp_sock->sk.sk_state != LLCP_LISTEN) continue; if (tmp_sock->service_name == NULL || @@ -467,9 +421,10 @@ static u8 nfc_llcp_reserve_sdp_ssap(struct nfc_llcp_local *local) static int nfc_llcp_build_gb(struct nfc_llcp_local *local) { u8 *gb_cur, *version_tlv, version, version_length; - u8 *lto_tlv, lto_length; + u8 *lto_tlv, lto, lto_length; u8 *wks_tlv, wks_length; u8 *miux_tlv, miux_length; + __be16 miux; u8 gb_len = 0; int ret = 0; @@ -478,7 +433,9 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) 1, &version_length); gb_len += version_length; - lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, <o_length); + /* 1500 ms */ + lto = 150; + lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, <o, 1, <o_length); gb_len += lto_length; pr_debug("Local wks 0x%lx\n", local->local_wks); @@ -486,7 +443,8 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) &wks_length); gb_len += wks_length; - miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, + miux = cpu_to_be16(LLCP_MAX_MIUX); + miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, &miux_length); gb_len += miux_length; @@ -652,12 +610,7 @@ static void nfc_llcp_tx_work(struct work_struct *work) if (skb != NULL) { sk = skb->sk; llcp_sock = nfc_llcp_sock(sk); - - if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) { - nfc_llcp_send_symm(local->dev); - } else { - struct sk_buff *copy_skb = NULL; - u8 ptype = nfc_llcp_ptype(skb); + if (llcp_sock != NULL) { int ret; pr_debug("Sending pending skb\n"); @@ -665,29 +618,24 @@ static void nfc_llcp_tx_work(struct work_struct *work) DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, true); - if (ptype == LLCP_PDU_I) - copy_skb = skb_copy(skb, GFP_ATOMIC); - nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_TX); ret = nfc_data_exchange(local->dev, local->target_idx, skb, nfc_llcp_recv, local); - if (ret) { - kfree_skb(copy_skb); - goto out; - } - - if (ptype == LLCP_PDU_I && copy_skb) + if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) { + skb = skb_get(skb); skb_queue_tail(&llcp_sock->tx_pending_queue, - copy_skb); + skb); + } + } else { + nfc_llcp_send_symm(local->dev); } } else { nfc_llcp_send_symm(local->dev); } -out: mod_timer(&local->link_timer, jiffies + msecs_to_jiffies(2 * local->remote_lto)); } @@ -756,39 +704,6 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len) return NULL; } -static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, - struct sk_buff *skb) -{ - struct nfc_llcp_sock *llcp_sock; - struct nfc_llcp_ui_cb *ui_cb; - u8 dsap, ssap; - - dsap = nfc_llcp_dsap(skb); - ssap = nfc_llcp_ssap(skb); - - ui_cb = nfc_llcp_ui_skb_cb(skb); - ui_cb->dsap = dsap; - ui_cb->ssap = ssap; - - printk("%s %d %d\n", __func__, dsap, ssap); - - pr_debug("%d %d\n", dsap, ssap); - - /* We're looking for a bound socket, not a client one */ - llcp_sock = nfc_llcp_sock_get(local, dsap, LLCP_SAP_SDP); - if (llcp_sock == NULL || llcp_sock->sk.sk_type != SOCK_DGRAM) - return; - - /* There is no sequence with UI frames */ - skb_pull(skb, LLCP_HEADER_SIZE); - if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) { - pr_err("receive queue is full\n"); - skb_queue_head(&llcp_sock->tx_backlog_queue, skb); - } - - nfc_llcp_sock_put(llcp_sock); -} - static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, struct sk_buff *skb) { @@ -908,6 +823,9 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, fail: /* Send DM */ nfc_llcp_send_dm(local, dsap, ssap, reason); + + return; + } int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) @@ -1035,9 +953,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, sk = &llcp_sock->sk; lock_sock(sk); - - nfc_llcp_socket_purge(llcp_sock); - if (sk->sk_state == LLCP_CLOSED) { release_sock(sk); nfc_llcp_sock_put(llcp_sock); @@ -1112,7 +1027,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) } if (llcp_sock == NULL) { - pr_debug("Already closed\n"); + pr_err("Invalid DM\n"); return; } @@ -1123,100 +1038,8 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) sk->sk_state_change(sk); nfc_llcp_sock_put(llcp_sock); -} - -static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, - struct sk_buff *skb) -{ - struct nfc_llcp_sock *llcp_sock; - u8 dsap, ssap, *tlv, type, length, tid, sap; - u16 tlv_len, offset; - char *service_name; - size_t service_name_len; - - dsap = nfc_llcp_dsap(skb); - ssap = nfc_llcp_ssap(skb); - - pr_debug("%d %d\n", dsap, ssap); - - if (dsap != LLCP_SAP_SDP || ssap != LLCP_SAP_SDP) { - pr_err("Wrong SNL SAP\n"); - return; - } - - tlv = &skb->data[LLCP_HEADER_SIZE]; - tlv_len = skb->len - LLCP_HEADER_SIZE; - offset = 0; - - while (offset < tlv_len) { - type = tlv[0]; - length = tlv[1]; - - switch (type) { - case LLCP_TLV_SDREQ: - tid = tlv[2]; - service_name = (char *) &tlv[3]; - service_name_len = length - 1; - - pr_debug("Looking for %.16s\n", service_name); - - if (service_name_len == strlen("urn:nfc:sn:sdp") && - !strncmp(service_name, "urn:nfc:sn:sdp", - service_name_len)) { - sap = 1; - goto send_snl; - } - - llcp_sock = nfc_llcp_sock_from_sn(local, service_name, - service_name_len); - if (!llcp_sock) { - sap = 0; - goto send_snl; - } - /* - * We found a socket but its ssap has not been reserved - * yet. We need to assign it for good and send a reply. - * The ssap will be freed when the socket is closed. - */ - if (llcp_sock->ssap == LLCP_SDP_UNBOUND) { - atomic_t *client_count; - - sap = nfc_llcp_reserve_sdp_ssap(local); - - pr_debug("Reserving %d\n", sap); - - if (sap == LLCP_SAP_MAX) { - sap = 0; - goto send_snl; - } - - client_count = - &local->local_sdp_cnt[sap - - LLCP_WKS_NUM_SAP]; - - atomic_inc(client_count); - - llcp_sock->ssap = sap; - llcp_sock->reserved_ssap = sap; - } else { - sap = llcp_sock->ssap; - } - - pr_debug("%p %d\n", llcp_sock, sap); - -send_snl: - nfc_llcp_send_snl(local, tid, sap); - break; - - default: - pr_err("Invalid SNL tlv value 0x%x\n", type); - break; - } - - offset += length + 2; - tlv += length + 2; - } + return; } static void nfc_llcp_rx_work(struct work_struct *work) @@ -1249,11 +1072,6 @@ static void nfc_llcp_rx_work(struct work_struct *work) pr_debug("SYMM\n"); break; - case LLCP_PDU_UI: - pr_debug("UI\n"); - nfc_llcp_recv_ui(local, skb); - break; - case LLCP_PDU_CONNECT: pr_debug("CONNECT\n"); nfc_llcp_recv_connect(local, skb); @@ -1274,11 +1092,6 @@ static void nfc_llcp_rx_work(struct work_struct *work) nfc_llcp_recv_dm(local, skb); break; - case LLCP_PDU_SNL: - pr_debug("SNL\n"); - nfc_llcp_recv_snl(local, skb); - break; - case LLCP_PDU_I: case LLCP_PDU_RR: case LLCP_PDU_RNR: @@ -1291,6 +1104,8 @@ static void nfc_llcp_rx_work(struct work_struct *work) schedule_work(&local->tx_work); kfree_skb(local->rx_pending); local->rx_pending = NULL; + + return; } void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) @@ -1306,6 +1121,8 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) local->rx_pending = skb_get(skb); del_timer(&local->link_timer); schedule_work(&local->rx_work); + + return; } int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb) @@ -1388,16 +1205,12 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) rwlock_init(&local->connecting_sockets.lock); rwlock_init(&local->raw_sockets.lock); - local->lto = 150; /* 1500 ms */ - local->rw = LLCP_MAX_RW; - local->miux = cpu_to_be16(LLCP_MAX_MIUX); - nfc_llcp_build_gb(local); local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&local->list, &llcp_devices); + list_add(&llcp_devices, &local->list); return 0; } diff --git a/trunk/net/nfc/llcp/llcp.h b/trunk/net/nfc/llcp/llcp.h index 0d62366f8cc3..fdb2d24e60bd 100644 --- a/trunk/net/nfc/llcp/llcp.h +++ b/trunk/net/nfc/llcp/llcp.h @@ -64,9 +64,6 @@ struct nfc_llcp_local { u32 target_idx; u8 rf_mode; u8 comm_mode; - u8 lto; - u8 rw; - __be16 miux; unsigned long local_wks; /* Well known services */ unsigned long local_sdp; /* Local services */ unsigned long local_sap; /* Local SAPs, not available for discovery */ @@ -127,13 +124,6 @@ struct nfc_llcp_sock { struct sock *parent; }; -struct nfc_llcp_ui_cb { - __u8 dsap; - __u8 ssap; -}; - -#define nfc_llcp_ui_skb_cb(__skb) ((struct nfc_llcp_ui_cb *)&((__skb)->cb[0])) - #define nfc_llcp_sock(sk) ((struct nfc_llcp_sock *) (sk)) #define nfc_llcp_dev(sk) (nfc_llcp_sock((sk))->dev) @@ -219,13 +209,10 @@ int nfc_llcp_disconnect(struct nfc_llcp_sock *sock); int nfc_llcp_send_symm(struct nfc_dev *dev); int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); -int nfc_llcp_send_snl(struct nfc_llcp_local *local, u8 tid, u8 sap); int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, struct msghdr *msg, size_t len); -int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, - struct msghdr *msg, size_t len); int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); /* Socket API */ diff --git a/trunk/net/nfc/llcp/sock.c b/trunk/net/nfc/llcp/sock.c index 0fa1e92ceac8..63e4cdc92376 100644 --- a/trunk/net/nfc/llcp/sock.c +++ b/trunk/net/nfc/llcp/sock.c @@ -205,8 +205,8 @@ static int llcp_sock_listen(struct socket *sock, int backlog) lock_sock(sk); - if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) || - sk->sk_state != LLCP_BOUND) { + if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) + || sk->sk_state != LLCP_BOUND) { ret = -EBADFD; goto error; } @@ -608,25 +608,6 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); - if (sk->sk_type == SOCK_DGRAM) { - struct sockaddr_nfc_llcp *addr = - (struct sockaddr_nfc_llcp *)msg->msg_name; - - if (msg->msg_namelen < sizeof(*addr)) { - release_sock(sk); - - pr_err("Invalid socket address length %d\n", - msg->msg_namelen); - - return -EINVAL; - } - - release_sock(sk); - - return nfc_llcp_send_ui_frame(llcp_sock, addr->dsap, addr->ssap, - msg, len); - } - if (sk->sk_state != LLCP_CONNECTED) { release_sock(sk); return -ENOTCONN; @@ -682,28 +663,11 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, return -EFAULT; } - if (sk->sk_type == SOCK_DGRAM && msg->msg_name) { - struct nfc_llcp_ui_cb *ui_cb = nfc_llcp_ui_skb_cb(skb); - struct sockaddr_nfc_llcp sockaddr; - - pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap); - - sockaddr.sa_family = AF_NFC; - sockaddr.nfc_protocol = NFC_PROTO_NFC_DEP; - sockaddr.dsap = ui_cb->dsap; - sockaddr.ssap = ui_cb->ssap; - - memcpy(msg->msg_name, &sockaddr, sizeof(sockaddr)); - msg->msg_namelen = sizeof(sockaddr); - } - /* Mark read part of skb as used */ if (!(flags & MSG_PEEK)) { /* SOCK_STREAM: re-queue skb if it contains unreceived data */ - if (sk->sk_type == SOCK_STREAM || - sk->sk_type == SOCK_DGRAM || - sk->sk_type == SOCK_RAW) { + if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_RAW) { skb_pull(skb, copied); if (skb->len) { skb_queue_head(&sk->sk_receive_queue, skb); diff --git a/trunk/net/nfc/nci/Kconfig b/trunk/net/nfc/nci/Kconfig index 6d69b5f0f19b..decdc49b26d8 100644 --- a/trunk/net/nfc/nci/Kconfig +++ b/trunk/net/nfc/nci/Kconfig @@ -1,6 +1,6 @@ config NFC_NCI - depends on NFC - tristate "NCI protocol support" + depends on NFC && EXPERIMENTAL + tristate "NCI protocol support (EXPERIMENTAL)" default n help NCI (NFC Controller Interface) is a communication protocol between diff --git a/trunk/net/nfc/nci/core.c b/trunk/net/nfc/nci/core.c index 5f98dc1bf039..acf9abb7d99b 100644 --- a/trunk/net/nfc/nci/core.c +++ b/trunk/net/nfc/nci/core.c @@ -205,10 +205,10 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) cmd.num_disc_configs = 0; if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && - (protocols & NFC_PROTO_JEWEL_MASK || - protocols & NFC_PROTO_MIFARE_MASK || - protocols & NFC_PROTO_ISO14443_MASK || - protocols & NFC_PROTO_NFC_DEP_MASK)) { + (protocols & NFC_PROTO_JEWEL_MASK + || protocols & NFC_PROTO_MIFARE_MASK + || protocols & NFC_PROTO_ISO14443_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = NCI_NFC_A_PASSIVE_POLL_MODE; cmd.disc_configs[cmd.num_disc_configs].frequency = 1; @@ -224,8 +224,8 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) } if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && - (protocols & NFC_PROTO_FELICA_MASK || - protocols & NFC_PROTO_NFC_DEP_MASK)) { + (protocols & NFC_PROTO_FELICA_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = NCI_NFC_F_PASSIVE_POLL_MODE; cmd.disc_configs[cmd.num_disc_configs].frequency = 1; @@ -414,13 +414,13 @@ static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev) struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); struct nci_set_config_param param; __u8 local_gb[NFC_MAX_GT_LEN]; - int i; + int i, rc = 0; param.val = nfc_get_local_general_bytes(nfc_dev, ¶m.len); if ((param.val == NULL) || (param.len == 0)) - return 0; + return rc; - if (param.len > NFC_MAX_GT_LEN) + if (param.len > NCI_MAX_PARAM_LEN) return -EINVAL; for (i = 0; i < param.len; i++) @@ -429,8 +429,10 @@ static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev) param.id = NCI_PN_ATR_REQ_GEN_BYTES; param.val = local_gb; - return nci_request(ndev, nci_set_config_req, (unsigned long)¶m, - msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT)); + rc = nci_request(ndev, nci_set_config_req, (unsigned long)¶m, + msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT)); + + return rc; } static int nci_start_poll(struct nfc_dev *nfc_dev, @@ -577,6 +579,7 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, } } + static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, __u8 comm_mode, __u8 *gb, size_t gb_len) { @@ -803,8 +806,8 @@ int nci_recv_frame(struct sk_buff *skb) pr_debug("len %d\n", skb->len); - if (!ndev || (!test_bit(NCI_UP, &ndev->flags) && - !test_bit(NCI_INIT, &ndev->flags))) { + if (!ndev || (!test_bit(NCI_UP, &ndev->flags) + && !test_bit(NCI_INIT, &ndev->flags))) { kfree_skb(skb); return -ENXIO; } diff --git a/trunk/net/nfc/netlink.c b/trunk/net/nfc/netlink.c index 3568ae16786d..c1b5285cbde7 100644 --- a/trunk/net/nfc/netlink.c +++ b/trunk/net/nfc/netlink.c @@ -29,8 +29,6 @@ #include "nfc.h" -#include "llcp/llcp.h" - static struct genl_multicast_group nfc_genl_event_mcgrp = { .name = NFC_GENL_MCAST_EVENT_NAME, }; @@ -366,8 +364,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) || nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) || - nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) || - nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode)) + nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up)) goto nla_put_failure; return genlmsg_end(msg, hdr); @@ -593,7 +590,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] && !info->attrs[NFC_ATTR_PROTOCOLS]) && - !info->attrs[NFC_ATTR_TM_PROTOCOLS])) + !info->attrs[NFC_ATTR_TM_PROTOCOLS])) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); @@ -718,146 +715,6 @@ static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info) return rc; } -static int nfc_genl_send_params(struct sk_buff *msg, - struct nfc_llcp_local *local, - u32 portid, u32 seq) -{ - void *hdr; - - hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0, - NFC_CMD_LLC_GET_PARAMS); - if (!hdr) - return -EMSGSIZE; - - if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) || - nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) || - nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) || - nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux))) - goto nla_put_failure; - - return genlmsg_end(msg, hdr); - -nla_put_failure: - - genlmsg_cancel(msg, hdr); - return -EMSGSIZE; -} - -static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info) -{ - struct nfc_dev *dev; - struct nfc_llcp_local *local; - int rc = 0; - struct sk_buff *msg = NULL; - u32 idx; - - if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) - return -EINVAL; - - idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); - - dev = nfc_get_device(idx); - if (!dev) - return -ENODEV; - - device_lock(&dev->dev); - - local = nfc_llcp_find_local(dev); - if (!local) { - rc = -ENODEV; - goto exit; - } - - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - rc = -ENOMEM; - goto exit; - } - - rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq); - -exit: - device_unlock(&dev->dev); - - nfc_put_device(dev); - - if (rc < 0) { - if (msg) - nlmsg_free(msg); - - return rc; - } - - return genlmsg_reply(msg, info); -} - -static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) -{ - struct nfc_dev *dev; - struct nfc_llcp_local *local; - u8 rw = 0; - u16 miux = 0; - u32 idx; - int rc = 0; - - if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || - (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] && - !info->attrs[NFC_ATTR_LLC_PARAM_RW] && - !info->attrs[NFC_ATTR_LLC_PARAM_MIUX])) - return -EINVAL; - - if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) { - rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]); - - if (rw > LLCP_MAX_RW) - return -EINVAL; - } - - if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) { - miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]); - - if (miux > LLCP_MAX_MIUX) - return -EINVAL; - } - - idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); - - dev = nfc_get_device(idx); - if (!dev) - return -ENODEV; - - device_lock(&dev->dev); - - local = nfc_llcp_find_local(dev); - if (!local) { - nfc_put_device(dev); - rc = -ENODEV; - goto exit; - } - - if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) { - if (dev->dep_link_up) { - rc = -EINPROGRESS; - goto exit; - } - - local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]); - } - - if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) - local->rw = rw; - - if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) - local->miux = cpu_to_be16(miux); - -exit: - device_unlock(&dev->dev); - - nfc_put_device(dev); - - return rc; -} - static struct genl_ops nfc_genl_ops[] = { { .cmd = NFC_CMD_GET_DEVICE, @@ -902,16 +759,6 @@ static struct genl_ops nfc_genl_ops[] = { .done = nfc_genl_dump_targets_done, .policy = nfc_genl_policy, }, - { - .cmd = NFC_CMD_LLC_GET_PARAMS, - .doit = nfc_genl_llc_get_params, - .policy = nfc_genl_policy, - }, - { - .cmd = NFC_CMD_LLC_SET_PARAMS, - .doit = nfc_genl_llc_set_params, - .policy = nfc_genl_policy, - }, }; diff --git a/trunk/net/nfc/nfc.h b/trunk/net/nfc/nfc.h index 87d914d2876a..c5e42b79a418 100644 --- a/trunk/net/nfc/nfc.h +++ b/trunk/net/nfc/nfc.h @@ -56,7 +56,6 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev); int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); -struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); int __init nfc_llcp_init(void); void nfc_llcp_exit(void); @@ -98,11 +97,6 @@ static inline int nfc_llcp_data_received(struct nfc_dev *dev, return 0; } -static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) -{ - return NULL; -} - static inline int nfc_llcp_init(void) { return 0; diff --git a/trunk/net/nfc/rawsock.c b/trunk/net/nfc/rawsock.c index 313bf1bc848a..8b8a6a2b2bad 100644 --- a/trunk/net/nfc/rawsock.c +++ b/trunk/net/nfc/rawsock.c @@ -256,6 +256,7 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, return rc ? : copied; } + static const struct proto_ops rawsock_ops = { .family = PF_NFC, .owner = THIS_MODULE, diff --git a/trunk/net/wireless/Kconfig b/trunk/net/wireless/Kconfig index 16d08b399210..fe4adb12b3ef 100644 --- a/trunk/net/wireless/Kconfig +++ b/trunk/net/wireless/Kconfig @@ -140,13 +140,14 @@ config CFG80211_WEXT extensions with cfg80211-based drivers. config LIB80211 - tristate + tristate "Common routines for IEEE802.11 drivers" default n help This options enables a library of common routines used by IEEE802.11 wireless LAN drivers. - Drivers should select this themselves if needed. + Drivers should select this themselves if needed. Say Y if + you want this built into your kernel. config LIB80211_CRYPT_WEP tristate diff --git a/trunk/net/wireless/Makefile b/trunk/net/wireless/Makefile index a761670af31d..0f7e0d621ab0 100644 --- a/trunk/net/wireless/Makefile +++ b/trunk/net/wireless/Makefile @@ -10,13 +10,11 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o -CFLAGS_trace.o := -I$(src) - ccflags-y += -D__CHECK_ENDIAN__ $(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk diff --git a/trunk/net/wireless/ap.c b/trunk/net/wireless/ap.c index 324e8d851dc4..fcc60d8dbefa 100644 --- a/trunk/net/wireless/ap.c +++ b/trunk/net/wireless/ap.c @@ -3,7 +3,6 @@ #include #include "nl80211.h" #include "core.h" -#include "rdev-ops.h" static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, @@ -24,11 +23,10 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, if (!wdev->beacon_interval) return -ENOENT; - err = rdev_stop_ap(rdev, dev); + err = rdev->ops->stop_ap(&rdev->wiphy, dev); if (!err) { wdev->beacon_interval = 0; wdev->channel = NULL; - wdev->ssid_len = 0; } return err; diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index 48febd2160ba..2f876b9ee344 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -9,7 +9,6 @@ #include #include #include "core.h" -#include "rdev-ops.h" struct ieee80211_channel * rdev_freq_to_chan(struct cfg80211_registered_device *rdev, @@ -53,8 +52,6 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, struct ieee80211_channel *sec_chan; int diff; - trace_cfg80211_can_beacon_sec_chan(wiphy, chan, channel_type); - switch (channel_type) { case NL80211_CHAN_HT40PLUS: diff = 20; @@ -63,25 +60,20 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, diff = -20; break; default: - trace_cfg80211_return_bool(true); return true; } sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); - if (!sec_chan) { - trace_cfg80211_return_bool(false); + if (!sec_chan) return false; - } /* we'll need a DFS capability later */ if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR)) { - trace_cfg80211_return_bool(false); + IEEE80211_CHAN_RADAR)) return false; - } - trace_cfg80211_return_bool(true); + return true; } EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan); @@ -100,7 +92,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, if (!chan) return -EINVAL; - return rdev_set_monitor_channel(rdev, chan, chantype); + return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); } void diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 14d990400354..443d4d7deea2 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -26,7 +26,6 @@ #include "debugfs.h" #include "wext-compat.h" #include "ethtool.h" -#include "rdev-ops.h" /* name for sysfs, %d is appended */ #define PHY_NAME "phy" @@ -217,7 +216,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) { struct cfg80211_registered_device *rdev = data; - rdev_rfkill_poll(rdev); + rdev->ops->rfkill_poll(&rdev->wiphy); } static int cfg80211_rfkill_set_block(void *data, bool blocked) @@ -241,7 +240,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) case NL80211_IFTYPE_P2P_DEVICE: if (!wdev->p2p_started) break; - rdev_stop_p2p_device(rdev, wdev); + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); wdev->p2p_started = false; rdev->opencount--; break; @@ -326,8 +325,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) mutex_init(&rdev->devlist_mtx); mutex_init(&rdev->sched_scan_mtx); INIT_LIST_HEAD(&rdev->wdev_list); - INIT_LIST_HEAD(&rdev->beacon_registrations); - spin_lock_init(&rdev->beacon_registrations_lock); spin_lock_init(&rdev->bss_lock); INIT_LIST_HEAD(&rdev->bss_list); INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); @@ -373,8 +370,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) rdev->wiphy.rts_threshold = (u32) -1; rdev->wiphy.coverage_class = 0; - rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; - return &rdev->wiphy; } EXPORT_SYMBOL(wiphy_new); @@ -531,7 +526,8 @@ int wiphy_register(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; - sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mag = + sband->channels[i].max_antenna_gain; sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band; @@ -692,7 +688,7 @@ void wiphy_unregister(struct wiphy *wiphy) flush_work(&rdev->event_work); if (rdev->wowlan && rdev->ops->set_wakeup) - rdev_set_wakeup(rdev, false); + rdev->ops->set_wakeup(&rdev->wiphy, false); cfg80211_rdev_free_wowlan(rdev); } EXPORT_SYMBOL(wiphy_unregister); @@ -700,15 +696,10 @@ EXPORT_SYMBOL(wiphy_unregister); void cfg80211_dev_free(struct cfg80211_registered_device *rdev) { struct cfg80211_internal_bss *scan, *tmp; - struct cfg80211_beacon_registration *reg, *treg; rfkill_destroy(rdev->rfkill); mutex_destroy(&rdev->mtx); mutex_destroy(&rdev->devlist_mtx); mutex_destroy(&rdev->sched_scan_mtx); - list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { - list_del(®->list); - kfree(reg); - } list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) cfg80211_put_bss(&scan->pub); kfree(rdev); @@ -780,7 +771,7 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev) case NL80211_IFTYPE_P2P_DEVICE: if (!wdev->p2p_started) break; - rdev_stop_p2p_device(rdev, wdev); + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); wdev->p2p_started = false; rdev->opencount--; break; @@ -971,8 +962,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && rdev->ops->set_power_mgmt) - if (rdev_set_power_mgmt(rdev, dev, wdev->ps, - wdev->ps_timeout)) { + if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, + wdev->ps, + wdev->ps_timeout)) { /* assume this means it's off */ wdev->ps = false; } diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index e53831c876bb..a343be4a52bd 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -55,8 +55,7 @@ struct cfg80211_registered_device { int opencount; /* also protected by devlist_mtx */ wait_queue_head_t dev_wait; - struct list_head beacon_registrations; - spinlock_t beacon_registrations_lock; + u32 ap_beacons_nlportid; /* protected by RTNL only */ int num_running_ifaces; @@ -261,10 +260,6 @@ enum cfg80211_chan_mode { CHAN_MODE_EXCLUSIVE, }; -struct cfg80211_beacon_registration { - struct list_head list; - u32 nlportid; -}; /* free object */ extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); @@ -325,15 +320,13 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, const u8 *bssid, const u8 *ssid, int ssid_len, const u8 *ie, int ie_len, - const u8 *key, int key_len, int key_idx, - const u8 *sae_data, int sae_data_len); + const u8 *key, int key_len, int key_idx); int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_auth_type auth_type, const u8 *bssid, const u8 *ssid, int ssid_len, const u8 *ie, int ie_len, - const u8 *key, int key_len, int key_idx, - const u8 *sae_data, int sae_data_len); + const u8 *key, int key_len, int key_idx); int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, struct net_device *dev, struct ieee80211_channel *chan, diff --git a/trunk/net/wireless/ethtool.c b/trunk/net/wireless/ethtool.c index 48c48ffafa1d..7eecdf40cf80 100644 --- a/trunk/net/wireless/ethtool.c +++ b/trunk/net/wireless/ethtool.c @@ -2,7 +2,6 @@ #include #include "core.h" #include "ethtool.h" -#include "rdev-ops.h" static void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -48,8 +47,9 @@ static void cfg80211_get_ringparam(struct net_device *dev, memset(rp, 0, sizeof(*rp)); if (rdev->ops->get_ringparam) - rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending, - &rp->rx_pending, &rp->rx_max_pending); + rdev->ops->get_ringparam(wdev->wiphy, + &rp->tx_pending, &rp->tx_max_pending, + &rp->rx_pending, &rp->rx_max_pending); } static int cfg80211_set_ringparam(struct net_device *dev, @@ -62,7 +62,8 @@ static int cfg80211_set_ringparam(struct net_device *dev, return -EINVAL; if (rdev->ops->set_ringparam) - return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending); + return rdev->ops->set_ringparam(wdev->wiphy, + rp->tx_pending, rp->rx_pending); return -ENOTSUPP; } @@ -72,7 +73,7 @@ static int cfg80211_get_sset_count(struct net_device *dev, int sset) struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); if (rdev->ops->get_et_sset_count) - return rdev_get_et_sset_count(rdev, dev, sset); + return rdev->ops->get_et_sset_count(wdev->wiphy, dev, sset); return -EOPNOTSUPP; } @@ -82,7 +83,7 @@ static void cfg80211_get_stats(struct net_device *dev, struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); if (rdev->ops->get_et_stats) - rdev_get_et_stats(rdev, dev, stats, data); + rdev->ops->get_et_stats(wdev->wiphy, dev, stats, data); } static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) @@ -90,7 +91,7 @@ static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data) struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); if (rdev->ops->get_et_strings) - rdev_get_et_strings(rdev, dev, sset, data); + rdev->ops->get_et_strings(wdev->wiphy, dev, sset, data); } const struct ethtool_ops cfg80211_ethtool_ops = { diff --git a/trunk/net/wireless/ibss.c b/trunk/net/wireless/ibss.c index 27941d5db72b..ca5672f6ee2f 100644 --- a/trunk/net/wireless/ibss.c +++ b/trunk/net/wireless/ibss.c @@ -11,7 +11,6 @@ #include #include "wext-compat.h" #include "nl80211.h" -#include "rdev-ops.h" void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) @@ -62,8 +61,6 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) struct cfg80211_event *ev; unsigned long flags; - trace_cfg80211_ibss_joined(dev, bssid); - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); ev = kzalloc(sizeof(*ev), gfp); @@ -131,7 +128,7 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, return err; } - err = rdev_join_ibss(rdev, dev, params); + err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); if (err) { wdev->connect_keys = NULL; wdev->sme_state = CFG80211_SME_IDLE; @@ -178,7 +175,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev_del_key(rdev, dev, i, false, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); @@ -214,7 +211,7 @@ int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, if (!wdev->ssid_len) return -ENOLINK; - err = rdev_leave_ibss(rdev, dev); + err = rdev->ops->leave_ibss(&rdev->wiphy, dev); if (err) return err; diff --git a/trunk/net/wireless/mesh.c b/trunk/net/wireless/mesh.c index 966cfc4cd79d..c384e77ff77a 100644 --- a/trunk/net/wireless/mesh.c +++ b/trunk/net/wireless/mesh.c @@ -3,7 +3,6 @@ #include #include "nl80211.h" #include "core.h" -#include "rdev-ops.h" /* Default values, timeouts in ms */ #define MESH_TTL 31 @@ -161,7 +160,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, if (err) return err; - err = rdev_join_mesh(rdev, dev, conf, setup); + err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); if (!err) { memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); wdev->mesh_id_len = setup->mesh_id_len; @@ -221,8 +220,9 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, if (err) return err; - err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, - channel); + err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, + wdev->netdev, + channel); if (!err) wdev->channel = channel; @@ -242,7 +242,6 @@ void cfg80211_notify_new_peer_candidate(struct net_device *dev, { struct wireless_dev *wdev = dev->ieee80211_ptr; - trace_cfg80211_notify_new_peer_candidate(dev, macaddr); if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) return; @@ -268,7 +267,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, if (!wdev->mesh_id_len) return -ENOTCONN; - err = rdev_leave_mesh(rdev, dev); + err = rdev->ops->leave_mesh(&rdev->wiphy, dev); if (!err) { wdev->mesh_id_len = 0; wdev->channel = NULL; diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index 4bfd14f7c592..8016fee0752b 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -15,8 +15,6 @@ #include #include "core.h" #include "nl80211.h" -#include "rdev-ops.h" - void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) { @@ -24,7 +22,6 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_send_rx_auth(dev); wdev_lock(wdev); nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); @@ -45,7 +42,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, u8 *ie = mgmt->u.assoc_resp.variable; int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); - trace_cfg80211_send_rx_assoc(dev, bss); wdev_lock(wdev); status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); @@ -102,7 +98,6 @@ void __cfg80211_send_deauth(struct net_device *dev, const u8 *bssid = mgmt->bssid; bool was_current = false; - trace___cfg80211_send_deauth(dev); ASSERT_WDEV_LOCK(wdev); if (wdev->current_bss && @@ -152,7 +147,6 @@ void __cfg80211_send_disassoc(struct net_device *dev, u16 reason_code; bool from_ap; - trace___cfg80211_send_disassoc(dev); ASSERT_WDEV_LOCK(wdev); nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); @@ -194,7 +188,6 @@ void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_send_unprot_deauth(dev); nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC); } EXPORT_SYMBOL(cfg80211_send_unprot_deauth); @@ -206,7 +199,6 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_send_unprot_disassoc(dev); nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC); } EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); @@ -217,7 +209,6 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_send_auth_timeout(dev, addr); wdev_lock(wdev); nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); @@ -236,7 +227,6 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_send_assoc_timeout(dev, addr); wdev_lock(wdev); nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); @@ -271,7 +261,6 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, } #endif - trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc); nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp); } EXPORT_SYMBOL(cfg80211_michael_mic_failure); @@ -284,8 +273,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, const u8 *bssid, const u8 *ssid, int ssid_len, const u8 *ie, int ie_len, - const u8 *key, int key_len, int key_idx, - const u8 *sae_data, int sae_data_len) + const u8 *key, int key_len, int key_idx) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_auth_request req; @@ -305,8 +293,6 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, req.ie = ie; req.ie_len = ie_len; - req.sae_data = sae_data; - req.sae_data_len = sae_data_len; req.auth_type = auth_type; req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); @@ -321,7 +307,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, if (err) goto out; - err = rdev_auth(rdev, dev, &req); + err = rdev->ops->auth(&rdev->wiphy, dev, &req); out: cfg80211_put_bss(req.bss); @@ -333,8 +319,7 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, enum nl80211_auth_type auth_type, const u8 *bssid, const u8 *ssid, int ssid_len, const u8 *ie, int ie_len, - const u8 *key, int key_len, int key_idx, - const u8 *sae_data, int sae_data_len) + const u8 *key, int key_len, int key_idx) { int err; @@ -342,8 +327,7 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, wdev_lock(dev->ieee80211_ptr); err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, ssid, ssid_len, ie, ie_len, - key, key_len, key_idx, - sae_data, sae_data_len); + key, key_len, key_idx); wdev_unlock(dev->ieee80211_ptr); mutex_unlock(&rdev->devlist_mtx); @@ -426,7 +410,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, if (err) goto out; - err = rdev_assoc(rdev, dev, &req); + err = rdev->ops->assoc(&rdev->wiphy, dev, &req); out: if (err) { @@ -473,16 +457,22 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, .reason_code = reason, .ie = ie, .ie_len = ie_len, - .local_state_change = local_state_change, }; ASSERT_WDEV_LOCK(wdev); - if (local_state_change && (!wdev->current_bss || - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) + if (local_state_change) { + if (wdev->current_bss && + ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { + cfg80211_unhold_bss(wdev->current_bss); + cfg80211_put_bss(&wdev->current_bss->pub); + wdev->current_bss = NULL; + } + return 0; + } - return rdev_deauth(rdev, dev, &req); + return rdev->ops->deauth(&rdev->wiphy, dev, &req); } int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, @@ -527,7 +517,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, else return -ENOTCONN; - return rdev_disassoc(rdev, dev, &req); + return rdev->ops->disassoc(&rdev->wiphy, dev, &req); } int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, @@ -568,7 +558,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); req.bssid = bssid; - rdev_deauth(rdev, dev, &req); + rdev->ops->deauth(&rdev->wiphy, dev, &req); if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); @@ -585,8 +575,6 @@ void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, - duration); nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type, duration, gfp); } @@ -600,8 +588,6 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan, - channel_type); nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, channel_type, gfp); } @@ -613,7 +599,6 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_new_sta(dev, mac_addr, sinfo); nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp); } EXPORT_SYMBOL(cfg80211_new_sta); @@ -623,7 +608,6 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp) struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_del_sta(dev, mac_addr); nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp); } EXPORT_SYMBOL(cfg80211_del_sta); @@ -704,7 +688,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid, list_add(&nreg->list, &wdev->mgmt_registrations); if (rdev->ops->mgmt_frame_register) - rdev_mgmt_frame_register(rdev, wdev, frame_type, true); + rdev->ops->mgmt_frame_register(wiphy, wdev, frame_type, true); out: spin_unlock_bh(&wdev->mgmt_registrations_lock); @@ -727,8 +711,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid) if (rdev->ops->mgmt_frame_register) { u16 frame_type = le16_to_cpu(reg->frame_type); - rdev_mgmt_frame_register(rdev, wdev, - frame_type, false); + rdev->ops->mgmt_frame_register(wiphy, wdev, + frame_type, false); } list_del(®->list); @@ -854,10 +838,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, return -EINVAL; /* Transmit the Action frame as requested by user space */ - return rdev_mgmt_tx(rdev, wdev, chan, offchan, - channel_type, channel_type_valid, - wait, buf, len, no_cck, dont_wait_for_ack, - cookie); + return rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, + channel_type, channel_type_valid, + wait, buf, len, no_cck, dont_wait_for_ack, + cookie); } bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, @@ -876,13 +860,10 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); u16 stype; - trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm); stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; - if (!(stypes->rx & BIT(stype))) { - trace_cfg80211_return_bool(false); + if (!(stypes->rx & BIT(stype))) return false; - } data = buf + ieee80211_hdrlen(mgmt->frame_control); data_len = len - ieee80211_hdrlen(mgmt->frame_control); @@ -913,7 +894,6 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, spin_unlock_bh(&wdev->mgmt_registrations_lock); - trace_cfg80211_return_bool(result); return result; } EXPORT_SYMBOL(cfg80211_rx_mgmt); @@ -924,8 +904,6 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_mgmt_tx_status(wdev, cookie, ack); - /* Indicate TX status of the Action frame to user space */ nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp); } @@ -939,8 +917,6 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_cqm_rssi_notify(dev, rssi_event); - /* Indicate roaming trigger event to user space */ nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp); } @@ -953,8 +929,6 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets); - /* Indicate roaming trigger event to user space */ nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp); } @@ -980,7 +954,6 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_gtk_rekey_notify(dev, bssid); nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); } EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); @@ -992,7 +965,6 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth); nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); } EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); @@ -1005,8 +977,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); struct ieee80211_channel *chan; - trace_cfg80211_ch_switch_notify(dev, freq, type); - wdev_lock(wdev); if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && @@ -1029,18 +999,12 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; - bool ret; - - trace_cfg80211_rx_spurious_frame(dev, addr); if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && - wdev->iftype != NL80211_IFTYPE_P2P_GO)) { - trace_cfg80211_return_bool(false); + wdev->iftype != NL80211_IFTYPE_P2P_GO)) return false; - } - ret = nl80211_unexpected_frame(dev, addr, gfp); - trace_cfg80211_return_bool(ret); - return ret; + + return nl80211_unexpected_frame(dev, addr, gfp); } EXPORT_SYMBOL(cfg80211_rx_spurious_frame); @@ -1048,18 +1012,12 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; - bool ret; - - trace_cfg80211_rx_unexpected_4addr_frame(dev, addr); if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && wdev->iftype != NL80211_IFTYPE_P2P_GO && - wdev->iftype != NL80211_IFTYPE_AP_VLAN)) { - trace_cfg80211_return_bool(false); + wdev->iftype != NL80211_IFTYPE_AP_VLAN)) return false; - } - ret = nl80211_unexpected_4addr_frame(dev, addr, gfp); - trace_cfg80211_return_bool(ret); - return ret; + + return nl80211_unexpected_4addr_frame(dev, addr, gfp); } EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index c18b2fc9d492..0418a6d5c1a6 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -22,8 +22,8 @@ #include "core.h" #include "nl80211.h" #include "reg.h" -#include "rdev-ops.h" +static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type); static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, struct genl_info *info, struct cfg80211_crypto_settings *settings, @@ -355,9 +355,6 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, - [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, }, - [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, - [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, }; /* policy for the key attributes */ @@ -693,7 +690,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) static struct cfg80211_cached_keys * nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, - struct nlattr *keys, bool *no_ht) + struct nlattr *keys) { struct key_parse parse; struct nlattr *key; @@ -736,12 +733,6 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, result->params[parse.idx].key_len = parse.p.key_len; result->params[parse.idx].key = result->data[parse.idx]; memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); - - if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 || - parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) { - if (no_ht) - *no_ht = true; - } } return result; @@ -952,7 +943,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { u32 tx_ant = 0, rx_ant = 0; int res; - res = rdev_get_antenna(dev, &tx_ant, &rx_ant); + res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); if (!res) { if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant) || @@ -1110,7 +1101,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag goto nla_put_failure; } CMD(start_p2p_device, START_P2P_DEVICE); - CMD(set_mcast_rate, SET_MCAST_RATE); #ifdef CONFIG_NL80211_TESTMODE CMD(testmode_cmd, TESTMODE); @@ -1467,7 +1457,7 @@ static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); - return rdev_set_wds_peer(rdev, dev, bssid); + return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); } @@ -1517,8 +1507,10 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) result = 0; mutex_lock(&rdev->mtx); - } else + } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr)) wdev = netdev->ieee80211_ptr; + else + wdev = NULL; /* * end workaround code, by now the rdev is available @@ -1570,29 +1562,24 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) if (result) goto bad_res; - result = rdev_set_txq_params(rdev, netdev, - &txq_params); + result = rdev->ops->set_txq_params(&rdev->wiphy, + netdev, + &txq_params); if (result) goto bad_res; } } if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { - result = __nl80211_set_channel(rdev, - nl80211_can_set_dev_channel(wdev) ? wdev : NULL, - info); + result = __nl80211_set_channel(rdev, wdev, info); if (result) goto bad_res; } if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { - struct wireless_dev *txp_wdev = wdev; enum nl80211_tx_power_setting type; int idx, mbm = 0; - if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) - txp_wdev = NULL; - if (!rdev->ops->set_tx_power) { result = -EOPNOTSUPP; goto bad_res; @@ -1612,7 +1599,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) mbm = nla_get_u32(info->attrs[idx]); } - result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); + result = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); if (result) goto bad_res; } @@ -1641,7 +1628,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; - result = rdev_set_antenna(rdev, tx_ant, rx_ant); + result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); if (result) goto bad_res; } @@ -1726,7 +1713,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) if (changed & WIPHY_PARAM_COVERAGE_CLASS) rdev->wiphy.coverage_class = coverage_class; - result = rdev_set_wiphy_params(rdev, changed); + result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); if (result) { rdev->wiphy.retry_short = old_retry_short; rdev->wiphy.retry_long = old_retry_long; @@ -1778,7 +1765,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag struct ieee80211_channel *chan; enum nl80211_channel_type channel_type; - chan = rdev_get_channel(rdev, wdev, &channel_type); + chan = rdev->ops->get_channel(&rdev->wiphy, wdev, + &channel_type); if (chan && (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || @@ -1787,11 +1775,6 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag goto nla_put_failure; } - if (wdev->ssid_len) { - if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) - goto nla_put_failure; - } - return genlmsg_end(msg, hdr); nla_put_failure: @@ -2031,9 +2014,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, &flags); - wdev = rdev_add_virtual_intf(rdev, - nla_data(info->attrs[NL80211_ATTR_IFNAME]), - type, err ? NULL : &flags, ¶ms); + wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, + nla_data(info->attrs[NL80211_ATTR_IFNAME]), + type, err ? NULL : &flags, ¶ms); if (IS_ERR(wdev)) { nlmsg_free(msg); return PTR_ERR(wdev); @@ -2100,7 +2083,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) if (!wdev->netdev) info->user_ptr[1] = NULL; - return rdev_del_virtual_intf(rdev, wdev); + return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); } static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) @@ -2117,7 +2100,7 @@ static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]); - return rdev_set_noack_map(rdev, dev, noack_map); + return rdev->ops->set_noack_map(&rdev->wiphy, dev, noack_map); } struct get_key_cookie { @@ -2227,8 +2210,8 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) return -ENOENT; - err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, - get_key_callback); + err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise, + mac_addr, &cookie, get_key_callback); if (err) goto free_msg; @@ -2276,7 +2259,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) if (err) goto out; - err = rdev_set_default_key(rdev, dev, key.idx, + err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, key.def_uni, key.def_multi); if (err) @@ -2300,7 +2283,8 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) if (err) goto out; - err = rdev_set_default_mgmt_key(rdev, dev, key.idx); + err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, + dev, key.idx); if (err) goto out; @@ -2356,9 +2340,9 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); if (!err) - err = rdev_add_key(rdev, dev, key.idx, - key.type == NL80211_KEYTYPE_PAIRWISE, - mac_addr, &key.p); + err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr, &key.p); wdev_unlock(dev->ieee80211_ptr); return err; @@ -2402,9 +2386,9 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) err = -ENOENT; if (!err) - err = rdev_del_key(rdev, dev, key.idx, - key.type == NL80211_KEYTYPE_PAIRWISE, - mac_addr); + err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr); #ifdef CONFIG_CFG80211_WEXT if (!err) { @@ -2506,30 +2490,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, return ret; } -static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, - enum nl80211_auth_type auth_type, - enum nl80211_commands cmd) -{ - if (auth_type > NL80211_AUTHTYPE_MAX) - return false; - - switch (cmd) { - case NL80211_CMD_AUTHENTICATE: - if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) && - auth_type == NL80211_AUTHTYPE_SAE) - return false; - return true; - case NL80211_CMD_CONNECT: - case NL80211_CMD_START_AP: - /* SAE not supported yet */ - if (auth_type == NL80211_AUTHTYPE_SAE) - return false; - return true; - default: - return false; - } -} - static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2599,8 +2559,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { params.auth_type = nla_get_u32( info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(rdev, params.auth_type, - NL80211_CMD_START_AP)) + if (!nl80211_valid_auth_type(params.auth_type)) return -EINVAL; } else params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; @@ -2648,14 +2607,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) if (err) return err; - err = rdev_start_ap(rdev, dev, ¶ms); + err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); if (!err) { wdev->preset_chan = params.channel; wdev->preset_chantype = params.channel_type; wdev->beacon_interval = params.beacon_interval; wdev->channel = params.channel; - wdev->ssid_len = params.ssid_len; - memcpy(wdev->ssid, params.ssid, wdev->ssid_len); } return err; } @@ -2682,7 +2639,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) if (err) return err; - return rdev_change_beacon(rdev, dev, ¶ms); + return rdev->ops->change_beacon(&rdev->wiphy, dev, ¶ms); } static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) @@ -2966,8 +2923,8 @@ static int nl80211_dump_station(struct sk_buff *skb, while (1) { memset(&sinfo, 0, sizeof(sinfo)); - err = rdev_dump_station(dev, netdev, sta_idx, - mac_addr, &sinfo); + err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, + mac_addr, &sinfo); if (err == -ENOENT) break; if (err) @@ -3012,7 +2969,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->get_station) return -EOPNOTSUPP; - err = rdev_get_station(rdev, dev, mac_addr, &sinfo); + err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); if (err) return err; @@ -3189,7 +3146,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) /* be aware of params.vlan when changing code here */ - err = rdev_change_station(rdev, dev, mac_addr, ¶ms); + err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, ¶ms); if (params.vlan) dev_put(params.vlan); @@ -3241,10 +3198,6 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) params.ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); - if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) - params.vht_capa = - nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); - if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) params.plink_action = nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); @@ -3322,7 +3275,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) /* be aware of params.vlan when changing code here */ - err = rdev_add_station(rdev, dev, mac_addr, ¶ms); + err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, ¶ms); if (params.vlan) dev_put(params.vlan); @@ -3347,7 +3300,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_station) return -EOPNOTSUPP; - return rdev_del_station(rdev, dev, mac_addr); + return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); } static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, @@ -3429,8 +3382,8 @@ static int nl80211_dump_mpath(struct sk_buff *skb, } while (1) { - err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop, - &pinfo); + err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx, + dst, next_hop, &pinfo); if (err == -ENOENT) break; if (err) @@ -3477,7 +3430,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo); + err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); if (err) return err; @@ -3516,7 +3469,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - return rdev_change_mpath(rdev, dev, dst, next_hop); + return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); } static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) @@ -3541,7 +3494,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; - return rdev_add_mpath(rdev, dev, dst, next_hop); + return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); } static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) @@ -3556,7 +3509,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->del_mpath) return -EOPNOTSUPP; - return rdev_del_mpath(rdev, dev, dst); + return rdev->ops->del_mpath(&rdev->wiphy, dev, dst); } static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) @@ -3601,7 +3554,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) return -EOPNOTSUPP; - return rdev_change_bss(rdev, dev, ¶ms); + return rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); } static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { @@ -3715,7 +3668,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, if (!wdev->mesh_id_len) memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); else - err = rdev_get_mesh_config(rdev, dev, &cur_params); + err = rdev->ops->get_mesh_config(&rdev->wiphy, dev, + &cur_params); wdev_unlock(wdev); if (err) @@ -4017,7 +3971,8 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, err = -ENOLINK; if (!err) - err = rdev_update_mesh_config(rdev, dev, mask, &cfg); + err = rdev->ops->update_mesh_config(&rdev->wiphy, dev, + mask, &cfg); wdev_unlock(wdev); @@ -4382,27 +4337,14 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) } } - if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { - request->flags = nla_get_u32( - info->attrs[NL80211_ATTR_SCAN_FLAGS]); - if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || - ((request->flags & NL80211_SCAN_FLAG_FLUSH) && - !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { - err = -EOPNOTSUPP; - goto out_free; - } - } - request->no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); request->wdev = wdev; request->wiphy = &rdev->wiphy; - request->scan_start = jiffies; rdev->scan_req = request; - err = rdev_scan(rdev, request); + err = rdev->ops->scan(&rdev->wiphy, request); if (!err) { nl80211_send_scan_start(rdev, wdev); @@ -4626,24 +4568,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->ie_len); } - if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { - request->flags = nla_get_u32( - info->attrs[NL80211_ATTR_SCAN_FLAGS]); - if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && - !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || - ((request->flags & NL80211_SCAN_FLAG_FLUSH) && - !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { - err = -EOPNOTSUPP; - goto out_free; - } - } - request->dev = dev; request->wiphy = &rdev->wiphy; request->interval = interval; - request->scan_start = jiffies; - err = rdev_sched_scan_start(rdev, dev, request); + err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); if (!err) { rdev->sched_scan_req = request; nl80211_send_sched_scan(rdev, dev, @@ -4886,7 +4815,8 @@ static int nl80211_dump_survey(struct sk_buff *skb, while (1) { struct ieee80211_channel *chan; - res = rdev_dump_survey(dev, netdev, survey_idx, &survey); + res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, + &survey); if (res == -ENOENT) break; if (res) @@ -4922,6 +4852,11 @@ static int nl80211_dump_survey(struct sk_buff *skb, return res; } +static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type) +{ + return auth_type <= NL80211_AUTHTYPE_MAX; +} + static bool nl80211_valid_wpa_versions(u32 wpa_versions) { return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | @@ -4933,8 +4868,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; - const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL; - int err, ssid_len, ie_len = 0, sae_data_len = 0; + const u8 *bssid, *ssid, *ie = NULL; + int err, ssid_len, ie_len = 0; enum nl80211_auth_type auth_type; struct key_parse key; bool local_state_change; @@ -5010,23 +4945,9 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) } auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE)) - return -EINVAL; - - if (auth_type == NL80211_AUTHTYPE_SAE && - !info->attrs[NL80211_ATTR_SAE_DATA]) + if (!nl80211_valid_auth_type(auth_type)) return -EINVAL; - if (info->attrs[NL80211_ATTR_SAE_DATA]) { - if (auth_type != NL80211_AUTHTYPE_SAE) - return -EINVAL; - sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]); - sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]); - /* need to include at least Auth Transaction and Status Code */ - if (sae_data_len < 4) - return -EINVAL; - } - local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; /* @@ -5038,8 +4959,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, ssid, ssid_len, ie, ie_len, - key.p.key, key.p.key_len, key.idx, - sae_data, sae_data_len); + key.p.key, key.p.key_len, key.idx); } static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, @@ -5419,18 +5339,10 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) return -EINVAL; if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { - bool no_ht = false; - connkeys = nl80211_parse_connkeys(rdev, - info->attrs[NL80211_ATTR_KEYS], - &no_ht); + info->attrs[NL80211_ATTR_KEYS]); if (IS_ERR(connkeys)) return PTR_ERR(connkeys); - - if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { - kfree(connkeys); - return -EINVAL; - } } ibss.control_port = @@ -5456,36 +5368,6 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) return cfg80211_leave_ibss(rdev, dev, false); } -static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct net_device *dev = info->user_ptr[1]; - int mcast_rate[IEEE80211_NUM_BANDS]; - u32 nla_rate; - int err; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) - return -EOPNOTSUPP; - - if (!rdev->ops->set_mcast_rate) - return -EOPNOTSUPP; - - memset(mcast_rate, 0, sizeof(mcast_rate)); - - if (!info->attrs[NL80211_ATTR_MCAST_RATE]) - return -EINVAL; - - nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]); - if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate)) - return -EINVAL; - - err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate); - - return err; -} - - #ifdef CONFIG_NL80211_TESTMODE static struct genl_multicast_group nl80211_testmode_mcgrp = { .name = "testmode", @@ -5502,7 +5384,7 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) err = -EOPNOTSUPP; if (rdev->ops->testmode_cmd) { rdev->testmode_info = info; - err = rdev_testmode_cmd(rdev, + err = rdev->ops->testmode_cmd(&rdev->wiphy, nla_data(info->attrs[NL80211_ATTR_TESTDATA]), nla_len(info->attrs[NL80211_ATTR_TESTDATA])); rdev->testmode_info = NULL; @@ -5584,7 +5466,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb, genlmsg_cancel(skb, hdr); break; } - err = rdev_testmode_dump(rdev, skb, cb, data, data_len); + err = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb, + data, data_len); nla_nest_end(skb, tmdata); if (err == -ENOBUFS || err == -ENOENT) { @@ -5713,8 +5596,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { connect.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(rdev, connect.auth_type, - NL80211_CMD_CONNECT)) + if (!nl80211_valid_auth_type(connect.auth_type)) return -EINVAL; } else connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; @@ -5760,7 +5642,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { connkeys = nl80211_parse_connkeys(rdev, - info->attrs[NL80211_ATTR_KEYS], NULL); + info->attrs[NL80211_ATTR_KEYS]); if (IS_ERR(connkeys)) return PTR_ERR(connkeys); } @@ -5889,7 +5771,7 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->flush_pmksa) return -EOPNOTSUPP; - return rdev_flush_pmksa(rdev, dev); + return rdev->ops->flush_pmksa(&rdev->wiphy, dev); } static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) @@ -5916,10 +5798,10 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); - return rdev_tdls_mgmt(rdev, dev, peer, action_code, - dialog_token, status_code, - nla_data(info->attrs[NL80211_ATTR_IE]), - nla_len(info->attrs[NL80211_ATTR_IE])); + return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, + dialog_token, status_code, + nla_data(info->attrs[NL80211_ATTR_IE]), + nla_len(info->attrs[NL80211_ATTR_IE])); } static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) @@ -5940,7 +5822,7 @@ static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]); peer = nla_data(info->attrs[NL80211_ATTR_MAC]); - return rdev_tdls_oper(rdev, dev, peer, operation); + return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation); } static int nl80211_remain_on_channel(struct sk_buff *skb, @@ -5995,8 +5877,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, goto free_msg; } - err = rdev_remain_on_channel(rdev, wdev, chan, channel_type, duration, - &cookie); + err = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, + channel_type, duration, &cookie); if (err) goto free_msg; @@ -6030,7 +5912,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); - return rdev_cancel_remain_on_channel(rdev, wdev, cookie); + return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); } static u32 rateset_to_mask(struct ieee80211_supported_band *sband, @@ -6173,7 +6055,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, } } - return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); + return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); } static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) @@ -6348,7 +6230,7 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); - return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie); + return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); } static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) @@ -6378,7 +6260,8 @@ static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) if (state == wdev->ps) return 0; - err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout); + err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state, + wdev->ps_timeout); if (!err) wdev->ps = state; return err; @@ -6458,7 +6341,8 @@ static int nl80211_set_cqm_txe(struct genl_info *info, wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl); + return rdev->ops->set_cqm_txe_config(wdev->wiphy, dev, + rate, pkts, intvl); } static int nl80211_set_cqm_rssi(struct genl_info *info, @@ -6480,7 +6364,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis); + return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, + threshold, hysteresis); } static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) @@ -6805,7 +6690,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) set_wakeup: if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) - rdev_set_wakeup(rdev, rdev->wowlan); + rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan); return 0; error: @@ -6861,7 +6746,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) goto out; } - err = rdev_set_rekey_data(rdev, dev, &rekey_data); + err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data); out: wdev_unlock(wdev); return err; @@ -6920,7 +6805,7 @@ static int nl80211_probe_client(struct sk_buff *skb, addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - err = rdev_probe_client(rdev, dev, addr, &cookie); + err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie); if (err) goto free_msg; @@ -6941,35 +6826,16 @@ static int nl80211_probe_client(struct sk_buff *skb, static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct cfg80211_beacon_registration *reg, *nreg; - int rv; if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) return -EOPNOTSUPP; - nreg = kzalloc(sizeof(*nreg), GFP_KERNEL); - if (!nreg) - return -ENOMEM; - - /* First, check if already registered. */ - spin_lock_bh(&rdev->beacon_registrations_lock); - list_for_each_entry(reg, &rdev->beacon_registrations, list) { - if (reg->nlportid == info->snd_portid) { - rv = -EALREADY; - goto out_err; - } - } - /* Add it to the list */ - nreg->nlportid = info->snd_portid; - list_add(&nreg->list, &rdev->beacon_registrations); + if (rdev->ap_beacons_nlportid) + return -EBUSY; - spin_unlock_bh(&rdev->beacon_registrations_lock); + rdev->ap_beacons_nlportid = info->snd_portid; return 0; -out_err: - spin_unlock_bh(&rdev->beacon_registrations_lock); - kfree(nreg); - return rv; } static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) @@ -6993,7 +6859,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) if (err) return err; - err = rdev_start_p2p_device(rdev, wdev); + err = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); if (err) return err; @@ -7019,7 +6885,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) if (!wdev->p2p_started) return 0; - rdev_stop_p2p_device(rdev, wdev); + rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); wdev->p2p_started = false; mutex_lock(&rdev->devlist_mtx); @@ -7686,14 +7552,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_WDEV_UP | NL80211_FLAG_NEED_RTNL, }, - { - .cmd = NL80211_CMD_SET_MCAST_RATE, - .doit = nl80211_set_mcast_rate, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV | - NL80211_FLAG_NEED_RTNL, - }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { @@ -7764,9 +7622,6 @@ static int nl80211_add_scan_req(struct sk_buff *msg, nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) goto nla_put_failure; - if (req->flags) - nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); - return 0; nla_put_failure: return -ENOBUFS; @@ -8945,10 +8800,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, void *hdr; int err; - trace_cfg80211_probe_status(dev, addr, cookie, acked); - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); - if (!msg) return; @@ -8983,46 +8835,41 @@ EXPORT_SYMBOL(cfg80211_probe_status); void cfg80211_report_obss_beacon(struct wiphy *wiphy, const u8 *frame, size_t len, - int freq, int sig_dbm) + int freq, int sig_dbm, gfp_t gfp) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); struct sk_buff *msg; void *hdr; - struct cfg80211_beacon_registration *reg; + u32 nlportid = ACCESS_ONCE(rdev->ap_beacons_nlportid); - trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm); + if (!nlportid) + return; - spin_lock_bh(&rdev->beacon_registrations_lock); - list_for_each_entry(reg, &rdev->beacon_registrations, list) { - msg = nlmsg_new(len + 100, GFP_ATOMIC); - if (!msg) { - spin_unlock_bh(&rdev->beacon_registrations_lock); - return; - } + msg = nlmsg_new(len + 100, gfp); + if (!msg) + return; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); - if (!hdr) - goto nla_put_failure; + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); + if (!hdr) { + nlmsg_free(msg); + return; + } - if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || - (freq && - nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || - (sig_dbm && - nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || - nla_put(msg, NL80211_ATTR_FRAME, len, frame)) - goto nla_put_failure; + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || + (freq && + nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || + (sig_dbm && + nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || + nla_put(msg, NL80211_ATTR_FRAME, len, frame)) + goto nla_put_failure; - genlmsg_end(msg, hdr); + genlmsg_end(msg, hdr); - genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid); - } - spin_unlock_bh(&rdev->beacon_registrations_lock); + genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); return; nla_put_failure: - spin_unlock_bh(&rdev->beacon_registrations_lock); - if (hdr) - genlmsg_cancel(msg, hdr); + genlmsg_cancel(msg, hdr); nlmsg_free(msg); } EXPORT_SYMBOL(cfg80211_report_obss_beacon); @@ -9034,7 +8881,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb, struct netlink_notify *notify = _notify; struct cfg80211_registered_device *rdev; struct wireless_dev *wdev; - struct cfg80211_beacon_registration *reg, *tmp; if (state != NETLINK_URELEASE) return NOTIFY_DONE; @@ -9044,17 +8890,8 @@ static int nl80211_netlink_notify(struct notifier_block * nb, list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) cfg80211_mlme_unregister_socket(wdev, notify->portid); - - spin_lock_bh(&rdev->beacon_registrations_lock); - list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, - list) { - if (reg->nlportid == notify->portid) { - list_del(®->list); - kfree(reg); - break; - } - } - spin_unlock_bh(&rdev->beacon_registrations_lock); + if (rdev->ap_beacons_nlportid == notify->portid) + rdev->ap_beacons_nlportid = 0; } rcu_read_unlock(); diff --git a/trunk/net/wireless/rdev-ops.h b/trunk/net/wireless/rdev-ops.h deleted file mode 100644 index 6e5fa659068d..000000000000 --- a/trunk/net/wireless/rdev-ops.h +++ /dev/null @@ -1,880 +0,0 @@ -#ifndef __CFG80211_RDEV_OPS -#define __CFG80211_RDEV_OPS - -#include -#include -#include "core.h" -#include "trace.h" - -static inline int rdev_suspend(struct cfg80211_registered_device *rdev) -{ - int ret; - trace_rdev_suspend(&rdev->wiphy, rdev->wowlan); - ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_resume(struct cfg80211_registered_device *rdev) -{ - int ret; - trace_rdev_resume(&rdev->wiphy); - ret = rdev->ops->resume(&rdev->wiphy); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void rdev_set_wakeup(struct cfg80211_registered_device *rdev, - bool enabled) -{ - trace_rdev_set_wakeup(&rdev->wiphy, enabled); - rdev->ops->set_wakeup(&rdev->wiphy, enabled); - trace_rdev_return_void(&rdev->wiphy); -} - -static inline struct wireless_dev -*rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - struct wireless_dev *ret; - trace_rdev_add_virtual_intf(&rdev->wiphy, name, type); - ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, type, flags, - params); - trace_rdev_return_wdev(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_del_virtual_intf(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) -{ - int ret; - trace_rdev_del_virtual_intf(&rdev->wiphy, wdev); - ret = rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_change_virtual_intf(struct cfg80211_registered_device *rdev, - struct net_device *dev, enum nl80211_iftype type, - u32 *flags, struct vif_params *params) -{ - int ret; - trace_rdev_change_virtual_intf(&rdev->wiphy, dev, type); - ret = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, type, flags, - params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_add_key(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr, - struct key_params *params) -{ - int ret; - trace_rdev_add_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); - ret = rdev->ops->add_key(&rdev->wiphy, netdev, key_index, pairwise, - mac_addr, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_get_key(struct cfg80211_registered_device *rdev, struct net_device *netdev, - u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, - void (*callback)(void *cookie, struct key_params*)) -{ - int ret; - trace_rdev_get_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); - ret = rdev->ops->get_key(&rdev->wiphy, netdev, key_index, pairwise, - mac_addr, cookie, callback); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_del_key(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr) -{ - int ret; - trace_rdev_del_key(&rdev->wiphy, netdev, key_index, pairwise, mac_addr); - ret = rdev->ops->del_key(&rdev->wiphy, netdev, key_index, pairwise, - mac_addr); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_default_key(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u8 key_index, bool unicast, - bool multicast) -{ - int ret; - trace_rdev_set_default_key(&rdev->wiphy, netdev, key_index, - unicast, multicast); - ret = rdev->ops->set_default_key(&rdev->wiphy, netdev, key_index, - unicast, multicast); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_default_mgmt_key(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u8 key_index) -{ - int ret; - trace_rdev_set_default_mgmt_key(&rdev->wiphy, netdev, key_index); - ret = rdev->ops->set_default_mgmt_key(&rdev->wiphy, netdev, - key_index); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_start_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_ap_settings *settings) -{ - int ret; - trace_rdev_start_ap(&rdev->wiphy, dev, settings); - ret = rdev->ops->start_ap(&rdev->wiphy, dev, settings); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_change_beacon(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_beacon_data *info) -{ - int ret; - trace_rdev_change_beacon(&rdev->wiphy, dev, info); - ret = rdev->ops->change_beacon(&rdev->wiphy, dev, info); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - int ret; - trace_rdev_stop_ap(&rdev->wiphy, dev); - ret = rdev->ops->stop_ap(&rdev->wiphy, dev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_add_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac, - struct station_parameters *params) -{ - int ret; - trace_rdev_add_station(&rdev->wiphy, dev, mac, params); - ret = rdev->ops->add_station(&rdev->wiphy, dev, mac, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_del_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac) -{ - int ret; - trace_rdev_del_station(&rdev->wiphy, dev, mac); - ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_change_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac, - struct station_parameters *params) -{ - int ret; - trace_rdev_change_station(&rdev->wiphy, dev, mac, params); - ret = rdev->ops->change_station(&rdev->wiphy, dev, mac, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_get_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *mac, - struct station_info *sinfo) -{ - int ret; - trace_rdev_get_station(&rdev->wiphy, dev, mac); - ret = rdev->ops->get_station(&rdev->wiphy, dev, mac, sinfo); - trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo); - return ret; -} - -static inline int rdev_dump_station(struct cfg80211_registered_device *rdev, - struct net_device *dev, int idx, u8 *mac, - struct station_info *sinfo) -{ - int ret; - trace_rdev_dump_station(&rdev->wiphy, dev, idx, mac); - ret = rdev->ops->dump_station(&rdev->wiphy, dev, idx, mac, sinfo); - trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo); - return ret; -} - -static inline int rdev_add_mpath(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *dst, u8 *next_hop) -{ - int ret; - trace_rdev_add_mpath(&rdev->wiphy, dev, dst, next_hop); - ret = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_del_mpath(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *dst) -{ - int ret; - trace_rdev_del_mpath(&rdev->wiphy, dev, dst); - ret = rdev->ops->del_mpath(&rdev->wiphy, dev, dst); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_change_mpath(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *dst, - u8 *next_hop) -{ - int ret; - trace_rdev_change_mpath(&rdev->wiphy, dev, dst, next_hop); - ret = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_get_mpath(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *dst, u8 *next_hop, - struct mpath_info *pinfo) -{ - int ret; - trace_rdev_get_mpath(&rdev->wiphy, dev, dst, next_hop); - ret = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, pinfo); - trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); - return ret; - -} - -static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, - struct net_device *dev, int idx, u8 *dst, - u8 *next_hop, struct mpath_info *pinfo) - -{ - int ret; - trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); - ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, - pinfo); - trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); - return ret; -} - -static inline int -rdev_get_mesh_config(struct cfg80211_registered_device *rdev, - struct net_device *dev, struct mesh_config *conf) -{ - int ret; - trace_rdev_get_mesh_config(&rdev->wiphy, dev); - ret = rdev->ops->get_mesh_config(&rdev->wiphy, dev, conf); - trace_rdev_return_int_mesh_config(&rdev->wiphy, ret, conf); - return ret; -} - -static inline int -rdev_update_mesh_config(struct cfg80211_registered_device *rdev, - struct net_device *dev, u32 mask, - const struct mesh_config *nconf) -{ - int ret; - trace_rdev_update_mesh_config(&rdev->wiphy, dev, mask, nconf); - ret = rdev->ops->update_mesh_config(&rdev->wiphy, dev, mask, nconf); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_join_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev, - const struct mesh_config *conf, - const struct mesh_setup *setup) -{ - int ret; - trace_rdev_join_mesh(&rdev->wiphy, dev, conf, setup); - ret = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - - -static inline int rdev_leave_mesh(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - int ret; - trace_rdev_leave_mesh(&rdev->wiphy, dev); - ret = rdev->ops->leave_mesh(&rdev->wiphy, dev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_change_bss(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct bss_parameters *params) - -{ - int ret; - trace_rdev_change_bss(&rdev->wiphy, dev, params); - ret = rdev->ops->change_bss(&rdev->wiphy, dev, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_set_txq_params(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_txq_params *params) - -{ - int ret; - trace_rdev_set_txq_params(&rdev->wiphy, dev, params); - ret = rdev->ops->set_txq_params(&rdev->wiphy, dev, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_channel *chan) -{ - int ret; - trace_rdev_libertas_set_mesh_channel(&rdev->wiphy, dev, chan); - ret = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, dev, chan); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_monitor_channel(struct cfg80211_registered_device *rdev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - int ret; - trace_rdev_set_monitor_channel(&rdev->wiphy, chan, channel_type); - ret = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, channel_type); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_scan(struct cfg80211_registered_device *rdev, - struct cfg80211_scan_request *request) -{ - int ret; - trace_rdev_scan(&rdev->wiphy, request); - ret = rdev->ops->scan(&rdev->wiphy, request); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_auth(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_auth_request *req) -{ - int ret; - trace_rdev_auth(&rdev->wiphy, dev, req); - ret = rdev->ops->auth(&rdev->wiphy, dev, req); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_assoc(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_assoc_request *req) -{ - int ret; - trace_rdev_assoc(&rdev->wiphy, dev, req); - ret = rdev->ops->assoc(&rdev->wiphy, dev, req); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_deauth(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_deauth_request *req) -{ - int ret; - trace_rdev_deauth(&rdev->wiphy, dev, req); - ret = rdev->ops->deauth(&rdev->wiphy, dev, req); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_disassoc(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_disassoc_request *req) -{ - int ret; - trace_rdev_disassoc(&rdev->wiphy, dev, req); - ret = rdev->ops->disassoc(&rdev->wiphy, dev, req); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_connect(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_connect_params *sme) -{ - int ret; - trace_rdev_connect(&rdev->wiphy, dev, sme); - ret = rdev->ops->connect(&rdev->wiphy, dev, sme); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_disconnect(struct cfg80211_registered_device *rdev, - struct net_device *dev, u16 reason_code) -{ - int ret; - trace_rdev_disconnect(&rdev->wiphy, dev, reason_code); - ret = rdev->ops->disconnect(&rdev->wiphy, dev, reason_code); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_join_ibss(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_ibss_params *params) -{ - int ret; - trace_rdev_join_ibss(&rdev->wiphy, dev, params); - ret = rdev->ops->join_ibss(&rdev->wiphy, dev, params); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_leave_ibss(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - int ret; - trace_rdev_leave_ibss(&rdev->wiphy, dev); - ret = rdev->ops->leave_ibss(&rdev->wiphy, dev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed) -{ - int ret; - trace_rdev_set_wiphy_params(&rdev->wiphy, changed); - ret = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, int mbm) -{ - int ret; - trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm); - ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, int *dbm) -{ - int ret; - trace_rdev_get_tx_power(&rdev->wiphy, wdev); - ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm); - trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); - return ret; -} - -static inline int rdev_set_wds_peer(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *addr) -{ - int ret; - trace_rdev_set_wds_peer(&rdev->wiphy, dev, addr); - ret = rdev->ops->set_wds_peer(&rdev->wiphy, dev, addr); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void rdev_rfkill_poll(struct cfg80211_registered_device *rdev) -{ - trace_rdev_rfkill_poll(&rdev->wiphy); - rdev->ops->rfkill_poll(&rdev->wiphy); - trace_rdev_return_void(&rdev->wiphy); -} - - -#ifdef CONFIG_NL80211_TESTMODE -static inline int rdev_testmode_cmd(struct cfg80211_registered_device *rdev, - void *data, int len) -{ - int ret; - trace_rdev_testmode_cmd(&rdev->wiphy); - ret = rdev->ops->testmode_cmd(&rdev->wiphy, data, len); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_testmode_dump(struct cfg80211_registered_device *rdev, - struct sk_buff *skb, - struct netlink_callback *cb, void *data, - int len) -{ - int ret; - trace_rdev_testmode_dump(&rdev->wiphy); - ret = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb, data, len); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} -#endif - -static inline int -rdev_set_bitrate_mask(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *peer, - const struct cfg80211_bitrate_mask *mask) -{ - int ret; - trace_rdev_set_bitrate_mask(&rdev->wiphy, dev, peer, mask); - ret = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, peer, mask); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_dump_survey(struct cfg80211_registered_device *rdev, - struct net_device *netdev, int idx, - struct survey_info *info) -{ - int ret; - trace_rdev_dump_survey(&rdev->wiphy, netdev, idx); - ret = rdev->ops->dump_survey(&rdev->wiphy, netdev, idx, info); - if (ret < 0) - trace_rdev_return_int(&rdev->wiphy, ret); - else - trace_rdev_return_int_survey_info(&rdev->wiphy, ret, info); - return ret; -} - -static inline int rdev_set_pmksa(struct cfg80211_registered_device *rdev, - struct net_device *netdev, - struct cfg80211_pmksa *pmksa) -{ - int ret; - trace_rdev_set_pmksa(&rdev->wiphy, netdev, pmksa); - ret = rdev->ops->set_pmksa(&rdev->wiphy, netdev, pmksa); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_del_pmksa(struct cfg80211_registered_device *rdev, - struct net_device *netdev, - struct cfg80211_pmksa *pmksa) -{ - int ret; - trace_rdev_del_pmksa(&rdev->wiphy, netdev, pmksa); - ret = rdev->ops->del_pmksa(&rdev->wiphy, netdev, pmksa); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_flush_pmksa(struct cfg80211_registered_device *rdev, - struct net_device *netdev) -{ - int ret; - trace_rdev_flush_pmksa(&rdev->wiphy, netdev); - ret = rdev->ops->flush_pmksa(&rdev->wiphy, netdev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_remain_on_channel(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - unsigned int duration, u64 *cookie) -{ - int ret; - trace_rdev_remain_on_channel(&rdev->wiphy, wdev, chan, channel_type, - duration); - ret = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, - channel_type, duration, cookie); - trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); - return ret; -} - -static inline int -rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, u64 cookie) -{ - int ret; - trace_rdev_cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); - ret = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - struct ieee80211_channel *chan, bool offchan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, unsigned int wait, - const u8 *buf, size_t len, bool no_cck, - bool dont_wait_for_ack, u64 *cookie) -{ - int ret; - trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, channel_type, - channel_type_valid, wait, no_cck, dont_wait_for_ack); - ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, - channel_type, channel_type_valid, wait, buf, - len, no_cck, dont_wait_for_ack, cookie); - trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); - return ret; -} - -static inline int -rdev_mgmt_tx_cancel_wait(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, u64 cookie) -{ - int ret; - trace_rdev_mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); - ret = rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_set_power_mgmt(struct cfg80211_registered_device *rdev, - struct net_device *dev, bool enabled, - int timeout) -{ - int ret; - trace_rdev_set_power_mgmt(&rdev->wiphy, dev, enabled, timeout); - ret = rdev->ops->set_power_mgmt(&rdev->wiphy, dev, enabled, timeout); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_cqm_rssi_config(struct cfg80211_registered_device *rdev, - struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) -{ - int ret; - trace_rdev_set_cqm_rssi_config(&rdev->wiphy, dev, rssi_thold, - rssi_hyst); - ret = rdev->ops->set_cqm_rssi_config(&rdev->wiphy, dev, rssi_thold, - rssi_hyst); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_set_cqm_txe_config(struct cfg80211_registered_device *rdev, - struct net_device *dev, u32 rate, u32 pkts, u32 intvl) -{ - int ret; - trace_rdev_set_cqm_txe_config(&rdev->wiphy, dev, rate, pkts, intvl); - ret = rdev->ops->set_cqm_txe_config(&rdev->wiphy, dev, rate, pkts, - intvl); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void -rdev_mgmt_frame_register(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, u16 frame_type, bool reg) -{ - trace_rdev_mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); - rdev->ops->mgmt_frame_register(&rdev->wiphy, wdev , frame_type, reg); - trace_rdev_return_void(&rdev->wiphy); -} - -static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev, - u32 tx_ant, u32 rx_ant) -{ - int ret; - trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant); - ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev, - u32 *tx_ant, u32 *rx_ant) -{ - int ret; - trace_rdev_get_antenna(&rdev->wiphy); - ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant); - if (ret) - trace_rdev_return_int(&rdev->wiphy, ret); - else - trace_rdev_return_int_tx_rx(&rdev->wiphy, ret, *tx_ant, - *rx_ant); - return ret; -} - -static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev, - u32 tx, u32 rx) -{ - int ret; - trace_rdev_set_ringparam(&rdev->wiphy, tx, rx); - ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev, - u32 *tx, u32 *tx_max, u32 *rx, - u32 *rx_max) -{ - trace_rdev_get_ringparam(&rdev->wiphy); - rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max); - trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max); -} - -static inline int -rdev_sched_scan_start(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_sched_scan_request *request) -{ - int ret; - trace_rdev_sched_scan_start(&rdev->wiphy, dev, request); - ret = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_sched_scan_stop(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - int ret; - trace_rdev_sched_scan_stop(&rdev->wiphy, dev); - ret = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct cfg80211_gtk_rekey_data *data) -{ - int ret; - trace_rdev_set_rekey_data(&rdev->wiphy, dev); - ret = rdev->ops->set_rekey_data(&rdev->wiphy, dev, data); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *peer, - u8 action_code, u8 dialog_token, - u16 status_code, const u8 *buf, size_t len) -{ - int ret; - trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, - dialog_token, status_code, buf, len); - ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, - dialog_token, status_code, buf, len); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_tdls_oper(struct cfg80211_registered_device *rdev, - struct net_device *dev, u8 *peer, - enum nl80211_tdls_operation oper) -{ - int ret; - trace_rdev_tdls_oper(&rdev->wiphy, dev, peer, oper); - ret = rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, oper); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int rdev_probe_client(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *peer, - u64 *cookie) -{ - int ret; - trace_rdev_probe_client(&rdev->wiphy, dev, peer); - ret = rdev->ops->probe_client(&rdev->wiphy, dev, peer, cookie); - trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); - return ret; -} - -static inline int rdev_set_noack_map(struct cfg80211_registered_device *rdev, - struct net_device *dev, u16 noack_map) -{ - int ret; - trace_rdev_set_noack_map(&rdev->wiphy, dev, noack_map); - ret = rdev->ops->set_noack_map(&rdev->wiphy, dev, noack_map); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline int -rdev_get_et_sset_count(struct cfg80211_registered_device *rdev, - struct net_device *dev, int sset) -{ - int ret; - trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset); - ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ethtool_stats *stats, u64 *data) -{ - trace_rdev_get_et_stats(&rdev->wiphy, dev); - rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data); - trace_rdev_return_void(&rdev->wiphy); -} - -static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev, - struct net_device *dev, u32 sset, - u8 *data) -{ - trace_rdev_get_et_strings(&rdev->wiphy, dev, sset); - rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data); - trace_rdev_return_void(&rdev->wiphy); -} - -static inline struct ieee80211_channel -*rdev_get_channel(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, enum nl80211_channel_type *type) -{ - struct ieee80211_channel *ret; - trace_rdev_get_channel(&rdev->wiphy, wdev); - ret = rdev->ops->get_channel(&rdev->wiphy, wdev, type); - trace_rdev_return_channel(&rdev->wiphy, ret, *type); - return ret; -} - -static inline int rdev_start_p2p_device(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) -{ - int ret; - - trace_rdev_start_p2p_device(&rdev->wiphy, wdev); - ret = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); - trace_rdev_return_int(&rdev->wiphy, ret); - return ret; -} - -static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) -{ - trace_rdev_stop_p2p_device(&rdev->wiphy, wdev); - rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); - trace_rdev_return_void(&rdev->wiphy); -} -#endif /* __CFG80211_RDEV_OPS */ diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index b75756b05af7..3b8cbbc214db 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -141,8 +141,9 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. */ - REG_RULE(2467-10, 2472+10, 40, 6, 20, + /* IEEE 802.11b/g, channels 12..13. No HT40 + * channel fits here. */ + REG_RULE(2467-10, 2472+10, 20, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables @@ -907,7 +908,7 @@ static void handle_channel(struct wiphy *wiphy, map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = chan->orig_mag = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = chan->orig_mpwr = + chan->max_power = chan->orig_mpwr = (int) MBM_TO_DBM(power_rule->max_eirp); return; } @@ -1330,8 +1331,7 @@ static void handle_channel_custom(struct wiphy *wiphy, chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = - (int) MBM_TO_DBM(power_rule->max_eirp); + chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, diff --git a/trunk/net/wireless/scan.c b/trunk/net/wireless/scan.c index 7f97a087f452..9730c9862bdc 100644 --- a/trunk/net/wireless/scan.c +++ b/trunk/net/wireless/scan.c @@ -17,58 +17,9 @@ #include "core.h" #include "nl80211.h" #include "wext-compat.h" -#include "rdev-ops.h" #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) -static void bss_release(struct kref *ref) -{ - struct cfg80211_internal_bss *bss; - - bss = container_of(ref, struct cfg80211_internal_bss, ref); - if (bss->pub.free_priv) - bss->pub.free_priv(&bss->pub); - - if (bss->beacon_ies_allocated) - kfree(bss->pub.beacon_ies); - if (bss->proberesp_ies_allocated) - kfree(bss->pub.proberesp_ies); - - BUG_ON(atomic_read(&bss->hold)); - - kfree(bss); -} - -/* must hold dev->bss_lock! */ -static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, - struct cfg80211_internal_bss *bss) -{ - list_del_init(&bss->list); - rb_erase(&bss->rbn, &dev->bss_tree); - kref_put(&bss->ref, bss_release); -} - -/* must hold dev->bss_lock! */ -static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, - unsigned long expire_time) -{ - struct cfg80211_internal_bss *bss, *tmp; - bool expired = false; - - list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { - if (atomic_read(&bss->hold)) - continue; - if (!time_after(expire_time, bss->ts)) - continue; - - __cfg80211_unlink_bss(dev, bss); - expired = true; - } - - if (expired) - dev->bss_generation++; -} - void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) { struct cfg80211_scan_request *request; @@ -94,17 +45,10 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) if (wdev->netdev) cfg80211_sme_scan_done(wdev->netdev); - if (request->aborted) { + if (request->aborted) nl80211_send_scan_aborted(rdev, wdev); - } else { - if (request->flags & NL80211_SCAN_FLAG_FLUSH) { - /* flush entries from previous scans */ - spin_lock_bh(&rdev->bss_lock); - __cfg80211_bss_expire(rdev, request->scan_start); - spin_unlock_bh(&rdev->bss_lock); - } + else nl80211_send_scan_done(rdev, wdev); - } #ifdef CONFIG_CFG80211_WEXT if (wdev->netdev && !request->aborted) { @@ -145,7 +89,6 @@ void __cfg80211_scan_done(struct work_struct *wk) void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) { - trace_cfg80211_scan_done(request, aborted); WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); request->aborted = aborted; @@ -156,34 +99,22 @@ EXPORT_SYMBOL(cfg80211_scan_done); void __cfg80211_sched_scan_results(struct work_struct *wk) { struct cfg80211_registered_device *rdev; - struct cfg80211_sched_scan_request *request; rdev = container_of(wk, struct cfg80211_registered_device, sched_scan_results_wk); - request = rdev->sched_scan_req; - mutex_lock(&rdev->sched_scan_mtx); /* we don't have sched_scan_req anymore if the scan is stopping */ - if (request) { - if (request->flags & NL80211_SCAN_FLAG_FLUSH) { - /* flush entries from previous scans */ - spin_lock_bh(&rdev->bss_lock); - __cfg80211_bss_expire(rdev, request->scan_start); - spin_unlock_bh(&rdev->bss_lock); - request->scan_start = - jiffies + msecs_to_jiffies(request->interval); - } - nl80211_send_sched_scan_results(rdev, request->dev); - } + if (rdev->sched_scan_req) + nl80211_send_sched_scan_results(rdev, + rdev->sched_scan_req->dev); mutex_unlock(&rdev->sched_scan_mtx); } void cfg80211_sched_scan_results(struct wiphy *wiphy) { - trace_cfg80211_sched_scan_results(wiphy); /* ignore if we're not scanning */ if (wiphy_to_dev(wiphy)->sched_scan_req) queue_work(cfg80211_wq, @@ -195,8 +126,6 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - trace_cfg80211_sched_scan_stopped(wiphy); - mutex_lock(&rdev->sched_scan_mtx); __cfg80211_stop_sched_scan(rdev, true); mutex_unlock(&rdev->sched_scan_mtx); @@ -216,7 +145,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, dev = rdev->sched_scan_req->dev; if (!driver_initiated) { - int err = rdev_sched_scan_stop(rdev, dev); + int err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); if (err) return err; } @@ -229,6 +158,24 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, return 0; } +static void bss_release(struct kref *ref) +{ + struct cfg80211_internal_bss *bss; + + bss = container_of(ref, struct cfg80211_internal_bss, ref); + if (bss->pub.free_priv) + bss->pub.free_priv(&bss->pub); + + if (bss->beacon_ies_allocated) + kfree(bss->pub.beacon_ies); + if (bss->proberesp_ies_allocated) + kfree(bss->pub.proberesp_ies); + + BUG_ON(atomic_read(&bss->hold)); + + kfree(bss); +} + /* must hold dev->bss_lock! */ void cfg80211_bss_age(struct cfg80211_registered_device *dev, unsigned long age_secs) @@ -241,9 +188,32 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, } } +/* must hold dev->bss_lock! */ +static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, + struct cfg80211_internal_bss *bss) +{ + list_del_init(&bss->list); + rb_erase(&bss->rbn, &dev->bss_tree); + kref_put(&bss->ref, bss_release); +} + +/* must hold dev->bss_lock! */ void cfg80211_bss_expire(struct cfg80211_registered_device *dev) { - __cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE); + struct cfg80211_internal_bss *bss, *tmp; + bool expired = false; + + list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { + if (atomic_read(&bss->hold)) + continue; + if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) + continue; + __cfg80211_unlink_bss(dev, bss); + expired = true; + } + + if (expired) + dev->bss_generation++; } const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) @@ -489,9 +459,6 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, struct cfg80211_internal_bss *bss, *res = NULL; unsigned long now = jiffies; - trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, - capa_val); - spin_lock_bh(&dev->bss_lock); list_for_each_entry(bss, &dev->bss_list, list) { @@ -513,7 +480,6 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, spin_unlock_bh(&dev->bss_lock); if (!res) return NULL; - trace_cfg80211_return_bss(&res->pub); return &res->pub; } EXPORT_SYMBOL(cfg80211_get_bss); @@ -826,7 +792,6 @@ cfg80211_inform_bss(struct wiphy *wiphy, if (res->pub.capability & WLAN_CAPABILITY_ESS) regulatory_hint_found_beacon(wiphy, channel, gfp); - trace_cfg80211_return_bss(&res->pub); /* cfg80211_bss_update gives us a referenced result */ return &res->pub; } @@ -839,13 +804,10 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, s32 signal, gfp_t gfp) { struct cfg80211_internal_bss *res; - size_t ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); size_t privsz; - trace_cfg80211_inform_bss_frame(wiphy, channel, mgmt, len, signal); - if (WARN_ON(!mgmt)) return NULL; @@ -899,7 +861,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, if (res->pub.capability & WLAN_CAPABILITY_ESS) regulatory_hint_found_beacon(wiphy, channel, gfp); - trace_cfg80211_return_bss(&res->pub); /* cfg80211_bss_update gives us a referenced result */ return &res->pub; } @@ -1001,7 +962,6 @@ int cfg80211_wext_siwscan(struct net_device *dev, creq->ssids = (void *)&creq->channels[n_channels]; creq->n_channels = n_channels; creq->n_ssids = 1; - creq->scan_start = jiffies; /* translate "Scan on frequencies" request */ i = 0; @@ -1066,7 +1026,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; rdev->scan_req = creq; - err = rdev_scan(rdev, creq); + err = rdev->ops->scan(wiphy, creq); if (err) { rdev->scan_req = NULL; /* creq will be freed below */ diff --git a/trunk/net/wireless/sme.c b/trunk/net/wireless/sme.c index c7490027237d..6f39cb808302 100644 --- a/trunk/net/wireless/sme.c +++ b/trunk/net/wireless/sme.c @@ -16,7 +16,6 @@ #include #include "nl80211.h" #include "reg.h" -#include "rdev-ops.h" struct cfg80211_conn { struct cfg80211_connect_params params; @@ -139,11 +138,10 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) request->wdev = wdev; request->wiphy = &rdev->wiphy; - request->scan_start = jiffies; rdev->scan_req = request; - err = rdev_scan(rdev, request); + err = rdev->ops->scan(wdev->wiphy, request); if (!err) { wdev->conn->state = CFG80211_CONN_SCANNING; nl80211_send_scan_start(rdev, wdev); @@ -181,7 +179,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) params->ssid, params->ssid_len, NULL, 0, params->key, params->key_len, - params->key_idx, NULL, 0); + params->key_idx); case CFG80211_CONN_ASSOCIATE_NEXT: BUG_ON(!rdev->ops->assoc); wdev->conn->state = CFG80211_CONN_ASSOCIATING; @@ -718,7 +716,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev_del_key(rdev, dev, i, false, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); #ifdef CONFIG_CFG80211_WEXT memset(&wrqu, 0, sizeof(wrqu)); @@ -894,7 +892,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, } else { wdev->sme_state = CFG80211_SME_CONNECTING; wdev->connect_keys = connkeys; - err = rdev_connect(rdev, dev, connect); + err = rdev->ops->connect(&rdev->wiphy, dev, connect); if (err) { wdev->connect_keys = NULL; wdev->sme_state = CFG80211_SME_IDLE; @@ -966,7 +964,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, if (err) return err; } else { - err = rdev_disconnect(rdev, dev, reason); + err = rdev->ops->disconnect(&rdev->wiphy, dev, reason); if (err) return err; } diff --git a/trunk/net/wireless/sysfs.c b/trunk/net/wireless/sysfs.c index 9bf6d5e32166..ff574597a854 100644 --- a/trunk/net/wireless/sysfs.c +++ b/trunk/net/wireless/sysfs.c @@ -16,7 +16,6 @@ #include #include "sysfs.h" #include "core.h" -#include "rdev-ops.h" static inline struct cfg80211_registered_device *dev_to_rdev( struct device *dev) @@ -95,7 +94,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) if (rdev->ops->suspend) { rtnl_lock(); if (rdev->wiphy.registered) - ret = rdev_suspend(rdev); + ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); rtnl_unlock(); } @@ -115,7 +114,7 @@ static int wiphy_resume(struct device *dev) if (rdev->ops->resume) { rtnl_lock(); if (rdev->wiphy.registered) - ret = rdev_resume(rdev); + ret = rdev->ops->resume(&rdev->wiphy); rtnl_unlock(); } diff --git a/trunk/net/wireless/trace.c b/trunk/net/wireless/trace.c deleted file mode 100644 index 95f997fad755..000000000000 --- a/trunk/net/wireless/trace.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#ifndef __CHECKER__ -#define CREATE_TRACE_POINTS -#include "trace.h" - -#endif diff --git a/trunk/net/wireless/trace.h b/trunk/net/wireless/trace.h deleted file mode 100644 index 8e03c6382a8a..000000000000 --- a/trunk/net/wireless/trace.h +++ /dev/null @@ -1,2298 +0,0 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM cfg80211 - -#if !defined(__RDEV_OPS_TRACE) || defined(TRACE_HEADER_MULTI_READ) -#define __RDEV_OPS_TRACE - -#include - -#include -#include -#include "core.h" - -#define MAC_ENTRY(entry_mac) __array(u8, entry_mac, ETH_ALEN) -#define MAC_ASSIGN(entry_mac, given_mac) do { \ - if (given_mac) \ - memcpy(__entry->entry_mac, given_mac, ETH_ALEN); \ - else \ - memset(__entry->entry_mac, 0, ETH_ALEN); \ - } while (0) -#define MAC_PR_FMT "%pM" -#define MAC_PR_ARG(entry_mac) (__entry->entry_mac) - -#define WIPHY_ENTRY MAC_ENTRY(wiphy_mac) -#define WIPHY_ASSIGN MAC_ASSIGN(wiphy_mac, wiphy->perm_addr) -#define WIPHY_PR_FMT "wiphy " MAC_PR_FMT -#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) - -#define WDEV_ENTRY __field(u32, id) -#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) -#define WDEV_PR_FMT ", wdev id: %u" -#define WDEV_PR_ARG (__entry->id) - -#define NETDEV_ENTRY __array(char, name, IFNAMSIZ) \ - MAC_ENTRY(netdev_addr) \ - __field(int, ifindex) -#define NETDEV_ASSIGN \ - do { \ - memcpy(__entry->name, netdev->name, IFNAMSIZ); \ - MAC_ASSIGN(netdev_addr, netdev->dev_addr); \ - (__entry->ifindex) = (netdev->ifindex); \ - } while (0) -#define NETDEV_PR_FMT ", netdev - name: %s, addr: " MAC_PR_FMT \ - ", intf index: %d" -#define NETDEV_PR_ARG (__entry->name), MAC_PR_ARG(netdev_addr), \ - (__entry->ifindex) - -#define MESH_CFG_ENTRY __field(u16, dot11MeshRetryTimeout) \ - __field(u16, dot11MeshConfirmTimeout) \ - __field(u16, dot11MeshHoldingTimeout) \ - __field(u16, dot11MeshMaxPeerLinks) \ - __field(u8, dot11MeshMaxRetries) \ - __field(u8, dot11MeshTTL) \ - __field(u8, element_ttl) \ - __field(bool, auto_open_plinks) \ - __field(u32, dot11MeshNbrOffsetMaxNeighbor) \ - __field(u8, dot11MeshHWMPmaxPREQretries) \ - __field(u32, path_refresh_time) \ - __field(u32, dot11MeshHWMPactivePathTimeout) \ - __field(u16, min_discovery_timeout) \ - __field(u16, dot11MeshHWMPpreqMinInterval) \ - __field(u16, dot11MeshHWMPperrMinInterval) \ - __field(u16, dot11MeshHWMPnetDiameterTraversalTime) \ - __field(u8, dot11MeshHWMPRootMode) \ - __field(u16, dot11MeshHWMPRannInterval) \ - __field(bool, dot11MeshGateAnnouncementProtocol) \ - __field(bool, dot11MeshForwarding) \ - __field(s32, rssi_threshold) \ - __field(u16, ht_opmode) \ - __field(u32, dot11MeshHWMPactivePathToRootTimeout) \ - __field(u16, dot11MeshHWMProotInterval) \ - __field(u16, dot11MeshHWMPconfirmationInterval) -#define MESH_CFG_ASSIGN \ - do { \ - __entry->dot11MeshRetryTimeout = conf->dot11MeshRetryTimeout; \ - __entry->dot11MeshConfirmTimeout = \ - conf->dot11MeshConfirmTimeout; \ - __entry->dot11MeshHoldingTimeout = \ - conf->dot11MeshHoldingTimeout; \ - __entry->dot11MeshMaxPeerLinks = conf->dot11MeshMaxPeerLinks; \ - __entry->dot11MeshMaxRetries = conf->dot11MeshMaxRetries; \ - __entry->dot11MeshTTL = conf->dot11MeshTTL; \ - __entry->element_ttl = conf->element_ttl; \ - __entry->auto_open_plinks = conf->auto_open_plinks; \ - __entry->dot11MeshNbrOffsetMaxNeighbor = \ - conf->dot11MeshNbrOffsetMaxNeighbor; \ - __entry->dot11MeshHWMPmaxPREQretries = \ - conf->dot11MeshHWMPmaxPREQretries; \ - __entry->path_refresh_time = conf->path_refresh_time; \ - __entry->dot11MeshHWMPactivePathTimeout = \ - conf->dot11MeshHWMPactivePathTimeout; \ - __entry->min_discovery_timeout = conf->min_discovery_timeout; \ - __entry->dot11MeshHWMPpreqMinInterval = \ - conf->dot11MeshHWMPpreqMinInterval; \ - __entry->dot11MeshHWMPperrMinInterval = \ - conf->dot11MeshHWMPperrMinInterval; \ - __entry->dot11MeshHWMPnetDiameterTraversalTime = \ - conf->dot11MeshHWMPnetDiameterTraversalTime; \ - __entry->dot11MeshHWMPRootMode = conf->dot11MeshHWMPRootMode; \ - __entry->dot11MeshHWMPRannInterval = \ - conf->dot11MeshHWMPRannInterval; \ - __entry->dot11MeshGateAnnouncementProtocol = \ - conf->dot11MeshGateAnnouncementProtocol; \ - __entry->dot11MeshForwarding = conf->dot11MeshForwarding; \ - __entry->rssi_threshold = conf->rssi_threshold; \ - __entry->ht_opmode = conf->ht_opmode; \ - __entry->dot11MeshHWMPactivePathToRootTimeout = \ - conf->dot11MeshHWMPactivePathToRootTimeout; \ - __entry->dot11MeshHWMProotInterval = \ - conf->dot11MeshHWMProotInterval; \ - __entry->dot11MeshHWMPconfirmationInterval = \ - conf->dot11MeshHWMPconfirmationInterval; \ - } while (0) - -#define CHAN_ENTRY __field(enum ieee80211_band, band) \ - __field(u16, center_freq) -#define CHAN_ASSIGN(chan) \ - do { \ - if (chan) { \ - __entry->band = chan->band; \ - __entry->center_freq = chan->center_freq; \ - } else { \ - __entry->band = 0; \ - __entry->center_freq = 0; \ - } \ - } while (0) -#define CHAN_PR_FMT ", band: %d, freq: %u" -#define CHAN_PR_ARG __entry->band, __entry->center_freq - -#define SINFO_ENTRY __field(int, generation) \ - __field(u32, connected_time) \ - __field(u32, inactive_time) \ - __field(u32, rx_bytes) \ - __field(u32, tx_bytes) \ - __field(u32, rx_packets) \ - __field(u32, tx_packets) \ - __field(u32, tx_retries) \ - __field(u32, tx_failed) \ - __field(u32, rx_dropped_misc) \ - __field(u32, beacon_loss_count) \ - __field(u16, llid) \ - __field(u16, plid) \ - __field(u8, plink_state) -#define SINFO_ASSIGN \ - do { \ - __entry->generation = sinfo->generation; \ - __entry->connected_time = sinfo->connected_time; \ - __entry->inactive_time = sinfo->inactive_time; \ - __entry->rx_bytes = sinfo->rx_bytes; \ - __entry->tx_bytes = sinfo->tx_bytes; \ - __entry->rx_packets = sinfo->rx_packets; \ - __entry->tx_packets = sinfo->tx_packets; \ - __entry->tx_retries = sinfo->tx_retries; \ - __entry->tx_failed = sinfo->tx_failed; \ - __entry->rx_dropped_misc = sinfo->rx_dropped_misc; \ - __entry->beacon_loss_count = sinfo->beacon_loss_count; \ - __entry->llid = sinfo->llid; \ - __entry->plid = sinfo->plid; \ - __entry->plink_state = sinfo->plink_state; \ - } while (0) - -#define BOOL_TO_STR(bo) (bo) ? "true" : "false" - -/************************************************************* - * rdev->ops traces * - *************************************************************/ - -TRACE_EVENT(rdev_suspend, - TP_PROTO(struct wiphy *wiphy, struct cfg80211_wowlan *wow), - TP_ARGS(wiphy, wow), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(bool, any) - __field(bool, disconnect) - __field(bool, magic_pkt) - __field(bool, gtk_rekey_failure) - __field(bool, eap_identity_req) - __field(bool, four_way_handshake) - __field(bool, rfkill_release) - __field(bool, valid_wow) - ), - TP_fast_assign( - WIPHY_ASSIGN; - if (wow) { - __entry->any = wow->any; - __entry->disconnect = wow->disconnect; - __entry->magic_pkt = wow->magic_pkt; - __entry->gtk_rekey_failure = wow->gtk_rekey_failure; - __entry->eap_identity_req = wow->eap_identity_req; - __entry->four_way_handshake = wow->four_way_handshake; - __entry->rfkill_release = wow->rfkill_release; - __entry->valid_wow = true; - } else { - __entry->valid_wow = false; - } - ), - TP_printk(WIPHY_PR_FMT ", wow%s - any: %d, disconnect: %d, " - "magic pkt: %d, gtk rekey failure: %d, eap identify req: %d, " - "four way handshake: %d, rfkill release: %d.", - WIPHY_PR_ARG, __entry->valid_wow ? "" : "(Not configured!)", - __entry->any, __entry->disconnect, __entry->magic_pkt, - __entry->gtk_rekey_failure, __entry->eap_identity_req, - __entry->four_way_handshake, __entry->rfkill_release) -); - -TRACE_EVENT(rdev_return_int, - TP_PROTO(struct wiphy *wiphy, int ret), - TP_ARGS(wiphy, ret), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, ret) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->ret = ret; - ), - TP_printk(WIPHY_PR_FMT ", returned: %d", WIPHY_PR_ARG, __entry->ret) -); - -TRACE_EVENT(rdev_scan, - TP_PROTO(struct wiphy *wiphy, struct cfg80211_scan_request *request), - TP_ARGS(wiphy, request), - TP_STRUCT__entry( - WIPHY_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) -); - -DECLARE_EVENT_CLASS(wiphy_only_evt, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy), - TP_STRUCT__entry( - WIPHY_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) -); - -DEFINE_EVENT(wiphy_only_evt, rdev_resume, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DEFINE_EVENT(wiphy_only_evt, rdev_return_void, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DECLARE_EVENT_CLASS(wiphy_enabled_evt, - TP_PROTO(struct wiphy *wiphy, bool enabled), - TP_ARGS(wiphy, enabled), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(bool, enabled) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->enabled = enabled; - ), - TP_printk(WIPHY_PR_FMT ", %senabled ", - WIPHY_PR_ARG, __entry->enabled ? "" : "not ") -); - -DEFINE_EVENT(wiphy_enabled_evt, rdev_set_wakeup, - TP_PROTO(struct wiphy *wiphy, bool enabled), - TP_ARGS(wiphy, enabled) -); - -TRACE_EVENT(rdev_add_virtual_intf, - TP_PROTO(struct wiphy *wiphy, char *name, enum nl80211_iftype type), - TP_ARGS(wiphy, name, type), - TP_STRUCT__entry( - WIPHY_ENTRY - __string(vir_intf_name, name ? name : "") - __field(enum nl80211_iftype, type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __assign_str(vir_intf_name, name ? name : ""); - __entry->type = type; - ), - TP_printk(WIPHY_PR_FMT ", virtual intf name: %s, type: %d", - WIPHY_PR_ARG, __get_str(vir_intf_name), __entry->type) -); - -DECLARE_EVENT_CLASS(wiphy_wdev_evt, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_return_wdev, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_del_virtual_intf, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -TRACE_EVENT(rdev_change_virtual_intf, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - enum nl80211_iftype type), - TP_ARGS(wiphy, netdev, type), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(enum nl80211_iftype, type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->type = type; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", type: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->type) -); - -DECLARE_EVENT_CLASS(key_handle, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr), - TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(mac_addr) - __field(u8, key_index) - __field(bool, pairwise) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(mac_addr, mac_addr); - __entry->key_index = key_index; - __entry->pairwise = pairwise; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key_index: %u, pairwise: %s, mac addr: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, - BOOL_TO_STR(__entry->pairwise), MAC_PR_ARG(mac_addr)) -); - -DEFINE_EVENT(key_handle, rdev_add_key, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr), - TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) -); - -DEFINE_EVENT(key_handle, rdev_get_key, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr), - TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) -); - -DEFINE_EVENT(key_handle, rdev_del_key, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, - bool pairwise, const u8 *mac_addr), - TP_ARGS(wiphy, netdev, key_index, pairwise, mac_addr) -); - -TRACE_EVENT(rdev_set_default_key, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, - bool unicast, bool multicast), - TP_ARGS(wiphy, netdev, key_index, unicast, multicast), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u8, key_index) - __field(bool, unicast) - __field(bool, multicast) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->key_index = key_index; - __entry->unicast = unicast; - __entry->multicast = multicast; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u, unicast: %s, multicast: %s", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index, - BOOL_TO_STR(__entry->unicast), - BOOL_TO_STR(__entry->multicast)) -); - -TRACE_EVENT(rdev_set_default_mgmt_key, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index), - TP_ARGS(wiphy, netdev, key_index), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u8, key_index) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->key_index = key_index; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", key index: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index) -); - -TRACE_EVENT(rdev_start_ap, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_ap_settings *settings), - TP_ARGS(wiphy, netdev, settings), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - CHAN_ENTRY - __field(int, beacon_interval) - __field(int, dtim_period) - __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) - __field(enum nl80211_hidden_ssid, hidden_ssid) - __field(u32, wpa_ver) - __field(bool, privacy) - __field(enum nl80211_auth_type, auth_type) - __field(int, inactivity_timeout) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - CHAN_ASSIGN(settings->channel); - __entry->beacon_interval = settings->beacon_interval; - __entry->dtim_period = settings->dtim_period; - __entry->hidden_ssid = settings->hidden_ssid; - __entry->wpa_ver = settings->crypto.wpa_versions; - __entry->privacy = settings->privacy; - __entry->auth_type = settings->auth_type; - __entry->inactivity_timeout = settings->inactivity_timeout; - memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); - memcpy(__entry->ssid, settings->ssid, settings->ssid_len); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", AP settings - ssid: %s, " - CHAN_PR_FMT ", beacon interval: %d, dtim period: %d, " - "hidden ssid: %d, wpa versions: %u, privacy: %s, " - "auth type: %d, inactivity timeout: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ssid, CHAN_PR_ARG, - __entry->beacon_interval, __entry->dtim_period, - __entry->hidden_ssid, __entry->wpa_ver, - BOOL_TO_STR(__entry->privacy), __entry->auth_type, - __entry->inactivity_timeout) -); - -TRACE_EVENT(rdev_change_beacon, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_beacon_data *info), - TP_ARGS(wiphy, netdev, info), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __dynamic_array(u8, head, info ? info->head_len : 0) - __dynamic_array(u8, tail, info ? info->tail_len : 0) - __dynamic_array(u8, beacon_ies, info ? info->beacon_ies_len : 0) - __dynamic_array(u8, proberesp_ies, - info ? info->proberesp_ies_len : 0) - __dynamic_array(u8, assocresp_ies, - info ? info->assocresp_ies_len : 0) - __dynamic_array(u8, probe_resp, info ? info->probe_resp_len : 0) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - if (info) { - if (info->head) - memcpy(__get_dynamic_array(head), info->head, - info->head_len); - if (info->tail) - memcpy(__get_dynamic_array(tail), info->tail, - info->tail_len); - if (info->beacon_ies) - memcpy(__get_dynamic_array(beacon_ies), - info->beacon_ies, info->beacon_ies_len); - if (info->proberesp_ies) - memcpy(__get_dynamic_array(proberesp_ies), - info->proberesp_ies, - info->proberesp_ies_len); - if (info->assocresp_ies) - memcpy(__get_dynamic_array(assocresp_ies), - info->assocresp_ies, - info->assocresp_ies_len); - if (info->probe_resp) - memcpy(__get_dynamic_array(probe_resp), - info->probe_resp, info->probe_resp_len); - } - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) -); - -DECLARE_EVENT_CLASS(wiphy_netdev_evt, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_set_rekey_data, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_get_mesh_config, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_mesh, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ibss, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), - TP_ARGS(wiphy, netdev) -); - -DECLARE_EVENT_CLASS(station_add_change, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, - struct station_parameters *params), - TP_ARGS(wiphy, netdev, mac, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(sta_mac) - __field(u32, sta_flags_mask) - __field(u32, sta_flags_set) - __field(u32, sta_modify_mask) - __field(int, listen_interval) - __field(u16, aid) - __field(u8, plink_action) - __field(u8, plink_state) - __field(u8, uapsd_queues) - __array(u8, ht_capa, (int)sizeof(struct ieee80211_ht_cap)) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(sta_mac, mac); - __entry->sta_flags_mask = params->sta_flags_mask; - __entry->sta_flags_set = params->sta_flags_set; - __entry->sta_modify_mask = params->sta_modify_mask; - __entry->listen_interval = params->listen_interval; - __entry->aid = params->aid; - __entry->plink_action = params->plink_action; - __entry->plink_state = params->plink_state; - __entry->uapsd_queues = params->uapsd_queues; - memset(__entry->ht_capa, 0, sizeof(struct ieee80211_ht_cap)); - if (params->ht_capa) - memcpy(__entry->ht_capa, params->ht_capa, - sizeof(struct ieee80211_ht_cap)); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT - ", station flags mask: %u, station flags set: %u, " - "station modify mask: %u, listen interval: %d, aid: %u, " - "plink action: %u, plink state: %u, uapsd queues: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), - __entry->sta_flags_mask, __entry->sta_flags_set, - __entry->sta_modify_mask, __entry->listen_interval, - __entry->aid, __entry->plink_action, __entry->plink_state, - __entry->uapsd_queues) -); - -DEFINE_EVENT(station_add_change, rdev_add_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, - struct station_parameters *params), - TP_ARGS(wiphy, netdev, mac, params) -); - -DEFINE_EVENT(station_add_change, rdev_change_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *mac, - struct station_parameters *params), - TP_ARGS(wiphy, netdev, mac, params) -); - -DECLARE_EVENT_CLASS(wiphy_netdev_mac_evt, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(sta_mac) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(sta_mac, mac); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mac: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) -); - -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) -); - -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) -); - -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_mpath, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) -); - -DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_set_wds_peer, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), - TP_ARGS(wiphy, netdev, mac) -); - -TRACE_EVENT(rdev_dump_station, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, - u8 *mac), - TP_ARGS(wiphy, netdev, idx, mac), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(sta_mac) - __field(int, idx) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(sta_mac, mac); - __entry->idx = idx; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", station mac: " MAC_PR_FMT ", idx: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), - __entry->idx) -); - -TRACE_EVENT(rdev_return_int_station_info, - TP_PROTO(struct wiphy *wiphy, int ret, struct station_info *sinfo), - TP_ARGS(wiphy, ret, sinfo), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, ret) - SINFO_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->ret = ret; - SINFO_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT ", returned %d" , - WIPHY_PR_ARG, __entry->ret) -); - -DECLARE_EVENT_CLASS(mpath_evt, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, - u8 *next_hop), - TP_ARGS(wiphy, netdev, dst, next_hop), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(dst) - MAC_ENTRY(next_hop) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(dst, dst); - MAC_ASSIGN(next_hop, next_hop); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", destination: " MAC_PR_FMT ", next hop: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(dst), - MAC_PR_ARG(next_hop)) -); - -DEFINE_EVENT(mpath_evt, rdev_add_mpath, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, - u8 *next_hop), - TP_ARGS(wiphy, netdev, dst, next_hop) -); - -DEFINE_EVENT(mpath_evt, rdev_change_mpath, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, - u8 *next_hop), - TP_ARGS(wiphy, netdev, dst, next_hop) -); - -DEFINE_EVENT(mpath_evt, rdev_get_mpath, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 *dst, - u8 *next_hop), - TP_ARGS(wiphy, netdev, dst, next_hop) -); - -TRACE_EVENT(rdev_dump_mpath, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, - u8 *dst, u8 *next_hop), - TP_ARGS(wiphy, netdev, idx, dst, next_hop), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(dst) - MAC_ENTRY(next_hop) - __field(int, idx) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(dst, dst); - MAC_ASSIGN(next_hop, next_hop); - __entry->idx = idx; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d, destination: " - MAC_PR_FMT ", next hop: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), - MAC_PR_ARG(next_hop)) -); - -TRACE_EVENT(rdev_return_int_mpath_info, - TP_PROTO(struct wiphy *wiphy, int ret, struct mpath_info *pinfo), - TP_ARGS(wiphy, ret, pinfo), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, ret) - __field(int, generation) - __field(u32, filled) - __field(u32, frame_qlen) - __field(u32, sn) - __field(u32, metric) - __field(u32, exptime) - __field(u32, discovery_timeout) - __field(u8, discovery_retries) - __field(u8, flags) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->ret = ret; - __entry->generation = pinfo->generation; - __entry->filled = pinfo->filled; - __entry->frame_qlen = pinfo->frame_qlen; - __entry->sn = pinfo->sn; - __entry->metric = pinfo->metric; - __entry->exptime = pinfo->exptime; - __entry->discovery_timeout = pinfo->discovery_timeout; - __entry->discovery_retries = pinfo->discovery_retries; - __entry->flags = pinfo->flags; - ), - TP_printk(WIPHY_PR_FMT ", returned %d. mpath info - generation: %d, " - "filled: %u, frame qlen: %u, sn: %u, metric: %u, exptime: %u," - " discovery timeout: %u, discovery retries: %u, flags: %u", - WIPHY_PR_ARG, __entry->ret, __entry->generation, - __entry->filled, __entry->frame_qlen, __entry->sn, - __entry->metric, __entry->exptime, __entry->discovery_timeout, - __entry->discovery_retries, __entry->flags) -); - -TRACE_EVENT(rdev_return_int_mesh_config, - TP_PROTO(struct wiphy *wiphy, int ret, struct mesh_config *conf), - TP_ARGS(wiphy, ret, conf), - TP_STRUCT__entry( - WIPHY_ENTRY - MESH_CFG_ENTRY - __field(int, ret) - ), - TP_fast_assign( - WIPHY_ASSIGN; - MESH_CFG_ASSIGN; - __entry->ret = ret; - ), - TP_printk(WIPHY_PR_FMT ", returned: %d", - WIPHY_PR_ARG, __entry->ret) -); - -TRACE_EVENT(rdev_update_mesh_config, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 mask, - const struct mesh_config *conf), - TP_ARGS(wiphy, netdev, mask, conf), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MESH_CFG_ENTRY - __field(u32, mask) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MESH_CFG_ASSIGN; - __entry->mask = mask; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", mask: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mask) -); - -TRACE_EVENT(rdev_join_mesh, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - const struct mesh_config *conf, - const struct mesh_setup *setup), - TP_ARGS(wiphy, netdev, conf, setup), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MESH_CFG_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MESH_CFG_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG) -); - -TRACE_EVENT(rdev_change_bss, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct bss_parameters *params), - TP_ARGS(wiphy, netdev, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(int, use_cts_prot) - __field(int, use_short_preamble) - __field(int, use_short_slot_time) - __field(int, ap_isolate) - __field(int, ht_opmode) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->use_cts_prot = params->use_cts_prot; - __entry->use_short_preamble = params->use_short_preamble; - __entry->use_short_slot_time = params->use_short_slot_time; - __entry->ap_isolate = params->ap_isolate; - __entry->ht_opmode = params->ht_opmode; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", use cts prot: %d, " - "use short preamble: %d, use short slot time: %d, " - "ap isolate: %d, ht opmode: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot, - __entry->use_short_preamble, __entry->use_short_slot_time, - __entry->ap_isolate, __entry->ht_opmode) -); - -TRACE_EVENT(rdev_set_txq_params, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct ieee80211_txq_params *params), - TP_ARGS(wiphy, netdev, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(enum nl80211_ac, ac) - __field(u16, txop) - __field(u16, cwmin) - __field(u16, cwmax) - __field(u8, aifs) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->ac = params->ac; - __entry->txop = params->txop; - __entry->cwmin = params->cwmin; - __entry->cwmax = params->cwmax; - __entry->aifs = params->aifs; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", ac: %d, txop: %u, cwmin: %u, cwmax: %u, aifs: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->ac, __entry->txop, - __entry->cwmin, __entry->cwmax, __entry->aifs) -); - -TRACE_EVENT(rdev_libertas_set_mesh_channel, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct ieee80211_channel *chan), - TP_ARGS(wiphy, netdev, chan), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - CHAN_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - CHAN_ASSIGN(chan); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT CHAN_PR_FMT, WIPHY_PR_ARG, - NETDEV_PR_ARG, CHAN_PR_ARG) -); - -TRACE_EVENT(rdev_set_monitor_channel, - TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, - enum nl80211_channel_type chan_type), - TP_ARGS(wiphy, chan, chan_type), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - __field(enum nl80211_channel_type, chan_type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(chan); - __entry->chan_type = chan_type; - ), - TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type : %d", - WIPHY_PR_ARG, CHAN_PR_ARG, __entry->chan_type) -); - -TRACE_EVENT(rdev_auth, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_auth_request *req), - TP_ARGS(wiphy, netdev, req), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - __field(enum nl80211_auth_type, auth_type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - if (req->bss) - MAC_ASSIGN(bssid, req->bss->bssid); - else - memset(__entry->bssid, 0, ETH_ALEN); - __entry->auth_type = req->auth_type; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", auth type: %d, bssid: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->auth_type, - MAC_PR_ARG(bssid)) -); - -TRACE_EVENT(rdev_assoc, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_assoc_request *req), - TP_ARGS(wiphy, netdev, req), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - MAC_ENTRY(prev_bssid) - __field(bool, use_mfp) - __field(u32, flags) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - if (req->bss) - MAC_ASSIGN(bssid, req->bss->bssid); - else - memset(__entry->bssid, 0, ETH_ALEN); - MAC_ASSIGN(prev_bssid, req->prev_bssid); - __entry->use_mfp = req->use_mfp; - __entry->flags = req->flags; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT - ", previous bssid: " MAC_PR_FMT ", use mfp: %s, flags: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), - MAC_PR_ARG(prev_bssid), BOOL_TO_STR(__entry->use_mfp), - __entry->flags) -); - -TRACE_EVENT(rdev_deauth, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_deauth_request *req), - TP_ARGS(wiphy, netdev, req), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - __field(u16, reason_code) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(bssid, req->bssid); - __entry->reason_code = req->reason_code; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", reason: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), - __entry->reason_code) -); - -TRACE_EVENT(rdev_disassoc, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_disassoc_request *req), - TP_ARGS(wiphy, netdev, req), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - __field(u16, reason_code) - __field(bool, local_state_change) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - if (req->bss) - MAC_ASSIGN(bssid, req->bss->bssid); - else - memset(__entry->bssid, 0, ETH_ALEN); - __entry->reason_code = req->reason_code; - __entry->local_state_change = req->local_state_change; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT - ", reason: %u, local state change: %s", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), - __entry->reason_code, - BOOL_TO_STR(__entry->local_state_change)) -); - -TRACE_EVENT(rdev_mgmt_tx_cancel_wait, - TP_PROTO(struct wiphy *wiphy, - struct wireless_dev *wdev, u64 cookie), - TP_ARGS(wiphy, wdev, cookie), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - __field(u64, cookie) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - __entry->cookie = cookie; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu ", - WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) -); - -TRACE_EVENT(rdev_set_power_mgmt, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - bool enabled, int timeout), - TP_ARGS(wiphy, netdev, enabled, timeout), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(bool, enabled) - __field(int, timeout) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->enabled = enabled; - __entry->timeout = timeout; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", %senabled, timeout: %d ", - WIPHY_PR_ARG, NETDEV_PR_ARG, - __entry->enabled ? "" : "not ", __entry->timeout) -); - -TRACE_EVENT(rdev_connect, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_connect_params *sme), - TP_ARGS(wiphy, netdev, sme), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) - __field(enum nl80211_auth_type, auth_type) - __field(bool, privacy) - __field(u32, wpa_versions) - __field(u32, flags) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(bssid, sme->bssid); - memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); - memcpy(__entry->ssid, sme->ssid, sme->ssid_len); - __entry->auth_type = sme->auth_type; - __entry->privacy = sme->privacy; - __entry->wpa_versions = sme->crypto.wpa_versions; - __entry->flags = sme->flags; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT - ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, " - "flags: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid, - __entry->auth_type, BOOL_TO_STR(__entry->privacy), - __entry->wpa_versions, __entry->flags) -); - -TRACE_EVENT(rdev_set_cqm_rssi_config, - TP_PROTO(struct wiphy *wiphy, - struct net_device *netdev, s32 rssi_thold, - u32 rssi_hyst), - TP_ARGS(wiphy, netdev, rssi_thold, rssi_hyst), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(s32, rssi_thold) - __field(u32, rssi_hyst) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->rssi_thold = rssi_thold; - __entry->rssi_hyst = rssi_hyst; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT - ", rssi_thold: %d, rssi_hyst: %u ", - WIPHY_PR_ARG, NETDEV_PR_ARG, - __entry->rssi_thold, __entry->rssi_hyst) -); - -TRACE_EVENT(rdev_set_cqm_txe_config, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 rate, - u32 pkts, u32 intvl), - TP_ARGS(wiphy, netdev, rate, pkts, intvl), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u32, rate) - __field(u32, pkts) - __field(u32, intvl) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->rate = rate; - __entry->pkts = pkts; - __entry->intvl = intvl; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", rate: %u, packets: %u, interval: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->rate, __entry->pkts, - __entry->intvl) -); - -TRACE_EVENT(rdev_disconnect, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - u16 reason_code), - TP_ARGS(wiphy, netdev, reason_code), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u16, reason_code) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->reason_code = reason_code; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", reason code: %u", WIPHY_PR_ARG, - NETDEV_PR_ARG, __entry->reason_code) -); - -TRACE_EVENT(rdev_join_ibss, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_ibss_params *params), - TP_ARGS(wiphy, netdev, params), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - __array(char, ssid, IEEE80211_MAX_SSID_LEN + 1) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(bssid, params->bssid); - memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1); - memcpy(__entry->ssid, params->ssid, params->ssid_len); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) -); - -TRACE_EVENT(rdev_set_wiphy_params, - TP_PROTO(struct wiphy *wiphy, u32 changed), - TP_ARGS(wiphy, changed), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(u32, changed) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->changed = changed; - ), - TP_printk(WIPHY_PR_FMT ", changed: %u", - WIPHY_PR_ARG, __entry->changed) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -TRACE_EVENT(rdev_set_tx_power, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, int mbm), - TP_ARGS(wiphy, wdev, type, mbm), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - __field(enum nl80211_tx_power_setting, type) - __field(int, mbm) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - __entry->type = type; - __entry->mbm = mbm; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", type: %d, mbm: %d", - WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm) -); - -TRACE_EVENT(rdev_return_int_int, - TP_PROTO(struct wiphy *wiphy, int func_ret, int func_fill), - TP_ARGS(wiphy, func_ret, func_fill), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, func_ret) - __field(int, func_fill) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->func_ret = func_ret; - __entry->func_fill = func_fill; - ), - TP_printk(WIPHY_PR_FMT ", function returns: %d, function filled: %d", - WIPHY_PR_ARG, __entry->func_ret, __entry->func_fill) -); - -#ifdef CONFIG_NL80211_TESTMODE -TRACE_EVENT(rdev_testmode_cmd, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy), - TP_STRUCT__entry( - WIPHY_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) -); - -TRACE_EVENT(rdev_testmode_dump, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy), - TP_STRUCT__entry( - WIPHY_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG) -); -#endif /* CONFIG_NL80211_TESTMODE */ - -TRACE_EVENT(rdev_set_bitrate_mask, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - const u8 *peer, const struct cfg80211_bitrate_mask *mask), - TP_ARGS(wiphy, netdev, peer, mask), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(peer) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(peer, peer); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", peer: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) -); - -TRACE_EVENT(rdev_mgmt_frame_register, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, - u16 frame_type, bool reg), - TP_ARGS(wiphy, wdev, frame_type, reg), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - __field(u16, frame_type) - __field(bool, reg) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - __entry->frame_type = frame_type; - __entry->reg = reg; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", frame_type: %u, reg: %s ", - WIPHY_PR_ARG, WDEV_PR_ARG, __entry->frame_type, - __entry->reg ? "true" : "false") -); - -TRACE_EVENT(rdev_return_int_tx_rx, - TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx), - TP_ARGS(wiphy, ret, tx, rx), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, ret) - __field(u32, tx) - __field(u32, rx) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->ret = ret; - __entry->tx = tx; - __entry->rx = rx; - ), - TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u", - WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx) -); - -TRACE_EVENT(rdev_return_void_tx_rx, - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 tx_max, - u32 rx, u32 rx_max), - TP_ARGS(wiphy, tx, tx_max, rx, rx_max), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(u32, tx) - __field(u32, tx_max) - __field(u32, rx) - __field(u32, rx_max) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->tx = tx; - __entry->tx_max = tx_max; - __entry->rx = rx; - __entry->rx_max = rx_max; - ), - TP_printk(WIPHY_PR_FMT ", tx: %u, tx_max: %u, rx: %u, rx_max: %u ", - WIPHY_PR_ARG, __entry->tx, __entry->tx_max, __entry->rx, - __entry->rx_max) -); - -DECLARE_EVENT_CLASS(tx_rx_evt, - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), - TP_ARGS(wiphy, rx, tx), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(u32, tx) - __field(u32, rx) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->tx = tx; - __entry->rx = rx; - ), - TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u ", - WIPHY_PR_ARG, __entry->tx, __entry->rx) -); - -DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam, - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), - TP_ARGS(wiphy, rx, tx) -); - -DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, - TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), - TP_ARGS(wiphy, rx, tx) -); - -TRACE_EVENT(rdev_sched_scan_start, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_sched_scan_request *request), - TP_ARGS(wiphy, netdev, request), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG) -); - -TRACE_EVENT(rdev_tdls_mgmt, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - u8 *peer, u8 action_code, u8 dialog_token, - u16 status_code, const u8 *buf, size_t len), - TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, - buf, len), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(peer) - __field(u8, action_code) - __field(u8, dialog_token) - __field(u16, status_code) - __dynamic_array(u8, buf, len) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(peer, peer); - __entry->action_code = action_code; - __entry->dialog_token = dialog_token; - __entry->status_code = status_code; - memcpy(__get_dynamic_array(buf), buf, len); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", action_code: %u, " - "dialog_token: %u, status_code: %u, buf: %#.2x ", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), - __entry->action_code, __entry->dialog_token, - __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0]) -); - -TRACE_EVENT(rdev_dump_survey, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx), - TP_ARGS(wiphy, netdev, idx), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(int, idx) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->idx = idx; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", index: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx) -); - -TRACE_EVENT(rdev_return_int_survey_info, - TP_PROTO(struct wiphy *wiphy, int ret, struct survey_info *info), - TP_ARGS(wiphy, ret, info), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - __field(int, ret) - __field(u64, channel_time) - __field(u64, channel_time_busy) - __field(u64, channel_time_ext_busy) - __field(u64, channel_time_rx) - __field(u64, channel_time_tx) - __field(u32, filled) - __field(s8, noise) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(info->channel); - __entry->ret = ret; - __entry->channel_time = info->channel_time; - __entry->channel_time_busy = info->channel_time_busy; - __entry->channel_time_ext_busy = info->channel_time_ext_busy; - __entry->channel_time_rx = info->channel_time_rx; - __entry->channel_time_tx = info->channel_time_tx; - __entry->filled = info->filled; - __entry->noise = info->noise; - ), - TP_printk(WIPHY_PR_FMT ", returned: %d, " CHAN_PR_FMT - ", channel time: %llu, channel time busy: %llu, " - "channel time extension busy: %llu, channel time rx: %llu, " - "channel time tx: %llu, filled: %u, noise: %d", - WIPHY_PR_ARG, __entry->ret, CHAN_PR_ARG, - __entry->channel_time, __entry->channel_time_busy, - __entry->channel_time_ext_busy, __entry->channel_time_rx, - __entry->channel_time_tx, __entry->filled, __entry->noise) -); - -TRACE_EVENT(rdev_tdls_oper, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - u8 *peer, enum nl80211_tdls_operation oper), - TP_ARGS(wiphy, netdev, peer, oper), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(peer) - __field(enum nl80211_tdls_operation, oper) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(peer, peer); - __entry->oper = oper; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT ", oper: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->oper) -); - -DECLARE_EVENT_CLASS(rdev_pmksa, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_pmksa *pmksa), - TP_ARGS(wiphy, netdev, pmksa), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(bssid) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(bssid, pmksa->bssid); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", bssid: " MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid)) -); - -TRACE_EVENT(rdev_probe_client, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - const u8 *peer), - TP_ARGS(wiphy, netdev, peer), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - MAC_ENTRY(peer) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - MAC_ASSIGN(peer, peer); - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT MAC_PR_FMT, - WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer)) -); - -DEFINE_EVENT(rdev_pmksa, rdev_set_pmksa, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_pmksa *pmksa), - TP_ARGS(wiphy, netdev, pmksa) -); - -DEFINE_EVENT(rdev_pmksa, rdev_del_pmksa, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - struct cfg80211_pmksa *pmksa), - TP_ARGS(wiphy, netdev, pmksa) -); - -TRACE_EVENT(rdev_remain_on_channel, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, unsigned int duration), - TP_ARGS(wiphy, wdev, chan, channel_type, duration), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - CHAN_ENTRY - __field(enum nl80211_channel_type, channel_type) - __field(unsigned int, duration) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - CHAN_ASSIGN(chan); - __entry->channel_type = channel_type; - __entry->duration = duration; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", channel type: %d, duration: %u", - WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, __entry->channel_type, - __entry->duration) -); - -TRACE_EVENT(rdev_return_int_cookie, - TP_PROTO(struct wiphy *wiphy, int ret, u64 cookie), - TP_ARGS(wiphy, ret, cookie), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, ret) - __field(u64, cookie) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->ret = ret; - __entry->cookie = cookie; - ), - TP_printk(WIPHY_PR_FMT ", returned %d, cookie: %llu", - WIPHY_PR_ARG, __entry->ret, __entry->cookie) -); - -TRACE_EVENT(rdev_cancel_remain_on_channel, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie), - TP_ARGS(wiphy, wdev, cookie), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - __field(u64, cookie) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - __entry->cookie = cookie; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", cookie: %llu", - WIPHY_PR_ARG, WDEV_PR_ARG, __entry->cookie) -); - -TRACE_EVENT(rdev_mgmt_tx, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, bool offchan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, unsigned int wait, bool no_cck, - bool dont_wait_for_ack), - TP_ARGS(wiphy, wdev, chan, offchan, channel_type, channel_type_valid, - wait, no_cck, dont_wait_for_ack), - TP_STRUCT__entry( - WIPHY_ENTRY - WDEV_ENTRY - CHAN_ENTRY - __field(bool, offchan) - __field(enum nl80211_channel_type, channel_type) - __field(bool, channel_type_valid) - __field(unsigned int, wait) - __field(bool, no_cck) - __field(bool, dont_wait_for_ack) - ), - TP_fast_assign( - WIPHY_ASSIGN; - WDEV_ASSIGN; - CHAN_ASSIGN(chan); - __entry->offchan = offchan; - __entry->channel_type = channel_type; - __entry->channel_type_valid = channel_type_valid; - __entry->wait = wait; - __entry->no_cck = no_cck; - __entry->dont_wait_for_ack = dont_wait_for_ack; - ), - TP_printk(WIPHY_PR_FMT WDEV_PR_FMT CHAN_PR_FMT ", offchan: %s, " - "channel type: %d, channel type valid: %s, wait: %u, " - "no cck: %s, dont wait for ack: %s", - WIPHY_PR_ARG, WDEV_PR_ARG, CHAN_PR_ARG, - BOOL_TO_STR(__entry->offchan), __entry->channel_type, - BOOL_TO_STR(__entry->channel_type_valid), __entry->wait, - BOOL_TO_STR(__entry->no_cck), - BOOL_TO_STR(__entry->dont_wait_for_ack)) -); - -TRACE_EVENT(rdev_set_noack_map, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - u16 noack_map), - TP_ARGS(wiphy, netdev, noack_map), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u16, noack_map) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->noack_map = noack_map; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", noack_map: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) -); - -TRACE_EVENT(rdev_get_et_sset_count, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset), - TP_ARGS(wiphy, netdev, sset), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(int, sset) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->sset = sset; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %d", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) -); - -TRACE_EVENT(rdev_get_et_strings, - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset), - TP_ARGS(wiphy, netdev, sset), - TP_STRUCT__entry( - WIPHY_ENTRY - NETDEV_ENTRY - __field(u32, sset) - ), - TP_fast_assign( - WIPHY_ASSIGN; - NETDEV_ASSIGN; - __entry->sset = sset; - ), - TP_printk(WIPHY_PR_FMT NETDEV_PR_FMT ", sset: %u", - WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -TRACE_EVENT(rdev_return_channel, - TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *chan, - enum nl80211_channel_type type), - TP_ARGS(wiphy, chan, type), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - __field(enum nl80211_channel_type, type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(chan); - __entry->type = type; - ), - TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel type: %d", - WIPHY_PR_ARG, CHAN_PR_ARG, __entry->type) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_start_p2p_device, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device, - TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), - TP_ARGS(wiphy, wdev) -); - -/************************************************************* - * cfg80211 exported functions traces * - *************************************************************/ - -TRACE_EVENT(cfg80211_return_bool, - TP_PROTO(bool ret), - TP_ARGS(ret), - TP_STRUCT__entry( - __field(bool, ret) - ), - TP_fast_assign( - __entry->ret = ret; - ), - TP_printk("returned %s", BOOL_TO_STR(__entry->ret)) -); - -DECLARE_EVENT_CLASS(cfg80211_netdev_mac_evt, - TP_PROTO(struct net_device *netdev, const u8 *macaddr), - TP_ARGS(netdev, macaddr), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(macaddr) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(macaddr, macaddr); - ), - TP_printk(NETDEV_PR_FMT ", mac: " MAC_PR_FMT, - NETDEV_PR_ARG, MAC_PR_ARG(macaddr)) -); - -DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_notify_new_peer_candidate, - TP_PROTO(struct net_device *netdev, const u8 *macaddr), - TP_ARGS(netdev, macaddr) -); - -DECLARE_EVENT_CLASS(netdev_evt_only, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev), - TP_STRUCT__entry( - NETDEV_ENTRY - ), - TP_fast_assign( - NETDEV_ASSIGN; - ), - TP_printk(NETDEV_PR_FMT , NETDEV_PR_ARG) -); - -DEFINE_EVENT(netdev_evt_only, cfg80211_send_rx_auth, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev) -); - -TRACE_EVENT(cfg80211_send_rx_assoc, - TP_PROTO(struct net_device *netdev, struct cfg80211_bss *bss), - TP_ARGS(netdev, bss), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(bssid) - CHAN_ENTRY - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(bssid, bss->bssid); - CHAN_ASSIGN(bss->channel); - ), - TP_printk(NETDEV_PR_FMT MAC_PR_FMT CHAN_PR_FMT, - NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) -); - -DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev) -); - -DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev) -); - -DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_deauth, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev) -); - -DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_disassoc, - TP_PROTO(struct net_device *netdev), - TP_ARGS(netdev) -); - -DECLARE_EVENT_CLASS(netdev_mac_evt, - TP_PROTO(struct net_device *netdev, const u8 *mac), - TP_ARGS(netdev, mac), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(mac) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(mac, mac) - ), - TP_printk(NETDEV_PR_FMT ", mac: " MAC_PR_FMT, - NETDEV_PR_ARG, MAC_PR_ARG(mac)) -); - -DEFINE_EVENT(netdev_mac_evt, cfg80211_send_auth_timeout, - TP_PROTO(struct net_device *netdev, const u8 *mac), - TP_ARGS(netdev, mac) -); - -DEFINE_EVENT(netdev_mac_evt, cfg80211_send_assoc_timeout, - TP_PROTO(struct net_device *netdev, const u8 *mac), - TP_ARGS(netdev, mac) -); - -TRACE_EVENT(cfg80211_michael_mic_failure, - TP_PROTO(struct net_device *netdev, const u8 *addr, - enum nl80211_key_type key_type, int key_id, const u8 *tsc), - TP_ARGS(netdev, addr, key_type, key_id, tsc), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(addr) - __field(enum nl80211_key_type, key_type) - __field(int, key_id) - __array(u8, tsc, 6) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(addr, addr); - __entry->key_type = key_type; - __entry->key_id = key_id; - memcpy(__entry->tsc, tsc, 6); - ), - TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", - NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type, - __entry->key_id, __entry->tsc) -); - -TRACE_EVENT(cfg80211_ready_on_channel, - TP_PROTO(struct wireless_dev *wdev, u64 cookie, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, unsigned int duration), - TP_ARGS(wdev, cookie, chan, channel_type, duration), - TP_STRUCT__entry( - WDEV_ENTRY - __field(u64, cookie) - CHAN_ENTRY - __field(enum nl80211_channel_type, channel_type) - __field(unsigned int, duration) - ), - TP_fast_assign( - WDEV_ASSIGN; - __entry->cookie = cookie; - CHAN_ASSIGN(chan); - __entry->channel_type = channel_type; - __entry->duration = duration; - ), - TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d, duration: %u", - WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, - __entry->channel_type, __entry->duration) -); - -TRACE_EVENT(cfg80211_ready_on_channel_expired, - TP_PROTO(struct wireless_dev *wdev, u64 cookie, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type), - TP_ARGS(wdev, cookie, chan, channel_type), - TP_STRUCT__entry( - WDEV_ENTRY - __field(u64, cookie) - CHAN_ENTRY - __field(enum nl80211_channel_type, channel_type) - ), - TP_fast_assign( - WDEV_ASSIGN; - __entry->cookie = cookie; - CHAN_ASSIGN(chan); - __entry->channel_type = channel_type; - ), - TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT ", channel type: %d", - WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG, - __entry->channel_type) -); - -TRACE_EVENT(cfg80211_new_sta, - TP_PROTO(struct net_device *netdev, const u8 *mac_addr, - struct station_info *sinfo), - TP_ARGS(netdev, mac_addr, sinfo), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(mac_addr) - SINFO_ENTRY - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(mac_addr, mac_addr); - SINFO_ASSIGN; - ), - TP_printk(NETDEV_PR_FMT MAC_PR_FMT, - NETDEV_PR_ARG, MAC_PR_ARG(mac_addr)) -); - -DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_del_sta, - TP_PROTO(struct net_device *netdev, const u8 *macaddr), - TP_ARGS(netdev, macaddr) -); - -TRACE_EVENT(cfg80211_rx_mgmt, - TP_PROTO(struct wireless_dev *wdev, int freq, int sig_mbm), - TP_ARGS(wdev, freq, sig_mbm), - TP_STRUCT__entry( - WDEV_ENTRY - __field(int, freq) - __field(int, sig_mbm) - ), - TP_fast_assign( - WDEV_ASSIGN; - __entry->freq = freq; - __entry->sig_mbm = sig_mbm; - ), - TP_printk(WDEV_PR_FMT ", freq: %d, sig mbm: %d", - WDEV_PR_ARG, __entry->freq, __entry->sig_mbm) -); - -TRACE_EVENT(cfg80211_mgmt_tx_status, - TP_PROTO(struct wireless_dev *wdev, u64 cookie, bool ack), - TP_ARGS(wdev, cookie, ack), - TP_STRUCT__entry( - WDEV_ENTRY - __field(u64, cookie) - __field(bool, ack) - ), - TP_fast_assign( - WDEV_ASSIGN; - __entry->cookie = cookie; - __entry->ack = ack; - ), - TP_printk(WDEV_PR_FMT", cookie: %llu, ack: %s", - WDEV_PR_ARG, __entry->cookie, BOOL_TO_STR(__entry->ack)) -); - -TRACE_EVENT(cfg80211_cqm_rssi_notify, - TP_PROTO(struct net_device *netdev, - enum nl80211_cqm_rssi_threshold_event rssi_event), - TP_ARGS(netdev, rssi_event), - TP_STRUCT__entry( - NETDEV_ENTRY - __field(enum nl80211_cqm_rssi_threshold_event, rssi_event) - ), - TP_fast_assign( - NETDEV_ASSIGN; - __entry->rssi_event = rssi_event; - ), - TP_printk(NETDEV_PR_FMT ", rssi event: %d", - NETDEV_PR_ARG, __entry->rssi_event) -); - -TRACE_EVENT(cfg80211_can_beacon_sec_chan, - TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type), - TP_ARGS(wiphy, channel, channel_type), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - __field(enum nl80211_channel_type, channel_type) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(channel); - __entry->channel_type = channel_type; - ), - TP_printk(WIPHY_PR_FMT CHAN_PR_FMT ", channel_type: %d", - WIPHY_PR_ARG, CHAN_PR_ARG, __entry->channel_type) -); - -TRACE_EVENT(cfg80211_ch_switch_notify, - TP_PROTO(struct net_device *netdev, int freq, - enum nl80211_channel_type type), - TP_ARGS(netdev, freq, type), - TP_STRUCT__entry( - NETDEV_ENTRY - __field(int, freq) - __field(enum nl80211_channel_type, type) - ), - TP_fast_assign( - NETDEV_ASSIGN; - __entry->freq = freq; - __entry->type = type; - ), - TP_printk(NETDEV_PR_FMT ", freq: %d, type: %d", NETDEV_PR_ARG, - __entry->freq, __entry->type) -); - -DECLARE_EVENT_CLASS(cfg80211_rx_evt, - TP_PROTO(struct net_device *netdev, const u8 *addr), - TP_ARGS(netdev, addr), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(addr) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(addr, addr); - ), - TP_printk(NETDEV_PR_FMT MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr)) -); - -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined, - TP_PROTO(struct net_device *netdev, const u8 *addr), - TP_ARGS(netdev, addr) -); - -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame, - TP_PROTO(struct net_device *netdev, const u8 *addr), - TP_ARGS(netdev, addr) -); - -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_unexpected_4addr_frame, - TP_PROTO(struct net_device *netdev, const u8 *addr), - TP_ARGS(netdev, addr) -); - -TRACE_EVENT(cfg80211_probe_status, - TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie, - bool acked), - TP_ARGS(netdev, addr, cookie, acked), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(addr) - __field(u64, cookie) - __field(bool, acked) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(addr, addr); - __entry->cookie = cookie; - __entry->acked = acked; - ), - TP_printk(NETDEV_PR_FMT MAC_PR_FMT ", cookie: %llu, acked: %s", - NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->cookie, - BOOL_TO_STR(__entry->acked)) -); - -TRACE_EVENT(cfg80211_cqm_pktloss_notify, - TP_PROTO(struct net_device *netdev, const u8 *peer, u32 num_packets), - TP_ARGS(netdev, peer, num_packets), - TP_STRUCT__entry( - NETDEV_ENTRY - MAC_ENTRY(peer) - __field(u32, num_packets) - ), - TP_fast_assign( - NETDEV_ASSIGN; - MAC_ASSIGN(peer, peer); - __entry->num_packets = num_packets; - ), - TP_printk(NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", num of lost packets: %u", - NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->num_packets) -); - -DEFINE_EVENT(cfg80211_netdev_mac_evt, cfg80211_gtk_rekey_notify, - TP_PROTO(struct net_device *netdev, const u8 *macaddr), - TP_ARGS(netdev, macaddr) -); - -TRACE_EVENT(cfg80211_pmksa_candidate_notify, - TP_PROTO(struct net_device *netdev, int index, const u8 *bssid, - bool preauth), - TP_ARGS(netdev, index, bssid, preauth), - TP_STRUCT__entry( - NETDEV_ENTRY - __field(int, index) - MAC_ENTRY(bssid) - __field(bool, preauth) - ), - TP_fast_assign( - NETDEV_ASSIGN; - __entry->index = index; - MAC_ASSIGN(bssid, bssid); - __entry->preauth = preauth; - ), - TP_printk(NETDEV_PR_FMT ", index:%d, bssid: " MAC_PR_FMT ", pre auth: %s", - NETDEV_PR_ARG, __entry->index, MAC_PR_ARG(bssid), - BOOL_TO_STR(__entry->preauth)) -); - -TRACE_EVENT(cfg80211_report_obss_beacon, - TP_PROTO(struct wiphy *wiphy, const u8 *frame, size_t len, - int freq, int sig_dbm), - TP_ARGS(wiphy, frame, len, freq, sig_dbm), - TP_STRUCT__entry( - WIPHY_ENTRY - __field(int, freq) - __field(int, sig_dbm) - ), - TP_fast_assign( - WIPHY_ASSIGN; - __entry->freq = freq; - __entry->sig_dbm = sig_dbm; - ), - TP_printk(WIPHY_PR_FMT ", freq: %d, sig_dbm: %d", - WIPHY_PR_ARG, __entry->freq, __entry->sig_dbm) -); - -TRACE_EVENT(cfg80211_scan_done, - TP_PROTO(struct cfg80211_scan_request *request, bool aborted), - TP_ARGS(request, aborted), - TP_STRUCT__entry( - __field(u32, n_channels) - __dynamic_array(u8, ie, request ? request->ie_len : 0) - __array(u32, rates, IEEE80211_NUM_BANDS) - __field(u32, wdev_id) - MAC_ENTRY(wiphy_mac) - __field(bool, no_cck) - __field(bool, aborted) - ), - TP_fast_assign( - if (request) { - memcpy(__get_dynamic_array(ie), request->ie, - request->ie_len); - memcpy(__entry->rates, request->rates, - IEEE80211_NUM_BANDS); - __entry->wdev_id = request->wdev ? - request->wdev->identifier : 0; - if (request->wiphy) - MAC_ASSIGN(wiphy_mac, - request->wiphy->perm_addr); - __entry->no_cck = request->no_cck; - } - __entry->aborted = aborted; - ), - TP_printk("aborted: %s", BOOL_TO_STR(__entry->aborted)) -); - -DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_stopped, - TP_PROTO(struct wiphy *wiphy), - TP_ARGS(wiphy) -); - -TRACE_EVENT(cfg80211_get_bss, - TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, - const u8 *bssid, const u8 *ssid, size_t ssid_len, - u16 capa_mask, u16 capa_val), - TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, capa_mask, capa_val), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - MAC_ENTRY(bssid) - __dynamic_array(u8, ssid, ssid_len) - __field(u16, capa_mask) - __field(u16, capa_val) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(channel); - MAC_ASSIGN(bssid, bssid); - memcpy(__get_dynamic_array(ssid), ssid, ssid_len); - __entry->capa_mask = capa_mask; - __entry->capa_val = capa_val; - ), - TP_printk(WIPHY_PR_FMT CHAN_PR_FMT MAC_PR_FMT ", buf: %#.2x, " - "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, - MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], - __entry->capa_mask, __entry->capa_val) -); - -TRACE_EVENT(cfg80211_inform_bss_frame, - TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, - struct ieee80211_mgmt *mgmt, size_t len, - s32 signal), - TP_ARGS(wiphy, channel, mgmt, len, signal), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_ENTRY - __dynamic_array(u8, mgmt, len) - __field(s32, signal) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_ASSIGN(channel); - if (mgmt) - memcpy(__get_dynamic_array(mgmt), mgmt, len); - __entry->signal = signal; - ), - TP_printk(WIPHY_PR_FMT CHAN_PR_FMT "signal: %d", - WIPHY_PR_ARG, CHAN_PR_ARG, __entry->signal) -); - -DECLARE_EVENT_CLASS(cfg80211_bss_evt, - TP_PROTO(struct cfg80211_bss *pub), - TP_ARGS(pub), - TP_STRUCT__entry( - MAC_ENTRY(bssid) - CHAN_ENTRY - ), - TP_fast_assign( - MAC_ASSIGN(bssid, pub->bssid); - CHAN_ASSIGN(pub->channel); - ), - TP_printk(MAC_PR_FMT CHAN_PR_FMT, MAC_PR_ARG(bssid), CHAN_PR_ARG) -); - -DEFINE_EVENT(cfg80211_bss_evt, cfg80211_return_bss, - TP_PROTO(struct cfg80211_bss *pub), - TP_ARGS(pub) -); - -TRACE_EVENT(cfg80211_return_uint, - TP_PROTO(unsigned int ret), - TP_ARGS(ret), - TP_STRUCT__entry( - __field(unsigned int, ret) - ), - TP_fast_assign( - __entry->ret = ret; - ), - TP_printk("ret: %d", __entry->ret) -); - -TRACE_EVENT(cfg80211_return_u32, - TP_PROTO(u32 ret), - TP_ARGS(ret), - TP_STRUCT__entry( - __field(u32, ret) - ), - TP_fast_assign( - __entry->ret = ret; - ), - TP_printk("ret: %u", __entry->ret) -); - -#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE trace -#include diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index b99f01cda1f6..ef35f4ef2aa6 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -11,8 +11,6 @@ #include #include #include "core.h" -#include "rdev-ops.h" - struct ieee80211_rate * ieee80211_get_response_rate(struct ieee80211_supported_band *sband, @@ -311,21 +309,23 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) +static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) { int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 802.11-2012, 8.2.4.7.3 */ + /* 7.1.3.5a.2 */ switch (ae) { - default: case 0: return 6; case MESH_FLAGS_AE_A4: return 12; case MESH_FLAGS_AE_A5_A6: return 18; + case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): + return 24; + default: + return 6; } } -EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype) @@ -373,8 +373,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A4) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), @@ -399,8 +397,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A5_A6) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A4) skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), @@ -707,18 +703,19 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) for (i = 0; i < 6; i++) { if (!wdev->connect_keys->params[i].cipher) continue; - if (rdev_add_key(rdev, dev, i, false, NULL, - &wdev->connect_keys->params[i])) { + if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, + &wdev->connect_keys->params[i])) { netdev_err(dev, "failed to set key %d\n", i); continue; } if (wdev->connect_keys->def == i) - if (rdev_set_default_key(rdev, dev, i, true, true)) { + if (rdev->ops->set_default_key(wdev->wiphy, dev, + i, true, true)) { netdev_err(dev, "failed to set defkey %d\n", i); continue; } if (wdev->connect_keys->defmgmt == i) - if (rdev_set_default_mgmt_key(rdev, dev, i)) + if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i)) netdev_err(dev, "failed to set mgtdef %d\n", i); } @@ -851,7 +848,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, cfg80211_process_rdev_events(rdev); } - err = rdev_change_virtual_intf(rdev, dev, ntype, flags, params); + err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev, + ntype, flags, params); WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); @@ -980,105 +978,6 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate) } EXPORT_SYMBOL(cfg80211_calculate_bitrate); -unsigned int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, - u8 attr, u8 *buf, unsigned int bufsize) -{ - u8 *out = buf; - u16 attr_remaining = 0; - bool desired_attr = false; - u16 desired_len = 0; - - while (len > 0) { - unsigned int iedatalen; - unsigned int copy; - const u8 *iedata; - - if (len < 2) - return -EILSEQ; - iedatalen = ies[1]; - if (iedatalen + 2 > len) - return -EILSEQ; - - if (ies[0] != WLAN_EID_VENDOR_SPECIFIC) - goto cont; - - if (iedatalen < 4) - goto cont; - - iedata = ies + 2; - - /* check WFA OUI, P2P subtype */ - if (iedata[0] != 0x50 || iedata[1] != 0x6f || - iedata[2] != 0x9a || iedata[3] != 0x09) - goto cont; - - iedatalen -= 4; - iedata += 4; - - /* check attribute continuation into this IE */ - copy = min_t(unsigned int, attr_remaining, iedatalen); - if (copy && desired_attr) { - desired_len += copy; - if (out) { - memcpy(out, iedata, min(bufsize, copy)); - out += min(bufsize, copy); - bufsize -= min(bufsize, copy); - } - - - if (copy == attr_remaining) - return desired_len; - } - - attr_remaining -= copy; - if (attr_remaining) - goto cont; - - iedatalen -= copy; - iedata += copy; - - while (iedatalen > 0) { - u16 attr_len; - - /* P2P attribute ID & size must fit */ - if (iedatalen < 3) - return -EILSEQ; - desired_attr = iedata[0] == attr; - attr_len = get_unaligned_le16(iedata + 1); - iedatalen -= 3; - iedata += 3; - - copy = min_t(unsigned int, attr_len, iedatalen); - - if (desired_attr) { - desired_len += copy; - if (out) { - memcpy(out, iedata, min(bufsize, copy)); - out += min(bufsize, copy); - bufsize -= min(bufsize, copy); - } - - if (copy == attr_len) - return desired_len; - } - - iedata += copy; - iedatalen -= copy; - attr_remaining = attr_len - copy; - } - - cont: - len -= ies[1] + 2; - ies += ies[1] + 2; - } - - if (attr_remaining && desired_attr) - return -EILSEQ; - - return -ENOENT; -} -EXPORT_SYMBOL(cfg80211_get_p2p_attr); - int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, u32 beacon_int) { diff --git a/trunk/net/wireless/wext-compat.c b/trunk/net/wireless/wext-compat.c index 742ab6ec4c9d..494379eb464f 100644 --- a/trunk/net/wireless/wext-compat.c +++ b/trunk/net/wireless/wext-compat.c @@ -19,7 +19,6 @@ #include #include "wext-compat.h" #include "core.h" -#include "rdev-ops.h" int cfg80211_wext_giwname(struct net_device *dev, struct iw_request_info *info, @@ -302,7 +301,8 @@ int cfg80211_wext_siwrts(struct net_device *dev, else wdev->wiphy->rts_threshold = rts->value; - err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_RTS_THRESHOLD); + err = rdev->ops->set_wiphy_params(wdev->wiphy, + WIPHY_PARAM_RTS_THRESHOLD); if (err) wdev->wiphy->rts_threshold = orts; @@ -342,7 +342,8 @@ int cfg80211_wext_siwfrag(struct net_device *dev, wdev->wiphy->frag_threshold = frag->value & ~0x1; } - err = rdev_set_wiphy_params(rdev, WIPHY_PARAM_FRAG_THRESHOLD); + err = rdev->ops->set_wiphy_params(wdev->wiphy, + WIPHY_PARAM_FRAG_THRESHOLD); if (err) wdev->wiphy->frag_threshold = ofrag; @@ -395,7 +396,7 @@ static int cfg80211_wext_siwretry(struct net_device *dev, if (!changed) return 0; - err = rdev_set_wiphy_params(rdev, changed); + err = rdev->ops->set_wiphy_params(wdev->wiphy, changed); if (err) { wdev->wiphy->retry_short = oshort; wdev->wiphy->retry_long = olong; @@ -489,8 +490,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) err = -ENOENT; else - err = rdev_del_key(rdev, dev, idx, pairwise, - addr); + err = rdev->ops->del_key(&rdev->wiphy, dev, idx, + pairwise, addr); } wdev->wext.connect.privacy = false; /* @@ -524,7 +525,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, err = 0; if (wdev->current_bss) - err = rdev_add_key(rdev, dev, idx, pairwise, addr, params); + err = rdev->ops->add_key(&rdev->wiphy, dev, idx, + pairwise, addr, params); if (err) return err; @@ -550,7 +552,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, __cfg80211_leave_ibss(rdev, wdev->netdev, true); rejoin = true; } - err = rdev_set_default_key(rdev, dev, idx, true, true); + err = rdev->ops->set_default_key(&rdev->wiphy, dev, + idx, true, true); } if (!err) { wdev->wext.default_key = idx; @@ -563,7 +566,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { if (wdev->current_bss) - err = rdev_set_default_mgmt_key(rdev, dev, idx); + err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, + dev, idx); if (!err) wdev->wext.default_mgmt_key = idx; return err; @@ -627,8 +631,8 @@ static int cfg80211_wext_siwencode(struct net_device *dev, err = 0; wdev_lock(wdev); if (wdev->current_bss) - err = rdev_set_default_key(rdev, dev, idx, true, - true); + err = rdev->ops->set_default_key(&rdev->wiphy, dev, + idx, true, true); if (!err) wdev->wext.default_key = idx; wdev_unlock(wdev); @@ -835,7 +839,7 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, if (!rdev->ops->get_channel) return -EINVAL; - chan = rdev_get_channel(rdev, wdev, &channel_type); + chan = rdev->ops->get_channel(wdev->wiphy, wdev, &channel_type); if (!chan) return -EINVAL; freq->m = chan->center_freq; @@ -895,7 +899,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev, return 0; } - return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm)); + return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); } static int cfg80211_wext_giwtxpower(struct net_device *dev, @@ -914,7 +918,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev, if (!rdev->ops->get_tx_power) return -EOPNOTSUPP; - err = rdev_get_tx_power(rdev, wdev, &val); + err = rdev->ops->get_tx_power(wdev->wiphy, &val); if (err) return err; @@ -1154,7 +1158,7 @@ static int cfg80211_wext_siwpower(struct net_device *dev, timeout = wrq->value / 1000; } - err = rdev_set_power_mgmt(rdev, dev, ps, timeout); + err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout); if (err) return err; @@ -1196,7 +1200,7 @@ static int cfg80211_wds_wext_siwap(struct net_device *dev, if (!rdev->ops->set_wds_peer) return -EOPNOTSUPP; - err = rdev_set_wds_peer(rdev, dev, (u8 *)&addr->sa_data); + err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data); if (err) return err; @@ -1268,7 +1272,7 @@ static int cfg80211_wext_siwrate(struct net_device *dev, if (!match) return -EINVAL; - return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); + return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); } static int cfg80211_wext_giwrate(struct net_device *dev, @@ -1298,7 +1302,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, if (err) return err; - err = rdev_get_station(rdev, dev, addr, &sinfo); + err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo); if (err) return err; @@ -1335,7 +1339,7 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); wdev_unlock(wdev); - if (rdev_get_station(rdev, dev, bssid, &sinfo)) + if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo)) return NULL; memset(&wstats, 0, sizeof(wstats)); @@ -1470,19 +1474,19 @@ static int cfg80211_wext_siwpmksa(struct net_device *dev, if (!rdev->ops->set_pmksa) return -EOPNOTSUPP; - return rdev_set_pmksa(rdev, dev, &cfg_pmksa); + return rdev->ops->set_pmksa(&rdev->wiphy, dev, &cfg_pmksa); case IW_PMKSA_REMOVE: if (!rdev->ops->del_pmksa) return -EOPNOTSUPP; - return rdev_del_pmksa(rdev, dev, &cfg_pmksa); + return rdev->ops->del_pmksa(&rdev->wiphy, dev, &cfg_pmksa); case IW_PMKSA_FLUSH: if (!rdev->ops->flush_pmksa) return -EOPNOTSUPP; - return rdev_flush_pmksa(rdev, dev); + return rdev->ops->flush_pmksa(&rdev->wiphy, dev); default: return -EOPNOTSUPP;