Unified · Split
| @@ -7509,6 +7509,12 @@ S: Maintained · 7508 unmodified lines | |||
| 7509 | F: Documentation/usb/acm.txt | 7509 | F: Documentation/usb/acm.txt |
| 7510 | F: drivers/usb/class/cdc-acm.* | 7510 | F: drivers/usb/class/cdc-acm.* |
| 7511 | 7511 | ||
| 7512 | USB AR5523 WIRELESS DRIVER | ||
| 7513 | M: Pontus Fuchs <pontus.fuchs@gmail.com> | ||
| 7514 | L: linux-wireless@vger.kernel.org | ||
| 7515 | S: Maintained | ||
| 7516 | F: drivers/net/wireless/ath/ar5523/ | ||
| 7517 | |||
| 7512 | USB ATTACHED SCSI | 7518 | USB ATTACHED SCSI |
| 7513 | M: Matthew Wilcox <willy@linux.intel.com> | 7519 | M: Matthew Wilcox <willy@linux.intel.com> |
| 7514 | M: Sarah Sharp <sarah.a.sharp@linux.intel.com> | 7520 | M: Sarah Sharp <sarah.a.sharp@linux.intel.com> |
| @@ -43,8 +43,8 @@ static void early_nvram_init(void) · 42 unmodified lines | |||
| 43 | #ifdef CONFIG_BCM47XX_SSB | 43 | #ifdef CONFIG_BCM47XX_SSB |
| 44 | case BCM47XX_BUS_TYPE_SSB: | 44 | case BCM47XX_BUS_TYPE_SSB: |
| 45 | mcore_ssb = &bcm47xx_bus.ssb.mipscore; | 45 | mcore_ssb = &bcm47xx_bus.ssb.mipscore; |
| 46 | base = mcore_ssb->flash_window; | 46 | base = mcore_ssb->pflash.window; |
| 47 | lim = mcore_ssb->flash_window_size; | 47 | lim = mcore_ssb->pflash.window_size; |
| 48 | break; | 48 | break; |
| 49 | #endif | 49 | #endif |
| 50 | #ifdef CONFIG_BCM47XX_BCMA | 50 | #ifdef CONFIG_BCM47XX_BCMA |
| @@ -156,10 +156,10 @@ static int __init wgt634u_init(void) · 155 unmodified lines | |||
| 156 | SSB_CHIPCO_IRQ_GPIO); | 156 | SSB_CHIPCO_IRQ_GPIO); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | wgt634u_flash_data.width = mcore->flash_buswidth; | 159 | wgt634u_flash_data.width = mcore->pflash.buswidth; |
| 160 | wgt634u_flash_resource.start = mcore->flash_window; | 160 | wgt634u_flash_resource.start = mcore->pflash.window; |
| 161 | wgt634u_flash_resource.end = mcore->flash_window | 161 | wgt634u_flash_resource.end = mcore->pflash.window |
| 162 | + mcore->flash_window_size | 162 | + mcore->pflash.window_size |
| 163 | - 1; | 163 | - 1; |
| 164 | return platform_add_devices(wgt634u_devices, | 164 | return platform_add_devices(wgt634u_devices, |
| 165 | ARRAY_SIZE(wgt634u_devices)); | 165 | ARRAY_SIZE(wgt634u_devices)); |
| @@ -22,12 +22,9 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, · 21 unmodified lines | |||
| 22 | return value; | 22 | return value; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) | 25 | void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) |
| 26 | { | 26 | { |
| 27 | u32 leddc_on = 10; | 27 | if (cc->early_setup_done) |
| 28 | u32 leddc_off = 90; | ||
| 29 | |||
| 30 | if (cc->setup_done) | ||
| 31 | return; | 28 | return; |
| 32 | 29 | ||
| 33 | if (cc->core->id.rev >= 11) | 30 | if (cc->core->id.rev >= 11) |
| @@ -36,6 +33,22 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) · 2 unmodified lines | |||
| 36 | if (cc->core->id.rev >= 35) | 33 | if (cc->core->id.rev >= 35) |
| 37 | cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); | 34 | cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); |
| 38 | 35 | ||
| 36 | if (cc->capabilities & BCMA_CC_CAP_PMU) | ||
| 37 | bcma_pmu_early_init(cc); | ||
| 38 | |||
| 39 | cc->early_setup_done = true; | ||
| 40 | } | ||
| 41 | |||
| 42 | void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) | ||
| 43 | { | ||
| 44 | u32 leddc_on = 10; | ||
| 45 | u32 leddc_off = 90; | ||
| 46 | |||
| 47 | if (cc->setup_done) | ||
| 48 | return; | ||
| 49 | |||
| 50 | bcma_core_chipcommon_early_init(cc); | ||
| 51 | |||
| 39 | if (cc->core->id.rev >= 20) { | 52 | if (cc->core->id.rev >= 20) { |
| 40 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); | 53 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); |
| 41 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); | 54 | bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); |
| @@ -32,6 +32,9 @@ int bcma_nflash_init(struct bcma_drv_cc *cc) · 31 unmodified lines | |||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | cc->nflash.present = true; | 34 | cc->nflash.present = true; |
| 35 | if (cc->core->id.rev == 38 && | ||
| 36 | (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) | ||
| 37 | cc->nflash.boot = true; | ||
| 35 | 38 | ||
| 36 | /* Prepare platform device, but don't register it yet. It's too early, | 39 | /* Prepare platform device, but don't register it yet. It's too early, |
| 37 | * malloc (required by device_private_init) is not available yet. */ | 40 | * malloc (required by device_private_init) is not available yet. */ |
| @@ -144,7 +144,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc) · 143 unmodified lines | |||
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void bcma_pmu_init(struct bcma_drv_cc *cc) | 147 | void bcma_pmu_early_init(struct bcma_drv_cc *cc) |
| 148 | { | 148 | { |
| 149 | u32 pmucap; | 149 | u32 pmucap; |
| 150 | 150 | ||
| @@ -153,7 +153,10 @@ void bcma_pmu_init(struct bcma_drv_cc *cc) · 2 unmodified lines | |||
| 153 | 153 | ||
| 154 | bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", | 154 | bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", |
| 155 | cc->pmu.rev, pmucap); | 155 | cc->pmu.rev, pmucap); |
| 156 | } | ||
| 156 | 157 | ||
| 158 | void bcma_pmu_init(struct bcma_drv_cc *cc) | ||
| 159 | { | ||
| 157 | if (cc->pmu.rev == 1) | 160 | if (cc->pmu.rev == 1) |
| 158 | bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, | 161 | bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, |
| 159 | ~BCMA_CC_PMU_CTL_NOILPONW); | 162 | ~BCMA_CC_PMU_CTL_NOILPONW); |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | static struct resource bcma_sflash_resource = { | 13 | static struct resource bcma_sflash_resource = { |
| 14 | .name = "bcma_sflash", | 14 | .name = "bcma_sflash", |
| 15 | .start = BCMA_SFLASH, | 15 | .start = BCMA_SOC_FLASH2, |
| 16 | .end = 0, | 16 | .end = 0, |
| 17 | .flags = IORESOURCE_MEM | IORESOURCE_READONLY, | 17 | .flags = IORESOURCE_MEM | IORESOURCE_READONLY, |
| 18 | }; | 18 | }; |
| @@ -31,15 +31,42 @@ struct bcma_sflash_tbl_e { · 12 unmodified lines | |||
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { | 33 | static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { |
| 34 | { "", 0x14, 0x10000, 32, }, | 34 | { "M25P20", 0x11, 0x10000, 4, }, |
| 35 | { "M25P40", 0x12, 0x10000, 8, }, | ||
| 36 | |||
| 37 | { "M25P16", 0x14, 0x10000, 32, }, | ||
| 38 | { "M25P32", 0x14, 0x10000, 64, }, | ||
| 39 | { "M25P64", 0x16, 0x10000, 128, }, | ||
| 40 | { "M25FL128", 0x17, 0x10000, 256, }, | ||
| 35 | { 0 }, | 41 | { 0 }, |
| 36 | }; | 42 | }; |
| 37 | 43 | ||
| 38 | static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { | 44 | static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { |
| 45 | { "SST25WF512", 1, 0x1000, 16, }, | ||
| 46 | { "SST25VF512", 0x48, 0x1000, 16, }, | ||
| 47 | { "SST25WF010", 2, 0x1000, 32, }, | ||
| 48 | { "SST25VF010", 0x49, 0x1000, 32, }, | ||
| 49 | { "SST25WF020", 3, 0x1000, 64, }, | ||
| 50 | { "SST25VF020", 0x43, 0x1000, 64, }, | ||
| 51 | { "SST25WF040", 4, 0x1000, 128, }, | ||
| 52 | { "SST25VF040", 0x44, 0x1000, 128, }, | ||
| 53 | { "SST25VF040B", 0x8d, 0x1000, 128, }, | ||
| 54 | { "SST25WF080", 5, 0x1000, 256, }, | ||
| 55 | { "SST25VF080B", 0x8e, 0x1000, 256, }, | ||
| 56 | { "SST25VF016", 0x41, 0x1000, 512, }, | ||
| 57 | { "SST25VF032", 0x4a, 0x1000, 1024, }, | ||
| 58 | { "SST25VF064", 0x4b, 0x1000, 2048, }, | ||
| 39 | { 0 }, | 59 | { 0 }, |
| 40 | }; | 60 | }; |
| 41 | 61 | ||
| 42 | static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { | 62 | static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { |
| 63 | { "AT45DB011", 0xc, 256, 512, }, | ||
| 64 | { "AT45DB021", 0x14, 256, 1024, }, | ||
| 65 | { "AT45DB041", 0x1c, 256, 2048, }, | ||
| 66 | { "AT45DB081", 0x24, 256, 4096, }, | ||
| 67 | { "AT45DB161", 0x2c, 512, 4096, }, | ||
| 68 | { "AT45DB321", 0x34, 512, 8192, }, | ||
| 69 | { "AT45DB642", 0x3c, 1024, 8192, }, | ||
| 43 | { 0 }, | 70 | { 0 }, |
| 44 | }; | 71 | }; |
| 45 | 72 | ||
| @@ -84,6 +111,8 @@ int bcma_sflash_init(struct bcma_drv_cc *cc) · 38 unmodified lines | |||
| 84 | break; | 111 | break; |
| 85 | } | 112 | } |
| 86 | break; | 113 | break; |
| 114 | case 0x13: | ||
| 115 | return -ENOTSUPP; | ||
| 87 | default: | 116 | default: |
| 88 | for (e = bcma_sflash_st_tbl; e->name; e++) { | 117 | for (e = bcma_sflash_st_tbl; e->name; e++) { |
| 89 | if (e->id == id) | 118 | if (e->id == id) |
| @@ -116,7 +145,7 @@ int bcma_sflash_init(struct bcma_drv_cc *cc) · 26 unmodified lines | |||
| 116 | return -ENOTSUPP; | 145 | return -ENOTSUPP; |
| 117 | } | 146 | } |
| 118 | 147 | ||
| 119 | sflash->window = BCMA_SFLASH; | 148 | sflash->window = BCMA_SOC_FLASH2; |
| 120 | sflash->blocksize = e->blocksize; | 149 | sflash->blocksize = e->blocksize; |
| 121 | sflash->numblocks = e->numblocks; | 150 | sflash->numblocks = e->numblocks; |
| 122 | sflash->size = sflash->blocksize * sflash->numblocks; | 151 | sflash->size = sflash->blocksize * sflash->numblocks; |
| @@ -181,47 +181,66 @@ EXPORT_SYMBOL(bcma_cpu_clock); · 180 unmodified lines | |||
| 181 | static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | 181 | static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) |
| 182 | { | 182 | { |
| 183 | struct bcma_bus *bus = mcore->core->bus; | 183 | struct bcma_bus *bus = mcore->core->bus; |
| 184 | struct bcma_drv_cc *cc = &bus->drv_cc; | ||
| 184 | 185 | ||
| 185 | switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { | 186 | switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { |
| 186 | case BCMA_CC_FLASHT_STSER: | 187 | case BCMA_CC_FLASHT_STSER: |
| 187 | case BCMA_CC_FLASHT_ATSER: | 188 | case BCMA_CC_FLASHT_ATSER: |
| 188 | bcma_debug(bus, "Found serial flash\n"); | 189 | bcma_debug(bus, "Found serial flash\n"); |
| 189 | bcma_sflash_init(&bus->drv_cc); | 190 | bcma_sflash_init(cc); |
| 190 | break; | 191 | break; |
| 191 | case BCMA_CC_FLASHT_PARA: | 192 | case BCMA_CC_FLASHT_PARA: |
| 192 | bcma_debug(bus, "Found parallel flash\n"); | 193 | bcma_debug(bus, "Found parallel flash\n"); |
| 193 | bus->drv_cc.pflash.window = 0x1c000000; | 194 | cc->pflash.present = true; |
| 194 | bus->drv_cc.pflash.window_size = 0x02000000; | 195 | cc->pflash.window = BCMA_SOC_FLASH2; |
| 196 | cc->pflash.window_size = BCMA_SOC_FLASH2_SZ; | ||
| 195 | 197 | ||
| 196 | if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) & | 198 | if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & |
| 197 | BCMA_CC_FLASH_CFG_DS) == 0) | 199 | BCMA_CC_FLASH_CFG_DS) == 0) |
| 198 | bus->drv_cc.pflash.buswidth = 1; | 200 | cc->pflash.buswidth = 1; |
| 199 | else | 201 | else |
| 200 | bus->drv_cc.pflash.buswidth = 2; | 202 | cc->pflash.buswidth = 2; |
| 201 | break; | 203 | break; |
| 202 | default: | 204 | default: |
| 203 | bcma_err(bus, "Flash type not supported\n"); | 205 | bcma_err(bus, "Flash type not supported\n"); |
| 204 | } | 206 | } |
| 205 | 207 | ||
| 206 | if (bus->drv_cc.core->id.rev == 38 || | 208 | if (cc->core->id.rev == 38 || |
| 207 | bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { | 209 | bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { |
| 208 | if (bus->drv_cc.capabilities & BCMA_CC_CAP_NFLASH) { | 210 | if (cc->capabilities & BCMA_CC_CAP_NFLASH) { |
| 209 | bcma_debug(bus, "Found NAND flash\n"); | 211 | bcma_debug(bus, "Found NAND flash\n"); |
| 210 | bcma_nflash_init(&bus->drv_cc); | 212 | bcma_nflash_init(cc); |
| 211 | } | 213 | } |
| 212 | } | 214 | } |
| 213 | } | 215 | } |
| 214 | 216 | ||
| 217 | void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) | ||
| 218 | { | ||
| 219 | struct bcma_bus *bus = mcore->core->bus; | ||
| 220 | |||
| 221 | if (mcore->early_setup_done) | ||
| 222 | return; | ||
| 223 | |||
| 224 | bcma_chipco_serial_init(&bus->drv_cc); | ||
| 225 | bcma_core_mips_flash_detect(mcore); | ||
| 226 | |||
| 227 | mcore->early_setup_done = true; | ||
| 228 | } | ||
| 229 | |||
| 215 | void bcma_core_mips_init(struct bcma_drv_mips *mcore) | 230 | void bcma_core_mips_init(struct bcma_drv_mips *mcore) |
| 216 | { | 231 | { |
| 217 | struct bcma_bus *bus; | 232 | struct bcma_bus *bus; |
| 218 | struct bcma_device *core; | 233 | struct bcma_device *core; |
| 219 | bus = mcore->core->bus; | 234 | bus = mcore->core->bus; |
| 220 | 235 | ||
| 236 | if (mcore->setup_done) | ||
| 237 | return; | ||
| 238 | |||
| 221 | bcma_info(bus, "Initializing MIPS core...\n"); | 239 | bcma_info(bus, "Initializing MIPS core...\n"); |
| 222 | 240 | ||
| 223 | if (!mcore->setup_done) | 241 | bcma_core_mips_early_init(mcore); |
| 224 | mcore->assigned_irqs = 1; | 242 | |
| 243 | mcore->assigned_irqs = 1; | ||
| 225 | 244 | ||
| 226 | /* Assign IRQs to all cores on the bus */ | 245 | /* Assign IRQs to all cores on the bus */ |
| 227 | list_for_each_entry(core, &bus->cores, list) { | 246 | list_for_each_entry(core, &bus->cores, list) { |
| @@ -256,10 +275,5 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore) · 28 unmodified lines | |||
| 256 | bcma_info(bus, "IRQ reconfiguration done\n"); | 275 | bcma_info(bus, "IRQ reconfiguration done\n"); |
| 257 | bcma_core_mips_dump_irq(bus); | 276 | bcma_core_mips_dump_irq(bus); |
| 258 | 277 | ||
| 259 | if (mcore->setup_done) | ||
| 260 | return; | ||
| 261 | |||
| 262 | bcma_chipco_serial_init(&bus->drv_cc); | ||
| 263 | bcma_core_mips_flash_detect(mcore); | ||
| 264 | mcore->setup_done = true; | 278 | mcore->setup_done = true; |
| 265 | } | 279 | } |
| @@ -35,11 +35,6 @@ bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) · 34 unmodified lines | |||
| 35 | chipid_top != 0x5300) | 35 | chipid_top != 0x5300) |
| 36 | return false; | 36 | return false; |
| 37 | 37 | ||
| 38 | if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { | ||
| 39 | bcma_info(bus, "This PCI core is disabled and not working\n"); | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | |||
| 43 | bcma_core_enable(pc->core, 0); | 38 | bcma_core_enable(pc->core, 0); |
| 44 | 39 | ||
| 45 | return !mips_busprobe32(tmp, pc->core->io_addr); | 40 | return !mips_busprobe32(tmp, pc->core->io_addr); |
| @@ -396,6 +391,11 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) · 350 unmodified lines | |||
| 396 | 391 | ||
| 397 | bcma_info(bus, "PCIEcore in host mode found\n"); | 392 | bcma_info(bus, "PCIEcore in host mode found\n"); |
| 398 | 393 | ||
| 394 | if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { | ||
| 395 | bcma_info(bus, "This PCIE core is disabled and not working\n"); | ||
| 396 | return; | ||
| 397 | } | ||
| 398 | |||
| 399 | pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); | 399 | pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); |
| 400 | if (!pc_host) { | 400 | if (!pc_host) { |
| 401 | bcma_err(bus, "can not allocate memory"); | 401 | bcma_err(bus, "can not allocate memory"); |
| @@ -452,6 +452,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) · 50 unmodified lines | |||
| 452 | pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; | 452 | pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; |
| 453 | pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + | 453 | pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + |
| 454 | BCMA_SOC_PCI_MEM_SZ - 1; | 454 | BCMA_SOC_PCI_MEM_SZ - 1; |
| 455 | pc_host->io_resource.start = 0x100; | ||
| 456 | pc_host->io_resource.end = 0x47F; | ||
| 455 | pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; | 457 | pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; |
| 456 | pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, | 458 | pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, |
| 457 | tmp | BCMA_SOC_PCI_MEM); | 459 | tmp | BCMA_SOC_PCI_MEM); |
| @@ -459,6 +461,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) · 1 unmodified line | |||
| 459 | pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; | 461 | pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; |
| 460 | pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + | 462 | pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + |
| 461 | BCMA_SOC_PCI_MEM_SZ - 1; | 463 | BCMA_SOC_PCI_MEM_SZ - 1; |
| 464 | pc_host->io_resource.start = 0x480; | ||
| 465 | pc_host->io_resource.end = 0x7FF; | ||
| 462 | pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; | 466 | pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; |
| 463 | pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; | 467 | pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; |
| 464 | pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, | 468 | pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, |
| @@ -238,7 +238,7 @@ static void __devexit bcma_host_pci_remove(struct pci_dev *dev) · 237 unmodified lines | |||
| 238 | pci_set_drvdata(dev, NULL); | 238 | pci_set_drvdata(dev, NULL); |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | #ifdef CONFIG_PM | 241 | #ifdef CONFIG_PM_SLEEP |
| 242 | static int bcma_host_pci_suspend(struct device *dev) | 242 | static int bcma_host_pci_suspend(struct device *dev) |
| 243 | { | 243 | { |
| 244 | struct pci_dev *pdev = to_pci_dev(dev); | 244 | struct pci_dev *pdev = to_pci_dev(dev); |
| @@ -261,11 +261,11 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, · 16 unmodified lines | |||
| 261 | bcma_host_pci_resume); | 261 | bcma_host_pci_resume); |
| 262 | #define BCMA_PM_OPS (&bcma_pm_ops) | 262 | #define BCMA_PM_OPS (&bcma_pm_ops) |
| 263 | 263 | ||
| 264 | #else /* CONFIG_PM */ | 264 | #else /* CONFIG_PM_SLEEP */ |
| 265 | 265 | ||
| 266 | #define BCMA_PM_OPS NULL | 266 | #define BCMA_PM_OPS NULL |
| 267 | 267 | ||
| 268 | #endif /* CONFIG_PM */ | 268 | #endif /* CONFIG_PM_SLEEP */ |
| 269 | 269 | ||
| 270 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | 270 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { |
| 271 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, | 271 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, |
| @@ -81,6 +81,18 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) · 80 unmodified lines | |||
| 81 | } | 81 | } |
| 82 | EXPORT_SYMBOL_GPL(bcma_find_core); | 82 | EXPORT_SYMBOL_GPL(bcma_find_core); |
| 83 | 83 | ||
| 84 | static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, | ||
| 85 | u8 unit) | ||
| 86 | { | ||
| 87 | struct bcma_device *core; | ||
| 88 | |||
| 89 | list_for_each_entry(core, &bus->cores, list) { | ||
| 90 | if (core->id.id == coreid && core->core_unit == unit) | ||
| 91 | return core; | ||
| 92 | } | ||
| 93 | return NULL; | ||
| 94 | } | ||
| 95 | |||
| 84 | static void bcma_release_core_dev(struct device *dev) | 96 | static void bcma_release_core_dev(struct device *dev) |
| 85 | { | 97 | { |
| 86 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); | 98 | struct bcma_device *core = container_of(dev, struct bcma_device, dev); |
| @@ -183,6 +195,20 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) · 96 unmodified lines | |||
| 183 | return -1; | 195 | return -1; |
| 184 | } | 196 | } |
| 185 | 197 | ||
| 198 | /* Early init CC core */ | ||
| 199 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); | ||
| 200 | if (core) { | ||
| 201 | bus->drv_cc.core = core; | ||
| 202 | bcma_core_chipcommon_early_init(&bus->drv_cc); | ||
| 203 | } | ||
| 204 | |||
| 205 | /* Try to get SPROM */ | ||
| 206 | err = bcma_sprom_get(bus); | ||
| 207 | if (err == -ENOENT) { | ||
| 208 | bcma_err(bus, "No SPROM available\n"); | ||
| 209 | } else if (err) | ||
| 210 | bcma_err(bus, "Failed to get SPROM: %d\n", err); | ||
| 211 | |||
| 186 | /* Init CC core */ | 212 | /* Init CC core */ |
| 187 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); | 213 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); |
| 188 | if (core) { | 214 | if (core) { |
| @@ -198,10 +224,17 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) · 9 unmodified lines | |||
| 198 | } | 224 | } |
| 199 | 225 | ||
| 200 | /* Init PCIE core */ | 226 | /* Init PCIE core */ |
| 201 | core = bcma_find_core(bus, BCMA_CORE_PCIE); | 227 | core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0); |
| 202 | if (core) { | 228 | if (core) { |
| 203 | bus->drv_pci.core = core; | 229 | bus->drv_pci[0].core = core; |
| 204 | bcma_core_pci_init(&bus->drv_pci); | 230 | bcma_core_pci_init(&bus->drv_pci[0]); |
| 231 | } | ||
| 232 | |||
| 233 | /* Init PCIE core */ | ||
| 234 | core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1); | ||
| 235 | if (core) { | ||
| 236 | bus->drv_pci[1].core = core; | ||
| 237 | bcma_core_pci_init(&bus->drv_pci[1]); | ||
| 205 | } | 238 | } |
| 206 | 239 | ||
| 207 | /* Init GBIT MAC COMMON core */ | 240 | /* Init GBIT MAC COMMON core */ |
| @@ -211,13 +244,6 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) · 3 unmodified lines | |||
| 211 | bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn); | 244 | bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn); |
| 212 | } | 245 | } |
| 213 | 246 | ||
| 214 | /* Try to get SPROM */ | ||
| 215 | err = bcma_sprom_get(bus); | ||
| 216 | if (err == -ENOENT) { | ||
| 217 | bcma_err(bus, "No SPROM available\n"); | ||
| 218 | } else if (err) | ||
| 219 | bcma_err(bus, "Failed to get SPROM: %d\n", err); | ||
| 220 | |||
| 221 | /* Register found cores */ | 247 | /* Register found cores */ |
| 222 | bcma_register_cores(bus); | 248 | bcma_register_cores(bus); |
| 223 | 249 | ||
| @@ -275,18 +301,18 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, · 51 unmodified lines | |||
| 275 | return -1; | 301 | return -1; |
| 276 | } | 302 | } |
| 277 | 303 | ||
| 278 | /* Init CC core */ | 304 | /* Early init CC core */ |
| 279 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); | 305 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); |
| 280 | if (core) { | 306 | if (core) { |
| 281 | bus->drv_cc.core = core; | 307 | bus->drv_cc.core = core; |
| 282 | bcma_core_chipcommon_init(&bus->drv_cc); | 308 | bcma_core_chipcommon_early_init(&bus->drv_cc); |
| 283 | } | 309 | } |
| 284 | 310 | ||
| 285 | /* Init MIPS core */ | 311 | /* Early init MIPS core */ |
| 286 | core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); | 312 | core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); |
| 287 | if (core) { | 313 | if (core) { |
| 288 | bus->drv_mips.core = core; | 314 | bus->drv_mips.core = core; |
| 289 | bcma_core_mips_init(&bus->drv_mips); | 315 | bcma_core_mips_early_init(&bus->drv_mips); |
| 290 | } | 316 | } |
| 291 | 317 | ||
| 292 | bcma_info(bus, "Early bus registered\n"); | 318 | bcma_info(bus, "Early bus registered\n"); |
| @@ -595,8 +595,11 @@ int bcma_sprom_get(struct bcma_bus *bus) · 594 unmodified lines | |||
| 595 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); | 595 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); |
| 596 | 596 | ||
| 597 | err = bcma_sprom_valid(sprom); | 597 | err = bcma_sprom_valid(sprom); |
| 598 | if (err) | 598 | if (err) { |
| 599 | bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n"); | ||
| 600 | err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); | ||
| 599 | goto out; | 601 | goto out; |
| 602 | } | ||
| 600 | 603 | ||
| 601 | bcma_sprom_extract_r8(bus, sprom); | 604 | bcma_sprom_extract_r8(bus, sprom); |
| 602 | 605 | ||
| @@ -492,7 +492,7 @@ done: · 491 unmodified lines | |||
| 492 | static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | 492 | static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) |
| 493 | { | 493 | { |
| 494 | u16 buf_len = 0; | 494 | u16 buf_len = 0; |
| 495 | int ret, buf_block_len, blksz; | 495 | int ret, num_blocks, blksz; |
| 496 | struct sk_buff *skb = NULL; | 496 | struct sk_buff *skb = NULL; |
| 497 | u32 type; | 497 | u32 type; |
| 498 | u8 *payload = NULL; | 498 | u8 *payload = NULL; |
| @@ -514,18 +514,17 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) · 15 unmodified lines | |||
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | blksz = SDIO_BLOCK_SIZE; | 516 | blksz = SDIO_BLOCK_SIZE; |
| 517 | buf_block_len = (buf_len + blksz - 1) / blksz; | 517 | num_blocks = DIV_ROUND_UP(buf_len, blksz); |
| 518 | 518 | ||
| 519 | if (buf_len <= SDIO_HEADER_LEN | 519 | if (buf_len <= SDIO_HEADER_LEN |
| 520 | || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { | 520 | || (num_blocks * blksz) > ALLOC_BUF_SIZE) { |
| 521 | BT_ERR("invalid packet length: %d", buf_len); | 521 | BT_ERR("invalid packet length: %d", buf_len); |
| 522 | ret = -EINVAL; | 522 | ret = -EINVAL; |
| 523 | goto exit; | 523 | goto exit; |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | /* Allocate buffer */ | 526 | /* Allocate buffer */ |
| 527 | skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN, | 527 | skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC); |
| 528 | GFP_ATOMIC); | ||
| 529 | if (skb == NULL) { | 528 | if (skb == NULL) { |
| 530 | BT_ERR("No free skb"); | 529 | BT_ERR("No free skb"); |
| 531 | goto exit; | 530 | goto exit; |
| @@ -541,7 +540,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) · 9 unmodified lines | |||
| 541 | payload = skb->data; | 540 | payload = skb->data; |
| 542 | 541 | ||
| 543 | ret = sdio_readsb(card->func, payload, card->ioport, | 542 | ret = sdio_readsb(card->func, payload, card->ioport, |
| 544 | buf_block_len * blksz); | 543 | num_blocks * blksz); |
| 545 | if (ret < 0) { | 544 | if (ret < 0) { |
| 546 | BT_ERR("readsb failed: %d", ret); | 545 | BT_ERR("readsb failed: %d", ret); |
| 547 | ret = -EIO; | 546 | ret = -EIO; |
| @@ -553,7 +552,16 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) · 5 unmodified lines | |||
| 553 | */ | 552 | */ |
| 554 | 553 | ||
| 555 | buf_len = payload[0]; | 554 | buf_len = payload[0]; |
| 556 | buf_len |= (u16) payload[1] << 8; | 555 | buf_len |= payload[1] << 8; |
| 556 | buf_len |= payload[2] << 16; | ||
| 557 | |||
| 558 | if (buf_len > blksz * num_blocks) { | ||
| 559 | BT_ERR("Skip incorrect packet: hdrlen %d buffer %d", | ||
| 560 | buf_len, blksz * num_blocks); | ||
| 561 | ret = -EIO; | ||
| 562 | goto exit; | ||
| 563 | } | ||
| 564 | |||
| 557 | type = payload[3]; | 565 | type = payload[3]; |
| 558 | 566 | ||
| 559 | switch (type) { | 567 | switch (type) { |
| @@ -589,8 +597,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) · 29 unmodified lines | |||
| 589 | 597 | ||
| 590 | default: | 598 | default: |
| 591 | BT_ERR("Unknown packet type:%d", type); | 599 | BT_ERR("Unknown packet type:%d", type); |
| 592 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload, | 600 | BT_ERR("hex: %*ph", blksz * num_blocks, payload); |
| 593 | blksz * buf_block_len); | ||
| 594 | 601 | ||
| 595 | kfree_skb(skb); | 602 | kfree_skb(skb); |
| 596 | skb = NULL; | 603 | skb = NULL; |
| @@ -849,8 +856,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, · 252 unmodified lines | |||
| 849 | if (ret < 0) { | 856 | if (ret < 0) { |
| 850 | i++; | 857 | i++; |
| 851 | BT_ERR("i=%d writesb failed: %d", i, ret); | 858 | BT_ERR("i=%d writesb failed: %d", i, ret); |
| 852 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, | 859 | BT_ERR("hex: %*ph", nb, payload); |
| 853 | payload, nb); | ||
| 854 | ret = -EIO; | 860 | ret = -EIO; |
| 855 | if (i > MAX_WRITE_IOMEM_RETRY) | 861 | if (i > MAX_WRITE_IOMEM_RETRY) |
| 856 | goto exit; | 862 | goto exit; |
| @@ -452,7 +452,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf, · 451 unmodified lines | |||
| 452 | if (rsn) | 452 | if (rsn) |
| 453 | *buf++ = WLAN_EID_RSN; | 453 | *buf++ = WLAN_EID_RSN; |
| 454 | else | 454 | else |
| 455 | *buf++ = WLAN_EID_GENERIC; | 455 | *buf++ = WLAN_EID_VENDOR_SPECIFIC; |
| 456 | 456 | ||
| 457 | /* length filed; set later */ | 457 | /* length filed; set later */ |
| 458 | buf++; | 458 | buf++; |
| @@ -540,7 +540,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len, · 81 unmodified lines | |||
| 540 | break; | 540 | break; |
| 541 | 541 | ||
| 542 | switch (item_id) { | 542 | switch (item_id) { |
| 543 | case WLAN_EID_GENERIC: | 543 | case WLAN_EID_VENDOR_SPECIFIC: |
| 544 | if ((OUI_LEN + 1 <= item_len) && | 544 | if ((OUI_LEN + 1 <= item_len) && |
| 545 | !memcmp(pos, wpa_oui, OUI_LEN) && | 545 | !memcmp(pos, wpa_oui, OUI_LEN) && |
| 546 | pos[OUI_LEN] == 0x01) { | 546 | pos[OUI_LEN] == 0x01) { |
| @@ -7433,7 +7433,7 @@ static inline char *airo_translate_scan(struct net_device *dev, · 7432 unmodified lines | |||
| 7433 | num_null_ies++; | 7433 | num_null_ies++; |
| 7434 | break; | 7434 | break; |
| 7435 | 7435 | ||
| 7436 | case WLAN_EID_GENERIC: | 7436 | case WLAN_EID_VENDOR_SPECIFIC: |
| 7437 | if (ie[1] >= 4 && | 7437 | if (ie[1] >= 4 && |
| 7438 | ie[2] == 0x00 && | 7438 | ie[2] == 0x00 && |
| 7439 | ie[3] == 0x50 && | 7439 | ie[3] == 0x50 && |
| @@ -26,5 +26,6 @@ source "drivers/net/wireless/ath/ath5k/Kconfig" · 25 unmodified lines | |||
| 26 | source "drivers/net/wireless/ath/ath9k/Kconfig" | 26 | source "drivers/net/wireless/ath/ath9k/Kconfig" |
| 27 | source "drivers/net/wireless/ath/carl9170/Kconfig" | 27 | source "drivers/net/wireless/ath/carl9170/Kconfig" |
| 28 | source "drivers/net/wireless/ath/ath6kl/Kconfig" | 28 | source "drivers/net/wireless/ath/ath6kl/Kconfig" |
| 29 | source "drivers/net/wireless/ath/ar5523/Kconfig" | ||
| 29 | 30 | ||
| 30 | endif | 31 | endif |
| @@ -2,6 +2,7 @@ obj-$(CONFIG_ATH5K) += ath5k/ · 1 unmodified line | |||
| 2 | obj-$(CONFIG_ATH9K_HW) += ath9k/ | 2 | obj-$(CONFIG_ATH9K_HW) += ath9k/ |
| 3 | obj-$(CONFIG_CARL9170) += carl9170/ | 3 | obj-$(CONFIG_CARL9170) += carl9170/ |
| 4 | obj-$(CONFIG_ATH6KL) += ath6kl/ | 4 | obj-$(CONFIG_ATH6KL) += ath6kl/ |
| 5 | obj-$(CONFIG_AR5523) += ar5523/ | ||
| 5 | 6 | ||
| 6 | obj-$(CONFIG_ATH_COMMON) += ath.o | 7 | obj-$(CONFIG_ATH_COMMON) += ath.o |
| 7 | 8 | ||
| @@ -0,0 +1,7 @@ | |||
| 1 | config AR5523 | ||
| 2 | tristate "Atheros AR5523 wireless driver support" | ||
| 3 | depends on MAC80211 && USB | ||
| 4 | select FW_LOADER | ||
| 5 | ---help--- | ||
| 6 | This module add support for AR5523 based USB dongles such as D-Link | ||
| 7 | DWL-G132, Netgear WPN111 and many more. | ||
| @@ -0,0 +1 @@ | |||
| 1 | obj-$(CONFIG_AR5523) := ar5523.o | ||
| @@ -0,0 +1,1806 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr> | ||
| 3 | * Copyright (c) 2006 Sam Leffler, Errno Consulting | ||
| 4 | * Copyright (c) 2007 Christoph Hellwig <hch@lst.de> | ||
| 5 | * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> | ||
| 6 | * Copyright (c) 2012 Pontus Fuchs <pontus.fuchs@gmail.com> | ||
| 7 | * | ||
| 8 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 9 | * purpose with or without fee is hereby granted, provided that the above | ||
| 10 | * copyright notice and this permission notice appear in all copies. | ||
| 11 | * | ||
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * This driver is based on the uath driver written by Damien Bergamini for | ||
| 23 | * OpenBSD, who did black-box analysis of the Windows binary driver to find | ||
| 24 | * out how the hardware works. It contains a lot magic numbers because of | ||
| 25 | * that and only has minimal functionality. | ||
| 26 | */ | ||
| 27 | #include <linux/compiler.h> | ||
| 28 | #include <linux/init.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/list.h> | ||
| 32 | #include <linux/completion.h> | ||
| 33 | #include <linux/firmware.h> | ||
| 34 | #include <linux/skbuff.h> | ||
| 35 | #include <linux/usb.h> | ||
| 36 | #include <net/mac80211.h> | ||
| 37 | |||
| 38 | #include "ar5523.h" | ||
| 39 | #include "ar5523_hw.h" | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Various supported device vendors/products. | ||
| 43 | * UB51: AR5005UG 802.11b/g, UB52: AR5005UX 802.11a/b/g | ||
| 44 | */ | ||
| 45 | |||
| 46 | static int ar5523_submit_rx_cmd(struct ar5523 *ar); | ||
| 47 | static void ar5523_data_tx_pkt_put(struct ar5523 *ar); | ||
| 48 | |||
| 49 | static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr, | ||
| 50 | struct ar5523_tx_cmd *cmd) | ||
| 51 | { | ||
| 52 | int dlen, olen; | ||
| 53 | u32 *rp; | ||
| 54 | |||
| 55 | dlen = hdr->len - sizeof(*hdr); | ||
| 56 | |||
| 57 | if (dlen < 0) { | ||
| 58 | WARN_ON(1); | ||
| 59 | goto out; | ||
| 60 | } | ||
| 61 | |||
| 62 | ar5523_dbg(ar, "Code = %d len = %d\n", hdr->code & 0xff, dlen); | ||
| 63 | |||
| 64 | rp = (u32 *)(hdr + 1); | ||
| 65 | if (dlen >= sizeof(u32)) { | ||
| 66 | olen = be32_to_cpu(rp[0]); | ||
| 67 | dlen -= sizeof(u32); | ||
| 68 | if (olen == 0) { | ||
| 69 | /* convention is 0 =>'s one word */ | ||
| 70 | olen = sizeof(u32); | ||
| 71 | } | ||
| 72 | } else | ||
| 73 | olen = 0; | ||
| 74 | |||
| 75 | if (cmd->odata) { | ||
| 76 | if (cmd->olen < olen) { | ||
| 77 | ar5523_err(ar, "olen to small %d < %d\n", | ||
| 78 | cmd->olen, olen); | ||
| 79 | cmd->olen = 0; | ||
| 80 | cmd->res = -EOVERFLOW; | ||
| 81 | } else { | ||
| 82 | cmd->olen = olen; | ||
| 83 | memcpy(cmd->odata, &rp[1], olen); | ||
| 84 | cmd->res = 0; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | out: | ||
| 89 | complete(&cmd->done); | ||
| 90 | } | ||
| 91 | |||
| 92 | static void ar5523_cmd_rx_cb(struct urb *urb) | ||
| 93 | { | ||
| 94 | struct ar5523 *ar = urb->context; | ||
| 95 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; | ||
| 96 | struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; | ||
| 97 | int dlen; | ||
| 98 | |||
| 99 | if (urb->status) { | ||
| 100 | if (urb->status != -ESHUTDOWN) | ||
| 101 | ar5523_err(ar, "RX USB error %d.\n", urb->status); | ||
| 102 | goto skip; | ||
| 103 | } | ||
| 104 | |||
| 105 | if (urb->actual_length < sizeof(struct ar5523_cmd_hdr)) { | ||
| 106 | ar5523_err(ar, "RX USB to short.\n"); | ||
| 107 | goto skip; | ||
| 108 | } | ||
| 109 | |||
| 110 | ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, | ||
| 111 | be32_to_cpu(hdr->code) & 0xff, hdr->priv); | ||
| 112 | |||
| 113 | hdr->code = be32_to_cpu(hdr->code); | ||
| 114 | hdr->len = be32_to_cpu(hdr->len); | ||
| 115 | |||
| 116 | switch (hdr->code & 0xff) { | ||
| 117 | default: | ||
| 118 | /* reply to a read command */ | ||
| 119 | if (hdr->priv != AR5523_CMD_ID) { | ||
| 120 | ar5523_err(ar, "Unexpected command id: %02x\n", | ||
| 121 | hdr->code & 0xff); | ||
| 122 | goto skip; | ||
| 123 | } | ||
| 124 | ar5523_read_reply(ar, hdr, cmd); | ||
| 125 | break; | ||
| 126 | |||
| 127 | case WDCMSG_DEVICE_AVAIL: | ||
| 128 | ar5523_dbg(ar, "WDCMSG_DEVICE_AVAIL\n"); | ||
| 129 | cmd->res = 0; | ||
| 130 | cmd->olen = 0; | ||
| 131 | complete(&cmd->done); | ||
| 132 | break; | ||
| 133 | |||
| 134 | case WDCMSG_SEND_COMPLETE: | ||
| 135 | ar5523_dbg(ar, "WDCMSG_SEND_COMPLETE: %d pending\n", | ||
| 136 | atomic_read(&ar->tx_nr_pending)); | ||
| 137 | if (!test_bit(AR5523_HW_UP, &ar->flags)) | ||
| 138 | ar5523_dbg(ar, "Unexpected WDCMSG_SEND_COMPLETE\n"); | ||
| 139 | else { | ||
| 140 | mod_timer(&ar->tx_wd_timer, | ||
| 141 | jiffies + AR5523_TX_WD_TIMEOUT); | ||
| 142 | ar5523_data_tx_pkt_put(ar); | ||
| 143 | |||
| 144 | } | ||
| 145 | break; | ||
| 146 | |||
| 147 | case WDCMSG_TARGET_START: | ||
| 148 | /* This command returns a bogus id so it needs special | ||
| 149 | handling */ | ||
| 150 | dlen = hdr->len - sizeof(*hdr); | ||
| 151 | if (dlen != (int)sizeof(u32)) { | ||
| 152 | ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | memcpy(cmd->odata, hdr + 1, sizeof(u32)); | ||
| 156 | cmd->olen = sizeof(u32); | ||
| 157 | cmd->res = 0; | ||
| 158 | complete(&cmd->done); | ||
| 159 | break; | ||
| 160 | |||
| 161 | case WDCMSG_STATS_UPDATE: | ||
| 162 | ar5523_dbg(ar, "WDCMSG_STATS_UPDATE\n"); | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | |||
| 166 | skip: | ||
| 167 | ar5523_submit_rx_cmd(ar); | ||
| 168 | } | ||
| 169 | |||
| 170 | static int ar5523_alloc_rx_cmd(struct ar5523 *ar) | ||
| 171 | { | ||
| 172 | ar->rx_cmd_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 173 | if (!ar->rx_cmd_urb) | ||
| 174 | return -ENOMEM; | ||
| 175 | |||
| 176 | ar->rx_cmd_buf = usb_alloc_coherent(ar->dev, AR5523_MAX_RXCMDSZ, | ||
| 177 | GFP_KERNEL, | ||
| 178 | &ar->rx_cmd_urb->transfer_dma); | ||
| 179 | if (!ar->rx_cmd_buf) { | ||
| 180 | usb_free_urb(ar->rx_cmd_urb); | ||
| 181 | return -ENOMEM; | ||
| 182 | } | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void ar5523_cancel_rx_cmd(struct ar5523 *ar) | ||
| 187 | { | ||
| 188 | usb_kill_urb(ar->rx_cmd_urb); | ||
| 189 | } | ||
| 190 | |||
| 191 | static void ar5523_free_rx_cmd(struct ar5523 *ar) | ||
| 192 | { | ||
| 193 | usb_free_coherent(ar->dev, AR5523_MAX_RXCMDSZ, | ||
| 194 | ar->rx_cmd_buf, ar->rx_cmd_urb->transfer_dma); | ||
| 195 | usb_free_urb(ar->rx_cmd_urb); | ||
| 196 | } | ||
| 197 | |||
| 198 | static int ar5523_submit_rx_cmd(struct ar5523 *ar) | ||
| 199 | { | ||
| 200 | int error; | ||
| 201 | |||
| 202 | usb_fill_bulk_urb(ar->rx_cmd_urb, ar->dev, | ||
| 203 | ar5523_cmd_rx_pipe(ar->dev), ar->rx_cmd_buf, | ||
| 204 | AR5523_MAX_RXCMDSZ, ar5523_cmd_rx_cb, ar); | ||
| 205 | ar->rx_cmd_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 206 | |||
| 207 | error = usb_submit_urb(ar->rx_cmd_urb, GFP_ATOMIC); | ||
| 208 | if (error) { | ||
| 209 | if (error != -ENODEV) | ||
| 210 | ar5523_err(ar, "error %d when submitting rx urb\n", | ||
| 211 | error); | ||
| 212 | return error; | ||
| 213 | } | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Command submitted cb | ||
| 219 | */ | ||
| 220 | static void ar5523_cmd_tx_cb(struct urb *urb) | ||
| 221 | { | ||
| 222 | struct ar5523_tx_cmd *cmd = urb->context; | ||
| 223 | struct ar5523 *ar = cmd->ar; | ||
| 224 | |||
| 225 | if (urb->status) { | ||
| 226 | ar5523_err(ar, "Failed to TX command. Status = %d\n", | ||
| 227 | urb->status); | ||
| 228 | cmd->res = urb->status; | ||
| 229 | complete(&cmd->done); | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | |||
| 233 | if (!(cmd->flags & AR5523_CMD_FLAG_READ)) { | ||
| 234 | cmd->res = 0; | ||
| 235 | complete(&cmd->done); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata, | ||
| 240 | int ilen, void *odata, int olen, int flags) | ||
| 241 | { | ||
| 242 | struct ar5523_cmd_hdr *hdr; | ||
| 243 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; | ||
| 244 | int xferlen, error; | ||
| 245 | |||
| 246 | /* always bulk-out a multiple of 4 bytes */ | ||
| 247 | xferlen = (sizeof(struct ar5523_cmd_hdr) + ilen + 3) & ~3; | ||
| 248 | |||
| 249 | hdr = (struct ar5523_cmd_hdr *)cmd->buf_tx; | ||
| 250 | memset(hdr, 0, sizeof(struct ar5523_cmd_hdr)); | ||
| 251 | hdr->len = cpu_to_be32(xferlen); | ||
| 252 | hdr->code = cpu_to_be32(code); | ||
| 253 | hdr->priv = AR5523_CMD_ID; | ||
| 254 | |||
| 255 | if (flags & AR5523_CMD_FLAG_MAGIC) | ||
| 256 | hdr->magic = cpu_to_be32(1 << 24); | ||
| 257 | memcpy(hdr + 1, idata, ilen); | ||
| 258 | |||
| 259 | cmd->odata = odata; | ||
| 260 | cmd->olen = olen; | ||
| 261 | cmd->flags = flags; | ||
| 262 | |||
| 263 | ar5523_dbg(ar, "do cmd %02x\n", code); | ||
| 264 | |||
| 265 | usb_fill_bulk_urb(cmd->urb_tx, ar->dev, ar5523_cmd_tx_pipe(ar->dev), | ||
| 266 | cmd->buf_tx, xferlen, ar5523_cmd_tx_cb, cmd); | ||
| 267 | cmd->urb_tx->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 268 | |||
| 269 | error = usb_submit_urb(cmd->urb_tx, GFP_KERNEL); | ||
| 270 | if (error) { | ||
| 271 | ar5523_err(ar, "could not send command 0x%x, error=%d\n", | ||
| 272 | code, error); | ||
| 273 | return error; | ||
| 274 | } | ||
| 275 | |||
| 276 | if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) { | ||
| 277 | cmd->odata = NULL; | ||
| 278 | ar5523_err(ar, "timeout waiting for command %02x reply\n", | ||
| 279 | code); | ||
| 280 | cmd->res = -ETIMEDOUT; | ||
| 281 | } | ||
| 282 | return cmd->res; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int ar5523_cmd_write(struct ar5523 *ar, u32 code, const void *data, | ||
| 286 | int len, int flags) | ||
| 287 | { | ||
| 288 | flags &= ~AR5523_CMD_FLAG_READ; | ||
| 289 | return ar5523_cmd(ar, code, data, len, NULL, 0, flags); | ||
| 290 | } | ||
| 291 | |||
| 292 | static int ar5523_cmd_read(struct ar5523 *ar, u32 code, const void *idata, | ||
| 293 | int ilen, void *odata, int olen, int flags) | ||
| 294 | { | ||
| 295 | flags |= AR5523_CMD_FLAG_READ; | ||
| 296 | return ar5523_cmd(ar, code, idata, ilen, odata, olen, flags); | ||
| 297 | } | ||
| 298 | |||
| 299 | static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val) | ||
| 300 | { | ||
| 301 | struct ar5523_write_mac write; | ||
| 302 | int error; | ||
| 303 | |||
| 304 | write.reg = cpu_to_be32(reg); | ||
| 305 | write.len = cpu_to_be32(0); /* 0 = single write */ | ||
| 306 | *(u32 *)write.data = cpu_to_be32(val); | ||
| 307 | |||
| 308 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, | ||
| 309 | 3 * sizeof(u32), 0); | ||
| 310 | if (error != 0) | ||
| 311 | ar5523_err(ar, "could not write register 0x%02x\n", reg); | ||
| 312 | return error; | ||
| 313 | } | ||
| 314 | |||
| 315 | static int ar5523_config_multi(struct ar5523 *ar, u32 reg, const void *data, | ||
| 316 | int len) | ||
| 317 | { | ||
| 318 | struct ar5523_write_mac write; | ||
| 319 | int error; | ||
| 320 | |||
| 321 | write.reg = cpu_to_be32(reg); | ||
| 322 | write.len = cpu_to_be32(len); | ||
| 323 | memcpy(write.data, data, len); | ||
| 324 | |||
| 325 | /* properly handle the case where len is zero (reset) */ | ||
| 326 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, | ||
| 327 | (len == 0) ? sizeof(u32) : 2 * sizeof(u32) + len, 0); | ||
| 328 | if (error != 0) | ||
| 329 | ar5523_err(ar, "could not write %d bytes to register 0x%02x\n", | ||
| 330 | len, reg); | ||
| 331 | return error; | ||
| 332 | } | ||
| 333 | |||
| 334 | static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata, | ||
| 335 | int olen) | ||
| 336 | { | ||
| 337 | int error; | ||
| 338 | |||
| 339 | which = cpu_to_be32(which); | ||
| 340 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, | ||
| 341 | &which, sizeof(which), odata, olen, AR5523_CMD_FLAG_MAGIC); | ||
| 342 | if (error != 0) | ||
| 343 | ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", | ||
| 344 | be32_to_cpu(which)); | ||
| 345 | return error; | ||
| 346 | } | ||
| 347 | |||
| 348 | static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) | ||
| 349 | { | ||
| 350 | int error; | ||
| 351 | |||
| 352 | cap = cpu_to_be32(cap); | ||
| 353 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, | ||
| 354 | &cap, sizeof(cap), val, sizeof(u32), AR5523_CMD_FLAG_MAGIC); | ||
| 355 | if (error != 0) { | ||
| 356 | ar5523_err(ar, "could not read capability %u\n", | ||
| 357 | be32_to_cpu(cap)); | ||
| 358 | return error; | ||
| 359 | } | ||
| 360 | *val = be32_to_cpu(*val); | ||
| 361 | return error; | ||
| 362 | } | ||
| 363 | |||
| 364 | static int ar5523_get_devcap(struct ar5523 *ar) | ||
| 365 | { | ||
| 366 | #define GETCAP(x) do { \ | ||
| 367 | error = ar5523_get_capability(ar, x, &cap); \ | ||
| 368 | if (error != 0) \ | ||
| 369 | return error; \ | ||
| 370 | ar5523_info(ar, "Cap: " \ | ||
| 371 | "%s=0x%08x\n", #x, cap); \ | ||
| 372 | } while (0) | ||
| 373 | int error; | ||
| 374 | u32 cap; | ||
| 375 | |||
| 376 | /* collect device capabilities */ | ||
| 377 | GETCAP(CAP_TARGET_VERSION); | ||
| 378 | GETCAP(CAP_TARGET_REVISION); | ||
| 379 | GETCAP(CAP_MAC_VERSION); | ||
| 380 | GETCAP(CAP_MAC_REVISION); | ||
| 381 | GETCAP(CAP_PHY_REVISION); | ||
| 382 | GETCAP(CAP_ANALOG_5GHz_REVISION); | ||
| 383 | GETCAP(CAP_ANALOG_2GHz_REVISION); | ||
| 384 | |||
| 385 | GETCAP(CAP_REG_DOMAIN); | ||
| 386 | GETCAP(CAP_REG_CAP_BITS); | ||
| 387 | GETCAP(CAP_WIRELESS_MODES); | ||
| 388 | GETCAP(CAP_CHAN_SPREAD_SUPPORT); | ||
| 389 | GETCAP(CAP_COMPRESS_SUPPORT); | ||
| 390 | GETCAP(CAP_BURST_SUPPORT); | ||
| 391 | GETCAP(CAP_FAST_FRAMES_SUPPORT); | ||
| 392 | GETCAP(CAP_CHAP_TUNING_SUPPORT); | ||
| 393 | GETCAP(CAP_TURBOG_SUPPORT); | ||
| 394 | GETCAP(CAP_TURBO_PRIME_SUPPORT); | ||
| 395 | GETCAP(CAP_DEVICE_TYPE); | ||
| 396 | GETCAP(CAP_WME_SUPPORT); | ||
| 397 | GETCAP(CAP_TOTAL_QUEUES); | ||
| 398 | GETCAP(CAP_CONNECTION_ID_MAX); | ||
| 399 | |||
| 400 | GETCAP(CAP_LOW_5GHZ_CHAN); | ||
| 401 | GETCAP(CAP_HIGH_5GHZ_CHAN); | ||
| 402 | GETCAP(CAP_LOW_2GHZ_CHAN); | ||
| 403 | GETCAP(CAP_HIGH_2GHZ_CHAN); | ||
| 404 | GETCAP(CAP_TWICE_ANTENNAGAIN_5G); | ||
| 405 | GETCAP(CAP_TWICE_ANTENNAGAIN_2G); | ||
| 406 | |||
| 407 | GETCAP(CAP_CIPHER_AES_CCM); | ||
| 408 | GETCAP(CAP_CIPHER_TKIP); | ||
| 409 | GETCAP(CAP_MIC_TKIP); | ||
| 410 | return 0; | ||
| 411 | } | ||
| 412 | |||
| 413 | static int ar5523_set_ledsteady(struct ar5523 *ar, int lednum, int ledmode) | ||
| 414 | { | ||
| 415 | struct ar5523_cmd_ledsteady led; | ||
| 416 | |||
| 417 | led.lednum = cpu_to_be32(lednum); | ||
| 418 | led.ledmode = cpu_to_be32(ledmode); | ||
| 419 | |||
| 420 | ar5523_dbg(ar, "set %s led %s (steady)\n", | ||
| 421 | (lednum == UATH_LED_LINK) ? "link" : "activity", | ||
| 422 | ledmode ? "on" : "off"); | ||
| 423 | return ar5523_cmd_write(ar, WDCMSG_SET_LED_STEADY, &led, sizeof(led), | ||
| 424 | 0); | ||
| 425 | } | ||
| 426 | |||
| 427 | static int ar5523_set_rxfilter(struct ar5523 *ar, u32 bits, u32 op) | ||
| 428 | { | ||
| 429 | struct ar5523_cmd_rx_filter rxfilter; | ||
| 430 | |||
| 431 | rxfilter.bits = cpu_to_be32(bits); | ||
| 432 | rxfilter.op = cpu_to_be32(op); | ||
| 433 | |||
| 434 | ar5523_dbg(ar, "setting Rx filter=0x%x flags=0x%x\n", bits, op); | ||
| 435 | return ar5523_cmd_write(ar, WDCMSG_RX_FILTER, &rxfilter, | ||
| 436 | sizeof(rxfilter), 0); | ||
| 437 | } | ||
| 438 | |||
| 439 | static int ar5523_reset_tx_queues(struct ar5523 *ar) | ||
| 440 | { | ||
| 441 | __be32 qid = cpu_to_be32(0); | ||
| 442 | |||
| 443 | ar5523_dbg(ar, "resetting Tx queue\n"); | ||
| 444 | return ar5523_cmd_write(ar, WDCMSG_RELEASE_TX_QUEUE, | ||
| 445 | &qid, sizeof(qid), 0); | ||
| 446 | } | ||
| 447 | |||
| 448 | static int ar5523_set_chan(struct ar5523 *ar) | ||
| 449 | { | ||
| 450 | struct ieee80211_conf *conf = &ar->hw->conf; | ||
| 451 | |||
| 452 | struct ar5523_cmd_reset reset; | ||
| 453 | |||
| 454 | memset(&reset, 0, sizeof(reset)); | ||
| 455 | reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); | ||
| 456 | reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); | ||
| 457 | reset.freq = cpu_to_be32(conf->channel->center_freq); | ||
| 458 | reset.maxrdpower = cpu_to_be32(50); /* XXX */ | ||
| 459 | reset.channelchange = cpu_to_be32(1); | ||
| 460 | reset.keeprccontent = cpu_to_be32(0); | ||
| 461 | |||
| 462 | ar5523_dbg(ar, "set chan flags 0x%x freq %d\n", | ||
| 463 | be32_to_cpu(reset.flags), | ||
| 464 | conf->channel->center_freq); | ||
| 465 | return ar5523_cmd_write(ar, WDCMSG_RESET, &reset, sizeof(reset), 0); | ||
| 466 | } | ||
| 467 | |||
| 468 | static int ar5523_queue_init(struct ar5523 *ar) | ||
| 469 | { | ||
| 470 | struct ar5523_cmd_txq_setup qinfo; | ||
| 471 | |||
| 472 | ar5523_dbg(ar, "setting up Tx queue\n"); | ||
| 473 | qinfo.qid = cpu_to_be32(0); | ||
| 474 | qinfo.len = cpu_to_be32(sizeof(qinfo.attr)); | ||
| 475 | qinfo.attr.priority = cpu_to_be32(0); /* XXX */ | ||
| 476 | qinfo.attr.aifs = cpu_to_be32(3); | ||
| 477 | qinfo.attr.logcwmin = cpu_to_be32(4); | ||
| 478 | qinfo.attr.logcwmax = cpu_to_be32(10); | ||
| 479 | qinfo.attr.bursttime = cpu_to_be32(0); | ||
| 480 | qinfo.attr.mode = cpu_to_be32(0); | ||
| 481 | qinfo.attr.qflags = cpu_to_be32(1); /* XXX? */ | ||
| 482 | return ar5523_cmd_write(ar, WDCMSG_SETUP_TX_QUEUE, &qinfo, | ||
| 483 | sizeof(qinfo), 0); | ||
| 484 | } | ||
| 485 | |||
| 486 | static int ar5523_switch_chan(struct ar5523 *ar) | ||
| 487 | { | ||
| 488 | int error; | ||
| 489 | |||
| 490 | error = ar5523_set_chan(ar); | ||
| 491 | if (error) { | ||
| 492 | ar5523_err(ar, "could not set chan, error %d\n", error); | ||
| 493 | goto out_err; | ||
| 494 | } | ||
| 495 | |||
| 496 | /* reset Tx rings */ | ||
| 497 | error = ar5523_reset_tx_queues(ar); | ||
| 498 | if (error) { | ||
| 499 | ar5523_err(ar, "could not reset Tx queues, error %d\n", | ||
| 500 | error); | ||
| 501 | goto out_err; | ||
| 502 | } | ||
| 503 | /* set Tx rings WME properties */ | ||
| 504 | error = ar5523_queue_init(ar); | ||
| 505 | if (error) | ||
| 506 | ar5523_err(ar, "could not init wme, error %d\n", error); | ||
| 507 | |||
| 508 | out_err: | ||
| 509 | return error; | ||
| 510 | } | ||
| 511 | |||
| 512 | static void ar5523_rx_data_put(struct ar5523 *ar, | ||
| 513 | struct ar5523_rx_data *data) | ||
| 514 | { | ||
| 515 | unsigned long flags; | ||
| 516 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); | ||
| 517 | list_move(&data->list, &ar->rx_data_free); | ||
| 518 | spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); | ||
| 519 | } | ||
| 520 | |||
| 521 | static void ar5523_data_rx_cb(struct urb *urb) | ||
| 522 | { | ||
| 523 | struct ar5523_rx_data *data = urb->context; | ||
| 524 | struct ar5523 *ar = data->ar; | ||
| 525 | struct ar5523_rx_desc *desc; | ||
| 526 | struct ar5523_chunk *chunk; | ||
| 527 | struct ieee80211_hw *hw = ar->hw; | ||
| 528 | struct ieee80211_rx_status *rx_status; | ||
| 529 | u32 rxlen; | ||
| 530 | int usblen = urb->actual_length; | ||
| 531 | int hdrlen, pad; | ||
| 532 | |||
| 533 | ar5523_dbg(ar, "%s\n", __func__); | ||
| 534 | /* sync/async unlink faults aren't errors */ | ||
| 535 | if (urb->status) { | ||
| 536 | if (urb->status != -ESHUTDOWN) | ||
| 537 | ar5523_err(ar, "%s: USB err: %d\n", __func__, | ||
| 538 | urb->status); | ||
| 539 | goto skip; | ||
| 540 | } | ||
| 541 | |||
| 542 | if (usblen < AR5523_MIN_RXBUFSZ) { | ||
| 543 | ar5523_err(ar, "RX: wrong xfer size (usblen=%d)\n", usblen); | ||
| 544 | goto skip; | ||
| 545 | } | ||
| 546 | |||
| 547 | chunk = (struct ar5523_chunk *) data->skb->data; | ||
| 548 | |||
| 549 | if (((chunk->flags & UATH_CFLAGS_FINAL) == 0) || | ||
| 550 | chunk->seqnum != 0) { | ||
| 551 | ar5523_dbg(ar, "RX: No final flag. s: %d f: %02x l: %d\n", | ||
| 552 | chunk->seqnum, chunk->flags, | ||
| 553 | be16_to_cpu(chunk->length)); | ||
| 554 | goto skip; | ||
| 555 | } | ||
| 556 | |||
| 557 | /* Rx descriptor is located at the end, 32-bit aligned */ | ||
| 558 | desc = (struct ar5523_rx_desc *) | ||
| 559 | (data->skb->data + usblen - sizeof(struct ar5523_rx_desc)); | ||
| 560 | |||
| 561 | rxlen = be32_to_cpu(desc->len); | ||
| 562 | if (rxlen > ar->rxbufsz) { | ||
| 563 | ar5523_dbg(ar, "RX: Bad descriptor (len=%d)\n", | ||
| 564 | be32_to_cpu(desc->len)); | ||
| 565 | goto skip; | ||
| 566 | } | ||
| 567 | |||
| 568 | if (!rxlen) { | ||
| 569 | ar5523_dbg(ar, "RX: rxlen is 0\n"); | ||
| 570 | goto skip; | ||
| 571 | } | ||
| 572 | |||
| 573 | if (be32_to_cpu(desc->status) != 0) { | ||
| 574 | ar5523_dbg(ar, "Bad RX status (0x%x len = %d). Skip\n", | ||
| 575 | be32_to_cpu(desc->status), be32_to_cpu(desc->len)); | ||
| 576 | goto skip; | ||
| 577 | } | ||
| 578 | |||
| 579 | skb_reserve(data->skb, sizeof(*chunk)); | ||
| 580 | skb_put(data->skb, rxlen - sizeof(struct ar5523_rx_desc)); | ||
| 581 | |||
| 582 | hdrlen = ieee80211_get_hdrlen_from_skb(data->skb); | ||
| 583 | if (!IS_ALIGNED(hdrlen, 4)) { | ||
| 584 | ar5523_dbg(ar, "eek, alignment workaround activated\n"); | ||
| 585 | pad = ALIGN(hdrlen, 4) - hdrlen; | ||
| 586 | memmove(data->skb->data + pad, data->skb->data, hdrlen); | ||
| 587 | skb_pull(data->skb, pad); | ||
| 588 | skb_put(data->skb, pad); | ||
| 589 | } | ||
| 590 | |||
| 591 | rx_status = IEEE80211_SKB_RXCB(data->skb); | ||
| 592 | memset(rx_status, 0, sizeof(*rx_status)); | ||
| 593 | rx_status->freq = be32_to_cpu(desc->channel); | ||
| 594 | rx_status->band = hw->conf.channel->band; | ||
| 595 | rx_status->signal = -95 + be32_to_cpu(desc->rssi); | ||
| 596 | |||
| 597 | ieee80211_rx_irqsafe(hw, data->skb); | ||
| 598 | data->skb = NULL; | ||
| 599 | |||
| 600 | skip: | ||
| 601 | if (data->skb) { | ||
| 602 | dev_kfree_skb_irq(data->skb); | ||
| 603 | data->skb = NULL; | ||
| 604 | } | ||
| 605 | |||
| 606 | ar5523_rx_data_put(ar, data); | ||
| 607 | if (atomic_inc_return(&ar->rx_data_free_cnt) >= | ||
| 608 | AR5523_RX_DATA_REFILL_COUNT && | ||
| 609 | test_bit(AR5523_HW_UP, &ar->flags)) | ||
| 610 | queue_work(ar->wq, &ar->rx_refill_work); | ||
| 611 | } | ||
| 612 | |||
| 613 | static void ar5523_rx_refill_work(struct work_struct *work) | ||
| 614 | { | ||
| 615 | struct ar5523 *ar = container_of(work, struct ar5523, rx_refill_work); | ||
| 616 | struct ar5523_rx_data *data; | ||
| 617 | unsigned long flags; | ||
| 618 | int error; | ||
| 619 | |||
| 620 | ar5523_dbg(ar, "%s\n", __func__); | ||
| 621 | do { | ||
| 622 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); | ||
| 623 | |||
| 624 | if (!list_empty(&ar->rx_data_free)) | ||
| 625 | data = (struct ar5523_rx_data *) ar->rx_data_free.next; | ||
| 626 | else | ||
| 627 | data = NULL; | ||
| 628 | spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); | ||
| 629 | |||
| 630 | if (!data) | ||
| 631 | goto done; | ||
| 632 | |||
| 633 | data->skb = alloc_skb(ar->rxbufsz, GFP_KERNEL); | ||
| 634 | if (!data->skb) { | ||
| 635 | ar5523_err(ar, "could not allocate rx skbuff\n"); | ||
| 636 | return; | ||
| 637 | } | ||
| 638 | |||
| 639 | usb_fill_bulk_urb(data->urb, ar->dev, | ||
| 640 | ar5523_data_rx_pipe(ar->dev), data->skb->data, | ||
| 641 | ar->rxbufsz, ar5523_data_rx_cb, data); | ||
| 642 | |||
| 643 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); | ||
| 644 | list_move(&data->list, &ar->rx_data_used); | ||
| 645 | spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); | ||
| 646 | atomic_dec(&ar->rx_data_free_cnt); | ||
| 647 | |||
| 648 | error = usb_submit_urb(data->urb, GFP_KERNEL); | ||
| 649 | if (error) { | ||
| 650 | kfree_skb(data->skb); | ||
| 651 | if (error != -ENODEV) | ||
| 652 | ar5523_err(ar, "Err sending rx data urb %d\n", | ||
| 653 | error); | ||
| 654 | ar5523_rx_data_put(ar, data); | ||
| 655 | atomic_inc(&ar->rx_data_free_cnt); | ||
| 656 | return; | ||
| 657 | } | ||
| 658 | |||
| 659 | } while (true); | ||
| 660 | done: | ||
| 661 | return; | ||
| 662 | } | ||
| 663 | |||
| 664 | static void ar5523_cancel_rx_bufs(struct ar5523 *ar) | ||
| 665 | { | ||
| 666 | struct ar5523_rx_data *data; | ||
| 667 | unsigned long flags; | ||
| 668 | |||
| 669 | do { | ||
| 670 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); | ||
| 671 | if (!list_empty(&ar->rx_data_used)) | ||
| 672 | data = (struct ar5523_rx_data *) ar->rx_data_used.next; | ||
| 673 | else | ||
| 674 | data = NULL; | ||
| 675 | spin_unlock_irqrestore(&ar->rx_data_list_lock, flags); | ||
| 676 | |||
| 677 | if (!data) | ||
| 678 | break; | ||
| 679 | |||
| 680 | usb_kill_urb(data->urb); | ||
| 681 | list_move(&data->list, &ar->rx_data_free); | ||
| 682 | atomic_inc(&ar->rx_data_free_cnt); | ||
| 683 | } while (data); | ||
| 684 | } | ||
| 685 | |||
| 686 | static void ar5523_free_rx_bufs(struct ar5523 *ar) | ||
| 687 | { | ||
| 688 | struct ar5523_rx_data *data; | ||
| 689 | |||
| 690 | ar5523_cancel_rx_bufs(ar); | ||
| 691 | while (!list_empty(&ar->rx_data_free)) { | ||
| 692 | data = (struct ar5523_rx_data *) ar->rx_data_free.next; | ||
| 693 | list_del(&data->list); | ||
| 694 | usb_free_urb(data->urb); | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | static int ar5523_alloc_rx_bufs(struct ar5523 *ar) | ||
| 699 | { | ||
| 700 | int i; | ||
| 701 | |||
| 702 | for (i = 0; i < AR5523_RX_DATA_COUNT; i++) { | ||
| 703 | struct ar5523_rx_data *data = &ar->rx_data[i]; | ||
| 704 | |||
| 705 | data->ar = ar; | ||
| 706 | data->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 707 | if (!data->urb) { | ||
| 708 | ar5523_err(ar, "could not allocate rx data urb\n"); | ||
| 709 | goto err; | ||
| 710 | } | ||
| 711 | list_add_tail(&data->list, &ar->rx_data_free); | ||
| 712 | atomic_inc(&ar->rx_data_free_cnt); | ||
| 713 | } | ||
| 714 | return 0; | ||
| 715 | |||
| 716 | err: | ||
| 717 | ar5523_free_rx_bufs(ar); | ||
| 718 | return -ENOMEM; | ||
| 719 | } | ||
| 720 | |||
| 721 | static void ar5523_data_tx_pkt_put(struct ar5523 *ar) | ||
| 722 | { | ||
| 723 | atomic_dec(&ar->tx_nr_total); | ||
| 724 | if (!atomic_dec_return(&ar->tx_nr_pending)) { | ||
| 725 | del_timer(&ar->tx_wd_timer); | ||
| 726 | wake_up(&ar->tx_flush_waitq); | ||
| 727 | } | ||
| 728 | |||
| 729 | if (atomic_read(&ar->tx_nr_total) < AR5523_TX_DATA_RESTART_COUNT) { | ||
| 730 | ar5523_dbg(ar, "restart tx queue\n"); | ||
| 731 | ieee80211_wake_queues(ar->hw); | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | static void ar5523_data_tx_cb(struct urb *urb) | ||
| 736 | { | ||
| 737 | struct sk_buff *skb = urb->context; | ||
| 738 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); | ||
| 739 | struct ar5523_tx_data *data = (struct ar5523_tx_data *) | ||
| 740 | txi->driver_data; | ||
| 741 | struct ar5523 *ar = data->ar; | ||
| 742 | unsigned long flags; | ||
| 743 | |||
| 744 | ar5523_dbg(ar, "data tx urb completed: %d\n", urb->status); | ||
| 745 | |||
| 746 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); | ||
| 747 | list_del(&data->list); | ||
| 748 | spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); | ||
| 749 | |||
| 750 | if (urb->status) { | ||
| 751 | ar5523_dbg(ar, "%s: urb status: %d\n", __func__, urb->status); | ||
| 752 | ar5523_data_tx_pkt_put(ar); | ||
| 753 | ieee80211_free_txskb(ar->hw, skb); | ||
| 754 | } else { | ||
| 755 | skb_pull(skb, sizeof(struct ar5523_tx_desc) + sizeof(__be32)); | ||
| 756 | ieee80211_tx_status_irqsafe(ar->hw, skb); | ||
| 757 | } | ||
| 758 | usb_free_urb(urb); | ||
| 759 | } | ||
| 760 | |||
| 761 | static void ar5523_tx(struct ieee80211_hw *hw, | ||
| 762 | struct ieee80211_tx_control *control, | ||
| 763 | struct sk_buff *skb) | ||
| 764 | { | ||
| 765 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); | ||
| 766 | struct ar5523_tx_data *data = (struct ar5523_tx_data *) | ||
| 767 | txi->driver_data; | ||
| 768 | struct ar5523 *ar = hw->priv; | ||
| 769 | unsigned long flags; | ||
| 770 | |||
| 771 | ar5523_dbg(ar, "tx called\n"); | ||
| 772 | if (atomic_inc_return(&ar->tx_nr_total) >= AR5523_TX_DATA_COUNT) { | ||
| 773 | ar5523_dbg(ar, "tx queue full\n"); | ||
| 774 | ar5523_dbg(ar, "stop queues (tot %d pend %d)\n", | ||
| 775 | atomic_read(&ar->tx_nr_total), | ||
| 776 | atomic_read(&ar->tx_nr_pending)); | ||
| 777 | ieee80211_stop_queues(hw); | ||
| 778 | } | ||
| 779 | |||
| 780 | data->skb = skb; | ||
| 781 | |||
| 782 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); | ||
| 783 | list_add_tail(&data->list, &ar->tx_queue_pending); | ||
| 784 | spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); | ||
| 785 | |||
| 786 | ieee80211_queue_work(ar->hw, &ar->tx_work); | ||
| 787 | } | ||
| 788 | |||
| 789 | static void ar5523_tx_work_locked(struct ar5523 *ar) | ||
| 790 | { | ||
| 791 | struct ar5523_tx_data *data; | ||
| 792 | struct ar5523_tx_desc *desc; | ||
| 793 | struct ar5523_chunk *chunk; | ||
| 794 | struct ieee80211_tx_info *txi; | ||
| 795 | struct urb *urb; | ||
| 796 | struct sk_buff *skb; | ||
| 797 | int error = 0, paylen; | ||
| 798 | u32 txqid; | ||
| 799 | unsigned long flags; | ||
| 800 | |||
| 801 | BUILD_BUG_ON(sizeof(struct ar5523_tx_data) > | ||
| 802 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE); | ||
| 803 | |||
| 804 | ar5523_dbg(ar, "%s\n", __func__); | ||
| 805 | do { | ||
| 806 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); | ||
| 807 | if (!list_empty(&ar->tx_queue_pending)) { | ||
| 808 | data = (struct ar5523_tx_data *) | ||
| 809 | ar->tx_queue_pending.next; | ||
| 810 | list_del(&data->list); | ||
| 811 | } else | ||
| 812 | data = NULL; | ||
| 813 | spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); | ||
| 814 | |||
| 815 | if (!data) | ||
| 816 | break; | ||
| 817 | |||
| 818 | skb = data->skb; | ||
| 819 | txqid = 0; | ||
| 820 | txi = IEEE80211_SKB_CB(skb); | ||
| 821 | paylen = skb->len; | ||
| 822 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 823 | if (!urb) { | ||
| 824 | ar5523_err(ar, "Failed to allocate TX urb\n"); | ||
| 825 | ieee80211_free_txskb(ar->hw, skb); | ||
| 826 | continue; | ||
| 827 | } | ||
| 828 | |||
| 829 | data->ar = ar; | ||
| 830 | data->urb = urb; | ||
| 831 | |||
| 832 | desc = (struct ar5523_tx_desc *)skb_push(skb, sizeof(*desc)); | ||
| 833 | chunk = (struct ar5523_chunk *)skb_push(skb, sizeof(*chunk)); | ||
| 834 | |||
| 835 | chunk->seqnum = 0; | ||
| 836 | chunk->flags = UATH_CFLAGS_FINAL; | ||
| 837 | chunk->length = cpu_to_be16(skb->len); | ||
| 838 | |||
| 839 | desc->msglen = cpu_to_be32(skb->len); | ||
| 840 | desc->msgid = AR5523_DATA_ID; | ||
| 841 | desc->buflen = cpu_to_be32(paylen); | ||
| 842 | desc->type = cpu_to_be32(WDCMSG_SEND); | ||
| 843 | desc->flags = cpu_to_be32(UATH_TX_NOTIFY); | ||
| 844 | |||
| 845 | if (test_bit(AR5523_CONNECTED, &ar->flags)) | ||
| 846 | desc->connid = cpu_to_be32(AR5523_ID_BSS); | ||
| 847 | else | ||
| 848 | desc->connid = cpu_to_be32(AR5523_ID_BROADCAST); | ||
| 849 | |||
| 850 | if (txi->flags & IEEE80211_TX_CTL_USE_MINRATE) | ||
| 851 | txqid |= UATH_TXQID_MINRATE; | ||
| 852 | |||
| 853 | desc->txqid = cpu_to_be32(txqid); | ||
| 854 | |||
| 855 | urb->transfer_flags = URB_ZERO_PACKET; | ||
| 856 | usb_fill_bulk_urb(urb, ar->dev, ar5523_data_tx_pipe(ar->dev), | ||
| 857 | skb->data, skb->len, ar5523_data_tx_cb, skb); | ||
| 858 | |||
| 859 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); | ||
| 860 | list_add_tail(&data->list, &ar->tx_queue_submitted); | ||
| 861 | spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); | ||
| 862 | mod_timer(&ar->tx_wd_timer, jiffies + AR5523_TX_WD_TIMEOUT); | ||
| 863 | atomic_inc(&ar->tx_nr_pending); | ||
| 864 | |||
| 865 | ar5523_dbg(ar, "TX Frame (%d pending)\n", | ||
| 866 | atomic_read(&ar->tx_nr_pending)); | ||
| 867 | error = usb_submit_urb(urb, GFP_KERNEL); | ||
| 868 | if (error) { | ||
| 869 | ar5523_err(ar, "error %d when submitting tx urb\n", | ||
| 870 | error); | ||
| 871 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); | ||
| 872 | list_del(&data->list); | ||
| 873 | spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); | ||
| 874 | atomic_dec(&ar->tx_nr_pending); | ||
| 875 | ar5523_data_tx_pkt_put(ar); | ||
| 876 | usb_free_urb(urb); | ||
| 877 | ieee80211_free_txskb(ar->hw, skb); | ||
| 878 | } | ||
| 879 | } while (true); | ||
| 880 | } | ||
| 881 | |||
| 882 | static void ar5523_tx_work(struct work_struct *work) | ||
| 883 | { | ||
| 884 | struct ar5523 *ar = container_of(work, struct ar5523, tx_work); | ||
| 885 | |||
| 886 | ar5523_dbg(ar, "%s\n", __func__); | ||
| 887 | mutex_lock(&ar->mutex); | ||
| 888 | ar5523_tx_work_locked(ar); | ||
| 889 | mutex_unlock(&ar->mutex); | ||
| 890 | } | ||
| 891 | |||
| 892 | static void ar5523_tx_wd_timer(unsigned long arg) | ||
| 893 | { | ||
| 894 | struct ar5523 *ar = (struct ar5523 *) arg; | ||
| 895 | |||
| 896 | ar5523_dbg(ar, "TX watchdog timer triggered\n"); | ||
| 897 | ieee80211_queue_work(ar->hw, &ar->tx_wd_work); | ||
| 898 | } | ||
| 899 | |||
| 900 | static void ar5523_tx_wd_work(struct work_struct *work) | ||
| 901 | { | ||
| 902 | struct ar5523 *ar = container_of(work, struct ar5523, tx_wd_work); | ||
| 903 | |||
| 904 | /* Occasionally the TX queues stop responding. The only way to | ||
| 905 | * recover seems to be to reset the dongle. | ||
| 906 | */ | ||
| 907 | |||
| 908 | mutex_lock(&ar->mutex); | ||
| 909 | ar5523_err(ar, "TX queue stuck (tot %d pend %d)\n", | ||
| 910 | atomic_read(&ar->tx_nr_total), | ||
| 911 | atomic_read(&ar->tx_nr_pending)); | ||
| 912 | |||
| 913 | ar5523_err(ar, "Will restart dongle.\n"); | ||
| 914 | ar5523_cmd_write(ar, WDCMSG_TARGET_RESET, NULL, 0, 0); | ||
| 915 | mutex_unlock(&ar->mutex); | ||
| 916 | } | ||
| 917 | |||
| 918 | static void ar5523_flush_tx(struct ar5523 *ar) | ||
| 919 | { | ||
| 920 | ar5523_tx_work_locked(ar); | ||
| 921 | |||
| 922 | /* Don't waste time trying to flush if USB is disconnected */ | ||
| 923 | if (test_bit(AR5523_USB_DISCONNECTED, &ar->flags)) | ||
| 924 | return; | ||
| 925 | if (!wait_event_timeout(ar->tx_flush_waitq, | ||
| 926 | !atomic_read(&ar->tx_nr_pending), AR5523_FLUSH_TIMEOUT)) | ||
| 927 | ar5523_err(ar, "flush timeout (tot %d pend %d)\n", | ||
| 928 | atomic_read(&ar->tx_nr_total), | ||
| 929 | atomic_read(&ar->tx_nr_pending)); | ||
| 930 | } | ||
| 931 | |||
| 932 | static void ar5523_free_tx_cmd(struct ar5523 *ar) | ||
| 933 | { | ||
| 934 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; | ||
| 935 | |||
| 936 | usb_free_coherent(ar->dev, AR5523_MAX_RXCMDSZ, cmd->buf_tx, | ||
| 937 | cmd->urb_tx->transfer_dma); | ||
| 938 | usb_free_urb(cmd->urb_tx); | ||
| 939 | } | ||
| 940 | |||
| 941 | static int ar5523_alloc_tx_cmd(struct ar5523 *ar) | ||
| 942 | { | ||
| 943 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; | ||
| 944 | |||
| 945 | cmd->ar = ar; | ||
| 946 | init_completion(&cmd->done); | ||
| 947 | |||
| 948 | cmd->urb_tx = usb_alloc_urb(0, GFP_KERNEL); | ||
| 949 | if (!cmd->urb_tx) { | ||
| 950 | ar5523_err(ar, "could not allocate urb\n"); | ||
| 951 | return -ENOMEM; | ||
| 952 | } | ||
| 953 | cmd->buf_tx = usb_alloc_coherent(ar->dev, AR5523_MAX_TXCMDSZ, | ||
| 954 | GFP_KERNEL, | ||
| 955 | &cmd->urb_tx->transfer_dma); | ||
| 956 | if (!cmd->buf_tx) { | ||
| 957 | usb_free_urb(cmd->urb_tx); | ||
| 958 | return -ENOMEM; | ||
| 959 | } | ||
| 960 | return 0; | ||
| 961 | } | ||
| 962 | |||
| 963 | /* | ||
| 964 | * This function is called periodically (every second) when associated to | ||
| 965 | * query device statistics. | ||
| 966 | */ | ||
| 967 | static void ar5523_stat_work(struct work_struct *work) | ||
| 968 | { | ||
| 969 | struct ar5523 *ar = container_of(work, struct ar5523, stat_work.work); | ||
| 970 | int error; | ||
| 971 | |||
| 972 | ar5523_dbg(ar, "%s\n", __func__); | ||
| 973 | mutex_lock(&ar->mutex); | ||
| 974 | |||
| 975 | /* | ||
| 976 | * Send request for statistics asynchronously once a second. This | ||
| 977 | * seems to be important. Throughput is a lot better if this is done. | ||
| 978 | */ | ||
| 979 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_GET_STATS, NULL, 0, 0); | ||
| 980 | if (error) | ||
| 981 | ar5523_err(ar, "could not query stats, error %d\n", error); | ||
| 982 | mutex_unlock(&ar->mutex); | ||
| 983 | ieee80211_queue_delayed_work(ar->hw, &ar->stat_work, HZ); | ||
| 984 | } | ||
| 985 | |||
| 986 | /* | ||
| 987 | * Interface routines to the mac80211 stack. | ||
| 988 | */ | ||
| 989 | static int ar5523_start(struct ieee80211_hw *hw) | ||
| 990 | { | ||
| 991 | struct ar5523 *ar = hw->priv; | ||
| 992 | int error; | ||
| 993 | __be32 val; | ||
| 994 | |||
| 995 | ar5523_dbg(ar, "start called\n"); | ||
| 996 | |||
| 997 | mutex_lock(&ar->mutex); | ||
| 998 | val = cpu_to_be32(0); | ||
| 999 | ar5523_cmd_write(ar, WDCMSG_BIND, &val, sizeof(val), 0); | ||
| 1000 | |||
| 1001 | /* set MAC address */ | ||
| 1002 | ar5523_config_multi(ar, CFG_MAC_ADDR, &ar->hw->wiphy->perm_addr, | ||
| 1003 | ETH_ALEN); | ||
| 1004 | |||
| 1005 | /* XXX honor net80211 state */ | ||
| 1006 | ar5523_config(ar, CFG_RATE_CONTROL_ENABLE, 0x00000001); | ||
| 1007 | ar5523_config(ar, CFG_DIVERSITY_CTL, 0x00000001); | ||
| 1008 | ar5523_config(ar, CFG_ABOLT, 0x0000003f); | ||
| 1009 | ar5523_config(ar, CFG_WME_ENABLED, 0x00000000); | ||
| 1010 | |||
| 1011 | ar5523_config(ar, CFG_SERVICE_TYPE, 1); | ||
| 1012 | ar5523_config(ar, CFG_TP_SCALE, 0x00000000); | ||
| 1013 | ar5523_config(ar, CFG_TPC_HALF_DBM5, 0x0000003c); | ||
| 1014 | ar5523_config(ar, CFG_TPC_HALF_DBM2, 0x0000003c); | ||
| 1015 | ar5523_config(ar, CFG_OVERRD_TX_POWER, 0x00000000); | ||
| 1016 | ar5523_config(ar, CFG_GMODE_PROTECTION, 0x00000000); | ||
| 1017 | ar5523_config(ar, CFG_GMODE_PROTECT_RATE_INDEX, 0x00000003); | ||
| 1018 | ar5523_config(ar, CFG_PROTECTION_TYPE, 0x00000000); | ||
| 1019 | ar5523_config(ar, CFG_MODE_CTS, 0x00000002); | ||
| 1020 | |||
| 1021 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_START, NULL, 0, | ||
| 1022 | &val, sizeof(val), AR5523_CMD_FLAG_MAGIC); | ||
| 1023 | if (error) { | ||
| 1024 | ar5523_dbg(ar, "could not start target, error %d\n", error); | ||
| 1025 | goto err; | ||
| 1026 | } | ||
| 1027 | ar5523_dbg(ar, "WDCMSG_TARGET_START returns handle: 0x%x\n", | ||
| 1028 | be32_to_cpu(val)); | ||
| 1029 | |||
| 1030 | ar5523_switch_chan(ar); | ||
| 1031 | |||
| 1032 | val = cpu_to_be32(TARGET_DEVICE_AWAKE); | ||
| 1033 | ar5523_cmd_write(ar, WDCMSG_SET_PWR_MODE, &val, sizeof(val), 0); | ||
| 1034 | /* XXX? check */ | ||
| 1035 | ar5523_cmd_write(ar, WDCMSG_RESET_KEY_CACHE, NULL, 0, 0); | ||
| 1036 | |||
| 1037 | set_bit(AR5523_HW_UP, &ar->flags); | ||
| 1038 | queue_work(ar->wq, &ar->rx_refill_work); | ||
| 1039 | |||
| 1040 | /* enable Rx */ | ||
| 1041 | ar5523_set_rxfilter(ar, 0, UATH_FILTER_OP_INIT); | ||
| 1042 | ar5523_set_rxfilter(ar, | ||
| 1043 | UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | | ||
| 1044 | UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON, | ||
| 1045 | UATH_FILTER_OP_SET); | ||
| 1046 | |||
| 1047 | ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_ON); | ||
| 1048 | ar5523_dbg(ar, "start OK\n"); | ||
| 1049 | |||
| 1050 | err: | ||
| 1051 | mutex_unlock(&ar->mutex); | ||
| 1052 | return error; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | static void ar5523_stop(struct ieee80211_hw *hw) | ||
| 1056 | { | ||
| 1057 | struct ar5523 *ar = hw->priv; | ||
| 1058 | |||
| 1059 | ar5523_dbg(ar, "stop called\n"); | ||
| 1060 | |||
| 1061 | cancel_delayed_work_sync(&ar->stat_work); | ||
| 1062 | mutex_lock(&ar->mutex); | ||
| 1063 | clear_bit(AR5523_HW_UP, &ar->flags); | ||
| 1064 | |||
| 1065 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); | ||
| 1066 | ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_OFF); | ||
| 1067 | |||
| 1068 | ar5523_cmd_write(ar, WDCMSG_TARGET_STOP, NULL, 0, 0); | ||
| 1069 | |||
| 1070 | del_timer_sync(&ar->tx_wd_timer); | ||
| 1071 | cancel_work_sync(&ar->tx_wd_work); | ||
| 1072 | cancel_work_sync(&ar->rx_refill_work); | ||
| 1073 | ar5523_cancel_rx_bufs(ar); | ||
| 1074 | mutex_unlock(&ar->mutex); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | ||
| 1078 | { | ||
| 1079 | struct ar5523 *ar = hw->priv; | ||
| 1080 | int ret; | ||
| 1081 | |||
| 1082 | ar5523_dbg(ar, "set_rts_threshold called\n"); | ||
| 1083 | mutex_lock(&ar->mutex); | ||
| 1084 | |||
| 1085 | ret = ar5523_config(ar, CFG_USER_RTS_THRESHOLD, value); | ||
| 1086 | |||
| 1087 | mutex_unlock(&ar->mutex); | ||
| 1088 | return ret; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | static void ar5523_flush(struct ieee80211_hw *hw, bool drop) | ||
| 1092 | { | ||
| 1093 | struct ar5523 *ar = hw->priv; | ||
| 1094 | |||
| 1095 | ar5523_dbg(ar, "flush called\n"); | ||
| 1096 | ar5523_flush_tx(ar); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | static int ar5523_add_interface(struct ieee80211_hw *hw, | ||
| 1100 | struct ieee80211_vif *vif) | ||
| 1101 | { | ||
| 1102 | struct ar5523 *ar = hw->priv; | ||
| 1103 | |||
| 1104 | ar5523_dbg(ar, "add interface called\n"); | ||
| 1105 | |||
| 1106 | if (ar->vif) { | ||
| 1107 | ar5523_dbg(ar, "invalid add_interface\n"); | ||
| 1108 | return -EOPNOTSUPP; | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | switch (vif->type) { | ||
| 1112 | case NL80211_IFTYPE_STATION: | ||
| 1113 | ar->vif = vif; | ||
| 1114 | break; | ||
| 1115 | default: | ||
| 1116 | return -EOPNOTSUPP; | ||
| 1117 | } | ||
| 1118 | return 0; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | static void ar5523_remove_interface(struct ieee80211_hw *hw, | ||
| 1122 | struct ieee80211_vif *vif) | ||
| 1123 | { | ||
| 1124 | struct ar5523 *ar = hw->priv; | ||
| 1125 | |||
| 1126 | ar5523_dbg(ar, "remove interface called\n"); | ||
| 1127 | ar->vif = NULL; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | static int ar5523_hwconfig(struct ieee80211_hw *hw, u32 changed) | ||
| 1131 | { | ||
| 1132 | struct ar5523 *ar = hw->priv; | ||
| 1133 | |||
| 1134 | ar5523_dbg(ar, "config called\n"); | ||
| 1135 | mutex_lock(&ar->mutex); | ||
| 1136 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
| 1137 | ar5523_dbg(ar, "Do channel switch\n"); | ||
| 1138 | ar5523_flush_tx(ar); | ||
| 1139 | ar5523_switch_chan(ar); | ||
| 1140 | } | ||
| 1141 | mutex_unlock(&ar->mutex); | ||
| 1142 | return 0; | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | static int ar5523_get_wlan_mode(struct ar5523 *ar, | ||
| 1146 | struct ieee80211_bss_conf *bss_conf) | ||
| 1147 | { | ||
| 1148 | struct ieee80211_supported_band *band; | ||
| 1149 | int bit; | ||
| 1150 | struct ieee80211_sta *sta; | ||
| 1151 | u32 sta_rate_set; | ||
| 1152 | |||
| 1153 | band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; | ||
| 1154 | sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); | ||
| 1155 | if (!sta) { | ||
| 1156 | ar5523_info(ar, "STA not found!\n"); | ||
| 1157 | return WLAN_MODE_11b; | ||
| 1158 | } | ||
| 1159 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; | ||
| 1160 | |||
| 1161 | for (bit = 0; bit < band->n_bitrates; bit++) { | ||
| 1162 | if (sta_rate_set & 1) { | ||
| 1163 | int rate = band->bitrates[bit].bitrate; | ||
| 1164 | switch (rate) { | ||
| 1165 | case 60: | ||
| 1166 | case 90: | ||
| 1167 | case 120: | ||
| 1168 | case 180: | ||
| 1169 | case 240: | ||
| 1170 | case 360: | ||
| 1171 | case 480: | ||
| 1172 | case 540: | ||
| 1173 | return WLAN_MODE_11g; | ||
| 1174 | } | ||
| 1175 | } | ||
| 1176 | sta_rate_set >>= 1; | ||
| 1177 | } | ||
| 1178 | return WLAN_MODE_11b; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | static void ar5523_create_rateset(struct ar5523 *ar, | ||
| 1182 | struct ieee80211_bss_conf *bss_conf, | ||
| 1183 | struct ar5523_cmd_rateset *rs, | ||
| 1184 | bool basic) | ||
| 1185 | { | ||
| 1186 | struct ieee80211_supported_band *band; | ||
| 1187 | struct ieee80211_sta *sta; | ||
| 1188 | int bit, i = 0; | ||
| 1189 | u32 sta_rate_set, basic_rate_set; | ||
| 1190 | |||
| 1191 | sta = ieee80211_find_sta(ar->vif, bss_conf->bssid); | ||
| 1192 | basic_rate_set = bss_conf->basic_rates; | ||
| 1193 | if (!sta) { | ||
| 1194 | ar5523_info(ar, "STA not found. Cannot set rates\n"); | ||
| 1195 | sta_rate_set = bss_conf->basic_rates; | ||
| 1196 | } | ||
| 1197 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; | ||
| 1198 | |||
| 1199 | ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); | ||
| 1200 | |||
| 1201 | band = ar->hw->wiphy->bands[ar->hw->conf.channel->band]; | ||
| 1202 | for (bit = 0; bit < band->n_bitrates; bit++) { | ||
| 1203 | BUG_ON(i >= AR5523_MAX_NRATES); | ||
| 1204 | ar5523_dbg(ar, "Considering rate %d : %d\n", | ||
| 1205 | band->bitrates[bit].hw_value, sta_rate_set & 1); | ||
| 1206 | if (sta_rate_set & 1) { | ||
| 1207 | rs->set[i] = band->bitrates[bit].hw_value; | ||
| 1208 | if (basic_rate_set & 1 && basic) | ||
| 1209 | rs->set[i] |= 0x80; | ||
| 1210 | i++; | ||
| 1211 | } | ||
| 1212 | sta_rate_set >>= 1; | ||
| 1213 | basic_rate_set >>= 1; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | rs->length = i; | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | static int ar5523_set_basic_rates(struct ar5523 *ar, | ||
| 1220 | struct ieee80211_bss_conf *bss) | ||
| 1221 | { | ||
| 1222 | struct ar5523_cmd_rates rates; | ||
| 1223 | |||
| 1224 | memset(&rates, 0, sizeof(rates)); | ||
| 1225 | rates.connid = cpu_to_be32(2); /* XXX */ | ||
| 1226 | rates.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); | ||
| 1227 | ar5523_create_rateset(ar, bss, &rates.rateset, true); | ||
| 1228 | |||
| 1229 | return ar5523_cmd_write(ar, WDCMSG_SET_BASIC_RATE, &rates, | ||
| 1230 | sizeof(rates), 0); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | static int ar5523_create_connection(struct ar5523 *ar, | ||
| 1234 | struct ieee80211_vif *vif, | ||
| 1235 | struct ieee80211_bss_conf *bss) | ||
| 1236 | { | ||
| 1237 | struct ar5523_cmd_create_connection create; | ||
| 1238 | int wlan_mode; | ||
| 1239 | |||
| 1240 | memset(&create, 0, sizeof(create)); | ||
| 1241 | create.connid = cpu_to_be32(2); | ||
| 1242 | create.bssid = cpu_to_be32(0); | ||
| 1243 | /* XXX packed or not? */ | ||
| 1244 | create.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); | ||
| 1245 | |||
| 1246 | ar5523_create_rateset(ar, bss, &create.connattr.rateset, false); | ||
| 1247 | |||
| 1248 | wlan_mode = ar5523_get_wlan_mode(ar, bss); | ||
| 1249 | create.connattr.wlanmode = cpu_to_be32(wlan_mode); | ||
| 1250 | |||
| 1251 | return ar5523_cmd_write(ar, WDCMSG_CREATE_CONNECTION, &create, | ||
| 1252 | sizeof(create), 0); | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | static int ar5523_write_associd(struct ar5523 *ar, | ||
| 1256 | struct ieee80211_bss_conf *bss) | ||
| 1257 | { | ||
| 1258 | struct ar5523_cmd_set_associd associd; | ||
| 1259 | |||
| 1260 | memset(&associd, 0, sizeof(associd)); | ||
| 1261 | associd.defaultrateix = cpu_to_be32(0); /* XXX */ | ||
| 1262 | associd.associd = cpu_to_be32(bss->aid); | ||
| 1263 | associd.timoffset = cpu_to_be32(0x3b); /* XXX */ | ||
| 1264 | memcpy(associd.bssid, bss->bssid, ETH_ALEN); | ||
| 1265 | return ar5523_cmd_write(ar, WDCMSG_WRITE_ASSOCID, &associd, | ||
| 1266 | sizeof(associd), 0); | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static void ar5523_bss_info_changed(struct ieee80211_hw *hw, | ||
| 1270 | struct ieee80211_vif *vif, | ||
| 1271 | struct ieee80211_bss_conf *bss, | ||
| 1272 | u32 changed) | ||
| 1273 | { | ||
| 1274 | struct ar5523 *ar = hw->priv; | ||
| 1275 | int error; | ||
| 1276 | |||
| 1277 | ar5523_dbg(ar, "bss_info_changed called\n"); | ||
| 1278 | mutex_lock(&ar->mutex); | ||
| 1279 | |||
| 1280 | if (!(changed & BSS_CHANGED_ASSOC)) | ||
| 1281 | goto out_unlock; | ||
| 1282 | |||
| 1283 | if (bss->assoc) { | ||
| 1284 | error = ar5523_create_connection(ar, vif, bss); | ||
| 1285 | if (error) { | ||
| 1286 | ar5523_err(ar, "could not create connection\n"); | ||
| 1287 | goto out_unlock; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | error = ar5523_set_basic_rates(ar, bss); | ||
| 1291 | if (error) { | ||
| 1292 | ar5523_err(ar, "could not set negotiated rate set\n"); | ||
| 1293 | goto out_unlock; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | error = ar5523_write_associd(ar, bss); | ||
| 1297 | if (error) { | ||
| 1298 | ar5523_err(ar, "could not set association\n"); | ||
| 1299 | goto out_unlock; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /* turn link LED on */ | ||
| 1303 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_ON); | ||
| 1304 | set_bit(AR5523_CONNECTED, &ar->flags); | ||
| 1305 | ieee80211_queue_delayed_work(hw, &ar->stat_work, HZ); | ||
| 1306 | |||
| 1307 | } else { | ||
| 1308 | cancel_delayed_work(&ar->stat_work); | ||
| 1309 | clear_bit(AR5523_CONNECTED, &ar->flags); | ||
| 1310 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | out_unlock: | ||
| 1314 | mutex_unlock(&ar->mutex); | ||
| 1315 | |||
| 1316 | } | ||
| 1317 | |||
| 1318 | #define AR5523_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ | ||
| 1319 | FIF_ALLMULTI | \ | ||
| 1320 | FIF_FCSFAIL | \ | ||
| 1321 | FIF_OTHER_BSS) | ||
| 1322 | |||
| 1323 | static void ar5523_configure_filter(struct ieee80211_hw *hw, | ||
| 1324 | unsigned int changed_flags, | ||
| 1325 | unsigned int *total_flags, | ||
| 1326 | u64 multicast) | ||
| 1327 | { | ||
| 1328 | struct ar5523 *ar = hw->priv; | ||
| 1329 | u32 filter = 0; | ||
| 1330 | |||
| 1331 | ar5523_dbg(ar, "configure_filter called\n"); | ||
| 1332 | mutex_lock(&ar->mutex); | ||
| 1333 | ar5523_flush_tx(ar); | ||
| 1334 | |||
| 1335 | *total_flags &= AR5523_SUPPORTED_FILTERS; | ||
| 1336 | |||
| 1337 | /* The filters seems strange. UATH_FILTER_RX_BCAST and | ||
| 1338 | * UATH_FILTER_RX_MCAST does not result in those frames being RXed. | ||
| 1339 | * The only way I have found to get [mb]cast frames seems to be | ||
| 1340 | * to set UATH_FILTER_RX_PROM. */ | ||
| 1341 | filter |= UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | | ||
| 1342 | UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON | | ||
| 1343 | UATH_FILTER_RX_PROM; | ||
| 1344 | |||
| 1345 | ar5523_set_rxfilter(ar, 0, UATH_FILTER_OP_INIT); | ||
| 1346 | ar5523_set_rxfilter(ar, filter, UATH_FILTER_OP_SET); | ||
| 1347 | |||
| 1348 | mutex_unlock(&ar->mutex); | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | static const struct ieee80211_ops ar5523_ops = { | ||
| 1352 | .start = ar5523_start, | ||
| 1353 | .stop = ar5523_stop, | ||
| 1354 | .tx = ar5523_tx, | ||
| 1355 | .set_rts_threshold = ar5523_set_rts_threshold, | ||
| 1356 | .add_interface = ar5523_add_interface, | ||
| 1357 | .remove_interface = ar5523_remove_interface, | ||
| 1358 | .config = ar5523_hwconfig, | ||
| 1359 | .bss_info_changed = ar5523_bss_info_changed, | ||
| 1360 | .configure_filter = ar5523_configure_filter, | ||
| 1361 | .flush = ar5523_flush, | ||
| 1362 | }; | ||
| 1363 | |||
| 1364 | static int ar5523_host_available(struct ar5523 *ar) | ||
| 1365 | { | ||
| 1366 | struct ar5523_cmd_host_available setup; | ||
| 1367 | |||
| 1368 | /* inform target the host is available */ | ||
| 1369 | setup.sw_ver_major = cpu_to_be32(ATH_SW_VER_MAJOR); | ||
| 1370 | setup.sw_ver_minor = cpu_to_be32(ATH_SW_VER_MINOR); | ||
| 1371 | setup.sw_ver_patch = cpu_to_be32(ATH_SW_VER_PATCH); | ||
| 1372 | setup.sw_ver_build = cpu_to_be32(ATH_SW_VER_BUILD); | ||
| 1373 | return ar5523_cmd_read(ar, WDCMSG_HOST_AVAILABLE, | ||
| 1374 | &setup, sizeof(setup), NULL, 0, 0); | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | static int ar5523_get_devstatus(struct ar5523 *ar) | ||
| 1378 | { | ||
| 1379 | u8 macaddr[ETH_ALEN]; | ||
| 1380 | int error; | ||
| 1381 | |||
| 1382 | /* retrieve MAC address */ | ||
| 1383 | error = ar5523_get_status(ar, ST_MAC_ADDR, macaddr, ETH_ALEN); | ||
| 1384 | if (error) { | ||
| 1385 | ar5523_err(ar, "could not read MAC address\n"); | ||
| 1386 | return error; | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | SET_IEEE80211_PERM_ADDR(ar->hw, macaddr); | ||
| 1390 | |||
| 1391 | error = ar5523_get_status(ar, ST_SERIAL_NUMBER, | ||
| 1392 | &ar->serial[0], sizeof(ar->serial)); | ||
| 1393 | if (error) { | ||
| 1394 | ar5523_err(ar, "could not read device serial number\n"); | ||
| 1395 | return error; | ||
| 1396 | } | ||
| 1397 | return 0; | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | #define AR5523_SANE_RXBUFSZ 2000 | ||
| 1401 | |||
| 1402 | static int ar5523_get_max_rxsz(struct ar5523 *ar) | ||
| 1403 | { | ||
| 1404 | int error; | ||
| 1405 | __be32 rxsize; | ||
| 1406 | |||
| 1407 | /* Get max rx size */ | ||
| 1408 | error = ar5523_get_status(ar, ST_WDC_TRANSPORT_CHUNK_SIZE, &rxsize, | ||
| 1409 | sizeof(rxsize)); | ||
| 1410 | if (error != 0) { | ||
| 1411 | ar5523_err(ar, "could not read max RX size\n"); | ||
| 1412 | return error; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | ar->rxbufsz = be32_to_cpu(rxsize); | ||
| 1416 | |||
| 1417 | if (!ar->rxbufsz || ar->rxbufsz > AR5523_SANE_RXBUFSZ) { | ||
| 1418 | ar5523_err(ar, "Bad rxbufsz from device. Using %d instead\n", | ||
| 1419 | AR5523_SANE_RXBUFSZ); | ||
| 1420 | ar->rxbufsz = AR5523_SANE_RXBUFSZ; | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | ar5523_dbg(ar, "Max RX buf size: %d\n", ar->rxbufsz); | ||
| 1424 | return 0; | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | /* | ||
| 1428 | * This is copied from rtl818x, but we should probably move this | ||
| 1429 | * to common code as in OpenBSD. | ||
| 1430 | */ | ||
| 1431 | static const struct ieee80211_rate ar5523_rates[] = { | ||
| 1432 | { .bitrate = 10, .hw_value = 2, }, | ||
| 1433 | { .bitrate = 20, .hw_value = 4 }, | ||
| 1434 | { .bitrate = 55, .hw_value = 11, }, | ||
| 1435 | { .bitrate = 110, .hw_value = 22, }, | ||
| 1436 | { .bitrate = 60, .hw_value = 12, }, | ||
| 1437 | { .bitrate = 90, .hw_value = 18, }, | ||
| 1438 | { .bitrate = 120, .hw_value = 24, }, | ||
| 1439 | { .bitrate = 180, .hw_value = 36, }, | ||
| 1440 | { .bitrate = 240, .hw_value = 48, }, | ||
| 1441 | { .bitrate = 360, .hw_value = 72, }, | ||
| 1442 | { .bitrate = 480, .hw_value = 96, }, | ||
| 1443 | { .bitrate = 540, .hw_value = 108, }, | ||
| 1444 | }; | ||
| 1445 | |||
| 1446 | static const struct ieee80211_channel ar5523_channels[] = { | ||
| 1447 | { .center_freq = 2412 }, | ||
| 1448 | { .center_freq = 2417 }, | ||
| 1449 | { .center_freq = 2422 }, | ||
| 1450 | { .center_freq = 2427 }, | ||
| 1451 | { .center_freq = 2432 }, | ||
| 1452 | { .center_freq = 2437 }, | ||
| 1453 | { .center_freq = 2442 }, | ||
| 1454 | { .center_freq = 2447 }, | ||
| 1455 | { .center_freq = 2452 }, | ||
| 1456 | { .center_freq = 2457 }, | ||
| 1457 | { .center_freq = 2462 }, | ||
| 1458 | { .center_freq = 2467 }, | ||
| 1459 | { .center_freq = 2472 }, | ||
| 1460 | { .center_freq = 2484 }, | ||
| 1461 | }; | ||
| 1462 | |||
| 1463 | static int ar5523_init_modes(struct ar5523 *ar) | ||
| 1464 | { | ||
| 1465 | BUILD_BUG_ON(sizeof(ar->channels) != sizeof(ar5523_channels)); | ||
| 1466 | BUILD_BUG_ON(sizeof(ar->rates) != sizeof(ar5523_rates)); | ||
| 1467 | |||
| 1468 | memcpy(ar->channels, ar5523_channels, sizeof(ar5523_channels)); | ||
| 1469 | memcpy(ar->rates, ar5523_rates, sizeof(ar5523_rates)); | ||
| 1470 | |||
| 1471 | ar->band.band = IEEE80211_BAND_2GHZ; | ||
| 1472 | ar->band.channels = ar->channels; | ||
| 1473 | ar->band.n_channels = ARRAY_SIZE(ar5523_channels); | ||
| 1474 | ar->band.bitrates = ar->rates; | ||
| 1475 | ar->band.n_bitrates = ARRAY_SIZE(ar5523_rates); | ||
| 1476 | ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar->band; | ||
| 1477 | return 0; | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | /* | ||
| 1481 | * Load the MIPS R4000 microcode into the device. Once the image is loaded, | ||
| 1482 | * the device will detach itself from the bus and reattach later with a new | ||
| 1483 | * product Id (a la ezusb). | ||
| 1484 | */ | ||
| 1485 | static int ar5523_load_firmware(struct usb_device *dev) | ||
| 1486 | { | ||
| 1487 | struct ar5523_fwblock *txblock, *rxblock; | ||
| 1488 | const struct firmware *fw; | ||
| 1489 | void *fwbuf; | ||
| 1490 | int len, offset; | ||
| 1491 | int foolen; /* XXX(hch): handle short transfers */ | ||
| 1492 | int error = -ENXIO; | ||
| 1493 | |||
| 1494 | if (request_firmware(&fw, AR5523_FIRMWARE_FILE, &dev->dev)) { | ||
| 1495 | dev_err(&dev->dev, "no firmware found: %s\n", | ||
| 1496 | AR5523_FIRMWARE_FILE); | ||
| 1497 | return -ENOENT; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | txblock = kmalloc(sizeof(*txblock), GFP_KERNEL); | ||
| 1501 | if (!txblock) | ||
| 1502 | goto out; | ||
| 1503 | |||
| 1504 | rxblock = kmalloc(sizeof(*rxblock), GFP_KERNEL); | ||
| 1505 | if (!rxblock) | ||
| 1506 | goto out_free_txblock; | ||
| 1507 | |||
| 1508 | fwbuf = kmalloc(AR5523_MAX_FWBLOCK_SIZE, GFP_KERNEL); | ||
| 1509 | if (!fwbuf) | ||
| 1510 | goto out_free_rxblock; | ||
| 1511 | |||
| 1512 | memset(txblock, 0, sizeof(struct ar5523_fwblock)); | ||
| 1513 | txblock->flags = cpu_to_be32(AR5523_WRITE_BLOCK); | ||
| 1514 | txblock->total = cpu_to_be32(fw->size); | ||
| 1515 | |||
| 1516 | offset = 0; | ||
| 1517 | len = fw->size; | ||
| 1518 | while (len > 0) { | ||
| 1519 | int mlen = min(len, AR5523_MAX_FWBLOCK_SIZE); | ||
| 1520 | |||
| 1521 | txblock->remain = cpu_to_be32(len - mlen); | ||
| 1522 | txblock->len = cpu_to_be32(mlen); | ||
| 1523 | |||
| 1524 | /* send firmware block meta-data */ | ||
| 1525 | error = usb_bulk_msg(dev, ar5523_cmd_tx_pipe(dev), | ||
| 1526 | txblock, sizeof(*txblock), &foolen, | ||
| 1527 | AR5523_CMD_TIMEOUT); | ||
| 1528 | if (error) { | ||
| 1529 | dev_err(&dev->dev, | ||
| 1530 | "could not send firmware block info\n"); | ||
| 1531 | goto out_free_fwbuf; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | /* send firmware block data */ | ||
| 1535 | memcpy(fwbuf, fw->data + offset, mlen); | ||
| 1536 | error = usb_bulk_msg(dev, ar5523_data_tx_pipe(dev), | ||
| 1537 | fwbuf, mlen, &foolen, | ||
| 1538 | AR5523_DATA_TIMEOUT); | ||
| 1539 | if (error) { | ||
| 1540 | dev_err(&dev->dev, | ||
| 1541 | "could not send firmware block data\n"); | ||
| 1542 | goto out_free_fwbuf; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | /* wait for ack from firmware */ | ||
| 1546 | error = usb_bulk_msg(dev, ar5523_cmd_rx_pipe(dev), | ||
| 1547 | rxblock, sizeof(*rxblock), &foolen, | ||
| 1548 | AR5523_CMD_TIMEOUT); | ||
| 1549 | if (error) { | ||
| 1550 | dev_err(&dev->dev, | ||
| 1551 | "could not read firmware answer\n"); | ||
| 1552 | goto out_free_fwbuf; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | len -= mlen; | ||
| 1556 | offset += mlen; | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | /* | ||
| 1560 | * Set the error to -ENXIO to make sure we continue probing for | ||
| 1561 | * a driver. | ||
| 1562 | */ | ||
| 1563 | error = -ENXIO; | ||
| 1564 | |||
| 1565 | out_free_fwbuf: | ||
| 1566 | kfree(fwbuf); | ||
| 1567 | out_free_rxblock: | ||
| 1568 | kfree(rxblock); | ||
| 1569 | out_free_txblock: | ||
| 1570 | kfree(txblock); | ||
| 1571 | out: | ||
| 1572 | release_firmware(fw); | ||
| 1573 | return error; | ||
| 1574 | } | ||
| 1575 | |||
| 1576 | static int ar5523_probe(struct usb_interface *intf, | ||
| 1577 | const struct usb_device_id *id) | ||
| 1578 | { | ||
| 1579 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 1580 | struct ieee80211_hw *hw; | ||
| 1581 | struct ar5523 *ar; | ||
| 1582 | int error = -ENOMEM; | ||
| 1583 | |||
| 1584 | /* | ||
| 1585 | * Load firmware if the device requires it. This will return | ||
| 1586 | * -ENXIO on success and we'll get called back afer the usb | ||
| 1587 | * id changes to indicate that the firmware is present. | ||
| 1588 | */ | ||
| 1589 | if (id->driver_info & AR5523_FLAG_PRE_FIRMWARE) | ||
| 1590 | return ar5523_load_firmware(dev); | ||
| 1591 | |||
| 1592 | |||
| 1593 | hw = ieee80211_alloc_hw(sizeof(*ar), &ar5523_ops); | ||
| 1594 | if (!hw) | ||
| 1595 | goto out; | ||
| 1596 | SET_IEEE80211_DEV(hw, &intf->dev); | ||
| 1597 | |||
| 1598 | ar = hw->priv; | ||
| 1599 | ar->hw = hw; | ||
| 1600 | ar->dev = dev; | ||
| 1601 | mutex_init(&ar->mutex); | ||
| 1602 | |||
| 1603 | INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work); | ||
| 1604 | init_timer(&ar->tx_wd_timer); | ||
| 1605 | setup_timer(&ar->tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar); | ||
| 1606 | INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work); | ||
| 1607 | INIT_WORK(&ar->tx_work, ar5523_tx_work); | ||
| 1608 | INIT_LIST_HEAD(&ar->tx_queue_pending); | ||
| 1609 | INIT_LIST_HEAD(&ar->tx_queue_submitted); | ||
| 1610 | spin_lock_init(&ar->tx_data_list_lock); | ||
| 1611 | atomic_set(&ar->tx_nr_total, 0); | ||
| 1612 | atomic_set(&ar->tx_nr_pending, 0); | ||
| 1613 | init_waitqueue_head(&ar->tx_flush_waitq); | ||
| 1614 | |||
| 1615 | atomic_set(&ar->rx_data_free_cnt, 0); | ||
| 1616 | INIT_WORK(&ar->rx_refill_work, ar5523_rx_refill_work); | ||
| 1617 | INIT_LIST_HEAD(&ar->rx_data_free); | ||
| 1618 | INIT_LIST_HEAD(&ar->rx_data_used); | ||
| 1619 | spin_lock_init(&ar->rx_data_list_lock); | ||
| 1620 | |||
| 1621 | ar->wq = create_singlethread_workqueue("ar5523"); | ||
| 1622 | if (!ar->wq) { | ||
| 1623 | ar5523_err(ar, "Could not create wq\n"); | ||
| 1624 | goto out_free_ar; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | error = ar5523_alloc_rx_bufs(ar); | ||
| 1628 | if (error) { | ||
| 1629 | ar5523_err(ar, "Could not allocate rx buffers\n"); | ||
| 1630 | goto out_free_wq; | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | error = ar5523_alloc_rx_cmd(ar); | ||
| 1634 | if (error) { | ||
| 1635 | ar5523_err(ar, "Could not allocate rx command buffers\n"); | ||
| 1636 | goto out_free_rx_bufs; | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | error = ar5523_alloc_tx_cmd(ar); | ||
| 1640 | if (error) { | ||
| 1641 | ar5523_err(ar, "Could not allocate tx command buffers\n"); | ||
| 1642 | goto out_free_rx_cmd; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | error = ar5523_submit_rx_cmd(ar); | ||
| 1646 | if (error) { | ||
| 1647 | ar5523_err(ar, "Failed to submit rx cmd\n"); | ||
| 1648 | goto out_free_tx_cmd; | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | /* | ||
| 1652 | * We're now ready to send/receive firmware commands. | ||
| 1653 | */ | ||
| 1654 | error = ar5523_host_available(ar); | ||
| 1655 | if (error) { | ||
| 1656 | ar5523_err(ar, "could not initialize adapter\n"); | ||
| 1657 | goto out_cancel_rx_cmd; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | error = ar5523_get_max_rxsz(ar); | ||
| 1661 | if (error) { | ||
| 1662 | ar5523_err(ar, "could not get caps from adapter\n"); | ||
| 1663 | goto out_cancel_rx_cmd; | ||
| 1664 | } | ||
| 1665 | |||
| 1666 | error = ar5523_get_devcap(ar); | ||
| 1667 | if (error) { | ||
| 1668 | ar5523_err(ar, "could not get caps from adapter\n"); | ||
| 1669 | goto out_cancel_rx_cmd; | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | error = ar5523_get_devstatus(ar); | ||
| 1673 | if (error != 0) { | ||
| 1674 | ar5523_err(ar, "could not get device status\n"); | ||
| 1675 | goto out_cancel_rx_cmd; | ||
| 1676 | } | ||
| 1677 | |||
| 1678 | ar5523_info(ar, "MAC/BBP AR5523, RF AR%c112\n", | ||
| 1679 | (id->driver_info & AR5523_FLAG_ABG) ? '5' : '2'); | ||
| 1680 | |||
| 1681 | ar->vif = NULL; | ||
| 1682 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
| 1683 | IEEE80211_HW_SIGNAL_DBM | | ||
| 1684 | IEEE80211_HW_HAS_RATE_CONTROL; | ||
| 1685 | hw->extra_tx_headroom = sizeof(struct ar5523_tx_desc) + | ||
| 1686 | sizeof(struct ar5523_chunk); | ||
| 1687 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
| 1688 | hw->queues = 1; | ||
| 1689 | |||
| 1690 | error = ar5523_init_modes(ar); | ||
| 1691 | if (error) | ||
| 1692 | goto out_cancel_rx_cmd; | ||
| 1693 | |||
| 1694 | usb_set_intfdata(intf, hw); | ||
| 1695 | |||
| 1696 | error = ieee80211_register_hw(hw); | ||
| 1697 | if (error) { | ||
| 1698 | ar5523_err(ar, "could not register device\n"); | ||
| 1699 | goto out_cancel_rx_cmd; | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | ar5523_info(ar, "Found and initialized AR5523 device\n"); | ||
| 1703 | return 0; | ||
| 1704 | |||
| 1705 | out_cancel_rx_cmd: | ||
| 1706 | ar5523_cancel_rx_cmd(ar); | ||
| 1707 | out_free_tx_cmd: | ||
| 1708 | ar5523_free_tx_cmd(ar); | ||
| 1709 | out_free_rx_cmd: | ||
| 1710 | ar5523_free_rx_cmd(ar); | ||
| 1711 | out_free_rx_bufs: | ||
| 1712 | ar5523_free_rx_bufs(ar); | ||
| 1713 | out_free_wq: | ||
| 1714 | destroy_workqueue(ar->wq); | ||
| 1715 | out_free_ar: | ||
| 1716 | ieee80211_free_hw(hw); | ||
| 1717 | out: | ||
| 1718 | return error; | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | static void ar5523_disconnect(struct usb_interface *intf) | ||
| 1722 | { | ||
| 1723 | struct ieee80211_hw *hw = usb_get_intfdata(intf); | ||
| 1724 | struct ar5523 *ar = hw->priv; | ||
| 1725 | |||
| 1726 | ar5523_dbg(ar, "detaching\n"); | ||
| 1727 | set_bit(AR5523_USB_DISCONNECTED, &ar->flags); | ||
| 1728 | |||
| 1729 | ieee80211_unregister_hw(hw); | ||
| 1730 | |||
| 1731 | ar5523_cancel_rx_cmd(ar); | ||
| 1732 | ar5523_free_tx_cmd(ar); | ||
| 1733 | ar5523_free_rx_cmd(ar); | ||
| 1734 | ar5523_free_rx_bufs(ar); | ||
| 1735 | |||
| 1736 | destroy_workqueue(ar->wq); | ||
| 1737 | |||
| 1738 | ieee80211_free_hw(hw); | ||
| 1739 | usb_set_intfdata(intf, NULL); | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | #define AR5523_DEVICE_UG(vendor, device) \ | ||
| 1743 | { USB_DEVICE((vendor), (device)) }, \ | ||
| 1744 | { USB_DEVICE((vendor), (device) + 1), \ | ||
| 1745 | .driver_info = AR5523_FLAG_PRE_FIRMWARE } | ||
| 1746 | #define AR5523_DEVICE_UX(vendor, device) \ | ||
| 1747 | { USB_DEVICE((vendor), (device)), \ | ||
| 1748 | .driver_info = AR5523_FLAG_ABG }, \ | ||
| 1749 | { USB_DEVICE((vendor), (device) + 1), \ | ||
| 1750 | .driver_info = AR5523_FLAG_ABG|AR5523_FLAG_PRE_FIRMWARE } | ||
| 1751 | |||
| 1752 | static struct usb_device_id ar5523_id_table[] = { | ||
| 1753 | AR5523_DEVICE_UG(0x168c, 0x0001), /* Atheros / AR5523 */ | ||
| 1754 | AR5523_DEVICE_UG(0x0cf3, 0x0001), /* Atheros2 / AR5523_1 */ | ||
| 1755 | AR5523_DEVICE_UG(0x0cf3, 0x0003), /* Atheros2 / AR5523_2 */ | ||
| 1756 | AR5523_DEVICE_UX(0x0cf3, 0x0005), /* Atheros2 / AR5523_3 */ | ||
| 1757 | AR5523_DEVICE_UG(0x0d8e, 0x7801), /* Conceptronic / AR5523_1 */ | ||
| 1758 | AR5523_DEVICE_UX(0x0d8e, 0x7811), /* Conceptronic / AR5523_2 */ | ||
| 1759 | AR5523_DEVICE_UX(0x2001, 0x3a00), /* Dlink / DWLAG132 */ | ||
| 1760 | AR5523_DEVICE_UG(0x2001, 0x3a02), /* Dlink / DWLG132 */ | ||
| 1761 | AR5523_DEVICE_UX(0x2001, 0x3a04), /* Dlink / DWLAG122 */ | ||
| 1762 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ | ||
| 1763 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ | ||
| 1764 | AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 | ||
| 1765 | (CyberTAN Technology) */ | ||
| 1766 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ | ||
| 1767 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ | ||
| 1768 | AR5523_DEVICE_UG(0x0d8e, 0x7802), /* Globalsun / AR5523_3 */ | ||
| 1769 | AR5523_DEVICE_UX(0x0846, 0x4300), /* Netgear / WG111U */ | ||
| 1770 | AR5523_DEVICE_UG(0x0846, 0x4250), /* Netgear / WG111T */ | ||
| 1771 | AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */ | ||
| 1772 | AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1 */ | ||
| 1773 | AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */ | ||
| 1774 | AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / TEW444UBEU */ | ||
| 1775 | AR5523_DEVICE_UG(0x1435, 0x0826), /* Wistronneweb / AR5523_1 */ | ||
| 1776 | AR5523_DEVICE_UX(0x1435, 0x0828), /* Wistronneweb / AR5523_2 */ | ||
| 1777 | AR5523_DEVICE_UG(0x0cde, 0x0012), /* Zcom / AR5523 */ | ||
| 1778 | AR5523_DEVICE_UG(0x1385, 0x4250), /* Netgear3 / WG111T (2) */ | ||
| 1779 | AR5523_DEVICE_UG(0x1385, 0x5f00), /* Netgear / WPN111 */ | ||
| 1780 | AR5523_DEVICE_UG(0x1385, 0x5f02), /* Netgear / WPN111 */ | ||
| 1781 | { } | ||
| 1782 | }; | ||
| 1783 | MODULE_DEVICE_TABLE(usb, ar5523_id_table); | ||
| 1784 | |||
| 1785 | static struct usb_driver ar5523_driver = { | ||
| 1786 | .name = "ar5523", | ||
| 1787 | .id_table = ar5523_id_table, | ||
| 1788 | .probe = ar5523_probe, | ||
| 1789 | .disconnect = ar5523_disconnect, | ||
| 1790 | }; | ||
| 1791 | |||
| 1792 | static int __init ar5523_init(void) | ||
| 1793 | { | ||
| 1794 | return usb_register(&ar5523_driver); | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | static void __exit ar5523_exit(void) | ||
| 1798 | { | ||
| 1799 | usb_deregister(&ar5523_driver); | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | MODULE_LICENSE("Dual BSD/GPL"); | ||
| 1803 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); | ||
| 1804 | |||
| 1805 | module_init(ar5523_init); | ||
| 1806 | module_exit(ar5523_exit); | ||
| @@ -0,0 +1,152 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr> | ||
| 3 | * Copyright (c) 2006 Sam Leffler, Errno Consulting | ||
| 4 | * Copyright (c) 2007 Christoph Hellwig <hch@lst.de> | ||
| 5 | * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> | ||
| 6 | * Copyright (c) 2012 Pontus Fuchs <pontus.fuchs@gmail.com> | ||
| 7 | * | ||
| 8 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 9 | * purpose with or without fee is hereby granted, provided that the above | ||
| 10 | * copyright notice and this permission notice appear in all copies. | ||
| 11 | * | ||
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #define AR5523_FLAG_PRE_FIRMWARE (1 << 0) | ||
| 22 | #define AR5523_FLAG_ABG (1 << 1) | ||
| 23 | |||
| 24 | #define AR5523_FIRMWARE_FILE "ar5523.bin" | ||
| 25 | |||
| 26 | #define AR5523_CMD_TX_PIPE 0x01 | ||
| 27 | #define AR5523_DATA_TX_PIPE 0x02 | ||
| 28 | #define AR5523_CMD_RX_PIPE 0x81 | ||
| 29 | #define AR5523_DATA_RX_PIPE 0x82 | ||
| 30 | |||
| 31 | #define ar5523_cmd_tx_pipe(dev) \ | ||
| 32 | usb_sndbulkpipe((dev), AR5523_CMD_TX_PIPE) | ||
| 33 | #define ar5523_data_tx_pipe(dev) \ | ||
| 34 | usb_sndbulkpipe((dev), AR5523_DATA_TX_PIPE) | ||
| 35 | #define ar5523_cmd_rx_pipe(dev) \ | ||
| 36 | usb_rcvbulkpipe((dev), AR5523_CMD_RX_PIPE) | ||
| 37 | #define ar5523_data_rx_pipe(dev) \ | ||
| 38 | usb_rcvbulkpipe((dev), AR5523_DATA_RX_PIPE) | ||
| 39 | |||
| 40 | #define AR5523_DATA_TIMEOUT 10000 | ||
| 41 | #define AR5523_CMD_TIMEOUT 1000 | ||
| 42 | |||
| 43 | #define AR5523_TX_DATA_COUNT 8 | ||
| 44 | #define AR5523_TX_DATA_RESTART_COUNT 2 | ||
| 45 | #define AR5523_RX_DATA_COUNT 16 | ||
| 46 | #define AR5523_RX_DATA_REFILL_COUNT 8 | ||
| 47 | |||
| 48 | #define AR5523_CMD_ID 1 | ||
| 49 | #define AR5523_DATA_ID 2 | ||
| 50 | |||
| 51 | #define AR5523_TX_WD_TIMEOUT (HZ * 2) | ||
| 52 | #define AR5523_FLUSH_TIMEOUT (HZ * 3) | ||
| 53 | |||
| 54 | enum AR5523_flags { | ||
| 55 | AR5523_HW_UP, | ||
| 56 | AR5523_USB_DISCONNECTED, | ||
| 57 | AR5523_CONNECTED | ||
| 58 | }; | ||
| 59 | |||
| 60 | struct ar5523_tx_cmd { | ||
| 61 | struct ar5523 *ar; | ||
| 62 | struct urb *urb_tx; | ||
| 63 | void *buf_tx; | ||
| 64 | void *odata; | ||
| 65 | int olen; | ||
| 66 | int flags; | ||
| 67 | int res; | ||
| 68 | struct completion done; | ||
| 69 | }; | ||
| 70 | |||
| 71 | /* This struct is placed in tx_info->driver_data. It must not be larger | ||
| 72 | * than IEEE80211_TX_INFO_DRIVER_DATA_SIZE. | ||
| 73 | */ | ||
| 74 | struct ar5523_tx_data { | ||
| 75 | struct list_head list; | ||
| 76 | struct ar5523 *ar; | ||
| 77 | struct sk_buff *skb; | ||
| 78 | struct urb *urb; | ||
| 79 | }; | ||
| 80 | |||
| 81 | struct ar5523_rx_data { | ||
| 82 | struct list_head list; | ||
| 83 | struct ar5523 *ar; | ||
| 84 | struct urb *urb; | ||
| 85 | struct sk_buff *skb; | ||
| 86 | }; | ||
| 87 | |||
| 88 | struct ar5523 { | ||
| 89 | struct usb_device *dev; | ||
| 90 | struct ieee80211_hw *hw; | ||
| 91 | |||
| 92 | unsigned long flags; | ||
| 93 | struct mutex mutex; | ||
| 94 | struct workqueue_struct *wq; | ||
| 95 | |||
| 96 | struct ar5523_tx_cmd tx_cmd; | ||
| 97 | |||
| 98 | struct delayed_work stat_work; | ||
| 99 | |||
| 100 | struct timer_list tx_wd_timer; | ||
| 101 | struct work_struct tx_wd_work; | ||
| 102 | struct work_struct tx_work; | ||
| 103 | struct list_head tx_queue_pending; | ||
| 104 | struct list_head tx_queue_submitted; | ||
| 105 | spinlock_t tx_data_list_lock; | ||
| 106 | wait_queue_head_t tx_flush_waitq; | ||
| 107 | |||
| 108 | /* Queued + Submitted TX frames */ | ||
| 109 | atomic_t tx_nr_total; | ||
| 110 | |||
| 111 | /* Submitted TX frames */ | ||
| 112 | atomic_t tx_nr_pending; | ||
| 113 | |||
| 114 | void *rx_cmd_buf; | ||
| 115 | struct urb *rx_cmd_urb; | ||
| 116 | |||
| 117 | struct ar5523_rx_data rx_data[AR5523_RX_DATA_COUNT]; | ||
| 118 | spinlock_t rx_data_list_lock; | ||
| 119 | struct list_head rx_data_free; | ||
| 120 | struct list_head rx_data_used; | ||
| 121 | atomic_t rx_data_free_cnt; | ||
| 122 | |||
| 123 | struct work_struct rx_refill_work; | ||
| 124 | |||
| 125 | unsigned int rxbufsz; | ||
| 126 | u8 serial[16]; | ||
| 127 | |||
| 128 | struct ieee80211_channel channels[14]; | ||
| 129 | struct ieee80211_rate rates[12]; | ||
| 130 | struct ieee80211_supported_band band; | ||
| 131 | struct ieee80211_vif *vif; | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* flags for sending firmware commands */ | ||
| 135 | #define AR5523_CMD_FLAG_READ (1 << 1) | ||
| 136 | #define AR5523_CMD_FLAG_MAGIC (1 << 2) | ||
| 137 | |||
| 138 | #define ar5523_dbg(ar, format, arg...) \ | ||
| 139 | dev_dbg(&(ar)->dev->dev, format, ## arg) | ||
| 140 | |||
| 141 | /* On USB hot-unplug there can be a lot of URBs in flight and they'll all | ||
| 142 | * fail. Instead of dealing with them in every possible place just surpress | ||
| 143 | * any messages on USB disconnect. | ||
| 144 | */ | ||
| 145 | #define ar5523_err(ar, format, arg...) \ | ||
| 146 | do { \ | ||
| 147 | if (!test_bit(AR5523_USB_DISCONNECTED, &ar->flags)) { \ | ||
| 148 | dev_err(&(ar)->dev->dev, format, ## arg); \ | ||
| 149 | } \ | ||
| 150 | } while (0) | ||
| 151 | #define ar5523_info(ar, format, arg...) \ | ||
| 152 | dev_info(&(ar)->dev->dev, format, ## arg) | ||
| @@ -0,0 +1,431 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr> | ||
| 3 | * Copyright (c) 2006 Sam Leffler, Errno Consulting | ||
| 4 | * Copyright (c) 2007 Christoph Hellwig <hch@lst.de> | ||
| 5 | * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> | ||
| 6 | * Copyright (c) 2012 Pontus Fuchs <pontus.fuchs@gmail.com> | ||
| 7 | * | ||
| 8 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 9 | * purpose with or without fee is hereby granted, provided that the above | ||
| 10 | * copyright notice and this permission notice appear in all copies. | ||
| 11 | * | ||
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* all fields are big endian */ | ||
| 22 | struct ar5523_fwblock { | ||
| 23 | __be32 flags; | ||
| 24 | #define AR5523_WRITE_BLOCK (1 << 4) | ||
| 25 | |||
| 26 | __be32 len; | ||
| 27 | #define AR5523_MAX_FWBLOCK_SIZE 2048 | ||
| 28 | |||
| 29 | __be32 total; | ||
| 30 | __be32 remain; | ||
| 31 | __be32 rxtotal; | ||
| 32 | __be32 pad[123]; | ||
| 33 | } __packed; | ||
| 34 | |||
| 35 | #define AR5523_MAX_RXCMDSZ 1024 | ||
| 36 | #define AR5523_MAX_TXCMDSZ 1024 | ||
| 37 | |||
| 38 | struct ar5523_cmd_hdr { | ||
| 39 | __be32 len; | ||
| 40 | __be32 code; | ||
| 41 | /* NB: these are defined for rev 1.5 firmware; rev 1.6 is different */ | ||
| 42 | /* messages from Host -> Target */ | ||
| 43 | #define WDCMSG_HOST_AVAILABLE 0x01 | ||
| 44 | #define WDCMSG_BIND 0x02 | ||
| 45 | #define WDCMSG_TARGET_RESET 0x03 | ||
| 46 | #define WDCMSG_TARGET_GET_CAPABILITY 0x04 | ||
| 47 | #define WDCMSG_TARGET_SET_CONFIG 0x05 | ||
| 48 | #define WDCMSG_TARGET_GET_STATUS 0x06 | ||
| 49 | #define WDCMSG_TARGET_GET_STATS 0x07 | ||
| 50 | #define WDCMSG_TARGET_START 0x08 | ||
| 51 | #define WDCMSG_TARGET_STOP 0x09 | ||
| 52 | #define WDCMSG_TARGET_ENABLE 0x0a | ||
| 53 | #define WDCMSG_TARGET_DISABLE 0x0b | ||
| 54 | #define WDCMSG_CREATE_CONNECTION 0x0c | ||
| 55 | #define WDCMSG_UPDATE_CONNECT_ATTR 0x0d | ||
| 56 | #define WDCMSG_DELETE_CONNECT 0x0e | ||
| 57 | #define WDCMSG_SEND 0x0f | ||
| 58 | #define WDCMSG_FLUSH 0x10 | ||
| 59 | /* messages from Target -> Host */ | ||
| 60 | #define WDCMSG_STATS_UPDATE 0x11 | ||
| 61 | #define WDCMSG_BMISS 0x12 | ||
| 62 | #define WDCMSG_DEVICE_AVAIL 0x13 | ||
| 63 | #define WDCMSG_SEND_COMPLETE 0x14 | ||
| 64 | #define WDCMSG_DATA_AVAIL 0x15 | ||
| 65 | #define WDCMSG_SET_PWR_MODE 0x16 | ||
| 66 | #define WDCMSG_BMISS_ACK 0x17 | ||
| 67 | #define WDCMSG_SET_LED_STEADY 0x18 | ||
| 68 | #define WDCMSG_SET_LED_BLINK 0x19 | ||
| 69 | /* more messages */ | ||
| 70 | #define WDCMSG_SETUP_BEACON_DESC 0x1a | ||
| 71 | #define WDCMSG_BEACON_INIT 0x1b | ||
| 72 | #define WDCMSG_RESET_KEY_CACHE 0x1c | ||
| 73 | #define WDCMSG_RESET_KEY_CACHE_ENTRY 0x1d | ||
| 74 | #define WDCMSG_SET_KEY_CACHE_ENTRY 0x1e | ||
| 75 | #define WDCMSG_SET_DECOMP_MASK 0x1f | ||
| 76 | #define WDCMSG_SET_REGULATORY_DOMAIN 0x20 | ||
| 77 | #define WDCMSG_SET_LED_STATE 0x21 | ||
| 78 | #define WDCMSG_WRITE_ASSOCID 0x22 | ||
| 79 | #define WDCMSG_SET_STA_BEACON_TIMERS 0x23 | ||
| 80 | #define WDCMSG_GET_TSF 0x24 | ||
| 81 | #define WDCMSG_RESET_TSF 0x25 | ||
| 82 | #define WDCMSG_SET_ADHOC_MODE 0x26 | ||
| 83 | #define WDCMSG_SET_BASIC_RATE 0x27 | ||
| 84 | #define WDCMSG_MIB_CONTROL 0x28 | ||
| 85 | #define WDCMSG_GET_CHANNEL_DATA 0x29 | ||
| 86 | #define WDCMSG_GET_CUR_RSSI 0x2a | ||
| 87 | #define WDCMSG_SET_ANTENNA_SWITCH 0x2b | ||
| 88 | #define WDCMSG_USE_SHORT_SLOT_TIME 0x2f | ||
| 89 | #define WDCMSG_SET_POWER_MODE 0x30 | ||
| 90 | #define WDCMSG_SETUP_PSPOLL_DESC 0x31 | ||
| 91 | #define WDCMSG_SET_RX_MULTICAST_FILTER 0x32 | ||
| 92 | #define WDCMSG_RX_FILTER 0x33 | ||
| 93 | #define WDCMSG_PER_CALIBRATION 0x34 | ||
| 94 | #define WDCMSG_RESET 0x35 | ||
| 95 | #define WDCMSG_DISABLE 0x36 | ||
| 96 | #define WDCMSG_PHY_DISABLE 0x37 | ||
| 97 | #define WDCMSG_SET_TX_POWER_LIMIT 0x38 | ||
| 98 | #define WDCMSG_SET_TX_QUEUE_PARAMS 0x39 | ||
| 99 | #define WDCMSG_SETUP_TX_QUEUE 0x3a | ||
| 100 | #define WDCMSG_RELEASE_TX_QUEUE 0x3b | ||
| 101 | #define WDCMSG_SET_DEFAULT_KEY 0x43 | ||
| 102 | |||
| 103 | __u32 priv; /* driver private data, | ||
| 104 | don't care about endianess */ | ||
| 105 | __be32 magic; | ||
| 106 | __be32 reserved2[4]; | ||
| 107 | }; | ||
| 108 | |||
| 109 | struct ar5523_cmd_host_available { | ||
| 110 | __be32 sw_ver_major; | ||
| 111 | __be32 sw_ver_minor; | ||
| 112 | __be32 sw_ver_patch; | ||
| 113 | __be32 sw_ver_build; | ||
| 114 | } __packed; | ||
| 115 | |||
| 116 | #define ATH_SW_VER_MAJOR 1 | ||
| 117 | #define ATH_SW_VER_MINOR 5 | ||
| 118 | #define ATH_SW_VER_PATCH 0 | ||
| 119 | #define ATH_SW_VER_BUILD 9999 | ||
| 120 | |||
| 121 | struct ar5523_chunk { | ||
| 122 | u8 seqnum; /* sequence number for ordering */ | ||
| 123 | u8 flags; | ||
| 124 | #define UATH_CFLAGS_FINAL 0x01 /* final chunk of a msg */ | ||
| 125 | #define UATH_CFLAGS_RXMSG 0x02 /* chunk contains rx completion */ | ||
| 126 | #define UATH_CFLAGS_DEBUG 0x04 /* for debugging */ | ||
| 127 | __be16 length; /* chunk size in bytes */ | ||
| 128 | /* chunk data follows */ | ||
| 129 | } __packed; | ||
| 130 | |||
| 131 | /* | ||
| 132 | * Message format for a WDCMSG_DATA_AVAIL message from Target to Host. | ||
| 133 | */ | ||
| 134 | struct ar5523_rx_desc { | ||
| 135 | __be32 len; /* msg length including header */ | ||
| 136 | __be32 code; /* WDCMSG_DATA_AVAIL */ | ||
| 137 | __be32 gennum; /* generation number */ | ||
| 138 | __be32 status; /* start of RECEIVE_INFO */ | ||
| 139 | #define UATH_STATUS_OK 0 | ||
| 140 | #define UATH_STATUS_STOP_IN_PROGRESS 1 | ||
| 141 | #define UATH_STATUS_CRC_ERR 2 | ||
| 142 | #define UATH_STATUS_PHY_ERR 3 | ||
| 143 | #define UATH_STATUS_DECRYPT_CRC_ERR 4 | ||
| 144 | #define UATH_STATUS_DECRYPT_MIC_ERR 5 | ||
| 145 | #define UATH_STATUS_DECOMP_ERR 6 | ||
| 146 | #define UATH_STATUS_KEY_ERR 7 | ||
| 147 | #define UATH_STATUS_ERR 8 | ||
| 148 | __be32 tstamp_low; /* low-order 32-bits of rx timestamp */ | ||
| 149 | __be32 tstamp_high; /* high-order 32-bits of rx timestamp */ | ||
| 150 | __be32 framelen; /* frame length */ | ||
| 151 | __be32 rate; /* rx rate code */ | ||
| 152 | __be32 antenna; | ||
| 153 | __be32 rssi; | ||
| 154 | __be32 channel; | ||
| 155 | __be32 phyerror; | ||
| 156 | __be32 connix; /* key table ix for bss traffic */ | ||
| 157 | __be32 decrypterror; | ||
| 158 | __be32 keycachemiss; | ||
| 159 | __be32 pad; /* XXX? */ | ||
| 160 | } __packed; | ||
| 161 | |||
| 162 | struct ar5523_tx_desc { | ||
| 163 | __be32 msglen; | ||
| 164 | __be32 msgid; /* msg id (supplied by host) */ | ||
| 165 | __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ | ||
| 166 | __be32 txqid; /* tx queue id and flags */ | ||
| 167 | #define UATH_TXQID_MASK 0x0f | ||
| 168 | #define UATH_TXQID_MINRATE 0x10 /* use min tx rate */ | ||
| 169 | #define UATH_TXQID_FF 0x20 /* content is fast frame */ | ||
| 170 | __be32 connid; /* tx connection id */ | ||
| 171 | #define UATH_ID_INVALID 0xffffffff /* for sending prior to connection */ | ||
| 172 | __be32 flags; /* non-zero if response desired */ | ||
| 173 | #define UATH_TX_NOTIFY (1 << 24) /* f/w will send a UATH_NOTIF_TX */ | ||
| 174 | __be32 buflen; /* payload length */ | ||
| 175 | } __packed; | ||
| 176 | |||
| 177 | |||
| 178 | #define AR5523_ID_BSS 2 | ||
| 179 | #define AR5523_ID_BROADCAST 0xffffffff | ||
| 180 | |||
| 181 | /* structure for command UATH_CMD_WRITE_MAC */ | ||
| 182 | struct ar5523_write_mac { | ||
| 183 | __be32 reg; | ||
| 184 | __be32 len; | ||
| 185 | u8 data[32]; | ||
| 186 | } __packed; | ||
| 187 | |||
| 188 | struct ar5523_cmd_rateset { | ||
| 189 | __u8 length; | ||
| 190 | #define AR5523_MAX_NRATES 32 | ||
| 191 | __u8 set[AR5523_MAX_NRATES]; | ||
| 192 | }; | ||
| 193 | |||
| 194 | struct ar5523_cmd_set_associd { /* AR5523_WRITE_ASSOCID */ | ||
| 195 | __be32 defaultrateix; | ||
| 196 | __be32 associd; | ||
| 197 | __be32 timoffset; | ||
| 198 | __be32 turboprime; | ||
| 199 | __u8 bssid[6]; | ||
| 200 | } __packed; | ||
| 201 | |||
| 202 | /* structure for command WDCMSG_RESET */ | ||
| 203 | struct ar5523_cmd_reset { | ||
| 204 | __be32 flags; /* channel flags */ | ||
| 205 | #define UATH_CHAN_TURBO 0x0100 | ||
| 206 | #define UATH_CHAN_CCK 0x0200 | ||
| 207 | #define UATH_CHAN_OFDM 0x0400 | ||
| 208 | #define UATH_CHAN_2GHZ 0x1000 | ||
| 209 | #define UATH_CHAN_5GHZ 0x2000 | ||
| 210 | __be32 freq; /* channel frequency */ | ||
| 211 | __be32 maxrdpower; | ||
| 212 | __be32 cfgctl; | ||
| 213 | __be32 twiceantennareduction; | ||
| 214 | __be32 channelchange; | ||
| 215 | __be32 keeprccontent; | ||
| 216 | } __packed; | ||
| 217 | |||
| 218 | /* structure for command WDCMSG_SET_BASIC_RATE */ | ||
| 219 | struct ar5523_cmd_rates { | ||
| 220 | __be32 connid; | ||
| 221 | __be32 keeprccontent; | ||
| 222 | __be32 size; | ||
| 223 | struct ar5523_cmd_rateset rateset; | ||
| 224 | } __packed; | ||
| 225 | |||
| 226 | enum { | ||
| 227 | WLAN_MODE_NONE = 0, | ||
| 228 | WLAN_MODE_11b, | ||
| 229 | WLAN_MODE_11a, | ||
| 230 | WLAN_MODE_11g, | ||
| 231 | WLAN_MODE_11a_TURBO, | ||
| 232 | WLAN_MODE_11g_TURBO, | ||
| 233 | WLAN_MODE_11a_TURBO_PRIME, | ||
| 234 | WLAN_MODE_11g_TURBO_PRIME, | ||
| 235 | WLAN_MODE_11a_XR, | ||
| 236 | WLAN_MODE_11g_XR, | ||
| 237 | }; | ||
| 238 | |||
| 239 | struct ar5523_cmd_connection_attr { | ||
| 240 | __be32 longpreambleonly; | ||
| 241 | struct ar5523_cmd_rateset rateset; | ||
| 242 | __be32 wlanmode; | ||
| 243 | } __packed; | ||
| 244 | |||
| 245 | /* structure for command AR5523_CREATE_CONNECTION */ | ||
| 246 | struct ar5523_cmd_create_connection { | ||
| 247 | __be32 connid; | ||
| 248 | __be32 bssid; | ||
| 249 | __be32 size; | ||
| 250 | struct ar5523_cmd_connection_attr connattr; | ||
| 251 | } __packed; | ||
| 252 | |||
| 253 | struct ar5523_cmd_ledsteady { /* WDCMSG_SET_LED_STEADY */ | ||
| 254 | __be32 lednum; | ||
| 255 | #define UATH_LED_LINK 0 | ||
| 256 | #define UATH_LED_ACTIVITY 1 | ||
| 257 | __be32 ledmode; | ||
| 258 | #define UATH_LED_OFF 0 | ||
| 259 | #define UATH_LED_ON 1 | ||
| 260 | } __packed; | ||
| 261 | |||
| 262 | struct ar5523_cmd_ledblink { /* WDCMSG_SET_LED_BLINK */ | ||
| 263 | __be32 lednum; | ||
| 264 | __be32 ledmode; | ||
| 265 | __be32 blinkrate; | ||
| 266 | __be32 slowmode; | ||
| 267 | } __packed; | ||
| 268 | |||
| 269 | struct ar5523_cmd_ledstate { /* WDCMSG_SET_LED_STATE */ | ||
| 270 | __be32 connected; | ||
| 271 | } __packed; | ||
| 272 | |||
| 273 | struct ar5523_cmd_txq_attr { | ||
| 274 | __be32 priority; | ||
| 275 | __be32 aifs; | ||
| 276 | __be32 logcwmin; | ||
| 277 | __be32 logcwmax; | ||
| 278 | __be32 bursttime; | ||
| 279 | __be32 mode; | ||
| 280 | __be32 qflags; | ||
| 281 | } __packed; | ||
| 282 | |||
| 283 | struct ar5523_cmd_txq_setup { /* WDCMSG_SETUP_TX_QUEUE */ | ||
| 284 | __be32 qid; | ||
| 285 | __be32 len; | ||
| 286 | struct ar5523_cmd_txq_attr attr; | ||
| 287 | } __packed; | ||
| 288 | |||
| 289 | struct ar5523_cmd_rx_filter { /* WDCMSG_RX_FILTER */ | ||
| 290 | __be32 bits; | ||
| 291 | #define UATH_FILTER_RX_UCAST 0x00000001 | ||
| 292 | #define UATH_FILTER_RX_MCAST 0x00000002 | ||
| 293 | #define UATH_FILTER_RX_BCAST 0x00000004 | ||
| 294 | #define UATH_FILTER_RX_CONTROL 0x00000008 | ||
| 295 | #define UATH_FILTER_RX_BEACON 0x00000010 /* beacon frames */ | ||
| 296 | #define UATH_FILTER_RX_PROM 0x00000020 /* promiscuous mode */ | ||
| 297 | #define UATH_FILTER_RX_PHY_ERR 0x00000040 /* phy errors */ | ||
| 298 | #define UATH_FILTER_RX_PHY_RADAR 0x00000080 /* radar phy errors */ | ||
| 299 | #define UATH_FILTER_RX_XR_POOL 0x00000400 /* XR group polls */ | ||
| 300 | #define UATH_FILTER_RX_PROBE_REQ 0x00000800 | ||
| 301 | __be32 op; | ||
| 302 | #define UATH_FILTER_OP_INIT 0x0 | ||
| 303 | #define UATH_FILTER_OP_SET 0x1 | ||
| 304 | #define UATH_FILTER_OP_CLEAR 0x2 | ||
| 305 | #define UATH_FILTER_OP_TEMP 0x3 | ||
| 306 | #define UATH_FILTER_OP_RESTORE 0x4 | ||
| 307 | } __packed; | ||
| 308 | |||
| 309 | enum { | ||
| 310 | CFG_NONE, /* Sentinal to indicate "no config" */ | ||
| 311 | CFG_REG_DOMAIN, /* Regulatory Domain */ | ||
| 312 | CFG_RATE_CONTROL_ENABLE, | ||
| 313 | CFG_DEF_XMIT_DATA_RATE, /* NB: if rate control is not enabled */ | ||
| 314 | CFG_HW_TX_RETRIES, | ||
| 315 | CFG_SW_TX_RETRIES, | ||
| 316 | CFG_SLOW_CLOCK_ENABLE, | ||
| 317 | CFG_COMP_PROC, | ||
| 318 | CFG_USER_RTS_THRESHOLD, | ||
| 319 | CFG_XR2NORM_RATE_THRESHOLD, | ||
| 320 | CFG_XRMODE_SWITCH_COUNT, | ||
| 321 | CFG_PROTECTION_TYPE, | ||
| 322 | CFG_BURST_SEQ_THRESHOLD, | ||
| 323 | CFG_ABOLT, | ||
| 324 | CFG_IQ_LOG_COUNT_MAX, | ||
| 325 | CFG_MODE_CTS, | ||
| 326 | CFG_WME_ENABLED, | ||
| 327 | CFG_GPRS_CBR_PERIOD, | ||
| 328 | CFG_SERVICE_TYPE, | ||
| 329 | /* MAC Address to use. Overrides EEPROM */ | ||
| 330 | CFG_MAC_ADDR, | ||
| 331 | CFG_DEBUG_EAR, | ||
| 332 | CFG_INIT_REGS, | ||
| 333 | /* An ID for use in error & debug messages */ | ||
| 334 | CFG_DEBUG_ID, | ||
| 335 | CFG_COMP_WIN_SZ, | ||
| 336 | CFG_DIVERSITY_CTL, | ||
| 337 | CFG_TP_SCALE, | ||
| 338 | CFG_TPC_HALF_DBM5, | ||
| 339 | CFG_TPC_HALF_DBM2, | ||
| 340 | CFG_OVERRD_TX_POWER, | ||
| 341 | CFG_USE_32KHZ_CLOCK, | ||
| 342 | CFG_GMODE_PROTECTION, | ||
| 343 | CFG_GMODE_PROTECT_RATE_INDEX, | ||
| 344 | CFG_GMODE_NON_ERP_PREAMBLE, | ||
| 345 | CFG_WDC_TRANSPORT_CHUNK_SIZE, | ||
| 346 | }; | ||
| 347 | |||
| 348 | enum { | ||
| 349 | /* Sentinal to indicate "no capability" */ | ||
| 350 | CAP_NONE, | ||
| 351 | CAP_ALL, /* ALL capabilities */ | ||
| 352 | CAP_TARGET_VERSION, | ||
| 353 | CAP_TARGET_REVISION, | ||
| 354 | CAP_MAC_VERSION, | ||
| 355 | CAP_MAC_REVISION, | ||
| 356 | CAP_PHY_REVISION, | ||
| 357 | CAP_ANALOG_5GHz_REVISION, | ||
| 358 | CAP_ANALOG_2GHz_REVISION, | ||
| 359 | /* Target supports WDC message debug features */ | ||
| 360 | CAP_DEBUG_WDCMSG_SUPPORT, | ||
| 361 | |||
| 362 | CAP_REG_DOMAIN, | ||
| 363 | CAP_COUNTRY_CODE, | ||
| 364 | CAP_REG_CAP_BITS, | ||
| 365 | |||
| 366 | CAP_WIRELESS_MODES, | ||
| 367 | CAP_CHAN_SPREAD_SUPPORT, | ||
| 368 | CAP_SLEEP_AFTER_BEACON_BROKEN, | ||
| 369 | CAP_COMPRESS_SUPPORT, | ||
| 370 | CAP_BURST_SUPPORT, | ||
| 371 | CAP_FAST_FRAMES_SUPPORT, | ||
| 372 | CAP_CHAP_TUNING_SUPPORT, | ||
| 373 | CAP_TURBOG_SUPPORT, | ||
| 374 | CAP_TURBO_PRIME_SUPPORT, | ||
| 375 | CAP_DEVICE_TYPE, | ||
| 376 | CAP_XR_SUPPORT, | ||
| 377 | CAP_WME_SUPPORT, | ||
| 378 | CAP_TOTAL_QUEUES, | ||
| 379 | CAP_CONNECTION_ID_MAX, /* Should absorb CAP_KEY_CACHE_SIZE */ | ||
| 380 | |||
| 381 | CAP_LOW_5GHZ_CHAN, | ||
| 382 | CAP_HIGH_5GHZ_CHAN, | ||
| 383 | CAP_LOW_2GHZ_CHAN, | ||
| 384 | CAP_HIGH_2GHZ_CHAN, | ||
| 385 | |||
| 386 | CAP_MIC_AES_CCM, | ||
| 387 | CAP_MIC_CKIP, | ||
| 388 | CAP_MIC_TKIP, | ||
| 389 | CAP_MIC_TKIP_WME, | ||
| 390 | CAP_CIPHER_AES_CCM, | ||
| 391 | CAP_CIPHER_CKIP, | ||
| 392 | CAP_CIPHER_TKIP, | ||
| 393 | |||
| 394 | CAP_TWICE_ANTENNAGAIN_5G, | ||
| 395 | CAP_TWICE_ANTENNAGAIN_2G, | ||
| 396 | }; | ||
| 397 | |||
| 398 | enum { | ||
| 399 | ST_NONE, /* Sentinal to indicate "no status" */ | ||
| 400 | ST_ALL, | ||
| 401 | ST_SERVICE_TYPE, | ||
| 402 | ST_WLAN_MODE, | ||
| 403 | ST_FREQ, | ||
| 404 | ST_BAND, | ||
| 405 | ST_LAST_RSSI, | ||
| 406 | ST_PS_FRAMES_DROPPED, | ||
| 407 | ST_CACHED_DEF_ANT, | ||
| 408 | ST_COUNT_OTHER_RX_ANT, | ||
| 409 | ST_USE_FAST_DIVERSITY, | ||
| 410 | ST_MAC_ADDR, | ||
| 411 | ST_RX_GENERATION_NUM, | ||
| 412 | ST_TX_QUEUE_DEPTH, | ||
| 413 | ST_SERIAL_NUMBER, | ||
| 414 | ST_WDC_TRANSPORT_CHUNK_SIZE, | ||
| 415 | }; | ||
| 416 | |||
| 417 | enum { | ||
| 418 | TARGET_DEVICE_AWAKE, | ||
| 419 | TARGET_DEVICE_SLEEP, | ||
| 420 | TARGET_DEVICE_PWRDN, | ||
| 421 | TARGET_DEVICE_PWRSAVE, | ||
| 422 | TARGET_DEVICE_SUSPEND, | ||
| 423 | TARGET_DEVICE_RESUME, | ||
| 424 | }; | ||
| 425 | |||
| 426 | /* this is in net/ieee80211.h, but that conflicts with the mac80211 headers */ | ||
| 427 | #define IEEE80211_2ADDR_LEN 16 | ||
| 428 | |||
| 429 | #define AR5523_MIN_RXBUFSZ \ | ||
| 430 | (((sizeof(__be32) + IEEE80211_2ADDR_LEN + \ | ||
| 431 | sizeof(struct ar5523_rx_desc)) + 3) & ~3) | ||
| @@ -301,7 +301,7 @@ static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif) · 300 unmodified lines | |||
| 301 | 301 | ||
| 302 | static bool ath6kl_is_wpa_ie(const u8 *pos) | 302 | static bool ath6kl_is_wpa_ie(const u8 *pos) |
| 303 | { | 303 | { |
| 304 | return pos[0] == WLAN_EID_WPA && pos[1] >= 4 && | 304 | return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && |
| 305 | pos[2] == 0x00 && pos[3] == 0x50 && | 305 | pos[2] == 0x00 && pos[3] == 0x50 && |
| 306 | pos[4] == 0xf2 && pos[5] == 0x01; | 306 | pos[4] == 0xf2 && pos[5] == 0x01; |
| 307 | } | 307 | } |
| @@ -3651,7 +3651,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) · 3343 unmodified lines | |||
| 3651 | 3651 | ||
| 3652 | if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, | 3652 | if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, |
| 3653 | ar->fw_capabilities)) | 3653 | ar->fw_capabilities)) |
| 3654 | ar->wiphy->features = NL80211_FEATURE_INACTIVITY_TIMER; | 3654 | ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; |
| 3655 | 3655 | ||
| 3656 | ar->wiphy->probe_resp_offload = | 3656 | ar->wiphy->probe_resp_offload = |
| 3657 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | 3657 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | |
| @@ -276,6 +276,11 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) · 275 unmodified lines | |||
| 276 | offset_array[i], | 276 | offset_array[i], |
| 277 | REG_READ(ah, offset_array[i])); | 277 | REG_READ(ah, offset_array[i])); |
| 278 | 278 | ||
| 279 | if (AR_SREV_9565(ah) && | ||
| 280 | (iCoff == 63 || qCoff == 63 || | ||
| 281 | iCoff == -63 || qCoff == -63)) | ||
| 282 | return; | ||
| 283 | |||
| 279 | REG_RMW_FIELD(ah, offset_array[i], | 284 | REG_RMW_FIELD(ah, offset_array[i], |
| 280 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, | 285 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, |
| 281 | iCoff); | 286 | iCoff); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include "hw.h" | 18 | #include "hw.h" |
| 19 | #include "ar9003_phy.h" | 19 | #include "ar9003_phy.h" |
| 20 | #include "ar9003_eeprom.h" | 20 | #include "ar9003_eeprom.h" |
| 21 | #include "ar9003_mci.h" | ||
| 21 | 22 | ||
| 22 | #define COMP_HDR_LEN 4 | 23 | #define COMP_HDR_LEN 4 |
| 23 | #define COMP_CKSUM_LEN 2 | 24 | #define COMP_CKSUM_LEN 2 |
| @@ -41,7 +42,6 @@ · 17 unmodified lines | |||
| 41 | static int ar9003_hw_power_interpolate(int32_t x, | 42 | static int ar9003_hw_power_interpolate(int32_t x, |
| 42 | int32_t *px, int32_t *py, u_int16_t np); | 43 | int32_t *px, int32_t *py, u_int16_t np); |
| 43 | 44 | ||
| 44 | |||
| 45 | static const struct ar9300_eeprom ar9300_default = { | 45 | static const struct ar9300_eeprom ar9300_default = { |
| 46 | .eepromVersion = 2, | 46 | .eepromVersion = 2, |
| 47 | .templateVersion = 2, | 47 | .templateVersion = 2, |
| @@ -2989,7 +2989,7 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, · 2941 unmodified lines | |||
| 2989 | case EEP_PAPRD: | 2989 | case EEP_PAPRD: |
| 2990 | if (AR_SREV_9462(ah)) | 2990 | if (AR_SREV_9462(ah)) |
| 2991 | return false; | 2991 | return false; |
| 2992 | if (!ah->config.enable_paprd); | 2992 | if (!ah->config.enable_paprd) |
| 2993 | return false; | 2993 | return false; |
| 2994 | return !!(pBase->featureEnable & BIT(5)); | 2994 | return !!(pBase->featureEnable & BIT(5)); |
| 2995 | case EEP_CHAIN_MASK_REDUCE: | 2995 | case EEP_CHAIN_MASK_REDUCE: |
| @@ -3601,7 +3601,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) · 605 unmodified lines | |||
| 3601 | * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE | 3601 | * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE |
| 3602 | * SWITCH_TABLE_COM_SPDT_WLAN_IDLE | 3602 | * SWITCH_TABLE_COM_SPDT_WLAN_IDLE |
| 3603 | */ | 3603 | */ |
| 3604 | if (AR_SREV_9462_20_OR_LATER(ah)) { | 3604 | if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) { |
| 3605 | value = ar9003_switch_com_spdt_get(ah, is2ghz); | 3605 | value = ar9003_switch_com_spdt_get(ah, is2ghz); |
| 3606 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, | 3606 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, |
| 3607 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); | 3607 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); |
| @@ -5037,16 +5037,28 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, · 1429 unmodified lines | |||
| 5037 | case CTL_5GHT20: | 5037 | case CTL_5GHT20: |
| 5038 | case CTL_2GHT20: | 5038 | case CTL_2GHT20: |
| 5039 | for (i = ALL_TARGET_HT20_0_8_16; | 5039 | for (i = ALL_TARGET_HT20_0_8_16; |
| 5040 | i <= ALL_TARGET_HT20_23; i++) | 5040 | i <= ALL_TARGET_HT20_23; i++) { |
| 5041 | pPwrArray[i] = (u8)min((u16)pPwrArray[i], | 5041 | pPwrArray[i] = (u8)min((u16)pPwrArray[i], |
| 5042 | minCtlPower); | 5042 | minCtlPower); |
| 5043 | if (ath9k_hw_mci_is_enabled(ah)) | ||
| 5044 | pPwrArray[i] = | ||
| 5045 | (u8)min((u16)pPwrArray[i], | ||
| 5046 | ar9003_mci_get_max_txpower(ah, | ||
| 5047 | pCtlMode[ctlMode])); | ||
| 5048 | } | ||
| 5043 | break; | 5049 | break; |
| 5044 | case CTL_5GHT40: | 5050 | case CTL_5GHT40: |
| 5045 | case CTL_2GHT40: | 5051 | case CTL_2GHT40: |
| 5046 | for (i = ALL_TARGET_HT40_0_8_16; | 5052 | for (i = ALL_TARGET_HT40_0_8_16; |
| 5047 | i <= ALL_TARGET_HT40_23; i++) | 5053 | i <= ALL_TARGET_HT40_23; i++) { |
| 5048 | pPwrArray[i] = (u8)min((u16)pPwrArray[i], | 5054 | pPwrArray[i] = (u8)min((u16)pPwrArray[i], |
| 5049 | minCtlPower); | 5055 | minCtlPower); |
| 5056 | if (ath9k_hw_mci_is_enabled(ah)) | ||
| 5057 | pPwrArray[i] = | ||
| 5058 | (u8)min((u16)pPwrArray[i], | ||
| 5059 | ar9003_mci_get_max_txpower(ah, | ||
| 5060 | pCtlMode[ctlMode])); | ||
| 5061 | } | ||
| 5050 | break; | 5062 | break; |
| 5051 | default: | 5063 | default: |
| 5052 | break; | 5064 | break; |
| @@ -219,10 +219,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) · 218 unmodified lines | |||
| 219 | 219 | ||
| 220 | /* Awake -> Sleep Setting */ | 220 | /* Awake -> Sleep Setting */ |
| 221 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 221 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
| 222 | ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); | 222 | ar9462_pciephy_clkreq_disable_L1_2p0); |
| 223 | /* Sleep -> Awake Setting */ | 223 | /* Sleep -> Awake Setting */ |
| 224 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 224 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
| 225 | ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); | 225 | ar9462_pciephy_clkreq_disable_L1_2p0); |
| 226 | 226 | ||
| 227 | /* Fast clock modal settings */ | 227 | /* Fast clock modal settings */ |
| 228 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 228 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
| @@ -328,9 +328,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) · 99 unmodified lines | |||
| 328 | ar9565_1p0_Modes_lowest_ob_db_tx_gain_table); | 328 | ar9565_1p0_Modes_lowest_ob_db_tx_gain_table); |
| 329 | 329 | ||
| 330 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 330 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
| 331 | ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); | 331 | ar9565_1p0_pciephy_clkreq_disable_L1); |
| 332 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 332 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
| 333 | ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); | 333 | ar9565_1p0_pciephy_clkreq_disable_L1); |
| 334 | 334 | ||
| 335 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 335 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
| 336 | ar9565_1p0_modes_fast_clock); | 336 | ar9565_1p0_modes_fast_clock); |
| @@ -750,6 +750,9 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, · 749 unmodified lines | |||
| 750 | 750 | ||
| 751 | mci_hw->bt_state = MCI_BT_AWAKE; | 751 | mci_hw->bt_state = MCI_BT_AWAKE; |
| 752 | 752 | ||
| 753 | REG_CLR_BIT(ah, AR_PHY_TIMING4, | ||
| 754 | 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT); | ||
| 755 | |||
| 753 | if (caldata) { | 756 | if (caldata) { |
| 754 | caldata->done_txiqcal_once = false; | 757 | caldata->done_txiqcal_once = false; |
| 755 | caldata->done_txclcal_once = false; | 758 | caldata->done_txclcal_once = false; |
| @@ -759,6 +762,9 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, · 3 unmodified lines | |||
| 759 | if (!ath9k_hw_init_cal(ah, chan)) | 762 | if (!ath9k_hw_init_cal(ah, chan)) |
| 760 | return -EIO; | 763 | return -EIO; |
| 761 | 764 | ||
| 765 | REG_SET_BIT(ah, AR_PHY_TIMING4, | ||
| 766 | 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT); | ||
| 767 | |||
| 762 | exit: | 768 | exit: |
| 763 | ar9003_mci_enable_interrupt(ah); | 769 | ar9003_mci_enable_interrupt(ah); |
| 764 | return 0; | 770 | return 0; |
| @@ -799,6 +805,9 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) · 34 unmodified lines | |||
| 799 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | 805 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, |
| 800 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | 806 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); |
| 801 | 807 | ||
| 808 | if (AR_SREV_9565(ah)) | ||
| 809 | REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1); | ||
| 810 | |||
| 802 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | 811 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { |
| 803 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); | 812 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); |
| 804 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | 813 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, |
| @@ -818,7 +827,7 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, · 13 unmodified lines | |||
| 818 | { | 827 | { |
| 819 | struct ath_common *common = ath9k_hw_common(ah); | 828 | struct ath_common *common = ath9k_hw_common(ah); |
| 820 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 829 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
| 821 | u32 regval; | 830 | u32 regval, i; |
| 822 | 831 | ||
| 823 | ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", | 832 | ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", |
| 824 | is_full_sleep, is_2g); | 833 | is_full_sleep, is_2g); |
| @@ -847,11 +856,18 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, · 22 unmodified lines | |||
| 847 | SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | | 856 | SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | |
| 848 | SM(1, AR_BTCOEX_CTRL_PA_SHARED) | | 857 | SM(1, AR_BTCOEX_CTRL_PA_SHARED) | |
| 849 | SM(1, AR_BTCOEX_CTRL_LNA_SHARED) | | 858 | SM(1, AR_BTCOEX_CTRL_LNA_SHARED) | |
| 850 | SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | | ||
| 851 | SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) | | ||
| 852 | SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | | 859 | SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | |
| 853 | SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | | 860 | SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | |
| 854 | SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 861 | SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); |
| 862 | if (AR_SREV_9565(ah)) { | ||
| 863 | regval |= SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) | | ||
| 864 | SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK); | ||
| 865 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, | ||
| 866 | AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1); | ||
| 867 | } else { | ||
| 868 | regval |= SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | | ||
| 869 | SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK); | ||
| 870 | } | ||
| 855 | 871 | ||
| 856 | REG_WRITE(ah, AR_BTCOEX_CTRL, regval); | 872 | REG_WRITE(ah, AR_BTCOEX_CTRL, regval); |
| 857 | 873 | ||
| @@ -865,9 +881,24 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, · 7 unmodified lines | |||
| 865 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, | 881 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, |
| 866 | AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); | 882 | AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); |
| 867 | 883 | ||
| 868 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1); | 884 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0); |
| 869 | REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); | 885 | REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); |
| 870 | 886 | ||
| 887 | /* Set the time out to 3.125ms (5 BT slots) */ | ||
| 888 | REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090); | ||
| 889 | |||
| 890 | /* concurrent tx priority */ | ||
| 891 | if (mci->config & ATH_MCI_CONFIG_CONCUR_TX) { | ||
| 892 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, | ||
| 893 | AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0); | ||
| 894 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, | ||
| 895 | AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f); | ||
| 896 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
| 897 | AR_BTCOEX_CTRL_REDUCE_TXPWR, 0); | ||
| 898 | for (i = 0; i < 8; i++) | ||
| 899 | REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), 0x7f7f7f7f); | ||
| 900 | } | ||
| 901 | |||
| 871 | regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV); | 902 | regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV); |
| 872 | REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval); | 903 | REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval); |
| 873 | REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN); | 904 | REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN); |
| @@ -910,6 +941,9 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, · 36 unmodified lines | |||
| 910 | mci->ready = true; | 941 | mci->ready = true; |
| 911 | ar9003_mci_prep_interface(ah); | 942 | ar9003_mci_prep_interface(ah); |
| 912 | 943 | ||
| 944 | if (AR_SREV_9565(ah)) | ||
| 945 | REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL, | ||
| 946 | AR_MCI_DBG_CNT_CTRL_ENABLE, 0); | ||
| 913 | if (en_int) | 947 | if (en_int) |
| 914 | ar9003_mci_enable_interrupt(ah); | 948 | ar9003_mci_enable_interrupt(ah); |
| 915 | 949 | ||
| @@ -1028,7 +1062,9 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) · 112 unmodified lines | |||
| 1028 | 1062 | ||
| 1029 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) | 1063 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) |
| 1030 | ar9003_mci_osla_setup(ah, true); | 1064 | ar9003_mci_osla_setup(ah, true); |
| 1031 | REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); | 1065 | |
| 1066 | if (AR_SREV_9462(ah)) | ||
| 1067 | REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); | ||
| 1032 | } else { | 1068 | } else { |
| 1033 | ar9003_mci_send_lna_take(ah, true); | 1069 | ar9003_mci_send_lna_take(ah, true); |
| 1034 | udelay(5); | 1070 | udelay(5); |
| @@ -1170,7 +1206,7 @@ EXPORT_SYMBOL(ar9003_mci_cleanup); · 135 unmodified lines | |||
| 1170 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) | 1206 | u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) |
| 1171 | { | 1207 | { |
| 1172 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 1208 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
| 1173 | u32 value = 0; | 1209 | u32 value = 0, tsf; |
| 1174 | u8 query_type; | 1210 | u8 query_type; |
| 1175 | 1211 | ||
| 1176 | switch (state_type) { | 1212 | switch (state_type) { |
| @@ -1228,6 +1264,14 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) · 51 unmodified lines | |||
| 1228 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); | 1264 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); |
| 1229 | break; | 1265 | break; |
| 1230 | case MCI_STATE_RECOVER_RX: | 1266 | case MCI_STATE_RECOVER_RX: |
| 1267 | tsf = ath9k_hw_gettsf32(ah); | ||
| 1268 | if ((tsf - mci->last_recovery) <= MCI_RECOVERY_DUR_TSF) { | ||
| 1269 | ath_dbg(ath9k_hw_common(ah), MCI, | ||
| 1270 | "(MCI) ignore Rx recovery\n"); | ||
| 1271 | break; | ||
| 1272 | } | ||
| 1273 | ath_dbg(ath9k_hw_common(ah), MCI, "(MCI) RECOVER RX\n"); | ||
| 1274 | mci->last_recovery = tsf; | ||
| 1231 | ar9003_mci_prep_interface(ah); | 1275 | ar9003_mci_prep_interface(ah); |
| 1232 | mci->query_bt = true; | 1276 | mci->query_bt = true; |
| 1233 | mci->need_flush_btinfo = true; | 1277 | mci->need_flush_btinfo = true; |
| @@ -1426,3 +1470,17 @@ void ar9003_mci_send_wlan_channels(struct ath_hw *ah) · 192 unmodified lines | |||
| 1426 | ar9003_mci_send_coex_wlan_channels(ah, true); | 1470 | ar9003_mci_send_coex_wlan_channels(ah, true); |
| 1427 | } | 1471 | } |
| 1428 | EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); | 1472 | EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); |
| 1473 | |||
| 1474 | u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode) | ||
| 1475 | { | ||
| 1476 | if (!ah->btcoex_hw.mci.concur_tx) | ||
| 1477 | goto out; | ||
| 1478 | |||
| 1479 | if (ctlmode == CTL_2GHT20) | ||
| 1480 | return ATH_BTCOEX_HT20_MAX_TXPOWER; | ||
| 1481 | else if (ctlmode == CTL_2GHT40) | ||
| 1482 | return ATH_BTCOEX_HT40_MAX_TXPOWER; | ||
| 1483 | |||
| 1484 | out: | ||
| 1485 | return -1; | ||
| 1486 | } | ||
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #define AR9003_MCI_H | 18 | #define AR9003_MCI_H |
| 19 | 19 | ||
| 20 | #define MCI_FLAG_DISABLE_TIMESTAMP 0x00000001 /* Disable time stamp */ | 20 | #define MCI_FLAG_DISABLE_TIMESTAMP 0x00000001 /* Disable time stamp */ |
| 21 | #define MCI_RECOVERY_DUR_TSF (100 * 1000) /* 100 ms */ | ||
| 21 | 22 | ||
| 22 | /* Default remote BT device MCI COEX version */ | 23 | /* Default remote BT device MCI COEX version */ |
| 23 | #define MCI_GPM_COEX_MAJOR_VERSION_DEFAULT 3 | 24 | #define MCI_GPM_COEX_MAJOR_VERSION_DEFAULT 3 |
| @@ -125,6 +126,7 @@ enum ath_mci_gpm_coex_profile_type { · 101 unmodified lines | |||
| 125 | MCI_GPM_COEX_PROFILE_HID, | 126 | MCI_GPM_COEX_PROFILE_HID, |
| 126 | MCI_GPM_COEX_PROFILE_BNEP, | 127 | MCI_GPM_COEX_PROFILE_BNEP, |
| 127 | MCI_GPM_COEX_PROFILE_VOICE, | 128 | MCI_GPM_COEX_PROFILE_VOICE, |
| 129 | MCI_GPM_COEX_PROFILE_A2DPVO, | ||
| 128 | MCI_GPM_COEX_PROFILE_MAX | 130 | MCI_GPM_COEX_PROFILE_MAX |
| 129 | }; | 131 | }; |
| 130 | 132 | ||
| @@ -196,7 +198,6 @@ enum mci_state_type { · 65 unmodified lines | |||
| 196 | MCI_STATE_SEND_WLAN_COEX_VERSION, | 198 | MCI_STATE_SEND_WLAN_COEX_VERSION, |
| 197 | MCI_STATE_SEND_VERSION_QUERY, | 199 | MCI_STATE_SEND_VERSION_QUERY, |
| 198 | MCI_STATE_SEND_STATUS_QUERY, | 200 | MCI_STATE_SEND_STATUS_QUERY, |
| 199 | MCI_STATE_SET_CONCUR_TX_PRI, | ||
| 200 | MCI_STATE_RECOVER_RX, | 201 | MCI_STATE_RECOVER_RX, |
| 201 | MCI_STATE_NEED_FTP_STOMP, | 202 | MCI_STATE_NEED_FTP_STOMP, |
| 202 | MCI_STATE_DEBUG, | 203 | MCI_STATE_DEBUG, |
| @@ -278,6 +279,7 @@ void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); · 75 unmodified lines | |||
| 278 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); | 279 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); |
| 279 | void ar9003_mci_set_power_awake(struct ath_hw *ah); | 280 | void ar9003_mci_set_power_awake(struct ath_hw *ah); |
| 280 | void ar9003_mci_check_gpm_offset(struct ath_hw *ah); | 281 | void ar9003_mci_check_gpm_offset(struct ath_hw *ah); |
| 282 | u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode); | ||
| 281 | 283 | ||
| 282 | #else | 284 | #else |
| 283 | 285 | ||
| @@ -324,6 +326,10 @@ static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) · 40 unmodified lines | |||
| 324 | static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) | 326 | static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) |
| 325 | { | 327 | { |
| 326 | } | 328 | } |
| 329 | static inline u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode) | ||
| 330 | { | ||
| 331 | return -1; | ||
| 332 | } | ||
| 327 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 333 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
| 328 | 334 | ||
| 329 | #endif | 335 | #endif |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c) | 32 | #define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c) |
| 33 | #define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc) | 33 | #define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc) |
| 34 | #define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0) | 34 | #define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0) |
| 35 | #define AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT 16 | ||
| 35 | 36 | ||
| 36 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | 37 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 |
| 37 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | 38 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 |
| @@ -768,9 +768,9 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = { · 767 unmodified lines | |||
| 768 | {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 768 | {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
| 769 | }; | 769 | }; |
| 770 | 770 | ||
| 771 | static const u32 ar9565_1p0_pciephy_pll_on_clkreq_disable_L1[][2] = { | 771 | static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = { |
| 772 | /* Addr allmodes */ | 772 | /* Addr allmodes */ |
| 773 | {0x00018c00, 0x18212ede}, | 773 | {0x00018c00, 0x18213ede}, |
| 774 | {0x00018c04, 0x000801d8}, | 774 | {0x00018c04, 0x000801d8}, |
| 775 | {0x00018c08, 0x0003780c}, | 775 | {0x00018c08, 0x0003780c}, |
| 776 | }; | 776 | }; |
| @@ -437,6 +437,7 @@ void ath9k_set_beacon(struct ath_softc *sc); · 436 unmodified lines | |||
| 437 | #define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ | 437 | #define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ |
| 438 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | 438 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ |
| 439 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 439 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
| 440 | #define ATH_ANI_MAX_SKIP_COUNT 10 | ||
| 440 | 441 | ||
| 441 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 442 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
| 442 | #define ATH_PLL_WORK_INTERVAL 100 | 443 | #define ATH_PLL_WORK_INTERVAL 100 |
| @@ -478,6 +479,7 @@ struct ath_btcoex { · 35 unmodified lines | |||
| 478 | u32 btscan_no_stomp; /* in usec */ | 479 | u32 btscan_no_stomp; /* in usec */ |
| 479 | u32 duty_cycle; | 480 | u32 duty_cycle; |
| 480 | u32 bt_wait_time; | 481 | u32 bt_wait_time; |
| 482 | int rssi_count; | ||
| 481 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 483 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
| 482 | struct ath_mci_profile mci; | 484 | struct ath_mci_profile mci; |
| 483 | }; | 485 | }; |
| @@ -492,6 +494,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); · 8 unmodified lines | |||
| 492 | void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); | 494 | void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); |
| 493 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); | 495 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); |
| 494 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); | 496 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); |
| 497 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size); | ||
| 495 | #else | 498 | #else |
| 496 | static inline int ath9k_init_btcoex(struct ath_softc *sc) | 499 | static inline int ath9k_init_btcoex(struct ath_softc *sc) |
| 497 | { | 500 | { |
| @@ -518,6 +521,11 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, · 20 unmodified lines | |||
| 518 | static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | 521 | static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) |
| 519 | { | 522 | { |
| 520 | } | 523 | } |
| 524 | static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, | ||
| 525 | u32 len, u32 size) | ||
| 526 | { | ||
| 527 | return 0; | ||
| 528 | } | ||
| 521 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 529 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
| 522 | 530 | ||
| 523 | struct ath9k_wow_pattern { | 531 | struct ath9k_wow_pattern { |
| @@ -642,6 +650,7 @@ enum sc_op_flags { · 118 unmodified lines | |||
| 642 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) | 650 | #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) |
| 643 | #define PS_WAIT_FOR_TX_ACK BIT(3) | 651 | #define PS_WAIT_FOR_TX_ACK BIT(3) |
| 644 | #define PS_BEACON_SYNC BIT(4) | 652 | #define PS_BEACON_SYNC BIT(4) |
| 653 | #define PS_WAIT_FOR_ANI BIT(5) | ||
| 645 | 654 | ||
| 646 | struct ath_rate_table; | 655 | struct ath_rate_table; |
| 647 | 656 | ||
| @@ -195,7 +195,7 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah) · 194 unmodified lines | |||
| 195 | ah->btcoex_hw.mci.need_flush_btinfo = false; | 195 | ah->btcoex_hw.mci.need_flush_btinfo = false; |
| 196 | ah->btcoex_hw.mci.wlan_cal_seq = 0; | 196 | ah->btcoex_hw.mci.wlan_cal_seq = 0; |
| 197 | ah->btcoex_hw.mci.wlan_cal_done = 0; | 197 | ah->btcoex_hw.mci.wlan_cal_done = 0; |
| 198 | ah->btcoex_hw.mci.config = 0x2201; | 198 | ah->btcoex_hw.mci.config = (AR_SREV_9462(ah)) ? 0x2201 : 0xa4c1; |
| 199 | } | 199 | } |
| 200 | EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci); | 200 | EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci); |
| 201 | 201 | ||
| @@ -218,27 +218,45 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, · 16 unmodified lines | |||
| 218 | enum ath_stomp_type stomp_type) | 218 | enum ath_stomp_type stomp_type) |
| 219 | { | 219 | { |
| 220 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 220 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
| 221 | struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; | ||
| 222 | u8 txprio_shift[] = { 24, 16, 16, 0 }; /* tx priority weight */ | ||
| 223 | bool concur_tx = (mci_hw->concur_tx && btcoex_hw->tx_prio[stomp_type]); | ||
| 224 | const u32 *weight = ar9003_wlan_weights[stomp_type]; | ||
| 225 | int i; | ||
| 221 | 226 | ||
| 222 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 227 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
| 223 | const u32 *weight = ar9003_wlan_weights[stomp_type]; | ||
| 224 | int i; | ||
| 225 | |||
| 226 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | ||
| 227 | if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && | ||
| 228 | btcoex_hw->mci.stomp_ftp) | ||
| 229 | stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; | ||
| 230 | weight = mci_wlan_weights[stomp_type]; | ||
| 231 | } | ||
| 232 | |||
| 233 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { | ||
| 234 | btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; | ||
| 235 | btcoex_hw->wlan_weight[i] = weight[i]; | ||
| 236 | } | ||
| 237 | } else { | ||
| 238 | btcoex_hw->bt_coex_weights = | 228 | btcoex_hw->bt_coex_weights = |
| 239 | SM(bt_weight, AR_BTCOEX_BT_WGHT) | | 229 | SM(bt_weight, AR_BTCOEX_BT_WGHT) | |
| 240 | SM(wlan_weight, AR_BTCOEX_WL_WGHT); | 230 | SM(wlan_weight, AR_BTCOEX_WL_WGHT); |
| 231 | return; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | ||
| 235 | enum ath_stomp_type stype = | ||
| 236 | ((stomp_type == ATH_BTCOEX_STOMP_LOW) && | ||
| 237 | btcoex_hw->mci.stomp_ftp) ? | ||
| 238 | ATH_BTCOEX_STOMP_LOW_FTP : stomp_type; | ||
| 239 | weight = mci_wlan_weights[stype]; | ||
| 241 | } | 240 | } |
| 241 | |||
| 242 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { | ||
| 243 | btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; | ||
| 244 | btcoex_hw->wlan_weight[i] = weight[i]; | ||
| 245 | if (concur_tx && i) { | ||
| 246 | btcoex_hw->wlan_weight[i] &= | ||
| 247 | ~(0xff << txprio_shift[i-1]); | ||
| 248 | btcoex_hw->wlan_weight[i] |= | ||
| 249 | (btcoex_hw->tx_prio[stomp_type] << | ||
| 250 | txprio_shift[i-1]); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | /* Last WLAN weight has to be adjusted wrt tx priority */ | ||
| 254 | if (concur_tx) { | ||
| 255 | btcoex_hw->wlan_weight[i-1] &= ~(0xff << txprio_shift[i-1]); | ||
| 256 | btcoex_hw->wlan_weight[i-1] |= (btcoex_hw->tx_prio[stomp_type] | ||
| 257 | << txprio_shift[i-1]); | ||
| 258 | } | ||
| 259 | |||
| 242 | } | 260 | } |
| 243 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); | 261 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); |
| 244 | 262 | ||
| @@ -385,3 +403,13 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, · 140 unmodified lines | |||
| 385 | } | 403 | } |
| 386 | } | 404 | } |
| 387 | EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); | 405 | EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); |
| 406 | |||
| 407 | void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio) | ||
| 408 | { | ||
| 409 | struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; | ||
| 410 | int i; | ||
| 411 | |||
| 412 | for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) | ||
| 413 | btcoex->tx_prio[i] = stomp_txprio[i]; | ||
| 414 | } | ||
| 415 | EXPORT_SYMBOL(ath9k_hw_btcoex_set_concur_txprio); | ||
| @@ -39,6 +39,9 @@ · 38 unmodified lines | |||
| 39 | #define ATH_BTCOEX_RX_WAIT_TIME 100 | 39 | #define ATH_BTCOEX_RX_WAIT_TIME 100 |
| 40 | #define ATH_BTCOEX_STOMP_FTP_THRESH 5 | 40 | #define ATH_BTCOEX_STOMP_FTP_THRESH 5 |
| 41 | 41 | ||
| 42 | #define ATH_BTCOEX_HT20_MAX_TXPOWER 0x14 | ||
| 43 | #define ATH_BTCOEX_HT40_MAX_TXPOWER 0x10 | ||
| 44 | |||
| 42 | #define AR9300_NUM_BT_WEIGHTS 4 | 45 | #define AR9300_NUM_BT_WEIGHTS 4 |
| 43 | #define AR9300_NUM_WLAN_WEIGHTS 4 | 46 | #define AR9300_NUM_WLAN_WEIGHTS 4 |
| 44 | /* Defines the BT AR_BT_COEX_WGHT used */ | 47 | /* Defines the BT AR_BT_COEX_WGHT used */ |
| @@ -84,6 +87,8 @@ struct ath9k_hw_mci { · 39 unmodified lines | |||
| 84 | u8 bt_ver_minor; | 87 | u8 bt_ver_minor; |
| 85 | u8 bt_state; | 88 | u8 bt_state; |
| 86 | u8 stomp_ftp; | 89 | u8 stomp_ftp; |
| 90 | bool concur_tx; | ||
| 91 | u32 last_recovery; | ||
| 87 | }; | 92 | }; |
| 88 | 93 | ||
| 89 | struct ath_btcoex_hw { | 94 | struct ath_btcoex_hw { |
| @@ -98,6 +103,7 @@ struct ath_btcoex_hw { · 8 unmodified lines | |||
| 98 | u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ | 103 | u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ |
| 99 | u32 bt_weight[AR9300_NUM_BT_WEIGHTS]; | 104 | u32 bt_weight[AR9300_NUM_BT_WEIGHTS]; |
| 100 | u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; | 105 | u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; |
| 106 | u8 tx_prio[ATH_BTCOEX_STOMP_MAX]; | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah); | 109 | void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah); |
| @@ -112,5 +118,6 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, · 8 unmodified lines | |||
| 112 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); | 118 | void ath9k_hw_btcoex_disable(struct ath_hw *ah); |
| 113 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | 119 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, |
| 114 | enum ath_stomp_type stomp_type); | 120 | enum ath_stomp_type stomp_type); |
| 121 | void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio); | ||
| 115 | 122 | ||
| 116 | #endif | 123 | #endif |
| @@ -410,6 +410,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, · 409 unmodified lines | |||
| 410 | 410 | ||
| 411 | ah->caldata->channel = chan->channel; | 411 | ah->caldata->channel = chan->channel; |
| 412 | ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; | 412 | ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; |
| 413 | ah->caldata->chanmode = chan->chanmode; | ||
| 413 | h = ah->caldata->nfCalHist; | 414 | h = ah->caldata->nfCalHist; |
| 414 | default_nf = ath9k_hw_get_default_nf(ah, chan); | 415 | default_nf = ath9k_hw_get_default_nf(ah, chan); |
| 415 | for (i = 0; i < NUM_NF_READINGS; i++) { | 416 | for (i = 0; i < NUM_NF_READINGS; i++) { |
| @@ -1586,6 +1586,35 @@ static const struct file_operations fops_samps = { · 1585 unmodified lines | |||
| 1586 | 1586 | ||
| 1587 | #endif | 1587 | #endif |
| 1588 | 1588 | ||
| 1589 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
| 1590 | static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, | ||
| 1591 | size_t count, loff_t *ppos) | ||
| 1592 | { | ||
| 1593 | struct ath_softc *sc = file->private_data; | ||
| 1594 | u32 len = 0, size = 1500; | ||
| 1595 | char *buf; | ||
| 1596 | size_t retval; | ||
| 1597 | |||
| 1598 | buf = kzalloc(size, GFP_KERNEL); | ||
| 1599 | if (buf == NULL) | ||
| 1600 | return -ENOMEM; | ||
| 1601 | |||
| 1602 | len = ath9k_dump_btcoex(sc, buf, len, size); | ||
| 1603 | |||
| 1604 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
| 1605 | kfree(buf); | ||
| 1606 | |||
| 1607 | return retval; | ||
| 1608 | } | ||
| 1609 | |||
| 1610 | static const struct file_operations fops_btcoex = { | ||
| 1611 | .read = read_file_btcoex, | ||
| 1612 | .open = simple_open, | ||
| 1613 | .owner = THIS_MODULE, | ||
| 1614 | .llseek = default_llseek, | ||
| 1615 | }; | ||
| 1616 | #endif | ||
| 1617 | |||
| 1589 | int ath9k_init_debug(struct ath_hw *ah) | 1618 | int ath9k_init_debug(struct ath_hw *ah) |
| 1590 | { | 1619 | { |
| 1591 | struct ath_common *common = ath9k_hw_common(ah); | 1620 | struct ath_common *common = ath9k_hw_common(ah); |
| @@ -1658,6 +1687,9 @@ int ath9k_init_debug(struct ath_hw *ah) · 66 unmodified lines | |||
| 1658 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); | 1687 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); |
| 1659 | debugfs_create_file("diversity", S_IRUSR | S_IWUSR, | 1688 | debugfs_create_file("diversity", S_IRUSR | S_IWUSR, |
| 1660 | sc->debug.debugfs_phy, sc, &fops_ant_diversity); | 1689 | sc->debug.debugfs_phy, sc, &fops_ant_diversity); |
| 1661 | 1690 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | |
| 1691 | debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
| 1692 | &fops_btcoex); | ||
| 1693 | #endif | ||
| 1662 | return 0; | 1694 | return 0; |
| 1663 | } | 1695 | } |
| @@ -187,6 +187,24 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) · 186 unmodified lines | |||
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | static void ath_mci_ftp_adjust(struct ath_softc *sc) | ||
| 191 | { | ||
| 192 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
| 193 | struct ath_mci_profile *mci = &btcoex->mci; | ||
| 194 | struct ath_hw *ah = sc->sc_ah; | ||
| 195 | |||
| 196 | if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { | ||
| 197 | if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && | ||
| 198 | (mci->num_pan || mci->num_other_acl)) | ||
| 199 | ah->btcoex_hw.mci.stomp_ftp = | ||
| 200 | (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); | ||
| 201 | else | ||
| 202 | ah->btcoex_hw.mci.stomp_ftp = false; | ||
| 203 | btcoex->bt_wait_time = 0; | ||
| 204 | sc->rx.num_pkts = 0; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 190 | /* | 208 | /* |
| 191 | * This is the master bt coex timer which runs for every | 209 | * This is the master bt coex timer which runs for every |
| 192 | * 45ms, bt traffic will be given priority during 55% of this | 210 | * 45ms, bt traffic will be given priority during 55% of this |
| @@ -197,41 +215,43 @@ static void ath_btcoex_period_timer(unsigned long data) · 4 unmodified lines | |||
| 197 | struct ath_softc *sc = (struct ath_softc *) data; | 215 | struct ath_softc *sc = (struct ath_softc *) data; |
| 198 | struct ath_hw *ah = sc->sc_ah; | 216 | struct ath_hw *ah = sc->sc_ah; |
| 199 | struct ath_btcoex *btcoex = &sc->btcoex; | 217 | struct ath_btcoex *btcoex = &sc->btcoex; |
| 200 | struct ath_mci_profile *mci = &btcoex->mci; | 218 | enum ath_stomp_type stomp_type; |
| 201 | u32 timer_period; | 219 | u32 timer_period; |
| 202 | bool is_btscan; | ||
| 203 | unsigned long flags; | 220 | unsigned long flags; |
| 204 | 221 | ||
| 205 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 222 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
| 206 | if (sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP) { | 223 | if (sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP) { |
| 224 | btcoex->bt_wait_time += btcoex->btcoex_period; | ||
| 207 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 225 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 208 | goto skip_hw_wakeup; | 226 | goto skip_hw_wakeup; |
| 209 | } | 227 | } |
| 210 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 228 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 211 | 229 | ||
| 230 | ath9k_mci_update_rssi(sc); | ||
| 231 | |||
| 212 | ath9k_ps_wakeup(sc); | 232 | ath9k_ps_wakeup(sc); |
| 233 | |||
| 213 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 234 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
| 214 | ath_detect_bt_priority(sc); | 235 | ath_detect_bt_priority(sc); |
| 215 | is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); | ||
| 216 | 236 | ||
| 217 | btcoex->bt_wait_time += btcoex->btcoex_period; | 237 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) |
| 218 | if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { | 238 | ath_mci_ftp_adjust(sc); |
| 219 | if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && | ||
| 220 | (mci->num_pan || mci->num_other_acl)) | ||
| 221 | ah->btcoex_hw.mci.stomp_ftp = | ||
| 222 | (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); | ||
| 223 | else | ||
| 224 | ah->btcoex_hw.mci.stomp_ftp = false; | ||
| 225 | btcoex->bt_wait_time = 0; | ||
| 226 | sc->rx.num_pkts = 0; | ||
| 227 | } | ||
| 228 | 239 | ||
| 229 | spin_lock_bh(&btcoex->btcoex_lock); | 240 | spin_lock_bh(&btcoex->btcoex_lock); |
| 230 | 241 | ||
| 231 | ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : | 242 | stomp_type = btcoex->bt_stomp_type; |
| 232 | btcoex->bt_stomp_type); | 243 | timer_period = btcoex->btcoex_no_stomp; |
| 244 | |||
| 245 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) { | ||
| 246 | if (test_bit(BT_OP_SCAN, &btcoex->op_flags)) { | ||
| 247 | stomp_type = ATH_BTCOEX_STOMP_ALL; | ||
| 248 | timer_period = btcoex->btscan_no_stomp; | ||
| 249 | } | ||
| 250 | } | ||
| 233 | 251 | ||
| 252 | ath9k_hw_btcoex_bt_stomp(ah, stomp_type); | ||
| 234 | ath9k_hw_btcoex_enable(ah); | 253 | ath9k_hw_btcoex_enable(ah); |
| 254 | |||
| 235 | spin_unlock_bh(&btcoex->btcoex_lock); | 255 | spin_unlock_bh(&btcoex->btcoex_lock); |
| 236 | 256 | ||
| 237 | /* | 257 | /* |
| @@ -243,17 +263,16 @@ static void ath_btcoex_period_timer(unsigned long data) · 5 unmodified lines | |||
| 243 | if (btcoex->hw_timer_enabled) | 263 | if (btcoex->hw_timer_enabled) |
| 244 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); | 264 | ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); |
| 245 | 265 | ||
| 246 | timer_period = is_btscan ? btcoex->btscan_no_stomp : | ||
| 247 | btcoex->btcoex_no_stomp; | ||
| 248 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, | 266 | ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, |
| 249 | timer_period * 10); | 267 | timer_period * 10); |
| 250 | btcoex->hw_timer_enabled = true; | 268 | btcoex->hw_timer_enabled = true; |
| 251 | } | 269 | } |
| 252 | 270 | ||
| 253 | ath9k_ps_restore(sc); | 271 | ath9k_ps_restore(sc); |
| 272 | |||
| 254 | skip_hw_wakeup: | 273 | skip_hw_wakeup: |
| 255 | timer_period = btcoex->btcoex_period; | 274 | mod_timer(&btcoex->period_timer, |
| 256 | mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); | 275 | jiffies + msecs_to_jiffies(btcoex->btcoex_period)); |
| 257 | } | 276 | } |
| 258 | 277 | ||
| 259 | /* | 278 | /* |
| @@ -273,7 +292,8 @@ static void ath_btcoex_no_stomp_timer(void *arg) · 13 unmodified lines | |||
| 273 | spin_lock_bh(&btcoex->btcoex_lock); | 292 | spin_lock_bh(&btcoex->btcoex_lock); |
| 274 | 293 | ||
| 275 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || | 294 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || |
| 276 | test_bit(BT_OP_SCAN, &btcoex->op_flags)) | 295 | (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && |
| 296 | test_bit(BT_OP_SCAN, &btcoex->op_flags))) | ||
| 277 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 297 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
| 278 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 298 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
| 279 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | 299 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
| @@ -474,4 +494,52 @@ int ath9k_init_btcoex(struct ath_softc *sc) · 194 unmodified lines | |||
| 474 | return 0; | 494 | return 0; |
| 475 | } | 495 | } |
| 476 | 496 | ||
| 497 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size) | ||
| 498 | { | ||
| 499 | #define ATH_DUMP_BTCOEX(_s, _val) \ | ||
| 500 | do { \ | ||
| 501 | len += snprintf(buf + len, size - len, \ | ||
| 502 | "%20s : %10d\n", _s, (_val)); \ | ||
| 503 | } while (0) | ||
| 504 | |||
| 505 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
| 506 | struct ath_mci_profile *mci = &btcoex->mci; | ||
| 507 | struct ath_hw *ah = sc->sc_ah; | ||
| 508 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | ||
| 509 | int i; | ||
| 510 | |||
| 511 | ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); | ||
| 512 | ATH_DUMP_BTCOEX("Number of MGMT", mci->num_mgmt); | ||
| 513 | ATH_DUMP_BTCOEX("Number of SCO", mci->num_sco); | ||
| 514 | ATH_DUMP_BTCOEX("Number of A2DP", mci->num_a2dp); | ||
| 515 | ATH_DUMP_BTCOEX("Number of HID", mci->num_hid); | ||
| 516 | ATH_DUMP_BTCOEX("Number of PAN", mci->num_pan); | ||
| 517 | ATH_DUMP_BTCOEX("Number of ACL", mci->num_other_acl); | ||
| 518 | ATH_DUMP_BTCOEX("Number of BDR", mci->num_bdr); | ||
| 519 | ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); | ||
| 520 | ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); | ||
| 521 | ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); | ||
| 522 | ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); | ||
| 523 | ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); | ||
| 524 | ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); | ||
| 525 | ATH_DUMP_BTCOEX("Concur RSSI count", btcoex->rssi_count); | ||
| 526 | len += snprintf(buf + len, size - len, "BT Weights: "); | ||
| 527 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) | ||
| 528 | len += snprintf(buf + len, size - len, "%08x ", | ||
| 529 | btcoex_hw->bt_weight[i]); | ||
| 530 | len += snprintf(buf + len, size - len, "\n"); | ||
| 531 | len += snprintf(buf + len, size - len, "WLAN Weights: "); | ||
| 532 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) | ||
| 533 | len += snprintf(buf + len, size - len, "%08x ", | ||
| 534 | btcoex_hw->wlan_weight[i]); | ||
| 535 | len += snprintf(buf + len, size - len, "\n"); | ||
| 536 | len += snprintf(buf + len, size - len, "Tx Priorities: "); | ||
| 537 | for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) | ||
| 538 | len += snprintf(buf + len, size - len, "%08x ", | ||
| 539 | btcoex_hw->tx_prio[i]); | ||
| 540 | len += snprintf(buf + len, size - len, "\n"); | ||
| 541 | #undef ATH_DUMP_BTCOEX | ||
| 542 | |||
| 543 | return len; | ||
| 544 | } | ||
| 477 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 545 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
| @@ -694,6 +694,20 @@ err_hw: · 693 unmodified lines | |||
| 694 | return ret; | 694 | return ret; |
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | static const struct ieee80211_iface_limit if_limits[] = { | ||
| 698 | { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | | ||
| 699 | BIT(NL80211_IFTYPE_P2P_CLIENT) }, | ||
| 700 | { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | | ||
| 701 | BIT(NL80211_IFTYPE_P2P_GO) }, | ||
| 702 | }; | ||
| 703 | |||
| 704 | static const struct ieee80211_iface_combination if_comb = { | ||
| 705 | .limits = if_limits, | ||
| 706 | .n_limits = ARRAY_SIZE(if_limits), | ||
| 707 | .max_interfaces = 2, | ||
| 708 | .num_different_channels = 1, | ||
| 709 | }; | ||
| 710 | |||
| 697 | static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | 711 | static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, |
| 698 | struct ieee80211_hw *hw) | 712 | struct ieee80211_hw *hw) |
| 699 | { | 713 | { |
| @@ -716,6 +730,9 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, · 16 unmodified lines | |||
| 716 | BIT(NL80211_IFTYPE_P2P_GO) | | 730 | BIT(NL80211_IFTYPE_P2P_GO) | |
| 717 | BIT(NL80211_IFTYPE_P2P_CLIENT); | 731 | BIT(NL80211_IFTYPE_P2P_CLIENT); |
| 718 | 732 | ||
| 733 | hw->wiphy->iface_combinations = &if_comb; | ||
| 734 | hw->wiphy->n_iface_combinations = 1; | ||
| 735 | |||
| 719 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 736 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
| 720 | 737 | ||
| 721 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | | 738 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN | |
| @@ -1036,26 +1036,6 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, · 1035 unmodified lines | |||
| 1036 | 1036 | ||
| 1037 | mutex_lock(&priv->mutex); | 1037 | mutex_lock(&priv->mutex); |
| 1038 | 1038 | ||
| 1039 | if (priv->nvifs >= ATH9K_HTC_MAX_VIF) { | ||
| 1040 | mutex_unlock(&priv->mutex); | ||
| 1041 | return -ENOBUFS; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | if (priv->num_ibss_vif || | ||
| 1045 | (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { | ||
| 1046 | ath_err(common, "IBSS coexistence with other modes is not allowed\n"); | ||
| 1047 | mutex_unlock(&priv->mutex); | ||
| 1048 | return -ENOBUFS; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | if (((vif->type == NL80211_IFTYPE_AP) || | ||
| 1052 | (vif->type == NL80211_IFTYPE_ADHOC)) && | ||
| 1053 | ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) { | ||
| 1054 | ath_err(common, "Max. number of beaconing interfaces reached\n"); | ||
| 1055 | mutex_unlock(&priv->mutex); | ||
| 1056 | return -ENOBUFS; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | ath9k_htc_ps_wakeup(priv); | 1039 | ath9k_htc_ps_wakeup(priv); |
| 1060 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | 1040 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); |
| 1061 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | 1041 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); |
| @@ -2153,9 +2153,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) · 2152 unmodified lines | |||
| 2153 | AR_RTC_FORCE_WAKE_EN); | 2153 | AR_RTC_FORCE_WAKE_EN); |
| 2154 | udelay(50); | 2154 | udelay(50); |
| 2155 | 2155 | ||
| 2156 | if (ath9k_hw_mci_is_enabled(ah)) | ||
| 2157 | ar9003_mci_set_power_awake(ah); | ||
| 2158 | |||
| 2159 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | 2156 | for (i = POWER_UP_TIME / 50; i > 0; i--) { |
| 2160 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | 2157 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; |
| 2161 | if (val == AR_RTC_STATUS_ON) | 2158 | if (val == AR_RTC_STATUS_ON) |
| @@ -2171,6 +2168,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) · 9 unmodified lines | |||
| 2171 | return false; | 2168 | return false; |
| 2172 | } | 2169 | } |
| 2173 | 2170 | ||
| 2171 | if (ath9k_hw_mci_is_enabled(ah)) | ||
| 2172 | ar9003_mci_set_power_awake(ah); | ||
| 2173 | |||
| 2174 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2174 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
| 2175 | 2175 | ||
| 2176 | return true; | 2176 | return true; |
| @@ -401,6 +401,7 @@ enum ath9k_int { · 400 unmodified lines | |||
| 401 | struct ath9k_hw_cal_data { | 401 | struct ath9k_hw_cal_data { |
| 402 | u16 channel; | 402 | u16 channel; |
| 403 | u32 channelFlags; | 403 | u32 channelFlags; |
| 404 | u32 chanmode; | ||
| 404 | int32_t CalValid; | 405 | int32_t CalValid; |
| 405 | int8_t iCoff; | 406 | int8_t iCoff; |
| 406 | int8_t qCoff; | 407 | int8_t qCoff; |
| @@ -834,6 +835,7 @@ struct ath_hw { · 427 unmodified lines | |||
| 834 | int coarse_low[5]; | 835 | int coarse_low[5]; |
| 835 | int firpwr[5]; | 836 | int firpwr[5]; |
| 836 | enum ath9k_ani_cmd ani_function; | 837 | enum ath9k_ani_cmd ani_function; |
| 838 | u32 ani_skip_count; | ||
| 837 | 839 | ||
| 838 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 840 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
| 839 | struct ath_btcoex_hw btcoex_hw; | 841 | struct ath_btcoex_hw btcoex_hw; |
| @@ -687,6 +687,7 @@ static const struct ieee80211_iface_combination if_comb = { · 686 unmodified lines | |||
| 687 | .n_limits = ARRAY_SIZE(if_limits), | 687 | .n_limits = ARRAY_SIZE(if_limits), |
| 688 | .max_interfaces = 2048, | 688 | .max_interfaces = 2048, |
| 689 | .num_different_channels = 1, | 689 | .num_different_channels = 1, |
| 690 | .beacon_int_infra_match = true, | ||
| 690 | }; | 691 | }; |
| 691 | 692 | ||
| 692 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 693 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
| @@ -350,8 +350,18 @@ void ath_ani_calibrate(unsigned long data) · 349 unmodified lines | |||
| 350 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | 350 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; |
| 351 | 351 | ||
| 352 | /* Only calibrate if awake */ | 352 | /* Only calibrate if awake */ |
| 353 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | 353 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) { |
| 354 | if (++ah->ani_skip_count >= ATH_ANI_MAX_SKIP_COUNT) { | ||
| 355 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
| 356 | sc->ps_flags |= PS_WAIT_FOR_ANI; | ||
| 357 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
| 358 | } | ||
| 354 | goto set_timer; | 359 | goto set_timer; |
| 360 | } | ||
| 361 | ah->ani_skip_count = 0; | ||
| 362 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
| 363 | sc->ps_flags &= ~PS_WAIT_FOR_ANI; | ||
| 364 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
| 355 | 365 | ||
| 356 | ath9k_ps_wakeup(sc); | 366 | ath9k_ps_wakeup(sc); |
| 357 | 367 | ||
| @@ -131,7 +131,8 @@ void ath9k_ps_restore(struct ath_softc *sc) · 130 unmodified lines | |||
| 131 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | | 131 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
| 132 | PS_WAIT_FOR_CAB | | 132 | PS_WAIT_FOR_CAB | |
| 133 | PS_WAIT_FOR_PSPOLL_DATA | | 133 | PS_WAIT_FOR_PSPOLL_DATA | |
| 134 | PS_WAIT_FOR_TX_ACK))) { | 134 | PS_WAIT_FOR_TX_ACK | |
| 135 | PS_WAIT_FOR_ANI))) { | ||
| 135 | mode = ATH9K_PM_NETWORK_SLEEP; | 136 | mode = ATH9K_PM_NETWORK_SLEEP; |
| 136 | if (ath9k_hw_btcoex_is_enabled(sc->sc_ah)) | 137 | if (ath9k_hw_btcoex_is_enabled(sc->sc_ah)) |
| 137 | ath9k_btcoex_stop_gen_timer(sc); | 138 | ath9k_btcoex_stop_gen_timer(sc); |
| @@ -292,6 +293,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, · 154 unmodified lines | |||
| 292 | goto out; | 293 | goto out; |
| 293 | } | 294 | } |
| 294 | 295 | ||
| 296 | if (ath9k_hw_mci_is_enabled(sc->sc_ah) && | ||
| 297 | (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | ||
| 298 | ath9k_mci_set_txpower(sc, true, false); | ||
| 299 | |||
| 295 | if (!ath_complete_reset(sc, true)) | 300 | if (!ath_complete_reset(sc, true)) |
| 296 | r = -EIO; | 301 | r = -EIO; |
| 297 | 302 | ||
| @@ -1449,6 +1454,9 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, · 1151 unmodified lines | |||
| 1449 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 1454 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
| 1450 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 1455 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 1451 | 1456 | ||
| 1457 | if (ath9k_hw_mci_is_enabled(sc->sc_ah)) | ||
| 1458 | ath9k_mci_update_wlan_channels(sc, false); | ||
| 1459 | |||
| 1452 | ath_dbg(common, CONFIG, | 1460 | ath_dbg(common, CONFIG, |
| 1453 | "Primary Station interface: %pM, BSSID: %pM\n", | 1461 | "Primary Station interface: %pM, BSSID: %pM\n", |
| 1454 | vif->addr, common->curbssid); | 1462 | vif->addr, common->curbssid); |
| @@ -1505,6 +1513,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, · 50 unmodified lines | |||
| 1505 | memset(common->curbssid, 0, ETH_ALEN); | 1513 | memset(common->curbssid, 0, ETH_ALEN); |
| 1506 | common->curaid = 0; | 1514 | common->curaid = 0; |
| 1507 | ath9k_hw_write_associd(sc->sc_ah); | 1515 | ath9k_hw_write_associd(sc->sc_ah); |
| 1516 | if (ath9k_hw_mci_is_enabled(sc->sc_ah)) | ||
| 1517 | ath9k_mci_update_wlan_channels(sc, true); | ||
| 1508 | } | 1518 | } |
| 1509 | } | 1519 | } |
| 1510 | 1520 | ||
| @@ -43,6 +43,7 @@ static bool ath_mci_add_profile(struct ath_common *common, · 42 unmodified lines | |||
| 43 | struct ath_mci_profile_info *info) | 43 | struct ath_mci_profile_info *info) |
| 44 | { | 44 | { |
| 45 | struct ath_mci_profile_info *entry; | 45 | struct ath_mci_profile_info *entry; |
| 46 | u8 voice_priority[] = { 110, 110, 110, 112, 110, 110, 114, 116, 118 }; | ||
| 46 | 47 | ||
| 47 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && | 48 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && |
| 48 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) | 49 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) |
| @@ -59,6 +60,12 @@ static bool ath_mci_add_profile(struct ath_common *common, · 10 unmodified lines | |||
| 59 | memcpy(entry, info, 10); | 60 | memcpy(entry, info, 10); |
| 60 | INC_PROF(mci, info); | 61 | INC_PROF(mci, info); |
| 61 | list_add_tail(&entry->list, &mci->info); | 62 | list_add_tail(&entry->list, &mci->info); |
| 63 | if (info->type == MCI_GPM_COEX_PROFILE_VOICE) { | ||
| 64 | if (info->voice_type < sizeof(voice_priority)) | ||
| 65 | mci->voice_priority = voice_priority[info->voice_type]; | ||
| 66 | else | ||
| 67 | mci->voice_priority = 110; | ||
| 68 | } | ||
| 62 | 69 | ||
| 63 | return true; | 70 | return true; |
| 64 | } | 71 | } |
| @@ -150,7 +157,7 @@ static void ath_mci_update_scheme(struct ath_softc *sc) · 85 unmodified lines | |||
| 150 | * For single PAN/FTP profile, allocate 35% for BT | 157 | * For single PAN/FTP profile, allocate 35% for BT |
| 151 | * to improve WLAN throughput. | 158 | * to improve WLAN throughput. |
| 152 | */ | 159 | */ |
| 153 | btcoex->duty_cycle = 35; | 160 | btcoex->duty_cycle = AR_SREV_9565(sc->sc_ah) ? 40 : 35; |
| 154 | btcoex->btcoex_period = 53; | 161 | btcoex->btcoex_period = 53; |
| 155 | ath_dbg(common, MCI, | 162 | ath_dbg(common, MCI, |
| 156 | "Single PAN/FTP bt period %d ms dutycycle %d\n", | 163 | "Single PAN/FTP bt period %d ms dutycycle %d\n", |
| @@ -250,6 +257,57 @@ static void ath9k_mci_work(struct work_struct *work) · 93 unmodified lines | |||
| 250 | ath_mci_update_scheme(sc); | 257 | ath_mci_update_scheme(sc); |
| 251 | } | 258 | } |
| 252 | 259 | ||
| 260 | static void ath_mci_update_stomp_txprio(u8 cur_txprio, u8 *stomp_prio) | ||
| 261 | { | ||
| 262 | if (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_NONE]) | ||
| 263 | stomp_prio[ATH_BTCOEX_STOMP_NONE] = cur_txprio; | ||
| 264 | |||
| 265 | if (cur_txprio > stomp_prio[ATH_BTCOEX_STOMP_ALL]) | ||
| 266 | stomp_prio[ATH_BTCOEX_STOMP_ALL] = cur_txprio; | ||
| 267 | |||
| 268 | if ((cur_txprio > ATH_MCI_HI_PRIO) && | ||
| 269 | (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_LOW])) | ||
| 270 | stomp_prio[ATH_BTCOEX_STOMP_LOW] = cur_txprio; | ||
| 271 | } | ||
| 272 | |||
| 273 | static void ath_mci_set_concur_txprio(struct ath_softc *sc) | ||
| 274 | { | ||
| 275 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
| 276 | struct ath_mci_profile *mci = &btcoex->mci; | ||
| 277 | u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */ | ||
| 278 | |||
| 279 | if (mci->num_mgmt) { | ||
| 280 | stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO; | ||
| 281 | if (!mci->num_pan && !mci->num_other_acl) | ||
| 282 | stomp_txprio[ATH_BTCOEX_STOMP_NONE] = | ||
| 283 | ATH_MCI_INQUIRY_PRIO; | ||
| 284 | } else { | ||
| 285 | u8 prof_prio[] = { 50, 90, 94, 52 };/* RFCOMM, A2DP, HID, PAN */ | ||
| 286 | |||
| 287 | stomp_txprio[ATH_BTCOEX_STOMP_LOW] = | ||
| 288 | stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0xff; | ||
| 289 | |||
| 290 | if (mci->num_sco) | ||
| 291 | ath_mci_update_stomp_txprio(mci->voice_priority, | ||
| 292 | stomp_txprio); | ||
| 293 | if (mci->num_other_acl) | ||
| 294 | ath_mci_update_stomp_txprio(prof_prio[0], stomp_txprio); | ||
| 295 | if (mci->num_a2dp) | ||
| 296 | ath_mci_update_stomp_txprio(prof_prio[1], stomp_txprio); | ||
| 297 | if (mci->num_hid) | ||
| 298 | ath_mci_update_stomp_txprio(prof_prio[2], stomp_txprio); | ||
| 299 | if (mci->num_pan) | ||
| 300 | ath_mci_update_stomp_txprio(prof_prio[3], stomp_txprio); | ||
| 301 | |||
| 302 | if (stomp_txprio[ATH_BTCOEX_STOMP_NONE] == 0xff) | ||
| 303 | stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0; | ||
| 304 | |||
| 305 | if (stomp_txprio[ATH_BTCOEX_STOMP_LOW] == 0xff) | ||
| 306 | stomp_txprio[ATH_BTCOEX_STOMP_LOW] = 0; | ||
| 307 | } | ||
| 308 | ath9k_hw_btcoex_set_concur_txprio(sc->sc_ah, stomp_txprio); | ||
| 309 | } | ||
| 310 | |||
| 253 | static u8 ath_mci_process_profile(struct ath_softc *sc, | 311 | static u8 ath_mci_process_profile(struct ath_softc *sc, |
| 254 | struct ath_mci_profile_info *info) | 312 | struct ath_mci_profile_info *info) |
| 255 | { | 313 | { |
| @@ -281,6 +339,7 @@ static u8 ath_mci_process_profile(struct ath_softc *sc, · 25 unmodified lines | |||
| 281 | } else | 339 | } else |
| 282 | ath_mci_del_profile(common, mci, entry); | 340 | ath_mci_del_profile(common, mci, entry); |
| 283 | 341 | ||
| 342 | ath_mci_set_concur_txprio(sc); | ||
| 284 | return 1; | 343 | return 1; |
| 285 | } | 344 | } |
| 286 | 345 | ||
| @@ -314,6 +373,7 @@ static u8 ath_mci_process_status(struct ath_softc *sc, · 27 unmodified lines | |||
| 314 | mci->num_mgmt++; | 373 | mci->num_mgmt++; |
| 315 | } while (++i < ATH_MCI_MAX_PROFILE); | 374 | } while (++i < ATH_MCI_MAX_PROFILE); |
| 316 | 375 | ||
| 376 | ath_mci_set_concur_txprio(sc); | ||
| 317 | if (old_num_mgmt != mci->num_mgmt) | 377 | if (old_num_mgmt != mci->num_mgmt) |
| 318 | return 1; | 378 | return 1; |
| 319 | 379 | ||
| @@ -600,3 +660,112 @@ void ath_mci_enable(struct ath_softc *sc) · 280 unmodified lines | |||
| 600 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | 660 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) |
| 601 | sc->sc_ah->imask |= ATH9K_INT_MCI; | 661 | sc->sc_ah->imask |= ATH9K_INT_MCI; |
| 602 | } | 662 | } |
| 663 | |||
| 664 | void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all) | ||
| 665 | { | ||
| 666 | struct ath_hw *ah = sc->sc_ah; | ||
| 667 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
| 668 | struct ath9k_channel *chan = ah->curchan; | ||
| 669 | u32 channelmap[] = {0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff}; | ||
| 670 | int i; | ||
| 671 | s16 chan_start, chan_end; | ||
| 672 | u16 wlan_chan; | ||
| 673 | |||
| 674 | if (!chan || !IS_CHAN_2GHZ(chan)) | ||
| 675 | return; | ||
| 676 | |||
| 677 | if (allow_all) | ||
| 678 | goto send_wlan_chan; | ||
| 679 | |||
| 680 | wlan_chan = chan->channel - 2402; | ||
| 681 | |||
| 682 | chan_start = wlan_chan - 10; | ||
| 683 | chan_end = wlan_chan + 10; | ||
| 684 | |||
| 685 | if (chan->chanmode == CHANNEL_G_HT40PLUS) | ||
| 686 | chan_end += 20; | ||
| 687 | else if (chan->chanmode == CHANNEL_G_HT40MINUS) | ||
| 688 | chan_start -= 20; | ||
| 689 | |||
| 690 | /* adjust side band */ | ||
| 691 | chan_start -= 7; | ||
| 692 | chan_end += 7; | ||
| 693 | |||
| 694 | if (chan_start <= 0) | ||
| 695 | chan_start = 0; | ||
| 696 | if (chan_end >= ATH_MCI_NUM_BT_CHANNELS) | ||
| 697 | chan_end = ATH_MCI_NUM_BT_CHANNELS - 1; | ||
| 698 | |||
| 699 | ath_dbg(ath9k_hw_common(ah), MCI, | ||
| 700 | "WLAN current channel %d mask BT channel %d - %d\n", | ||
| 701 | wlan_chan, chan_start, chan_end); | ||
| 702 | |||
| 703 | for (i = chan_start; i < chan_end; i++) | ||
| 704 | MCI_GPM_CLR_CHANNEL_BIT(&channelmap, i); | ||
| 705 | |||
| 706 | send_wlan_chan: | ||
| 707 | /* update and send wlan channels info to BT */ | ||
| 708 | for (i = 0; i < 4; i++) | ||
| 709 | mci->wlan_channels[i] = channelmap[i]; | ||
| 710 | ar9003_mci_send_wlan_channels(ah); | ||
| 711 | ar9003_mci_state(ah, MCI_STATE_SEND_VERSION_QUERY); | ||
| 712 | } | ||
| 713 | |||
| 714 | void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, | ||
| 715 | bool concur_tx) | ||
| 716 | { | ||
| 717 | struct ath_hw *ah = sc->sc_ah; | ||
| 718 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; | ||
| 719 | bool old_concur_tx = mci_hw->concur_tx; | ||
| 720 | |||
| 721 | if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) { | ||
| 722 | mci_hw->concur_tx = false; | ||
| 723 | return; | ||
| 724 | } | ||
| 725 | |||
| 726 | if (!IS_CHAN_2GHZ(ah->curchan)) | ||
| 727 | return; | ||
| 728 | |||
| 729 | if (setchannel) { | ||
| 730 | struct ath9k_hw_cal_data *caldata = &sc->caldata; | ||
| 731 | if ((caldata->chanmode == CHANNEL_G_HT40PLUS) && | ||
| 732 | (ah->curchan->channel > caldata->channel) && | ||
| 733 | (ah->curchan->channel <= caldata->channel + 20)) | ||
| 734 | return; | ||
| 735 | if ((caldata->chanmode == CHANNEL_G_HT40MINUS) && | ||
| 736 | (ah->curchan->channel < caldata->channel) && | ||
| 737 | (ah->curchan->channel >= caldata->channel - 20)) | ||
| 738 | return; | ||
| 739 | mci_hw->concur_tx = false; | ||
| 740 | } else | ||
| 741 | mci_hw->concur_tx = concur_tx; | ||
| 742 | |||
| 743 | if (old_concur_tx != mci_hw->concur_tx) | ||
| 744 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); | ||
| 745 | } | ||
| 746 | |||
| 747 | void ath9k_mci_update_rssi(struct ath_softc *sc) | ||
| 748 | { | ||
| 749 | struct ath_hw *ah = sc->sc_ah; | ||
| 750 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
| 751 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; | ||
| 752 | |||
| 753 | if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) | ||
| 754 | return; | ||
| 755 | |||
| 756 | if (ah->stats.avgbrssi >= 40) { | ||
| 757 | if (btcoex->rssi_count < 0) | ||
| 758 | btcoex->rssi_count = 0; | ||
| 759 | if (++btcoex->rssi_count >= ATH_MCI_CONCUR_TX_SWITCH) { | ||
| 760 | btcoex->rssi_count = 0; | ||
| 761 | ath9k_mci_set_txpower(sc, false, true); | ||
| 762 | } | ||
| 763 | } else { | ||
| 764 | if (btcoex->rssi_count > 0) | ||
| 765 | btcoex->rssi_count = 0; | ||
| 766 | if (--btcoex->rssi_count <= -ATH_MCI_CONCUR_TX_SWITCH) { | ||
| 767 | btcoex->rssi_count = 0; | ||
| 768 | ath9k_mci_set_txpower(sc, false, false); | ||
| 769 | } | ||
| 770 | } | ||
| 771 | } | ||
| @@ -32,6 +32,27 @@ · 31 unmodified lines | |||
| 32 | #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ | 32 | #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ |
| 33 | ATH_MCI_MAX_SCO_PROFILE) | 33 | ATH_MCI_MAX_SCO_PROFILE) |
| 34 | 34 | ||
| 35 | #define ATH_MCI_INQUIRY_PRIO 62 | ||
| 36 | #define ATH_MCI_HI_PRIO 60 | ||
| 37 | #define ATH_MCI_NUM_BT_CHANNELS 79 | ||
| 38 | #define ATH_MCI_CONCUR_TX_SWITCH 5 | ||
| 39 | |||
| 40 | #define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \ | ||
| 41 | do { \ | ||
| 42 | if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ | ||
| 43 | *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ | ||
| 44 | (_bt_chan / 8)) |= (1 << (_bt_chan & 7)); \ | ||
| 45 | } \ | ||
| 46 | } while (0) | ||
| 47 | |||
| 48 | #define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan) \ | ||
| 49 | do { \ | ||
| 50 | if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ | ||
| 51 | *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ | ||
| 52 | (_bt_chan / 8)) &= ~(1 << (_bt_chan & 7));\ | ||
| 53 | } \ | ||
| 54 | } while (0) | ||
| 55 | |||
| 35 | #define INC_PROF(_mci, _info) do { \ | 56 | #define INC_PROF(_mci, _info) do { \ |
| 36 | switch (_info->type) { \ | 57 | switch (_info->type) { \ |
| 37 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ | 58 | case MCI_GPM_COEX_PROFILE_RFCOMM:\ |
| @@ -49,6 +70,7 @@ · 11 unmodified lines | |||
| 49 | _mci->num_pan++; \ | 70 | _mci->num_pan++; \ |
| 50 | break; \ | 71 | break; \ |
| 51 | case MCI_GPM_COEX_PROFILE_VOICE: \ | 72 | case MCI_GPM_COEX_PROFILE_VOICE: \ |
| 73 | case MCI_GPM_COEX_PROFILE_A2DPVO:\ | ||
| 52 | _mci->num_sco++; \ | 74 | _mci->num_sco++; \ |
| 53 | break; \ | 75 | break; \ |
| 54 | default: \ | 76 | default: \ |
| @@ -73,6 +95,7 @@ · 18 unmodified lines | |||
| 73 | _mci->num_pan--; \ | 95 | _mci->num_pan--; \ |
| 74 | break; \ | 96 | break; \ |
| 75 | case MCI_GPM_COEX_PROFILE_VOICE: \ | 97 | case MCI_GPM_COEX_PROFILE_VOICE: \ |
| 98 | case MCI_GPM_COEX_PROFILE_A2DPVO:\ | ||
| 76 | _mci->num_sco--; \ | 99 | _mci->num_sco--; \ |
| 77 | break; \ | 100 | break; \ |
| 78 | default: \ | 101 | default: \ |
| @@ -113,6 +136,7 @@ struct ath_mci_profile { · 34 unmodified lines | |||
| 113 | u8 num_pan; | 136 | u8 num_pan; |
| 114 | u8 num_other_acl; | 137 | u8 num_other_acl; |
| 115 | u8 num_bdr; | 138 | u8 num_bdr; |
| 139 | u8 voice_priority; | ||
| 116 | }; | 140 | }; |
| 117 | 141 | ||
| 118 | struct ath_mci_buf { | 142 | struct ath_mci_buf { |
| @@ -130,13 +154,25 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci); · 11 unmodified lines | |||
| 130 | int ath_mci_setup(struct ath_softc *sc); | 154 | int ath_mci_setup(struct ath_softc *sc); |
| 131 | void ath_mci_cleanup(struct ath_softc *sc); | 155 | void ath_mci_cleanup(struct ath_softc *sc); |
| 132 | void ath_mci_intr(struct ath_softc *sc); | 156 | void ath_mci_intr(struct ath_softc *sc); |
| 157 | void ath9k_mci_update_rssi(struct ath_softc *sc); | ||
| 133 | 158 | ||
| 134 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 159 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
| 135 | void ath_mci_enable(struct ath_softc *sc); | 160 | void ath_mci_enable(struct ath_softc *sc); |
| 161 | void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all); | ||
| 162 | void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, | ||
| 163 | bool concur_tx); | ||
| 136 | #else | 164 | #else |
| 137 | static inline void ath_mci_enable(struct ath_softc *sc) | 165 | static inline void ath_mci_enable(struct ath_softc *sc) |
| 138 | { | 166 | { |
| 139 | } | 167 | } |
| 168 | static inline void ath9k_mci_update_wlan_channels(struct ath_softc *sc, | ||
| 169 | bool allow_all) | ||
| 170 | { | ||
| 171 | } | ||
| 172 | static inline void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, | ||
| 173 | bool concur_tx) | ||
| 174 | { | ||
| 175 | } | ||
| 140 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 176 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
| 141 | 177 | ||
| 142 | #endif /* MCI_H*/ | 178 | #endif /* MCI_H*/ |
| @@ -1105,7 +1105,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) · 1104 unmodified lines | |||
| 1105 | else | 1105 | else |
| 1106 | rs.is_mybeacon = false; | 1106 | rs.is_mybeacon = false; |
| 1107 | 1107 | ||
| 1108 | sc->rx.num_pkts++; | 1108 | if (ieee80211_is_data_present(hdr->frame_control) && |
| 1109 | !ieee80211_is_qos_nullfunc(hdr->frame_control)) | ||
| 1110 | sc->rx.num_pkts++; | ||
| 1111 | |||
| 1109 | ath_debug_stat_rx(sc, &rs); | 1112 | ath_debug_stat_rx(sc, &rs); |
| 1110 | 1113 | ||
| 1111 | /* | 1114 | /* |
| @@ -907,10 +907,6 @@ · 906 unmodified lines | |||
| 907 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | 907 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ |
| 908 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) | 908 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) |
| 909 | 909 | ||
| 910 | #define AR_SREV_9462_20_OR_LATER(_ah) \ | ||
| 911 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ | ||
| 912 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) | ||
| 913 | |||
| 914 | #define AR_SREV_9565(_ah) \ | 910 | #define AR_SREV_9565(_ah) \ |
| 915 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) | 911 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) |
| 916 | 912 | ||
| @@ -2315,6 +2311,8 @@ enum { · 1398 unmodified lines | |||
| 2315 | #define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2)) | 2311 | #define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2)) |
| 2316 | #define AR_BTCOEX_WL_LNA 0x1940 | 2312 | #define AR_BTCOEX_WL_LNA 0x1940 |
| 2317 | #define AR_BTCOEX_RFGAIN_CTRL 0x1944 | 2313 | #define AR_BTCOEX_RFGAIN_CTRL 0x1944 |
| 2314 | #define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF | ||
| 2315 | #define AR_BTCOEX_WL_LNA_TIMEOUT_S 0 | ||
| 2318 | 2316 | ||
| 2319 | #define AR_BTCOEX_CTRL2 0x1948 | 2317 | #define AR_BTCOEX_CTRL2 0x1948 |
| 2320 | #define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800 | 2318 | #define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800 |
| @@ -2360,4 +2358,11 @@ enum { · 39 unmodified lines | |||
| 2360 | #define AR_GLB_SWREG_DISCONT_MODE 0x2002c | 2358 | #define AR_GLB_SWREG_DISCONT_MODE 0x2002c |
| 2361 | #define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 | 2359 | #define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 |
| 2362 | 2360 | ||
| 2361 | #define AR_MCI_MISC 0x1a74 | ||
| 2362 | #define AR_MCI_MISC_HW_FIX_EN 0x00000001 | ||
| 2363 | #define AR_MCI_MISC_HW_FIX_EN_S 0 | ||
| 2364 | #define AR_MCI_DBG_CNT_CTRL 0x1a78 | ||
| 2365 | #define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001 | ||
| 2366 | #define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0 | ||
| 2367 | |||
| 2363 | #endif | 2368 | #endif |
| @@ -118,7 +118,7 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) · 117 unmodified lines | |||
| 118 | (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); | 118 | (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); |
| 119 | data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); | 119 | data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); |
| 120 | 120 | ||
| 121 | if (AR_SREV_9462_20_OR_LATER(ah)) { | 121 | if (AR_SREV_9462_20(ah)) { |
| 122 | /* AR9462 2.0 has an extra descriptor word (time based | 122 | /* AR9462 2.0 has an extra descriptor word (time based |
| 123 | * discard) compared to other chips */ | 123 | * discard) compared to other chips */ |
| 124 | REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); | 124 | REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); |
| @@ -343,7 +343,24 @@ int carl9170_set_operating_mode(struct ar9170 *ar) · 342 unmodified lines | |||
| 343 | break; | 343 | break; |
| 344 | } | 344 | } |
| 345 | } else { | 345 | } else { |
| 346 | mac_addr = NULL; | 346 | /* |
| 347 | * Enable monitor mode | ||
| 348 | * | ||
| 349 | * rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; | ||
| 350 | * sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; | ||
| 351 | * | ||
| 352 | * When the hardware is in SNIFFER_PROMISC mode, | ||
| 353 | * it generates spurious ACKs for every incoming | ||
| 354 | * frame. This confuses every peer in the | ||
| 355 | * vicinity and the network throughput will suffer | ||
| 356 | * badly. | ||
| 357 | * | ||
| 358 | * Hence, the hardware will be put into station | ||
| 359 | * mode and just the rx filters are disabled. | ||
| 360 | */ | ||
| 361 | cam_mode |= AR9170_MAC_CAM_STA; | ||
| 362 | rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; | ||
| 363 | mac_addr = common->macaddr; | ||
| 347 | bssid = NULL; | 364 | bssid = NULL; |
| 348 | } | 365 | } |
| 349 | rcu_read_unlock(); | 366 | rcu_read_unlock(); |
| @@ -355,8 +372,6 @@ int carl9170_set_operating_mode(struct ar9170 *ar) · 5 unmodified lines | |||
| 355 | enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; | 372 | enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; |
| 356 | 373 | ||
| 357 | if (ar->sniffer_enabled) { | 374 | if (ar->sniffer_enabled) { |
| 358 | rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; | ||
| 359 | sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; | ||
| 360 | enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; | 375 | enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; |
| 361 | } | 376 | } |
| 362 | 377 | ||
| @@ -164,9 +164,6 @@ void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) · 163 unmodified lines | |||
| 164 | struct carl9170_rsp *cmd = buf; | 164 | struct carl9170_rsp *cmd = buf; |
| 165 | struct ieee80211_vif *vif; | 165 | struct ieee80211_vif *vif; |
| 166 | 166 | ||
| 167 | if (carl9170_check_sequence(ar, cmd->hdr.seq)) | ||
| 168 | return; | ||
| 169 | |||
| 170 | if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { | 167 | if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { |
| 171 | if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) | 168 | if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) |
| 172 | carl9170_cmd_callback(ar, len, buf); | 169 | carl9170_cmd_callback(ar, len, buf); |
| @@ -663,6 +660,35 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, · 490 unmodified lines | |||
| 663 | return false; | 660 | return false; |
| 664 | } | 661 | } |
| 665 | 662 | ||
| 663 | static int carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len, | ||
| 664 | struct ieee80211_rx_status *status) | ||
| 665 | { | ||
| 666 | struct sk_buff *skb; | ||
| 667 | |||
| 668 | /* (driver) frame trap handler | ||
| 669 | * | ||
| 670 | * Because power-saving mode handing has to be implemented by | ||
| 671 | * the driver/firmware. We have to check each incoming beacon | ||
| 672 | * from the associated AP, if there's new data for us (either | ||
| 673 | * broadcast/multicast or unicast) we have to react quickly. | ||
| 674 | * | ||
| 675 | * So, if you have you want to add additional frame trap | ||
| 676 | * handlers, this would be the perfect place! | ||
| 677 | */ | ||
| 678 | |||
| 679 | carl9170_ps_beacon(ar, buf, len); | ||
| 680 | |||
| 681 | carl9170_ba_check(ar, buf, len); | ||
| 682 | |||
| 683 | skb = carl9170_rx_copy_data(buf, len); | ||
| 684 | if (!skb) | ||
| 685 | return -ENOMEM; | ||
| 686 | |||
| 687 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); | ||
| 688 | ieee80211_rx(ar->hw, skb); | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | |||
| 666 | /* | 692 | /* |
| 667 | * If the frame alignment is right (or the kernel has | 693 | * If the frame alignment is right (or the kernel has |
| 668 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there | 694 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there |
| @@ -672,14 +698,12 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, · 3 unmodified lines | |||
| 672 | * mode, and we need to observe the proper ordering, | 698 | * mode, and we need to observe the proper ordering, |
| 673 | * this is non-trivial. | 699 | * this is non-trivial. |
| 674 | */ | 700 | */ |
| 675 | 701 | static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) | |
| 676 | static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | ||
| 677 | { | 702 | { |
| 678 | struct ar9170_rx_head *head; | 703 | struct ar9170_rx_head *head; |
| 679 | struct ar9170_rx_macstatus *mac; | 704 | struct ar9170_rx_macstatus *mac; |
| 680 | struct ar9170_rx_phystatus *phy = NULL; | 705 | struct ar9170_rx_phystatus *phy = NULL; |
| 681 | struct ieee80211_rx_status status; | 706 | struct ieee80211_rx_status status; |
| 682 | struct sk_buff *skb; | ||
| 683 | int mpdu_len; | 707 | int mpdu_len; |
| 684 | u8 mac_status; | 708 | u8 mac_status; |
| 685 | 709 | ||
| @@ -791,18 +815,10 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) · 105 unmodified lines | |||
| 791 | if (phy) | 815 | if (phy) |
| 792 | carl9170_rx_phy_status(ar, phy, &status); | 816 | carl9170_rx_phy_status(ar, phy, &status); |
| 793 | 817 | ||
| 794 | carl9170_ps_beacon(ar, buf, mpdu_len); | 818 | if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status)) |
| 795 | |||
| 796 | carl9170_ba_check(ar, buf, mpdu_len); | ||
| 797 | |||
| 798 | skb = carl9170_rx_copy_data(buf, mpdu_len); | ||
| 799 | if (!skb) | ||
| 800 | goto drop; | 819 | goto drop; |
| 801 | 820 | ||
| 802 | memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); | ||
| 803 | ieee80211_rx(ar->hw, skb); | ||
| 804 | return; | 821 | return; |
| 805 | |||
| 806 | drop: | 822 | drop: |
| 807 | ar->rx_dropped++; | 823 | ar->rx_dropped++; |
| 808 | } | 824 | } |
| @@ -820,6 +836,9 @@ static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, · 11 unmodified lines | |||
| 820 | if (unlikely(i > resplen)) | 836 | if (unlikely(i > resplen)) |
| 821 | break; | 837 | break; |
| 822 | 838 | ||
| 839 | if (carl9170_check_sequence(ar, cmd->hdr.seq)) | ||
| 840 | break; | ||
| 841 | |||
| 823 | carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); | 842 | carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); |
| 824 | } | 843 | } |
| 825 | 844 | ||
| @@ -851,7 +870,7 @@ static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len) · 25 unmodified lines | |||
| 851 | if (i == 12) | 870 | if (i == 12) |
| 852 | carl9170_rx_untie_cmds(ar, buf, len); | 871 | carl9170_rx_untie_cmds(ar, buf, len); |
| 853 | else | 872 | else |
| 854 | carl9170_handle_mpdu(ar, buf, len); | 873 | carl9170_rx_untie_data(ar, buf, len); |
| 855 | } | 874 | } |
| 856 | 875 | ||
| 857 | static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) | 876 | static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) |
| @@ -295,6 +295,13 @@ static void carl9170_usb_rx_irq_complete(struct urb *urb) · 294 unmodified lines | |||
| 295 | goto resubmit; | 295 | goto resubmit; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | /* | ||
| 299 | * While the carl9170 firmware does not use this EP, the | ||
| 300 | * firmware loader in the EEPROM unfortunately does. | ||
| 301 | * Therefore we need to be ready to handle out-of-band | ||
| 302 | * responses and traps in case the firmware crashed and | ||
| 303 | * the loader took over again. | ||
| 304 | */ | ||
| 298 | carl9170_handle_command_response(ar, urb->transfer_buffer, | 305 | carl9170_handle_command_response(ar, urb->transfer_buffer, |
| 299 | urb->actual_length); | 306 | urb->actual_length); |
| 300 | 307 | ||
| @@ -20,8 +20,8 @@ · 19 unmodified lines | |||
| 20 | #include "ath.h" | 20 | #include "ath.h" |
| 21 | #include "reg.h" | 21 | #include "reg.h" |
| 22 | 22 | ||
| 23 | #define REG_READ (common->ops->read) | 23 | #define REG_READ (common->ops->read) |
| 24 | #define REG_WRITE (common->ops->write) | 24 | #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * ath_hw_set_bssid_mask - filter out bssids we listen | 27 | * ath_hw_set_bssid_mask - filter out bssids we listen |
| @@ -119,8 +119,8 @@ void ath_hw_setbssidmask(struct ath_common *common) · 91 unmodified lines | |||
| 119 | { | 119 | { |
| 120 | void *ah = common->ah; | 120 | void *ah = common->ah; |
| 121 | 121 | ||
| 122 | REG_WRITE(ah, get_unaligned_le32(common->bssidmask), AR_BSSMSKL); | 122 | REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask)); |
| 123 | REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); | 123 | REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4)); |
| 124 | } | 124 | } |
| 125 | EXPORT_SYMBOL(ath_hw_setbssidmask); | 125 | EXPORT_SYMBOL(ath_hw_setbssidmask); |
| 126 | 126 | ||
| @@ -139,7 +139,7 @@ void ath_hw_cycle_counters_update(struct ath_common *common) · 12 unmodified lines | |||
| 139 | void *ah = common->ah; | 139 | void *ah = common->ah; |
| 140 | 140 | ||
| 141 | /* freeze */ | 141 | /* freeze */ |
| 142 | REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC); | 142 | REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); |
| 143 | 143 | ||
| 144 | /* read */ | 144 | /* read */ |
| 145 | cycles = REG_READ(ah, AR_CCCNT); | 145 | cycles = REG_READ(ah, AR_CCCNT); |
| @@ -148,13 +148,13 @@ void ath_hw_cycle_counters_update(struct ath_common *common) · 2 unmodified lines | |||
| 148 | tx = REG_READ(ah, AR_TFCNT); | 148 | tx = REG_READ(ah, AR_TFCNT); |
| 149 | 149 | ||
| 150 | /* clear */ | 150 | /* clear */ |
| 151 | REG_WRITE(ah, 0, AR_CCCNT); | 151 | REG_WRITE(ah, AR_CCCNT, 0); |
| 152 | REG_WRITE(ah, 0, AR_RFCNT); | 152 | REG_WRITE(ah, AR_RFCNT, 0); |
| 153 | REG_WRITE(ah, 0, AR_RCCNT); | 153 | REG_WRITE(ah, AR_RCCNT, 0); |
| 154 | REG_WRITE(ah, 0, AR_TFCNT); | 154 | REG_WRITE(ah, AR_TFCNT, 0); |
| 155 | 155 | ||
| 156 | /* unfreeze */ | 156 | /* unfreeze */ |
| 157 | REG_WRITE(ah, 0, AR_MIBC); | 157 | REG_WRITE(ah, AR_MIBC, 0); |
| 158 | 158 | ||
| 159 | /* update all cycle counters here */ | 159 | /* update all cycle counters here */ |
| 160 | common->cc_ani.cycles += cycles; | 160 | common->cc_ani.cycles += cycles; |
| @@ -4652,7 +4652,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) · 4651 unmodified lines | |||
| 4652 | switch (dev->dev->bus_type) { | 4652 | switch (dev->dev->bus_type) { |
| 4653 | #ifdef CONFIG_B43_BCMA | 4653 | #ifdef CONFIG_B43_BCMA |
| 4654 | case B43_BUS_BCMA: | 4654 | case B43_BUS_BCMA: |
| 4655 | bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, | 4655 | bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], |
| 4656 | dev->dev->bdev, true); | 4656 | dev->dev->bdev, true); |
| 4657 | break; | 4657 | break; |
| 4658 | #endif | 4658 | #endif |
| @@ -24,6 +24,7 @@ ccflags-y += -D__CHECK_ENDIAN__ · 23 unmodified lines | |||
| 24 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | 24 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o |
| 25 | brcmfmac-objs += \ | 25 | brcmfmac-objs += \ |
| 26 | wl_cfg80211.o \ | 26 | wl_cfg80211.o \ |
| 27 | fwil.o \ | ||
| 27 | dhd_cdc.o \ | 28 | dhd_cdc.o \ |
| 28 | dhd_common.o \ | 29 | dhd_common.o \ |
| 29 | dhd_linux.o | 30 | dhd_linux.o |
| @@ -318,6 +318,12 @@ struct brcmf_event { · 317 unmodified lines | |||
| 318 | #define BRCMF_E_LINK_ASSOC_REC 3 | 318 | #define BRCMF_E_LINK_ASSOC_REC 3 |
| 319 | #define BRCMF_E_LINK_BSSCFG_DIS 4 | 319 | #define BRCMF_E_LINK_BSSCFG_DIS 4 |
| 320 | 320 | ||
| 321 | /* Small, medium and maximum buffer size for dcmd | ||
| 322 | */ | ||
| 323 | #define BRCMF_DCMD_SMLEN 256 | ||
| 324 | #define BRCMF_DCMD_MEDLEN 1536 | ||
| 325 | #define BRCMF_DCMD_MAXLEN 8192 | ||
| 326 | |||
| 321 | /* Pattern matching filter. Specifies an offset within received packets to | 327 | /* Pattern matching filter. Specifies an offset within received packets to |
| 322 | * start matching, the pattern to match, the size of the pattern, and a bitmask | 328 | * start matching, the pattern to match, the size of the pattern, and a bitmask |
| 323 | * that indicates which bits within the pattern should be matched. | 329 | * that indicates which bits within the pattern should be matched. |
| @@ -623,7 +629,6 @@ struct brcmf_pub { · 299 unmodified lines | |||
| 623 | u8 wme_dp; /* wme discard priority */ | 629 | u8 wme_dp; /* wme discard priority */ |
| 624 | 630 | ||
| 625 | /* Dongle media info */ | 631 | /* Dongle media info */ |
| 626 | bool iswl; /* Dongle-resident driver is wl */ | ||
| 627 | unsigned long drv_version; /* Version of dongle-resident driver */ | 632 | unsigned long drv_version; /* Version of dongle-resident driver */ |
| 628 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ | 633 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ |
| 629 | 634 | ||
| @@ -651,16 +656,10 @@ struct brcmf_pub { · 21 unmodified lines | |||
| 651 | int in_suspend; /* flag set to 1 when early suspend called */ | 656 | int in_suspend; /* flag set to 1 when early suspend called */ |
| 652 | int dtim_skip; /* dtim skip , default 0 means wake each dtim */ | 657 | int dtim_skip; /* dtim skip , default 0 means wake each dtim */ |
| 653 | 658 | ||
| 654 | /* Pkt filter defination */ | ||
| 655 | char *pktfilter[100]; | ||
| 656 | int pktfilter_count; | ||
| 657 | |||
| 658 | u8 country_code[BRCM_CNTRY_BUF_SZ]; | ||
| 659 | char eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
| 660 | |||
| 661 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; | 659 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; |
| 662 | 660 | ||
| 663 | struct mutex proto_block; | 661 | struct mutex proto_block; |
| 662 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; | ||
| 664 | 663 | ||
| 665 | struct work_struct setmacaddr_work; | 664 | struct work_struct setmacaddr_work; |
| 666 | struct work_struct multicast_work; | 665 | struct work_struct multicast_work; |
| @@ -671,6 +670,11 @@ struct brcmf_pub { · 4 unmodified lines | |||
| 671 | #endif | 670 | #endif |
| 672 | }; | 671 | }; |
| 673 | 672 | ||
| 673 | struct bcmevent_name { | ||
| 674 | uint event; | ||
| 675 | const char *name; | ||
| 676 | }; | ||
| 677 | |||
| 674 | struct brcmf_if_event { | 678 | struct brcmf_if_event { |
| 675 | u8 ifidx; | 679 | u8 ifidx; |
| 676 | u8 action; | 680 | u8 action; |
| @@ -678,47 +682,60 @@ struct brcmf_if_event { · 1 unmodified line | |||
| 678 | u8 bssidx; | 682 | u8 bssidx; |
| 679 | }; | 683 | }; |
| 680 | 684 | ||
| 681 | struct bcmevent_name { | 685 | /* forward declaration */ |
| 682 | uint event; | 686 | struct brcmf_cfg80211_vif; |
| 683 | const char *name; | 687 | |
| 688 | /** | ||
| 689 | * struct brcmf_if - interface control information. | ||
| 690 | * | ||
| 691 | * @drvr: points to device related information. | ||
| 692 | * @vif: points to cfg80211 specific interface information. | ||
| 693 | * @ndev: associated network device. | ||
| 694 | * @stats: interface specific network statistics. | ||
| 695 | * @idx: interface index in device firmware. | ||
| 696 | * @bssidx: index of bss associated with this interface. | ||
| 697 | * @mac_addr: assigned mac address. | ||
| 698 | */ | ||
| 699 | struct brcmf_if { | ||
| 700 | struct brcmf_pub *drvr; | ||
| 701 | struct brcmf_cfg80211_vif *vif; | ||
| 702 | struct net_device *ndev; | ||
| 703 | struct net_device_stats stats; | ||
| 704 | int idx; | ||
| 705 | s32 bssidx; | ||
| 706 | u8 mac_addr[ETH_ALEN]; | ||
| 684 | }; | 707 | }; |
| 685 | 708 | ||
| 709 | static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) | ||
| 710 | { | ||
| 711 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 712 | return ifp->bssidx; | ||
| 713 | } | ||
| 714 | |||
| 686 | extern const struct bcmevent_name bcmevent_names[]; | 715 | extern const struct bcmevent_name bcmevent_names[]; |
| 687 | 716 | ||
| 688 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, | 717 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, |
| 689 | char *buf, uint len); | 718 | char *buf, uint len); |
| 690 | extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, | ||
| 691 | char *buf, uint buflen, s32 bssidx); | ||
| 692 | 719 | ||
| 693 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 720 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
| 694 | 721 | ||
| 695 | extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); | ||
| 696 | extern int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd); | ||
| 697 | |||
| 698 | /* Return pointer to interface name */ | 722 | /* Return pointer to interface name */ |
| 699 | extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); | 723 | extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); |
| 700 | 724 | ||
| 701 | /* Query dongle */ | 725 | /* Query dongle */ |
| 702 | extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, | 726 | extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, |
| 703 | uint cmd, void *buf, uint len); | 727 | uint cmd, void *buf, uint len); |
| 704 | 728 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | |
| 705 | #ifdef DEBUG | 729 | void *buf, uint len); |
| 706 | extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); | ||
| 707 | #endif /* DEBUG */ | ||
| 708 | 730 | ||
| 709 | extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); | 731 | extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); |
| 710 | extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, | 732 | extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, |
| 711 | void *pktdata, struct brcmf_event_msg *, | 733 | void *pktdata, struct brcmf_event_msg *, |
| 712 | void **data_ptr); | 734 | void **data_ptr); |
| 713 | 735 | ||
| 736 | extern int brcmf_net_attach(struct brcmf_if *ifp); | ||
| 737 | extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | ||
| 738 | char *name, u8 *mac_addr); | ||
| 714 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); | 739 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); |
| 715 | 740 | ||
| 716 | extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); | ||
| 717 | extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, | ||
| 718 | int enable, int master_mode); | ||
| 719 | |||
| 720 | #define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */ | ||
| 721 | #define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */ | ||
| 722 | #define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */ | ||
| 723 | |||
| 724 | #endif /* _BRCMF_H_ */ | 741 | #endif /* _BRCMF_H_ */ |
| @@ -111,9 +111,6 @@ extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, · 110 unmodified lines | |||
| 111 | 111 | ||
| 112 | extern int brcmf_bus_start(struct device *dev); | 112 | extern int brcmf_bus_start(struct device *dev); |
| 113 | 113 | ||
| 114 | extern int brcmf_add_if(struct device *dev, int ifidx, | ||
| 115 | char *name, u8 *mac_addr); | ||
| 116 | |||
| 117 | #ifdef CONFIG_BRCMFMAC_SDIO | 114 | #ifdef CONFIG_BRCMFMAC_SDIO |
| 118 | extern void brcmf_sdio_exit(void); | 115 | extern void brcmf_sdio_exit(void); |
| 119 | extern void brcmf_sdio_init(void); | 116 | extern void brcmf_sdio_init(void); |
| @@ -458,35 +458,6 @@ void brcmf_proto_detach(struct brcmf_pub *drvr) · 457 unmodified lines | |||
| 458 | drvr->prot = NULL; | 458 | drvr->prot = NULL; |
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | int brcmf_proto_init(struct brcmf_pub *drvr) | ||
| 462 | { | ||
| 463 | int ret = 0; | ||
| 464 | char buf[128]; | ||
| 465 | |||
| 466 | brcmf_dbg(TRACE, "Enter\n"); | ||
| 467 | |||
| 468 | mutex_lock(&drvr->proto_block); | ||
| 469 | |||
| 470 | /* Get the device MAC address */ | ||
| 471 | strcpy(buf, "cur_etheraddr"); | ||
| 472 | ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, | ||
| 473 | buf, sizeof(buf)); | ||
| 474 | if (ret < 0) { | ||
| 475 | mutex_unlock(&drvr->proto_block); | ||
| 476 | return ret; | ||
| 477 | } | ||
| 478 | memcpy(drvr->mac, buf, ETH_ALEN); | ||
| 479 | |||
| 480 | mutex_unlock(&drvr->proto_block); | ||
| 481 | |||
| 482 | ret = brcmf_c_preinit_dcmds(drvr); | ||
| 483 | |||
| 484 | /* Always assumes wl for now */ | ||
| 485 | drvr->iswl = true; | ||
| 486 | |||
| 487 | return ret; | ||
| 488 | } | ||
| 489 | |||
| 490 | void brcmf_proto_stop(struct brcmf_pub *drvr) | 461 | void brcmf_proto_stop(struct brcmf_pub *drvr) |
| 491 | { | 462 | { |
| 492 | /* Nothing to do for CDC */ | 463 | /* Nothing to do for CDC */ |
| @@ -28,12 +28,17 @@ · 27 unmodified lines | |||
| 28 | #include "dhd_bus.h" | 28 | #include "dhd_bus.h" |
| 29 | #include "dhd_proto.h" | 29 | #include "dhd_proto.h" |
| 30 | #include "dhd_dbg.h" | 30 | #include "dhd_dbg.h" |
| 31 | #include "fwil.h" | ||
| 31 | 32 | ||
| 32 | #define BRCM_OUI "\x00\x10\x18" | 33 | #define BRCM_OUI "\x00\x10\x18" |
| 33 | #define DOT11_OUI_LEN 3 | 34 | #define DOT11_OUI_LEN 3 |
| 34 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | 35 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 |
| 35 | #define PKTFILTER_BUF_SIZE 2048 | 36 | #define PKTFILTER_BUF_SIZE 128 |
| 36 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ | 37 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ |
| 38 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 | ||
| 39 | #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 | ||
| 40 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 | ||
| 41 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" | ||
| 37 | 42 | ||
| 38 | #define MSGTRACE_VERSION 1 | 43 | #define MSGTRACE_VERSION 1 |
| 39 | 44 | ||
| @@ -88,52 +93,6 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) · 48 unmodified lines | |||
| 88 | return len; | 93 | return len; |
| 89 | } | 94 | } |
| 90 | 95 | ||
| 91 | uint | ||
| 92 | brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen, | ||
| 93 | char *buf, uint buflen, s32 bssidx) | ||
| 94 | { | ||
| 95 | const s8 *prefix = "bsscfg:"; | ||
| 96 | s8 *p; | ||
| 97 | u32 prefixlen; | ||
| 98 | u32 namelen; | ||
| 99 | u32 iolen; | ||
| 100 | __le32 bssidx_le; | ||
| 101 | |||
| 102 | if (bssidx == 0) | ||
| 103 | return brcmf_c_mkiovar(name, data, datalen, buf, buflen); | ||
| 104 | |||
| 105 | prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */ | ||
| 106 | namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */ | ||
| 107 | iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen; | ||
| 108 | |||
| 109 | if (buflen < 0 || iolen > (u32)buflen) { | ||
| 110 | brcmf_dbg(ERROR, "buffer is too short\n"); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | p = buf; | ||
| 115 | |||
| 116 | /* copy prefix, no null */ | ||
| 117 | memcpy(p, prefix, prefixlen); | ||
| 118 | p += prefixlen; | ||
| 119 | |||
| 120 | /* copy iovar name including null */ | ||
| 121 | memcpy(p, name, namelen); | ||
| 122 | p += namelen; | ||
| 123 | |||
| 124 | /* bss config index as first data */ | ||
| 125 | bssidx_le = cpu_to_le32(bssidx); | ||
| 126 | memcpy(p, &bssidx_le, sizeof(bssidx_le)); | ||
| 127 | p += sizeof(bssidx_le); | ||
| 128 | |||
| 129 | /* parameter buffer follows */ | ||
| 130 | if (datalen) | ||
| 131 | memcpy(p, data, datalen); | ||
| 132 | |||
| 133 | return iolen; | ||
| 134 | |||
| 135 | } | ||
| 136 | |||
| 137 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 96 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
| 138 | struct sk_buff *pkt, int prec) | 97 | struct sk_buff *pkt, int prec) |
| 139 | { | 98 | { |
| @@ -490,6 +449,7 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, · 350 unmodified lines | |||
| 490 | /* check whether packet is a BRCM event pkt */ | 449 | /* check whether packet is a BRCM event pkt */ |
| 491 | struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; | 450 | struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; |
| 492 | struct brcmf_if_event *ifevent; | 451 | struct brcmf_if_event *ifevent; |
| 452 | struct brcmf_if *ifp; | ||
| 493 | char *event_data; | 453 | char *event_data; |
| 494 | u32 type, status; | 454 | u32 type, status; |
| 495 | u16 flags; | 455 | u16 flags; |
| @@ -525,12 +485,17 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, · 29 unmodified lines | |||
| 525 | brcmf_dbg(TRACE, "if event\n"); | 485 | brcmf_dbg(TRACE, "if event\n"); |
| 526 | 486 | ||
| 527 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | 487 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { |
| 528 | if (ifevent->action == BRCMF_E_IF_ADD) | 488 | if (ifevent->action == BRCMF_E_IF_ADD) { |
| 529 | brcmf_add_if(drvr->dev, ifevent->ifidx, | 489 | ifp = brcmf_add_if(drvr->dev, ifevent->ifidx, |
| 530 | event->ifname, | 490 | ifevent->bssidx, |
| 531 | pvt_data->eth.h_dest); | 491 | event->ifname, |
| 532 | else | 492 | pvt_data->eth.h_dest); |
| 493 | if (IS_ERR(ifp)) | ||
| 494 | return PTR_ERR(ifp); | ||
| 495 | brcmf_net_attach(ifp); | ||
| 496 | } else { | ||
| 533 | brcmf_del_if(drvr, ifevent->ifidx); | 497 | brcmf_del_if(drvr, ifevent->ifidx); |
| 498 | } | ||
| 534 | } else { | 499 | } else { |
| 535 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", | 500 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", |
| 536 | ifevent->ifidx, event->ifname); | 501 | ifevent->ifidx, event->ifname); |
| @@ -603,90 +568,57 @@ static int brcmf_c_pattern_atoh(char *src, char *dst) · 66 unmodified lines | |||
| 603 | return i; | 568 | return i; |
| 604 | } | 569 | } |
| 605 | 570 | ||
| 606 | void | 571 | static void |
| 607 | brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, | 572 | brcmf_c_pktfilter_offload_enable(struct brcmf_if *ifp, char *arg, int enable, |
| 608 | int master_mode) | 573 | int master_mode) |
| 609 | { | 574 | { |
| 610 | unsigned long res; | 575 | unsigned long res; |
| 611 | char *argv[8]; | 576 | char *argv; |
| 612 | int i = 0; | ||
| 613 | const char *str; | ||
| 614 | int buf_len; | ||
| 615 | int str_len; | ||
| 616 | char *arg_save = NULL, *arg_org = NULL; | 577 | char *arg_save = NULL, *arg_org = NULL; |
| 617 | int rc; | 578 | s32 err; |
| 618 | char buf[128]; | ||
| 619 | struct brcmf_pkt_filter_enable_le enable_parm; | 579 | struct brcmf_pkt_filter_enable_le enable_parm; |
| 620 | struct brcmf_pkt_filter_enable_le *pkt_filterp; | ||
| 621 | __le32 mmode_le; | ||
| 622 | 580 | ||
| 623 | arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); | 581 | arg_save = kstrdup(arg, GFP_ATOMIC); |
| 624 | if (!arg_save) | 582 | if (!arg_save) |
| 625 | goto fail; | 583 | goto fail; |
| 626 | 584 | ||
| 627 | arg_org = arg_save; | 585 | arg_org = arg_save; |
| 628 | memcpy(arg_save, arg, strlen(arg) + 1); | ||
| 629 | 586 | ||
| 630 | argv[i] = strsep(&arg_save, " "); | 587 | argv = strsep(&arg_save, " "); |
| 631 | 588 | ||
| 632 | i = 0; | 589 | if (argv == NULL) { |
| 633 | if (NULL == argv[i]) { | ||
| 634 | brcmf_dbg(ERROR, "No args provided\n"); | 590 | brcmf_dbg(ERROR, "No args provided\n"); |
| 635 | goto fail; | 591 | goto fail; |
| 636 | } | 592 | } |
| 637 | 593 | ||
| 638 | str = "pkt_filter_enable"; | ||
| 639 | str_len = strlen(str); | ||
| 640 | strncpy(buf, str, str_len); | ||
| 641 | buf[str_len] = '\0'; | ||
| 642 | buf_len = str_len + 1; | ||
| 643 | |||
| 644 | pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1); | ||
| 645 | |||
| 646 | /* Parse packet filter id. */ | 594 | /* Parse packet filter id. */ |
| 647 | enable_parm.id = 0; | 595 | enable_parm.id = 0; |
| 648 | if (!kstrtoul(argv[i], 0, &res)) | 596 | if (!kstrtoul(argv, 0, &res)) |
| 649 | enable_parm.id = cpu_to_le32((u32)res); | 597 | enable_parm.id = cpu_to_le32((u32)res); |
| 650 | 598 | ||
| 651 | /* Parse enable/disable value. */ | 599 | /* Enable/disable the specified filter. */ |
| 652 | enable_parm.enable = cpu_to_le32(enable); | 600 | enable_parm.enable = cpu_to_le32(enable); |
| 653 | 601 | ||
| 654 | buf_len += sizeof(enable_parm); | 602 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_enable", &enable_parm, |
| 655 | memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); | 603 | sizeof(enable_parm)); |
| 604 | if (err) | ||
| 605 | brcmf_dbg(ERROR, "Set pkt_filter_enable error (%d)\n", err); | ||
| 656 | 606 | ||
| 657 | /* Enable/disable the specified filter. */ | 607 | /* Control the master mode */ |
| 658 | rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); | 608 | err = brcmf_fil_iovar_int_set(ifp, "pkt_filter_mode", master_mode); |
| 659 | rc = rc >= 0 ? 0 : rc; | 609 | if (err) |
| 660 | if (rc) | 610 | brcmf_dbg(ERROR, "Set pkt_filter_mode error (%d)\n", err); |
| 661 | brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", | ||
| 662 | arg, rc); | ||
| 663 | else | ||
| 664 | brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); | ||
| 665 | |||
| 666 | /* Contorl the master mode */ | ||
| 667 | mmode_le = cpu_to_le32(master_mode); | ||
| 668 | brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf, | ||
| 669 | sizeof(buf)); | ||
| 670 | rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, | ||
| 671 | sizeof(buf)); | ||
| 672 | rc = rc >= 0 ? 0 : rc; | ||
| 673 | if (rc) | ||
| 674 | brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", | ||
| 675 | arg, rc); | ||
| 676 | 611 | ||
| 677 | fail: | 612 | fail: |
| 678 | kfree(arg_org); | 613 | kfree(arg_org); |
| 679 | } | 614 | } |
| 680 | 615 | ||
| 681 | void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) | 616 | static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) |
| 682 | { | 617 | { |
| 683 | const char *str; | 618 | struct brcmf_pkt_filter_le *pkt_filter; |
| 684 | struct brcmf_pkt_filter_le pkt_filter; | ||
| 685 | struct brcmf_pkt_filter_le *pkt_filterp; | ||
| 686 | unsigned long res; | 619 | unsigned long res; |
| 687 | int buf_len; | 620 | int buf_len; |
| 688 | int str_len; | 621 | s32 err; |
| 689 | int rc; | ||
| 690 | u32 mask_size; | 622 | u32 mask_size; |
| 691 | u32 pattern_size; | 623 | u32 pattern_size; |
| 692 | char *argv[8], *buf = NULL; | 624 | char *argv[8], *buf = NULL; |
| @@ -704,104 +636,64 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) · 11 unmodified lines | |||
| 704 | goto fail; | 636 | goto fail; |
| 705 | 637 | ||
| 706 | argv[i] = strsep(&arg_save, " "); | 638 | argv[i] = strsep(&arg_save, " "); |
| 707 | while (argv[i++]) | 639 | while (argv[i]) { |
| 640 | i++; | ||
| 641 | if (i >= 8) { | ||
| 642 | brcmf_dbg(ERROR, "Too many parameters\n"); | ||
| 643 | goto fail; | ||
| 644 | } | ||
| 708 | argv[i] = strsep(&arg_save, " "); | 645 | argv[i] = strsep(&arg_save, " "); |
| 646 | } | ||
| 709 | 647 | ||
| 710 | i = 0; | 648 | if (i != 6) { |
| 711 | if (NULL == argv[i]) { | 649 | brcmf_dbg(ERROR, "Not enough args provided %d\n", i); |
| 712 | brcmf_dbg(ERROR, "No args provided\n"); | ||
| 713 | goto fail; | 650 | goto fail; |
| 714 | } | 651 | } |
| 715 | 652 | ||
| 716 | str = "pkt_filter_add"; | 653 | pkt_filter = (struct brcmf_pkt_filter_le *)buf; |
| 717 | strcpy(buf, str); | ||
| 718 | str_len = strlen(str); | ||
| 719 | buf_len = str_len + 1; | ||
| 720 | |||
| 721 | pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1); | ||
| 722 | 654 | ||
| 723 | /* Parse packet filter id. */ | 655 | /* Parse packet filter id. */ |
| 724 | pkt_filter.id = 0; | 656 | pkt_filter->id = 0; |
| 725 | if (!kstrtoul(argv[i], 0, &res)) | 657 | if (!kstrtoul(argv[0], 0, &res)) |
| 726 | pkt_filter.id = cpu_to_le32((u32)res); | 658 | pkt_filter->id = cpu_to_le32((u32)res); |
| 727 | |||
| 728 | if (NULL == argv[++i]) { | ||
| 729 | brcmf_dbg(ERROR, "Polarity not provided\n"); | ||
| 730 | goto fail; | ||
| 731 | } | ||
| 732 | 659 | ||
| 733 | /* Parse filter polarity. */ | 660 | /* Parse filter polarity. */ |
| 734 | pkt_filter.negate_match = 0; | 661 | pkt_filter->negate_match = 0; |
| 735 | if (!kstrtoul(argv[i], 0, &res)) | 662 | if (!kstrtoul(argv[1], 0, &res)) |
| 736 | pkt_filter.negate_match = cpu_to_le32((u32)res); | 663 | pkt_filter->negate_match = cpu_to_le32((u32)res); |
| 737 | |||
| 738 | if (NULL == argv[++i]) { | ||
| 739 | brcmf_dbg(ERROR, "Filter type not provided\n"); | ||
| 740 | goto fail; | ||
| 741 | } | ||
| 742 | 664 | ||
| 743 | /* Parse filter type. */ | 665 | /* Parse filter type. */ |
| 744 | pkt_filter.type = 0; | 666 | pkt_filter->type = 0; |
| 745 | if (!kstrtoul(argv[i], 0, &res)) | 667 | if (!kstrtoul(argv[2], 0, &res)) |
| 746 | pkt_filter.type = cpu_to_le32((u32)res); | 668 | pkt_filter->type = cpu_to_le32((u32)res); |
| 747 | |||
| 748 | if (NULL == argv[++i]) { | ||
| 749 | brcmf_dbg(ERROR, "Offset not provided\n"); | ||
| 750 | goto fail; | ||
| 751 | } | ||
| 752 | 669 | ||
| 753 | /* Parse pattern filter offset. */ | 670 | /* Parse pattern filter offset. */ |
| 754 | pkt_filter.u.pattern.offset = 0; | 671 | pkt_filter->u.pattern.offset = 0; |
| 755 | if (!kstrtoul(argv[i], 0, &res)) | 672 | if (!kstrtoul(argv[3], 0, &res)) |
| 756 | pkt_filter.u.pattern.offset = cpu_to_le32((u32)res); | 673 | pkt_filter->u.pattern.offset = cpu_to_le32((u32)res); |
| 757 | |||
| 758 | if (NULL == argv[++i]) { | ||
| 759 | brcmf_dbg(ERROR, "Bitmask not provided\n"); | ||
| 760 | goto fail; | ||
| 761 | } | ||
| 762 | 674 | ||
| 763 | /* Parse pattern filter mask. */ | 675 | /* Parse pattern filter mask. */ |
| 764 | mask_size = | 676 | mask_size = brcmf_c_pattern_atoh(argv[4], |
| 765 | brcmf_c_pattern_atoh | 677 | (char *)pkt_filter->u.pattern.mask_and_pattern); |
| 766 | (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); | ||
| 767 | |||
| 768 | if (NULL == argv[++i]) { | ||
| 769 | brcmf_dbg(ERROR, "Pattern not provided\n"); | ||
| 770 | goto fail; | ||
| 771 | } | ||
| 772 | 678 | ||
| 773 | /* Parse pattern filter pattern. */ | 679 | /* Parse pattern filter pattern. */ |
| 774 | pattern_size = | 680 | pattern_size = brcmf_c_pattern_atoh(argv[5], |
| 775 | brcmf_c_pattern_atoh(argv[i], | 681 | (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]); |
| 776 | (char *)&pkt_filterp->u.pattern. | ||
| 777 | mask_and_pattern[mask_size]); | ||
| 778 | 682 | ||
| 779 | if (mask_size != pattern_size) { | 683 | if (mask_size != pattern_size) { |
| 780 | brcmf_dbg(ERROR, "Mask and pattern not the same size\n"); | 684 | brcmf_dbg(ERROR, "Mask and pattern not the same size\n"); |
| 781 | goto fail; | 685 | goto fail; |
| 782 | } | 686 | } |
| 783 | 687 | ||
| 784 | pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size); | 688 | pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); |
| 785 | buf_len += BRCMF_PKT_FILTER_FIXED_LEN; | 689 | buf_len = sizeof(*pkt_filter); |
| 786 | buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); | 690 | buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern); |
| 787 | 691 | buf_len += mask_size + pattern_size; | |
| 788 | /* Keep-alive attributes are set in local | ||
| 789 | * variable (keep_alive_pkt), and | ||
| 790 | ** then memcpy'ed into buffer (keep_alive_pktp) since there is no | ||
| 791 | ** guarantee that the buffer is properly aligned. | ||
| 792 | */ | ||
| 793 | memcpy((char *)pkt_filterp, | ||
| 794 | &pkt_filter, | ||
| 795 | BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); | ||
| 796 | |||
| 797 | rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); | ||
| 798 | rc = rc >= 0 ? 0 : rc; | ||
| 799 | 692 | ||
| 800 | if (rc) | 693 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, |
| 801 | brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", | 694 | buf_len); |
| 802 | arg, rc); | 695 | if (err) |
| 803 | else | 696 | brcmf_dbg(ERROR, "Set pkt_filter_add error (%d)\n", err); |
| 804 | brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); | ||
| 805 | 697 | ||
| 806 | fail: | 698 | fail: |
| 807 | kfree(arg_org); | 699 | kfree(arg_org); |
| @@ -809,130 +701,125 @@ fail: · 1 unmodified line | |||
| 809 | kfree(buf); | 701 | kfree(buf); |
| 810 | } | 702 | } |
| 811 | 703 | ||
| 812 | static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) | 704 | int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) |
| 813 | { | 705 | { |
| 814 | char iovbuf[32]; | 706 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |
| 815 | int retcode; | 707 | u8 buf[BRCMF_DCMD_SMLEN]; |
| 816 | __le32 arp_mode_le; | 708 | char *ptr; |
| 817 | 709 | s32 err; | |
| 818 | arp_mode_le = cpu_to_le32(arp_mode); | ||
| 819 | brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf, | ||
| 820 | sizeof(iovbuf)); | ||
| 821 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, | ||
| 822 | iovbuf, sizeof(iovbuf)); | ||
| 823 | retcode = retcode >= 0 ? 0 : retcode; | ||
| 824 | if (retcode) | ||
| 825 | brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n", | ||
| 826 | arp_mode, retcode); | ||
| 827 | else | ||
| 828 | brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n", | ||
| 829 | arp_mode); | ||
| 830 | } | ||
| 831 | |||
| 832 | static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) | ||
| 833 | { | ||
| 834 | char iovbuf[32]; | ||
| 835 | int retcode; | ||
| 836 | __le32 arp_enable_le; | ||
| 837 | |||
| 838 | arp_enable_le = cpu_to_le32(arp_enable); | ||
| 839 | |||
| 840 | brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4, | ||
| 841 | iovbuf, sizeof(iovbuf)); | ||
| 842 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, | ||
| 843 | iovbuf, sizeof(iovbuf)); | ||
| 844 | retcode = retcode >= 0 ? 0 : retcode; | ||
| 845 | if (retcode) | ||
| 846 | brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n", | ||
| 847 | arp_enable, retcode); | ||
| 848 | else | ||
| 849 | brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n", | ||
| 850 | arp_enable); | ||
| 851 | } | ||
| 852 | |||
| 853 | int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | ||
| 854 | { | ||
| 855 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for | ||
| 856 | "event_msgs" + '\0' + bitvec */ | ||
| 857 | char buf[128], *ptr; | ||
| 858 | __le32 roaming_le = cpu_to_le32(1); | ||
| 859 | __le32 bcn_timeout_le = cpu_to_le32(3); | ||
| 860 | __le32 scan_assoc_time_le = cpu_to_le32(40); | ||
| 861 | __le32 scan_unassoc_time_le = cpu_to_le32(40); | ||
| 862 | int i; | ||
| 863 | struct brcmf_bus_dcmd *cmdlst; | 710 | struct brcmf_bus_dcmd *cmdlst; |
| 864 | struct list_head *cur, *q; | 711 | struct list_head *cur, *q; |
| 865 | 712 | ||
| 866 | mutex_lock(&drvr->proto_block); | 713 | /* retreive mac address */ |
| 867 | 714 | err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, | |
| 868 | /* Set Country code */ | 715 | sizeof(ifp->mac_addr)); |
| 869 | if (drvr->country_code[0] != 0) { | 716 | if (err < 0) { |
| 870 | if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY, | 717 | brcmf_dbg(ERROR, "Retreiving cur_etheraddr failed, %d\n", |
| 871 | drvr->country_code, | 718 | err); |
| 872 | sizeof(drvr->country_code)) < 0) | 719 | goto done; |
| 873 | brcmf_dbg(ERROR, "country code setting failed\n"); | ||
| 874 | } | 720 | } |
| 721 | memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); | ||
| 875 | 722 | ||
| 876 | /* query for 'ver' to get version info from firmware */ | 723 | /* query for 'ver' to get version info from firmware */ |
| 877 | memset(buf, 0, sizeof(buf)); | 724 | memset(buf, 0, sizeof(buf)); |
| 878 | ptr = buf; | 725 | strcpy(buf, "ver"); |
| 879 | brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf)); | 726 | err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); |
| 880 | brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); | 727 | if (err < 0) { |
| 728 | brcmf_dbg(ERROR, "Retreiving version information failed, %d\n", | ||
| 729 | err); | ||
| 730 | goto done; | ||
| 731 | } | ||
| 732 | ptr = (char *)buf; | ||
| 881 | strsep(&ptr, "\n"); | 733 | strsep(&ptr, "\n"); |
| 882 | /* Print fw version info */ | 734 | /* Print fw version info */ |
| 883 | brcmf_dbg(ERROR, "Firmware version = %s\n", buf); | 735 | brcmf_dbg(ERROR, "Firmware version = %s\n", buf); |
| 884 | 736 | ||
| 885 | /* Setup timeout if Beacons are lost and roam is off to report | 737 | /* |
| 886 | link down */ | 738 | * Setup timeout if Beacons are lost and roam is off to report |
| 887 | brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf, | 739 | * link down |
| 888 | sizeof(iovbuf)); | 740 | */ |
| 889 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | 741 | err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", |
| 890 | sizeof(iovbuf)); | 742 | BRCMF_DEFAULT_BCN_TIMEOUT); |
| 743 | if (err) { | ||
| 744 | brcmf_dbg(ERROR, "bcn_timeout error (%d)\n", err); | ||
| 745 | goto done; | ||
| 746 | } | ||
| 891 | 747 | ||
| 892 | /* Enable/Disable build-in roaming to allowed ext supplicant to take | 748 | /* Enable/Disable build-in roaming to allowed ext supplicant to take |
| 893 | of romaing */ | 749 | * of romaing |
| 894 | brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4, | 750 | */ |
| 895 | iovbuf, sizeof(iovbuf)); | 751 | err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1); |
| 896 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | 752 | if (err) { |
| 897 | sizeof(iovbuf)); | 753 | brcmf_dbg(ERROR, "roam_off error (%d)\n", err); |
| 898 | 754 | goto done; | |
| 899 | /* Setup event_msgs */ | 755 | } |
| 900 | brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, | 756 | |
| 901 | iovbuf, sizeof(iovbuf)); | 757 | /* Setup event_msgs, enable E_IF */ |
| 902 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | 758 | err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, |
| 903 | sizeof(iovbuf)); | 759 | BRCMF_EVENTING_MASK_LEN); |
| 904 | 760 | if (err) { | |
| 905 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, | 761 | brcmf_dbg(ERROR, "Get event_msgs error (%d)\n", err); |
| 906 | (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le)); | 762 | goto done; |
| 907 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, | 763 | } |
| 908 | (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le)); | 764 | setbit(eventmask, BRCMF_E_IF); |
| 909 | 765 | err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, | |
| 910 | /* Set and enable ARP offload feature */ | 766 | BRCMF_EVENTING_MASK_LEN); |
| 911 | brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); | 767 | if (err) { |
| 912 | brcmf_c_arp_offload_enable(drvr, true); | 768 | brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); |
| 913 | 769 | goto done; | |
| 914 | /* Set up pkt filter */ | 770 | } |
| 915 | for (i = 0; i < drvr->pktfilter_count; i++) { | 771 | |
| 916 | brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]); | 772 | /* Setup default scan channel time */ |
| 917 | brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i], | 773 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, |
| 918 | 0, true); | 774 | BRCMF_DEFAULT_SCAN_CHANNEL_TIME); |
| 775 | if (err) { | ||
| 776 | brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", | ||
| 777 | err); | ||
| 778 | goto done; | ||
| 919 | } | 779 | } |
| 920 | 780 | ||
| 781 | /* Setup default scan unassoc time */ | ||
| 782 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, | ||
| 783 | BRCMF_DEFAULT_SCAN_UNASSOC_TIME); | ||
| 784 | if (err) { | ||
| 785 | brcmf_dbg(ERROR, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", | ||
| 786 | err); | ||
| 787 | goto done; | ||
| 788 | } | ||
| 789 | |||
| 790 | /* Try to set and enable ARP offload feature, this may fail */ | ||
| 791 | err = brcmf_fil_iovar_int_set(ifp, "arp_ol", BRCMF_ARPOL_MODE); | ||
| 792 | if (err) { | ||
| 793 | brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", | ||
| 794 | BRCMF_ARPOL_MODE, err); | ||
| 795 | err = 0; | ||
| 796 | } else { | ||
| 797 | err = brcmf_fil_iovar_int_set(ifp, "arpoe", 1); | ||
| 798 | if (err) { | ||
| 799 | brcmf_dbg(TRACE, "failed to enable ARP offload err = %d\n", | ||
| 800 | err); | ||
| 801 | err = 0; | ||
| 802 | } else | ||
| 803 | brcmf_dbg(TRACE, "successfully enabled ARP offload to 0x%x\n", | ||
| 804 | BRCMF_ARPOL_MODE); | ||
| 805 | } | ||
| 806 | |||
| 807 | /* Setup packet filter */ | ||
| 808 | brcmf_c_pktfilter_offload_set(ifp, BRCMF_DEFAULT_PACKET_FILTER); | ||
| 809 | brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, | ||
| 810 | 0, true); | ||
| 811 | |||
| 921 | /* set bus specific command if there is any */ | 812 | /* set bus specific command if there is any */ |
| 922 | list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) { | 813 | list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { |
| 923 | cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); | 814 | cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); |
| 924 | if (cmdlst->name && cmdlst->param && cmdlst->param_len) { | 815 | if (cmdlst->name && cmdlst->param && cmdlst->param_len) { |
| 925 | brcmf_c_mkiovar(cmdlst->name, cmdlst->param, | 816 | brcmf_fil_iovar_data_set(ifp, cmdlst->name, |
| 926 | cmdlst->param_len, iovbuf, | 817 | cmdlst->param, |
| 927 | sizeof(iovbuf)); | 818 | cmdlst->param_len); |
| 928 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, | ||
| 929 | iovbuf, sizeof(iovbuf)); | ||
| 930 | } | 819 | } |
| 931 | list_del(cur); | 820 | list_del(cur); |
| 932 | kfree(cmdlst); | 821 | kfree(cmdlst); |
| 933 | } | 822 | } |
| 934 | 823 | done: | |
| 935 | mutex_unlock(&drvr->proto_block); | 824 | return err; |
| 936 | |||
| 937 | return 0; | ||
| 938 | } | 825 | } |
| @@ -16,8 +16,10 @@ · 15 unmodified lines | |||
| 16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
| 17 | #include <linux/if_ether.h> | 17 | #include <linux/if_ether.h> |
| 18 | #include <linux/if.h> | 18 | #include <linux/if.h> |
| 19 | #include <linux/netdevice.h> | ||
| 19 | #include <linux/ieee80211.h> | 20 | #include <linux/ieee80211.h> |
| 20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/netdevice.h> | ||
| 21 | 23 | ||
| 22 | #include <defs.h> | 24 | #include <defs.h> |
| 23 | #include <brcmu_wifi.h> | 25 | #include <brcmu_wifi.h> |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | #define BRCMF_EVENT_VAL 0x0800 | 31 | #define BRCMF_EVENT_VAL 0x0800 |
| 32 | #define BRCMF_BTA_VAL 0x1000 | 32 | #define BRCMF_BTA_VAL 0x1000 |
| 33 | #define BRCMF_ISCAN_VAL 0x2000 | 33 | #define BRCMF_ISCAN_VAL 0x2000 |
| 34 | #define BRCMF_FIL_VAL 0x4000 | ||
| 34 | 35 | ||
| 35 | #if defined(DEBUG) | 36 | #if defined(DEBUG) |
| 36 | 37 | ||
| @@ -56,6 +57,7 @@ do { \ · 19 unmodified lines | |||
| 56 | #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) | 57 | #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) |
| 57 | #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) | 58 | #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) |
| 58 | #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) | 59 | #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) |
| 60 | #define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) | ||
| 59 | 61 | ||
| 60 | #else /* (defined DEBUG) || (defined DEBUG) */ | 62 | #else /* (defined DEBUG) || (defined DEBUG) */ |
| 61 | 63 | ||
| @@ -67,6 +69,7 @@ do { \ · 5 unmodified lines | |||
| 67 | #define BRCMF_BYTES_ON() 0 | 69 | #define BRCMF_BYTES_ON() 0 |
| 68 | #define BRCMF_GLOM_ON() 0 | 70 | #define BRCMF_GLOM_ON() 0 |
| 69 | #define BRCMF_EVENT_ON() 0 | 71 | #define BRCMF_EVENT_ON() 0 |
| 72 | #define BRCMF_FIL_ON() 0 | ||
| 70 | 73 | ||
| 71 | #endif /* defined(DEBUG) */ | 74 | #endif /* defined(DEBUG) */ |
| 72 | 75 | ||
| @@ -52,16 +52,6 @@ MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); · 51 unmodified lines | |||
| 52 | MODULE_LICENSE("Dual BSD/GPL"); | 52 | MODULE_LICENSE("Dual BSD/GPL"); |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | /* Interface control information */ | ||
| 56 | struct brcmf_if { | ||
| 57 | struct brcmf_pub *drvr; /* back pointer to brcmf_pub */ | ||
| 58 | /* OS/stack specifics */ | ||
| 59 | struct net_device *ndev; | ||
| 60 | struct net_device_stats stats; | ||
| 61 | int idx; /* iface idx in dongle */ | ||
| 62 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ | ||
| 63 | }; | ||
| 64 | |||
| 65 | /* Error bits */ | 55 | /* Error bits */ |
| 66 | int brcmf_msg_level = BRCMF_ERROR_VAL; | 56 | int brcmf_msg_level = BRCMF_ERROR_VAL; |
| 67 | module_param(brcmf_msg_level, int, 0); | 57 | module_param(brcmf_msg_level, int, 0); |
| @@ -629,12 +619,9 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) · 561 unmodified lines | |||
| 629 | brcmf_dbg(ERROR, "dongle is not up\n"); | 619 | brcmf_dbg(ERROR, "dongle is not up\n"); |
| 630 | return -ENODEV; | 620 | return -ENODEV; |
| 631 | } | 621 | } |
| 632 | |||
| 633 | /* finally, report dongle driver type */ | 622 | /* finally, report dongle driver type */ |
| 634 | else if (drvr->iswl) | ||
| 635 | sprintf(info.driver, "wl"); | ||
| 636 | else | 623 | else |
| 637 | sprintf(info.driver, "xx"); | 624 | sprintf(info.driver, "wl"); |
| 638 | 625 | ||
| 639 | sprintf(info.version, "%lu", drvr->drv_version); | 626 | sprintf(info.version, "%lu", drvr->drv_version); |
| 640 | if (copy_to_user(uaddr, &info, sizeof(info))) | 627 | if (copy_to_user(uaddr, &info, sizeof(info))) |
| @@ -719,65 +706,6 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, · 78 unmodified lines | |||
| 719 | return -EOPNOTSUPP; | 706 | return -EOPNOTSUPP; |
| 720 | } | 707 | } |
| 721 | 708 | ||
| 722 | /* called only from within this driver. Sends a command to the dongle. */ | ||
| 723 | s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | ||
| 724 | { | ||
| 725 | struct brcmf_dcmd dcmd; | ||
| 726 | s32 err = 0; | ||
| 727 | int buflen = 0; | ||
| 728 | bool is_set_key_cmd; | ||
| 729 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 730 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 731 | |||
| 732 | memset(&dcmd, 0, sizeof(dcmd)); | ||
| 733 | dcmd.cmd = cmd; | ||
| 734 | dcmd.buf = arg; | ||
| 735 | dcmd.len = len; | ||
| 736 | |||
| 737 | if (dcmd.buf != NULL) | ||
| 738 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); | ||
| 739 | |||
| 740 | /* send to dongle (must be up, and wl) */ | ||
| 741 | if ((drvr->bus_if->state != BRCMF_BUS_DATA)) { | ||
| 742 | brcmf_dbg(ERROR, "DONGLE_DOWN\n"); | ||
| 743 | err = -EIO; | ||
| 744 | goto done; | ||
| 745 | } | ||
| 746 | |||
| 747 | if (!drvr->iswl) { | ||
| 748 | err = -EIO; | ||
| 749 | goto done; | ||
| 750 | } | ||
| 751 | |||
| 752 | /* | ||
| 753 | * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and | ||
| 754 | * set key CMD to prevent M4 encryption. | ||
| 755 | */ | ||
| 756 | is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) || | ||
| 757 | ((dcmd.cmd == BRCMF_C_SET_VAR) && | ||
| 758 | !(strncmp("wsec_key", dcmd.buf, 9))) || | ||
| 759 | ((dcmd.cmd == BRCMF_C_SET_VAR) && | ||
| 760 | !(strncmp("bsscfg:wsec_key", dcmd.buf, 15)))); | ||
| 761 | if (is_set_key_cmd) | ||
| 762 | brcmf_netdev_wait_pend8021x(ndev); | ||
| 763 | |||
| 764 | err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen); | ||
| 765 | |||
| 766 | done: | ||
| 767 | if (err > 0) | ||
| 768 | err = 0; | ||
| 769 | |||
| 770 | return err; | ||
| 771 | } | ||
| 772 | |||
| 773 | int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd) | ||
| 774 | { | ||
| 775 | brcmf_dbg(TRACE, "enter: cmd %x buf %p len %d\n", | ||
| 776 | dcmd->cmd, dcmd->buf, dcmd->len); | ||
| 777 | |||
| 778 | return brcmf_exec_dcmd(ndev, dcmd->cmd, dcmd->buf, dcmd->len); | ||
| 779 | } | ||
| 780 | |||
| 781 | static int brcmf_netdev_stop(struct net_device *ndev) | 709 | static int brcmf_netdev_stop(struct net_device *ndev) |
| 782 | { | 710 | { |
| 783 | struct brcmf_if *ifp = netdev_priv(ndev); | 711 | struct brcmf_if *ifp = netdev_priv(ndev); |
| @@ -851,7 +779,7 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { · 67 unmodified lines | |||
| 851 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | 779 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list |
| 852 | }; | 780 | }; |
| 853 | 781 | ||
| 854 | static int brcmf_net_attach(struct brcmf_if *ifp) | 782 | int brcmf_net_attach(struct brcmf_if *ifp) |
| 855 | { | 783 | { |
| 856 | struct brcmf_pub *drvr = ifp->drvr; | 784 | struct brcmf_pub *drvr = ifp->drvr; |
| 857 | struct net_device *ndev; | 785 | struct net_device *ndev; |
| @@ -885,15 +813,6 @@ static int brcmf_net_attach(struct brcmf_if *ifp) · 27 unmodified lines | |||
| 885 | 813 | ||
| 886 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 814 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); |
| 887 | 815 | ||
| 888 | /* attach to cfg80211 for primary interface */ | ||
| 889 | if (!ifp->idx) { | ||
| 890 | drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr); | ||
| 891 | if (drvr->config == NULL) { | ||
| 892 | brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); | ||
| 893 | goto fail; | ||
| 894 | } | ||
| 895 | } | ||
| 896 | |||
| 897 | if (register_netdev(ndev) != 0) { | 816 | if (register_netdev(ndev) != 0) { |
| 898 | brcmf_dbg(ERROR, "couldn't register the net device\n"); | 817 | brcmf_dbg(ERROR, "couldn't register the net device\n"); |
| 899 | goto fail; | 818 | goto fail; |
| @@ -905,11 +824,12 @@ static int brcmf_net_attach(struct brcmf_if *ifp) · 5 unmodified lines | |||
| 905 | 824 | ||
| 906 | fail: | 825 | fail: |
| 907 | ndev->netdev_ops = NULL; | 826 | ndev->netdev_ops = NULL; |
| 827 | free_netdev(ndev); | ||
| 908 | return -EBADE; | 828 | return -EBADE; |
| 909 | } | 829 | } |
| 910 | 830 | ||
| 911 | int | 831 | struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, |
| 912 | brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) | 832 | char *name, u8 *mac_addr) |
| 913 | { | 833 | { |
| 914 | struct brcmf_if *ifp; | 834 | struct brcmf_if *ifp; |
| 915 | struct net_device *ndev; | 835 | struct net_device *ndev; |
| @@ -936,7 +856,7 @@ brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) · 20 unmodified lines | |||
| 936 | ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); | 856 | ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); |
| 937 | if (!ndev) { | 857 | if (!ndev) { |
| 938 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); | 858 | brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); |
| 939 | return -ENOMEM; | 859 | return ERR_PTR(-ENOMEM); |
| 940 | } | 860 | } |
| 941 | 861 | ||
| 942 | ifp = netdev_priv(ndev); | 862 | ifp = netdev_priv(ndev); |
| @@ -944,20 +864,14 @@ brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) · 1 unmodified line | |||
| 944 | ifp->drvr = drvr; | 864 | ifp->drvr = drvr; |
| 945 | drvr->iflist[ifidx] = ifp; | 865 | drvr->iflist[ifidx] = ifp; |
| 946 | ifp->idx = ifidx; | 866 | ifp->idx = ifidx; |
| 867 | ifp->bssidx = bssidx; | ||
| 947 | if (mac_addr != NULL) | 868 | if (mac_addr != NULL) |
| 948 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | 869 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); |
| 949 | 870 | ||
| 950 | if (brcmf_net_attach(ifp)) { | ||
| 951 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); | ||
| 952 | free_netdev(ifp->ndev); | ||
| 953 | drvr->iflist[ifidx] = NULL; | ||
| 954 | return -EOPNOTSUPP; | ||
| 955 | } | ||
| 956 | |||
| 957 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", | 871 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", |
| 958 | current->pid, ifp->ndev->name); | 872 | current->pid, ifp->ndev->name); |
| 959 | 873 | ||
| 960 | return 0; | 874 | return ifp; |
| 961 | } | 875 | } |
| 962 | 876 | ||
| 963 | void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) | 877 | void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) |
| @@ -1036,10 +950,9 @@ fail: · 72 unmodified lines | |||
| 1036 | int brcmf_bus_start(struct device *dev) | 950 | int brcmf_bus_start(struct device *dev) |
| 1037 | { | 951 | { |
| 1038 | int ret = -1; | 952 | int ret = -1; |
| 1039 | /* Room for "event_msgs" + '\0' + bitvec */ | ||
| 1040 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; | ||
| 1041 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 953 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
| 1042 | struct brcmf_pub *drvr = bus_if->drvr; | 954 | struct brcmf_pub *drvr = bus_if->drvr; |
| 955 | struct brcmf_if *ifp; | ||
| 1043 | 956 | ||
| 1044 | brcmf_dbg(TRACE, "\n"); | 957 | brcmf_dbg(TRACE, "\n"); |
| 1045 | 958 | ||
| @@ -1050,49 +963,30 @@ int brcmf_bus_start(struct device *dev) · 4 unmodified lines | |||
| 1050 | return ret; | 963 | return ret; |
| 1051 | } | 964 | } |
| 1052 | 965 | ||
| 1053 | brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, | 966 | /* add primary networking interface */ |
| 1054 | iovbuf, sizeof(iovbuf)); | 967 | ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL); |
| 1055 | brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf, | 968 | if (IS_ERR(ifp)) |
| 1056 | sizeof(iovbuf)); | 969 | return PTR_ERR(ifp); |
| 1057 | memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); | 970 | |
| 1058 | 971 | /* signal bus ready */ | |
| 1059 | setbit(drvr->eventmask, BRCMF_E_SET_SSID); | 972 | bus_if->state = BRCMF_BUS_DATA; |
| 1060 | setbit(drvr->eventmask, BRCMF_E_PRUNE); | 973 | |
| 1061 | setbit(drvr->eventmask, BRCMF_E_AUTH); | 974 | /* Bus is ready, do any initialization */ |
| 1062 | setbit(drvr->eventmask, BRCMF_E_REASSOC); | 975 | ret = brcmf_c_preinit_dcmds(ifp); |
| 1063 | setbit(drvr->eventmask, BRCMF_E_REASSOC_IND); | ||
| 1064 | setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND); | ||
| 1065 | setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND); | ||
| 1066 | setbit(drvr->eventmask, BRCMF_E_DISASSOC); | ||
| 1067 | setbit(drvr->eventmask, BRCMF_E_JOIN); | ||
| 1068 | setbit(drvr->eventmask, BRCMF_E_ASSOC_IND); | ||
| 1069 | setbit(drvr->eventmask, BRCMF_E_PSK_SUP); | ||
| 1070 | setbit(drvr->eventmask, BRCMF_E_LINK); | ||
| 1071 | setbit(drvr->eventmask, BRCMF_E_NDIS_LINK); | ||
| 1072 | setbit(drvr->eventmask, BRCMF_E_MIC_ERROR); | ||
| 1073 | setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE); | ||
| 1074 | setbit(drvr->eventmask, BRCMF_E_TXFAIL); | ||
| 1075 | setbit(drvr->eventmask, BRCMF_E_JOIN_START); | ||
| 1076 | setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE); | ||
| 1077 | |||
| 1078 | /* enable dongle roaming event */ | ||
| 1079 | |||
| 1080 | drvr->pktfilter_count = 1; | ||
| 1081 | /* Setup filter to allow only unicast */ | ||
| 1082 | drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; | ||
| 1083 | |||
| 1084 | /* Bus is ready, do any protocol initialization */ | ||
| 1085 | ret = brcmf_proto_init(drvr); | ||
| 1086 | if (ret < 0) | 976 | if (ret < 0) |
| 1087 | return ret; | 977 | return ret; |
| 1088 | 978 | ||
| 1089 | /* add primary networking interface */ | 979 | drvr->config = brcmf_cfg80211_attach(drvr); |
| 1090 | ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac); | 980 | if (drvr->config == NULL) |
| 1091 | if (ret < 0) | 981 | return -ENOMEM; |
| 982 | |||
| 983 | ret = brcmf_net_attach(ifp); | ||
| 984 | if (ret < 0) { | ||
| 985 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); | ||
| 986 | drvr->iflist[0] = NULL; | ||
| 1092 | return ret; | 987 | return ret; |
| 988 | } | ||
| 1093 | 989 | ||
| 1094 | /* signal bus ready */ | ||
| 1095 | bus_if->state = BRCMF_BUS_DATA; | ||
| 1096 | return 0; | 990 | return 0; |
| 1097 | } | 991 | } |
| 1098 | 992 | ||
| @@ -1163,42 +1057,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) · 64 unmodified lines | |||
| 1163 | return pend; | 1057 | return pend; |
| 1164 | } | 1058 | } |
| 1165 | 1059 | ||
| 1166 | #ifdef DEBUG | ||
| 1167 | int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) | ||
| 1168 | { | ||
| 1169 | int ret = 0; | ||
| 1170 | struct file *fp; | ||
| 1171 | mm_segment_t old_fs; | ||
| 1172 | loff_t pos = 0; | ||
| 1173 | |||
| 1174 | /* change to KERNEL_DS address limit */ | ||
| 1175 | old_fs = get_fs(); | ||
| 1176 | set_fs(KERNEL_DS); | ||
| 1177 | |||
| 1178 | /* open file to write */ | ||
| 1179 | fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); | ||
| 1180 | if (!fp) { | ||
| 1181 | brcmf_dbg(ERROR, "open file error\n"); | ||
| 1182 | ret = -1; | ||
| 1183 | goto exit; | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | /* Write buf to file */ | ||
| 1187 | fp->f_op->write(fp, (char __user *)buf, size, &pos); | ||
| 1188 | |||
| 1189 | exit: | ||
| 1190 | /* free buf before return */ | ||
| 1191 | kfree(buf); | ||
| 1192 | /* close file before return */ | ||
| 1193 | if (fp) | ||
| 1194 | filp_close(fp, NULL); | ||
| 1195 | /* restore previous address limit */ | ||
| 1196 | set_fs(old_fs); | ||
| 1197 | |||
| 1198 | return ret; | ||
| 1199 | } | ||
| 1200 | #endif /* DEBUG */ | ||
| 1201 | |||
| 1202 | static void brcmf_driver_init(struct work_struct *work) | 1060 | static void brcmf_driver_init(struct work_struct *work) |
| 1203 | { | 1061 | { |
| 1204 | brcmf_debugfs_init(); | 1062 | brcmf_debugfs_init(); |
| @@ -27,11 +27,6 @@ extern int brcmf_proto_attach(struct brcmf_pub *drvr); · 26 unmodified lines | |||
| 27 | /* Unlink, frees allocated protocol memory (including brcmf_proto) */ | 27 | /* Unlink, frees allocated protocol memory (including brcmf_proto) */ |
| 28 | extern void brcmf_proto_detach(struct brcmf_pub *drvr); | 28 | extern void brcmf_proto_detach(struct brcmf_pub *drvr); |
| 29 | 29 | ||
| 30 | /* Initialize protocol: sync w/dongle state. | ||
| 31 | * Sets dongle media info (iswl, drv_version, mac address). | ||
| 32 | */ | ||
| 33 | extern int brcmf_proto_init(struct brcmf_pub *drvr); | ||
| 34 | |||
| 35 | /* Stop protocol: sync w/dongle state. */ | 30 | /* Stop protocol: sync w/dongle state. */ |
| 36 | extern void brcmf_proto_stop(struct brcmf_pub *drvr); | 31 | extern void brcmf_proto_stop(struct brcmf_pub *drvr); |
| 37 | 32 | ||
| @@ -45,7 +40,8 @@ extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, · 7 unmodified lines | |||
| 45 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, | 40 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, |
| 46 | struct brcmf_dcmd *dcmd, int len); | 41 | struct brcmf_dcmd *dcmd, int len); |
| 47 | 42 | ||
| 48 | extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr); | 43 | /* Sets dongle media info (drv_version, mac address). */ |
| 44 | extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); | ||
| 49 | 45 | ||
| 50 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, | 46 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, |
| 51 | uint cmd, void *buf, uint len); | 47 | uint cmd, void *buf, uint len); |
| @@ -614,6 +614,12 @@ static const uint max_roundup = 512; · 613 unmodified lines | |||
| 614 | 614 | ||
| 615 | #define ALIGNMENT 4 | 615 | #define ALIGNMENT 4 |
| 616 | 616 | ||
| 617 | enum brcmf_sdio_frmtype { | ||
| 618 | BRCMF_SDIO_FT_NORMAL, | ||
| 619 | BRCMF_SDIO_FT_SUPER, | ||
| 620 | BRCMF_SDIO_FT_SUB, | ||
| 621 | }; | ||
| 622 | |||
| 617 | static void pkt_align(struct sk_buff *p, int len, int align) | 623 | static void pkt_align(struct sk_buff *p, int len, int align) |
| 618 | { | 624 | { |
| 619 | uint datalign; | 625 | uint datalign; |
| @@ -1032,7 +1038,8 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) · 412 unmodified lines | |||
| 1032 | } | 1038 | } |
| 1033 | 1039 | ||
| 1034 | static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | 1040 | static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, |
| 1035 | struct brcmf_sdio_read *rd) | 1041 | struct brcmf_sdio_read *rd, |
| 1042 | enum brcmf_sdio_frmtype type) | ||
| 1036 | { | 1043 | { |
| 1037 | u16 len, checksum; | 1044 | u16 len, checksum; |
| 1038 | u8 rx_seq, fc, tx_seq_max; | 1045 | u8 rx_seq, fc, tx_seq_max; |
| @@ -1059,6 +1066,15 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, · 20 unmodified lines | |||
| 1059 | brcmf_dbg(ERROR, "HW header length error\n"); | 1066 | brcmf_dbg(ERROR, "HW header length error\n"); |
| 1060 | return false; | 1067 | return false; |
| 1061 | } | 1068 | } |
| 1069 | if (type == BRCMF_SDIO_FT_SUPER && | ||
| 1070 | (roundup(len, bus->blocksize) != rd->len)) { | ||
| 1071 | brcmf_dbg(ERROR, "HW superframe header length error\n"); | ||
| 1072 | return false; | ||
| 1073 | } | ||
| 1074 | if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { | ||
| 1075 | brcmf_dbg(ERROR, "HW subframe header length error\n"); | ||
| 1076 | return false; | ||
| 1077 | } | ||
| 1062 | rd->len = len; | 1078 | rd->len = len; |
| 1063 | 1079 | ||
| 1064 | /* | 1080 | /* |
| @@ -1071,9 +1087,16 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, · 6 unmodified lines | |||
| 1071 | * Byte 5: Maximum Sequence number allow for Tx | 1087 | * Byte 5: Maximum Sequence number allow for Tx |
| 1072 | * Byte 6~7: Reserved | 1088 | * Byte 6~7: Reserved |
| 1073 | */ | 1089 | */ |
| 1090 | if (type == BRCMF_SDIO_FT_SUPER && | ||
| 1091 | SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { | ||
| 1092 | brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); | ||
| 1093 | rd->len = 0; | ||
| 1094 | return false; | ||
| 1095 | } | ||
| 1074 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); | 1096 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); |
| 1075 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); | 1097 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); |
| 1076 | if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL) { | 1098 | if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && |
| 1099 | type != BRCMF_SDIO_FT_SUPER) { | ||
| 1077 | brcmf_dbg(ERROR, "HW header length too long\n"); | 1100 | brcmf_dbg(ERROR, "HW header length too long\n"); |
| 1078 | bus->sdiodev->bus_if->dstats.rx_errors++; | 1101 | bus->sdiodev->bus_if->dstats.rx_errors++; |
| 1079 | bus->sdcnt.rx_toolong++; | 1102 | bus->sdcnt.rx_toolong++; |
| @@ -1081,6 +1104,17 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, · 1 unmodified line | |||
| 1081 | rd->len = 0; | 1104 | rd->len = 0; |
| 1082 | return false; | 1105 | return false; |
| 1083 | } | 1106 | } |
| 1107 | if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { | ||
| 1108 | brcmf_dbg(ERROR, "Wrong channel for superframe\n"); | ||
| 1109 | rd->len = 0; | ||
| 1110 | return false; | ||
| 1111 | } | ||
| 1112 | if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && | ||
| 1113 | rd->channel != SDPCM_EVENT_CHANNEL) { | ||
| 1114 | brcmf_dbg(ERROR, "Wrong channel for subframe\n"); | ||
| 1115 | rd->len = 0; | ||
| 1116 | return false; | ||
| 1117 | } | ||
| 1084 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); | 1118 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); |
| 1085 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { | 1119 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { |
| 1086 | brcmf_dbg(ERROR, "seq %d: bad data offset\n", rx_seq); | 1120 | brcmf_dbg(ERROR, "seq %d: bad data offset\n", rx_seq); |
| @@ -1095,6 +1129,9 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, · 8 unmodified lines | |||
| 1095 | bus->sdcnt.rx_badseq++; | 1129 | bus->sdcnt.rx_badseq++; |
| 1096 | rd->seq_num = rx_seq; | 1130 | rd->seq_num = rx_seq; |
| 1097 | } | 1131 | } |
| 1132 | /* no need to check the reset for subframe */ | ||
| 1133 | if (type == BRCMF_SDIO_FT_SUB) | ||
| 1134 | return true; | ||
| 1098 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; | 1135 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; |
| 1099 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { | 1136 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { |
| 1100 | /* only warm for NON glom packet */ | 1137 | /* only warm for NON glom packet */ |
| @@ -1126,16 +1163,16 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 25 unmodified lines | |||
| 1126 | u16 dlen, totlen; | 1163 | u16 dlen, totlen; |
| 1127 | u8 *dptr, num = 0; | 1164 | u8 *dptr, num = 0; |
| 1128 | 1165 | ||
| 1129 | u16 sublen, check; | 1166 | u16 sublen; |
| 1130 | struct sk_buff *pfirst, *pnext; | 1167 | struct sk_buff *pfirst, *pnext; |
| 1131 | 1168 | ||
| 1132 | int errcode; | 1169 | int errcode; |
| 1133 | u8 chan, seq, doff, sfdoff; | 1170 | u8 doff, sfdoff; |
| 1134 | u8 txmax; | ||
| 1135 | 1171 | ||
| 1136 | int ifidx = 0; | 1172 | int ifidx = 0; |
| 1137 | bool usechain = bus->use_rxchain; | 1173 | bool usechain = bus->use_rxchain; |
| 1138 | u16 next_len; | 1174 | |
| 1175 | struct brcmf_sdio_read rd_new; | ||
| 1139 | 1176 | ||
| 1140 | /* If packets, issue read(s) and send up packet chain */ | 1177 | /* If packets, issue read(s) and send up packet chain */ |
| 1141 | /* Return sequence numbers consumed? */ | 1178 | /* Return sequence numbers consumed? */ |
| @@ -1279,68 +1316,15 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 137 unmodified lines | |||
| 1279 | pfirst->data, min_t(int, pfirst->len, 48), | 1316 | pfirst->data, min_t(int, pfirst->len, 48), |
| 1280 | "SUPERFRAME:\n"); | 1317 | "SUPERFRAME:\n"); |
| 1281 | 1318 | ||
| 1282 | /* Validate the superframe header */ | 1319 | rd_new.seq_num = rxseq; |
| 1283 | dptr = (u8 *) (pfirst->data); | 1320 | rd_new.len = dlen; |
| 1284 | sublen = get_unaligned_le16(dptr); | 1321 | errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, |
| 1285 | check = get_unaligned_le16(dptr + sizeof(u16)); | 1322 | BRCMF_SDIO_FT_SUPER); |
| 1286 | 1323 | bus->cur_read.len = rd_new.len_nxtfrm << 4; | |
| 1287 | chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1288 | seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1289 | next_len = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; | ||
| 1290 | if ((next_len << 4) > MAX_RX_DATASZ) { | ||
| 1291 | brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n", | ||
| 1292 | next_len, seq); | ||
| 1293 | next_len = 0; | ||
| 1294 | } | ||
| 1295 | bus->cur_read.len = next_len << 4; | ||
| 1296 | doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1297 | txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1298 | |||
| 1299 | errcode = 0; | ||
| 1300 | if ((u16)~(sublen ^ check)) { | ||
| 1301 | brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n", | ||
| 1302 | sublen, check); | ||
| 1303 | errcode = -1; | ||
| 1304 | } else if (roundup(sublen, bus->blocksize) != dlen) { | ||
| 1305 | brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", | ||
| 1306 | sublen, roundup(sublen, bus->blocksize), | ||
| 1307 | dlen); | ||
| 1308 | errcode = -1; | ||
| 1309 | } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != | ||
| 1310 | SDPCM_GLOM_CHANNEL) { | ||
| 1311 | brcmf_dbg(ERROR, "(superframe): bad channel %d\n", | ||
| 1312 | SDPCM_PACKET_CHANNEL( | ||
| 1313 | &dptr[SDPCM_FRAMETAG_LEN])); | ||
| 1314 | errcode = -1; | ||
| 1315 | } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { | ||
| 1316 | brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n"); | ||
| 1317 | errcode = -1; | ||
| 1318 | } else if ((doff < SDPCM_HDRLEN) || | ||
| 1319 | (doff > (pfirst->len - SDPCM_HDRLEN))) { | ||
| 1320 | brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n", | ||
| 1321 | doff, sublen, pfirst->len, SDPCM_HDRLEN); | ||
| 1322 | errcode = -1; | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | /* Check sequence number of superframe SW header */ | ||
| 1326 | if (rxseq != seq) { | ||
| 1327 | brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", | ||
| 1328 | seq, rxseq); | ||
| 1329 | bus->sdcnt.rx_badseq++; | ||
| 1330 | rxseq = seq; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | /* Check window for sanity */ | ||
| 1334 | if ((u8) (txmax - bus->tx_seq) > 0x40) { | ||
| 1335 | brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n", | ||
| 1336 | txmax, bus->tx_seq); | ||
| 1337 | txmax = bus->tx_seq + 2; | ||
| 1338 | } | ||
| 1339 | bus->tx_max = txmax; | ||
| 1340 | 1324 | ||
| 1341 | /* Remove superframe header, remember offset */ | 1325 | /* Remove superframe header, remember offset */ |
| 1342 | skb_pull(pfirst, doff); | 1326 | skb_pull(pfirst, rd_new.dat_offset); |
| 1343 | sfdoff = doff; | 1327 | sfdoff = rd_new.dat_offset; |
| 1344 | num = 0; | 1328 | num = 0; |
| 1345 | 1329 | ||
| 1346 | /* Validate all the subframe headers */ | 1330 | /* Validate all the subframe headers */ |
| @@ -1349,34 +1333,14 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 2 unmodified lines | |||
| 1349 | if (errcode) | 1333 | if (errcode) |
| 1350 | break; | 1334 | break; |
| 1351 | 1335 | ||
| 1352 | dptr = (u8 *) (pnext->data); | 1336 | rd_new.len = pnext->len; |
| 1353 | dlen = (u16) (pnext->len); | 1337 | rd_new.seq_num = rxseq++; |
| 1354 | sublen = get_unaligned_le16(dptr); | 1338 | errcode = -!brcmf_sdio_hdparser(bus, pnext->data, |
| 1355 | check = get_unaligned_le16(dptr + sizeof(u16)); | 1339 | &rd_new, |
| 1356 | chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); | 1340 | BRCMF_SDIO_FT_SUB); |
| 1357 | doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1358 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), | 1341 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), |
| 1359 | dptr, 32, "subframe:\n"); | 1342 | pnext->data, 32, "subframe:\n"); |
| 1360 | 1343 | ||
| 1361 | if ((u16)~(sublen ^ check)) { | ||
| 1362 | brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", | ||
| 1363 | num, sublen, check); | ||
| 1364 | errcode = -1; | ||
| 1365 | } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { | ||
| 1366 | brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n", | ||
| 1367 | num, sublen, dlen); | ||
| 1368 | errcode = -1; | ||
| 1369 | } else if ((chan != SDPCM_DATA_CHANNEL) && | ||
| 1370 | (chan != SDPCM_EVENT_CHANNEL)) { | ||
| 1371 | brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n", | ||
| 1372 | num, chan); | ||
| 1373 | errcode = -1; | ||
| 1374 | } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { | ||
| 1375 | brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n", | ||
| 1376 | num, doff, sublen, SDPCM_HDRLEN); | ||
| 1377 | errcode = -1; | ||
| 1378 | } | ||
| 1379 | /* increase the subframe count */ | ||
| 1380 | num++; | 1344 | num++; |
| 1381 | } | 1345 | } |
| 1382 | 1346 | ||
| @@ -1402,27 +1366,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) · 19 unmodified lines | |||
| 1402 | skb_queue_walk_safe(&bus->glom, pfirst, pnext) { | 1366 | skb_queue_walk_safe(&bus->glom, pfirst, pnext) { |
| 1403 | dptr = (u8 *) (pfirst->data); | 1367 | dptr = (u8 *) (pfirst->data); |
| 1404 | sublen = get_unaligned_le16(dptr); | 1368 | sublen = get_unaligned_le16(dptr); |
| 1405 | chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1406 | seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); | ||
| 1407 | doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); | 1369 | doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); |
| 1408 | 1370 | ||
| 1409 | brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", | ||
| 1410 | num, pfirst, pfirst->data, | ||
| 1411 | pfirst->len, sublen, chan, seq); | ||
| 1412 | |||
| 1413 | /* precondition: chan == SDPCM_DATA_CHANNEL || | ||
| 1414 | chan == SDPCM_EVENT_CHANNEL */ | ||
| 1415 | |||
| 1416 | if (rxseq != seq) { | ||
| 1417 | brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", | ||
| 1418 | seq, rxseq); | ||
| 1419 | bus->sdcnt.rx_badseq++; | ||
| 1420 | rxseq = seq; | ||
| 1421 | } | ||
| 1422 | rxseq++; | ||
| 1423 | |||
| 1424 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), | 1371 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), |
| 1425 | dptr, dlen, "Rx Subframe Data:\n"); | 1372 | dptr, pfirst->len, |
| 1373 | "Rx Subframe Data:\n"); | ||
| 1426 | 1374 | ||
| 1427 | __skb_trim(pfirst, sublen); | 1375 | __skb_trim(pfirst, sublen); |
| 1428 | skb_pull(pfirst, doff); | 1376 | skb_pull(pfirst, doff); |
| @@ -1642,7 +1590,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) · 213 unmodified lines | |||
| 1642 | bus->rxhdr, SDPCM_HDRLEN, | 1590 | bus->rxhdr, SDPCM_HDRLEN, |
| 1643 | "RxHdr:\n"); | 1591 | "RxHdr:\n"); |
| 1644 | 1592 | ||
| 1645 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd)) { | 1593 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, |
| 1594 | BRCMF_SDIO_FT_NORMAL)) { | ||
| 1646 | if (!bus->rxpending) | 1595 | if (!bus->rxpending) |
| 1647 | break; | 1596 | break; |
| 1648 | else | 1597 | else |
| @@ -1701,7 +1650,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) · 52 unmodified lines | |||
| 1701 | } else { | 1650 | } else { |
| 1702 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); | 1651 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); |
| 1703 | rd_new.seq_num = rd->seq_num; | 1652 | rd_new.seq_num = rd->seq_num; |
| 1704 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new)) { | 1653 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, |
| 1654 | BRCMF_SDIO_FT_NORMAL)) { | ||
| 1705 | rd->len = 0; | 1655 | rd->len = 0; |
| 1706 | brcmu_pkt_buf_free_skb(pkt); | 1656 | brcmu_pkt_buf_free_skb(pkt); |
| 1707 | } | 1657 | } |
| @@ -0,0 +1,336 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2012 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* FWIL is the Firmware Interface Layer. In this module the support functions | ||
| 18 | * are located to set and get variables to and from the firmware. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/netdevice.h> | ||
| 23 | #include <defs.h> | ||
| 24 | #include <brcmu_utils.h> | ||
| 25 | #include <brcmu_wifi.h> | ||
| 26 | #include "dhd.h" | ||
| 27 | #include "dhd_bus.h" | ||
| 28 | #include "dhd_dbg.h" | ||
| 29 | #include "fwil.h" | ||
| 30 | |||
| 31 | |||
| 32 | static s32 | ||
| 33 | brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | ||
| 34 | { | ||
| 35 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 36 | s32 err; | ||
| 37 | |||
| 38 | if (drvr->bus_if->state == BRCMF_BUS_DOWN) { | ||
| 39 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | ||
| 40 | return -EIO; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (data != NULL) | ||
| 44 | len = min_t(uint, len, BRCMF_DCMD_MAXLEN); | ||
| 45 | if (set) | ||
| 46 | err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len); | ||
| 47 | else | ||
| 48 | err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data, | ||
| 49 | len); | ||
| 50 | |||
| 51 | if (err >= 0) | ||
| 52 | err = 0; | ||
| 53 | else | ||
| 54 | brcmf_dbg(ERROR, "Failed err=%d\n", err); | ||
| 55 | |||
| 56 | return err; | ||
| 57 | } | ||
| 58 | |||
| 59 | s32 | ||
| 60 | brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | ||
| 61 | { | ||
| 62 | s32 err; | ||
| 63 | |||
| 64 | mutex_lock(&ifp->drvr->proto_block); | ||
| 65 | |||
| 66 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | ||
| 67 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 68 | |||
| 69 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); | ||
| 70 | mutex_unlock(&ifp->drvr->proto_block); | ||
| 71 | |||
| 72 | return err; | ||
| 73 | } | ||
| 74 | |||
| 75 | s32 | ||
| 76 | brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | ||
| 77 | { | ||
| 78 | s32 err; | ||
| 79 | |||
| 80 | mutex_lock(&ifp->drvr->proto_block); | ||
| 81 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); | ||
| 82 | |||
| 83 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | ||
| 84 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 85 | |||
| 86 | mutex_unlock(&ifp->drvr->proto_block); | ||
| 87 | |||
| 88 | return err; | ||
| 89 | } | ||
| 90 | |||
| 91 | |||
| 92 | s32 | ||
| 93 | brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data) | ||
| 94 | { | ||
| 95 | s32 err; | ||
| 96 | __le32 data_le = cpu_to_le32(data); | ||
| 97 | |||
| 98 | mutex_lock(&ifp->drvr->proto_block); | ||
| 99 | err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true); | ||
| 100 | mutex_unlock(&ifp->drvr->proto_block); | ||
| 101 | |||
| 102 | return err; | ||
| 103 | } | ||
| 104 | |||
| 105 | s32 | ||
| 106 | brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data) | ||
| 107 | { | ||
| 108 | s32 err; | ||
| 109 | __le32 data_le = cpu_to_le32(*data); | ||
| 110 | |||
| 111 | mutex_lock(&ifp->drvr->proto_block); | ||
| 112 | err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false); | ||
| 113 | mutex_unlock(&ifp->drvr->proto_block); | ||
| 114 | *data = le32_to_cpu(data_le); | ||
| 115 | |||
| 116 | return err; | ||
| 117 | } | ||
| 118 | |||
| 119 | static u32 | ||
| 120 | brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen) | ||
| 121 | { | ||
| 122 | u32 len; | ||
| 123 | |||
| 124 | len = strlen(name) + 1; | ||
| 125 | |||
| 126 | if ((len + datalen) > buflen) | ||
| 127 | return 0; | ||
| 128 | |||
| 129 | memcpy(buf, name, len); | ||
| 130 | |||
| 131 | /* append data onto the end of the name string */ | ||
| 132 | if (data && datalen) | ||
| 133 | memcpy(&buf[len], data, datalen); | ||
| 134 | |||
| 135 | return len + datalen; | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 139 | s32 | ||
| 140 | brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, | ||
| 141 | u32 len) | ||
| 142 | { | ||
| 143 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 144 | s32 err; | ||
| 145 | u32 buflen; | ||
| 146 | |||
| 147 | mutex_lock(&drvr->proto_block); | ||
| 148 | |||
| 149 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | ||
| 150 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 151 | |||
| 152 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, | ||
| 153 | sizeof(drvr->proto_buf)); | ||
| 154 | if (buflen) { | ||
| 155 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf, | ||
| 156 | buflen, true); | ||
| 157 | } else { | ||
| 158 | err = -EPERM; | ||
| 159 | brcmf_dbg(ERROR, "Creating iovar failed\n"); | ||
| 160 | } | ||
| 161 | |||
| 162 | mutex_unlock(&drvr->proto_block); | ||
| 163 | return err; | ||
| 164 | } | ||
| 165 | |||
| 166 | s32 | ||
| 167 | brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, | ||
| 168 | u32 len) | ||
| 169 | { | ||
| 170 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 171 | s32 err; | ||
| 172 | u32 buflen; | ||
| 173 | |||
| 174 | mutex_lock(&drvr->proto_block); | ||
| 175 | |||
| 176 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, | ||
| 177 | sizeof(drvr->proto_buf)); | ||
| 178 | if (buflen) { | ||
| 179 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, | ||
| 180 | buflen, false); | ||
| 181 | if (err == 0) | ||
| 182 | memcpy(data, drvr->proto_buf, len); | ||
| 183 | } else { | ||
| 184 | err = -EPERM; | ||
| 185 | brcmf_dbg(ERROR, "Creating iovar failed\n"); | ||
| 186 | } | ||
| 187 | |||
| 188 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | ||
| 189 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 190 | |||
| 191 | mutex_unlock(&drvr->proto_block); | ||
| 192 | return err; | ||
| 193 | } | ||
| 194 | |||
| 195 | s32 | ||
| 196 | brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data) | ||
| 197 | { | ||
| 198 | __le32 data_le = cpu_to_le32(data); | ||
| 199 | |||
| 200 | return brcmf_fil_iovar_data_set(ifp, name, &data_le, sizeof(data_le)); | ||
| 201 | } | ||
| 202 | |||
| 203 | s32 | ||
| 204 | brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data) | ||
| 205 | { | ||
| 206 | __le32 data_le = cpu_to_le32(*data); | ||
| 207 | s32 err; | ||
| 208 | |||
| 209 | err = brcmf_fil_iovar_data_get(ifp, name, &data_le, sizeof(data_le)); | ||
| 210 | if (err == 0) | ||
| 211 | *data = le32_to_cpu(data_le); | ||
| 212 | return err; | ||
| 213 | } | ||
| 214 | |||
| 215 | static u32 | ||
| 216 | brcmf_create_bsscfg(s32 bssidx, char *name, char *data, u32 datalen, char *buf, | ||
| 217 | u32 buflen) | ||
| 218 | { | ||
| 219 | const s8 *prefix = "bsscfg:"; | ||
| 220 | s8 *p; | ||
| 221 | u32 prefixlen; | ||
| 222 | u32 namelen; | ||
| 223 | u32 iolen; | ||
| 224 | __le32 bssidx_le; | ||
| 225 | |||
| 226 | if (bssidx == 0) | ||
| 227 | return brcmf_create_iovar(name, data, datalen, buf, buflen); | ||
| 228 | |||
| 229 | prefixlen = strlen(prefix); | ||
| 230 | namelen = strlen(name) + 1; /* lengh of iovar name + null */ | ||
| 231 | iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen; | ||
| 232 | |||
| 233 | if (buflen < iolen) { | ||
| 234 | brcmf_dbg(ERROR, "buffer is too short\n"); | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | p = buf; | ||
| 239 | |||
| 240 | /* copy prefix, no null */ | ||
| 241 | memcpy(p, prefix, prefixlen); | ||
| 242 | p += prefixlen; | ||
| 243 | |||
| 244 | /* copy iovar name including null */ | ||
| 245 | memcpy(p, name, namelen); | ||
| 246 | p += namelen; | ||
| 247 | |||
| 248 | /* bss config index as first data */ | ||
| 249 | bssidx_le = cpu_to_le32(bssidx); | ||
| 250 | memcpy(p, &bssidx_le, sizeof(bssidx_le)); | ||
| 251 | p += sizeof(bssidx_le); | ||
| 252 | |||
| 253 | /* parameter buffer follows */ | ||
| 254 | if (datalen) | ||
| 255 | memcpy(p, data, datalen); | ||
| 256 | |||
| 257 | return iolen; | ||
| 258 | } | ||
| 259 | |||
| 260 | s32 | ||
| 261 | brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, | ||
| 262 | void *data, u32 len) | ||
| 263 | { | ||
| 264 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 265 | s32 err; | ||
| 266 | u32 buflen; | ||
| 267 | |||
| 268 | mutex_lock(&drvr->proto_block); | ||
| 269 | |||
| 270 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | ||
| 271 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 272 | |||
| 273 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, | ||
| 274 | drvr->proto_buf, sizeof(drvr->proto_buf)); | ||
| 275 | if (buflen) { | ||
| 276 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf, | ||
| 277 | buflen, true); | ||
| 278 | } else { | ||
| 279 | err = -EPERM; | ||
| 280 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); | ||
| 281 | } | ||
| 282 | |||
| 283 | mutex_unlock(&drvr->proto_block); | ||
| 284 | return err; | ||
| 285 | } | ||
| 286 | |||
| 287 | s32 | ||
| 288 | brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, | ||
| 289 | void *data, u32 len) | ||
| 290 | { | ||
| 291 | struct brcmf_pub *drvr = ifp->drvr; | ||
| 292 | s32 err; | ||
| 293 | u32 buflen; | ||
| 294 | |||
| 295 | mutex_lock(&drvr->proto_block); | ||
| 296 | |||
| 297 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len, | ||
| 298 | drvr->proto_buf, sizeof(drvr->proto_buf)); | ||
| 299 | if (buflen) { | ||
| 300 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, | ||
| 301 | buflen, false); | ||
| 302 | if (err == 0) | ||
| 303 | memcpy(data, drvr->proto_buf, len); | ||
| 304 | } else { | ||
| 305 | err = -EPERM; | ||
| 306 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); | ||
| 307 | } | ||
| 308 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | ||
| 309 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | ||
| 310 | |||
| 311 | mutex_unlock(&drvr->proto_block); | ||
| 312 | return err; | ||
| 313 | |||
| 314 | } | ||
| 315 | |||
| 316 | s32 | ||
| 317 | brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data) | ||
| 318 | { | ||
| 319 | __le32 data_le = cpu_to_le32(data); | ||
| 320 | |||
| 321 | return brcmf_fil_bsscfg_data_set(ifp, name, &data_le, | ||
| 322 | sizeof(data_le)); | ||
| 323 | } | ||
| 324 | |||
| 325 | s32 | ||
| 326 | brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data) | ||
| 327 | { | ||
| 328 | __le32 data_le = cpu_to_le32(*data); | ||
| 329 | s32 err; | ||
| 330 | |||
| 331 | err = brcmf_fil_bsscfg_data_get(ifp, name, &data_le, | ||
| 332 | sizeof(data_le)); | ||
| 333 | if (err == 0) | ||
| 334 | *data = le32_to_cpu(data_le); | ||
| 335 | return err; | ||
| 336 | } | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2012 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _fwil_h_ | ||
| 18 | #define _fwil_h_ | ||
| 19 | |||
| 20 | s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); | ||
| 21 | s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); | ||
| 22 | s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); | ||
| 23 | s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data); | ||
| 24 | |||
| 25 | s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, | ||
| 26 | u32 len); | ||
| 27 | s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, | ||
| 28 | u32 len); | ||
| 29 | s32 brcmf_fil_iovar_int_set(struct brcmf_if *ifp, char *name, u32 data); | ||
| 30 | s32 brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data); | ||
| 31 | |||
| 32 | s32 brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, void *data, | ||
| 33 | u32 len); | ||
| 34 | s32 brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, void *data, | ||
| 35 | u32 len); | ||
| 36 | s32 brcmf_fil_bsscfg_int_set(struct brcmf_if *ifp, char *name, u32 data); | ||
| 37 | s32 brcmf_fil_bsscfg_int_get(struct brcmf_if *ifp, char *name, u32 *data); | ||
| 38 | |||
| 39 | #endif /* _fwil_h_ */ | ||
| @@ -42,7 +42,6 @@ · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | #define IOCTL_RESP_TIMEOUT 2000 | 43 | #define IOCTL_RESP_TIMEOUT 2000 |
| 44 | 44 | ||
| 45 | #define BRCMF_USB_SYNC_TIMEOUT 300 /* ms */ | ||
| 46 | #define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ | 45 | #define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ |
| 47 | #define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ | 46 | #define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ |
| 48 | 47 | ||
| @@ -116,10 +115,6 @@ struct brcmf_usbdev_info { · 67 unmodified lines | |||
| 116 | u8 *image; /* buffer for combine fw and nvram */ | 115 | u8 *image; /* buffer for combine fw and nvram */ |
| 117 | int image_len; | 116 | int image_len; |
| 118 | 117 | ||
| 119 | wait_queue_head_t wait; | ||
| 120 | bool waitdone; | ||
| 121 | int sync_urb_status; | ||
| 122 | |||
| 123 | struct usb_device *usbdev; | 118 | struct usb_device *usbdev; |
| 124 | struct device *dev; | 119 | struct device *dev; |
| 125 | 120 | ||
| @@ -131,7 +126,6 @@ struct brcmf_usbdev_info { · 5 unmodified lines | |||
| 131 | int ctl_urb_status; | 126 | int ctl_urb_status; |
| 132 | int ctl_completed; | 127 | int ctl_completed; |
| 133 | wait_queue_head_t ioctl_resp_wait; | 128 | wait_queue_head_t ioctl_resp_wait; |
| 134 | wait_queue_head_t ctrl_wait; | ||
| 135 | ulong ctl_op; | 129 | ulong ctl_op; |
| 136 | 130 | ||
| 137 | struct urb *bulk_urb; /* used for FW download */ | 131 | struct urb *bulk_urb; /* used for FW download */ |
| @@ -754,34 +748,14 @@ static void brcmf_usb_down(struct device *dev) · 616 unmodified lines | |||
| 754 | brcmf_usb_free_q(&devinfo->rx_postq, true); | 748 | brcmf_usb_free_q(&devinfo->rx_postq, true); |
| 755 | } | 749 | } |
| 756 | 750 | ||
| 757 | static int | ||
| 758 | brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time) | ||
| 759 | { | ||
| 760 | int ret; | ||
| 761 | int err = 0; | ||
| 762 | int ms = time; | ||
| 763 | |||
| 764 | ret = wait_event_interruptible_timeout(devinfo->wait, | ||
| 765 | devinfo->waitdone == true, (ms * HZ / 1000)); | ||
| 766 | |||
| 767 | if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) { | ||
| 768 | brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n", | ||
| 769 | ret, devinfo->sync_urb_status); | ||
| 770 | err = -EINVAL; | ||
| 771 | } | ||
| 772 | devinfo->waitdone = false; | ||
| 773 | return err; | ||
| 774 | } | ||
| 775 | |||
| 776 | static void | 751 | static void |
| 777 | brcmf_usb_sync_complete(struct urb *urb) | 752 | brcmf_usb_sync_complete(struct urb *urb) |
| 778 | { | 753 | { |
| 779 | struct brcmf_usbdev_info *devinfo = | 754 | struct brcmf_usbdev_info *devinfo = |
| 780 | (struct brcmf_usbdev_info *)urb->context; | 755 | (struct brcmf_usbdev_info *)urb->context; |
| 781 | 756 | ||
| 782 | devinfo->waitdone = true; | 757 | devinfo->ctl_completed = true; |
| 783 | wake_up_interruptible(&devinfo->wait); | 758 | brcmf_usb_ioctl_resp_wake(devinfo); |
| 784 | devinfo->sync_urb_status = urb->status; | ||
| 785 | } | 759 | } |
| 786 | 760 | ||
| 787 | static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, | 761 | static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, |
| @@ -813,6 +787,7 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, · 25 unmodified lines | |||
| 813 | (void *) tmpbuf, size, | 787 | (void *) tmpbuf, size, |
| 814 | (usb_complete_t)brcmf_usb_sync_complete, devinfo); | 788 | (usb_complete_t)brcmf_usb_sync_complete, devinfo); |
| 815 | 789 | ||
| 790 | devinfo->ctl_completed = false; | ||
| 816 | ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); | 791 | ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); |
| 817 | if (ret < 0) { | 792 | if (ret < 0) { |
| 818 | brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); | 793 | brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); |
| @@ -820,11 +795,11 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, · 1 unmodified line | |||
| 820 | return false; | 795 | return false; |
| 821 | } | 796 | } |
| 822 | 797 | ||
| 823 | ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); | 798 | ret = brcmf_usb_ioctl_resp_wait(devinfo); |
| 824 | memcpy(buffer, tmpbuf, buflen); | 799 | memcpy(buffer, tmpbuf, buflen); |
| 825 | kfree(tmpbuf); | 800 | kfree(tmpbuf); |
| 826 | 801 | ||
| 827 | return (ret == 0); | 802 | return ret; |
| 828 | } | 803 | } |
| 829 | 804 | ||
| 830 | static bool | 805 | static bool |
| @@ -918,13 +893,14 @@ brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len) · 87 unmodified lines | |||
| 918 | 893 | ||
| 919 | devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET; | 894 | devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET; |
| 920 | 895 | ||
| 896 | devinfo->ctl_completed = false; | ||
| 921 | ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC); | 897 | ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC); |
| 922 | if (ret) { | 898 | if (ret) { |
| 923 | brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); | 899 | brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); |
| 924 | return ret; | 900 | return ret; |
| 925 | } | 901 | } |
| 926 | ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); | 902 | ret = brcmf_usb_ioctl_resp_wait(devinfo); |
| 927 | return ret; | 903 | return (ret == 0); |
| 928 | } | 904 | } |
| 929 | 905 | ||
| 930 | static int | 906 | static int |
| @@ -1284,7 +1260,6 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, · 353 unmodified lines | |||
| 1284 | goto error; | 1260 | goto error; |
| 1285 | } | 1261 | } |
| 1286 | 1262 | ||
| 1287 | init_waitqueue_head(&devinfo->wait); | ||
| 1288 | if (!brcmf_usb_dlneeded(devinfo)) | 1263 | if (!brcmf_usb_dlneeded(devinfo)) |
| 1289 | return &devinfo->bus_pub; | 1264 | return &devinfo->bus_pub; |
| 1290 | 1265 | ||
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include <brcmu_wifi.h> | 35 | #include <brcmu_wifi.h> |
| 36 | #include "dhd.h" | 36 | #include "dhd.h" |
| 37 | #include "wl_cfg80211.h" | 37 | #include "wl_cfg80211.h" |
| 38 | #include "fwil.h" | ||
| 38 | 39 | ||
| 39 | #define BRCMF_SCAN_IE_LEN_MAX 2048 | 40 | #define BRCMF_SCAN_IE_LEN_MAX 2048 |
| 40 | #define BRCMF_PNO_VERSION 2 | 41 | #define BRCMF_PNO_VERSION 2 |
| @@ -48,6 +49,8 @@ · 7 unmodified lines | |||
| 48 | #define BRCMF_PNO_SCAN_COMPLETE 1 | 49 | #define BRCMF_PNO_SCAN_COMPLETE 1 |
| 49 | #define BRCMF_PNO_SCAN_INCOMPLETE 0 | 50 | #define BRCMF_PNO_SCAN_INCOMPLETE 0 |
| 50 | 51 | ||
| 52 | #define BRCMF_IFACE_MAX_CNT 2 | ||
| 53 | |||
| 51 | #define TLV_LEN_OFF 1 /* length offset */ | 54 | #define TLV_LEN_OFF 1 /* length offset */ |
| 52 | #define TLV_HDR_LEN 2 /* header length */ | 55 | #define TLV_HDR_LEN 2 /* header length */ |
| 53 | #define TLV_BODY_OFF 2 /* body offset */ | 56 | #define TLV_BODY_OFF 2 /* body offset */ |
| @@ -91,16 +94,13 @@ · 37 unmodified lines | |||
| 91 | #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ | 94 | #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ |
| 92 | (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) | 95 | (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) |
| 93 | 96 | ||
| 94 | static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; | ||
| 95 | |||
| 96 | static u32 brcmf_dbg_level = WL_DBG_ERR; | 97 | static u32 brcmf_dbg_level = WL_DBG_ERR; |
| 97 | 98 | ||
| 98 | static bool check_sys_up(struct wiphy *wiphy) | 99 | static bool check_vif_up(struct brcmf_cfg80211_vif *vif) |
| 99 | { | 100 | { |
| 100 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 101 | if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { |
| 101 | if (!test_bit(WL_STATUS_READY, &cfg->status)) { | 102 | WL_INFO("device is not ready : status (%lu)\n", |
| 102 | WL_INFO("device is not ready : status (%d)\n", | 103 | vif->sme_state); |
| 103 | (int)cfg->status); | ||
| 104 | return false; | 104 | return false; |
| 105 | } | 105 | } |
| 106 | return true; | 106 | return true; |
| @@ -391,55 +391,29 @@ static u8 brcmf_mw_to_qdbm(u16 mw) · 284 unmodified lines | |||
| 391 | return qdbm; | 391 | return qdbm; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | /* function for reading/writing a single u32 from/to the dongle */ | 394 | static u16 channel_to_chanspec(struct ieee80211_channel *ch) |
| 395 | static int | ||
| 396 | brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par) | ||
| 397 | { | 395 | { |
| 398 | int err; | 396 | u16 chanspec; |
| 399 | __le32 par_le = cpu_to_le32(*par); | ||
| 400 | |||
| 401 | err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32)); | ||
| 402 | *par = le32_to_cpu(par_le); | ||
| 403 | |||
| 404 | return err; | ||
| 405 | } | ||
| 406 | |||
| 407 | static s32 | ||
| 408 | brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name, | ||
| 409 | void *param, s32 paramlen, | ||
| 410 | void *buf, s32 buflen, s32 bssidx) | ||
| 411 | { | ||
| 412 | s32 err = -ENOMEM; | ||
| 413 | u32 len; | ||
| 414 | |||
| 415 | len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, | ||
| 416 | buf, buflen, bssidx); | ||
| 417 | BUG_ON(!len); | ||
| 418 | if (len > 0) | ||
| 419 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len); | ||
| 420 | if (err) | ||
| 421 | WL_ERR("error (%d)\n", err); | ||
| 422 | 397 | ||
| 423 | return err; | 398 | chanspec = ieee80211_frequency_to_channel(ch->center_freq); |
| 424 | } | 399 | chanspec &= WL_CHANSPEC_CHAN_MASK; |
| 425 | 400 | ||
| 426 | static s32 | 401 | if (ch->band == IEEE80211_BAND_2GHZ) |
| 427 | brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name, | 402 | chanspec |= WL_CHANSPEC_BAND_2G; |
| 428 | void *param, s32 paramlen, | 403 | else |
| 429 | void *buf, s32 buflen, s32 bssidx) | 404 | chanspec |= WL_CHANSPEC_BAND_5G; |
| 430 | { | ||
| 431 | s32 err = -ENOMEM; | ||
| 432 | u32 len; | ||
| 433 | |||
| 434 | len = brcmf_c_mkiovar_bsscfg(name, param, paramlen, | ||
| 435 | buf, buflen, bssidx); | ||
| 436 | BUG_ON(!len); | ||
| 437 | if (len > 0) | ||
| 438 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len); | ||
| 439 | if (err) | ||
| 440 | WL_ERR("error (%d)\n", err); | ||
| 441 | 405 | ||
| 442 | return err; | 406 | if (ch->flags & IEEE80211_CHAN_NO_HT40) { |
| 407 | chanspec |= WL_CHANSPEC_BW_20; | ||
| 408 | chanspec |= WL_CHANSPEC_CTL_SB_NONE; | ||
| 409 | } else { | ||
| 410 | chanspec |= WL_CHANSPEC_BW_40; | ||
| 411 | if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS) | ||
| 412 | chanspec |= WL_CHANSPEC_CTL_SB_LOWER; | ||
| 413 | else | ||
| 414 | chanspec |= WL_CHANSPEC_CTL_SB_UPPER; | ||
| 415 | } | ||
| 416 | return chanspec; | ||
| 443 | } | 417 | } |
| 444 | 418 | ||
| 445 | static void convert_key_from_CPU(struct brcmf_wsec_key *key, | 419 | static void convert_key_from_CPU(struct brcmf_wsec_key *key, |
| @@ -457,18 +431,17 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key, · 11 unmodified lines | |||
| 457 | } | 431 | } |
| 458 | 432 | ||
| 459 | static int | 433 | static int |
| 460 | send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx, | 434 | send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key) |
| 461 | struct net_device *ndev, struct brcmf_wsec_key *key) | ||
| 462 | { | 435 | { |
| 463 | int err; | 436 | int err; |
| 464 | struct brcmf_wsec_key_le key_le; | 437 | struct brcmf_wsec_key_le key_le; |
| 465 | 438 | ||
| 466 | convert_key_from_CPU(key, &key_le); | 439 | convert_key_from_CPU(key, &key_le); |
| 467 | 440 | ||
| 468 | err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, | 441 | brcmf_netdev_wait_pend8021x(ndev); |
| 469 | sizeof(key_le), | 442 | |
| 470 | cfg->extra_buf, | 443 | err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le, |
| 471 | WL_EXTRA_BUF_MAX, bssidx); | 444 | sizeof(key_le)); |
| 472 | 445 | ||
| 473 | if (err) | 446 | if (err) |
| 474 | WL_ERR("wsec_key error (%d)\n", err); | 447 | WL_ERR("wsec_key error (%d)\n", err); |
| @@ -480,6 +453,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 480 | enum nl80211_iftype type, u32 *flags, | 453 | enum nl80211_iftype type, u32 *flags, |
| 481 | struct vif_params *params) | 454 | struct vif_params *params) |
| 482 | { | 455 | { |
| 456 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 483 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 457 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 484 | s32 infra = 0; | 458 | s32 infra = 0; |
| 485 | s32 ap = 0; | 459 | s32 ap = 0; |
| @@ -511,7 +485,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, · 25 unmodified lines | |||
| 511 | } | 485 | } |
| 512 | 486 | ||
| 513 | if (ap) { | 487 | if (ap) { |
| 514 | set_bit(WL_STATUS_AP_CREATING, &cfg->status); | 488 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
| 515 | if (!cfg->ap_info) | 489 | if (!cfg->ap_info) |
| 516 | cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), | 490 | cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), |
| 517 | GFP_KERNEL); | 491 | GFP_KERNEL); |
| @@ -521,7 +495,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 521 | } | 495 | } |
| 522 | WL_INFO("IF Type = AP\n"); | 496 | WL_INFO("IF Type = AP\n"); |
| 523 | } else { | 497 | } else { |
| 524 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); | 498 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), |
| 499 | BRCMF_C_SET_INFRA, infra); | ||
| 525 | if (err) { | 500 | if (err) { |
| 526 | WL_ERR("WLC_SET_INFRA error (%d)\n", err); | 501 | WL_ERR("WLC_SET_INFRA error (%d)\n", err); |
| 527 | err = -EAGAIN; | 502 | err = -EAGAIN; |
| @@ -539,99 +514,13 @@ done: · 11 unmodified lines | |||
| 539 | return err; | 514 | return err; |
| 540 | } | 515 | } |
| 541 | 516 | ||
| 542 | static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val) | ||
| 543 | { | ||
| 544 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
| 545 | u32 len; | ||
| 546 | s32 err = 0; | ||
| 547 | __le32 val_le; | ||
| 548 | |||
| 549 | val_le = cpu_to_le32(val); | ||
| 550 | len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf, | ||
| 551 | sizeof(buf)); | ||
| 552 | BUG_ON(!len); | ||
| 553 | |||
| 554 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len); | ||
| 555 | if (err) | ||
| 556 | WL_ERR("error (%d)\n", err); | ||
| 557 | |||
| 558 | return err; | ||
| 559 | } | ||
| 560 | |||
| 561 | static s32 | ||
| 562 | brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval) | ||
| 563 | { | ||
| 564 | union { | ||
| 565 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
| 566 | __le32 val; | ||
| 567 | } var; | ||
| 568 | u32 len; | ||
| 569 | u32 data_null; | ||
| 570 | s32 err = 0; | ||
| 571 | |||
| 572 | len = | ||
| 573 | brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), | ||
| 574 | sizeof(var.buf)); | ||
| 575 | BUG_ON(!len); | ||
| 576 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len); | ||
| 577 | if (err) | ||
| 578 | WL_ERR("error (%d)\n", err); | ||
| 579 | |||
| 580 | *retval = le32_to_cpu(var.val); | ||
| 581 | |||
| 582 | return err; | ||
| 583 | } | ||
| 584 | |||
| 585 | static s32 | ||
| 586 | brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val, | ||
| 587 | s32 bssidx) | ||
| 588 | { | ||
| 589 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
| 590 | __le32 val_le; | ||
| 591 | |||
| 592 | val_le = cpu_to_le32(val); | ||
| 593 | |||
| 594 | return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le, | ||
| 595 | sizeof(val_le), buf, sizeof(buf), | ||
| 596 | bssidx); | ||
| 597 | } | ||
| 598 | |||
| 599 | static s32 | ||
| 600 | brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val, | ||
| 601 | s32 bssidx) | ||
| 602 | { | ||
| 603 | s8 buf[BRCMF_DCMD_SMLEN]; | ||
| 604 | s32 err; | ||
| 605 | __le32 val_le; | ||
| 606 | |||
| 607 | memset(buf, 0, sizeof(buf)); | ||
| 608 | err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf, | ||
| 609 | sizeof(buf), bssidx); | ||
| 610 | if (err == 0) { | ||
| 611 | memcpy(&val_le, buf, sizeof(val_le)); | ||
| 612 | *val = le32_to_cpu(val_le); | ||
| 613 | } | ||
| 614 | return err; | ||
| 615 | } | ||
| 616 | |||
| 617 | |||
| 618 | /* | ||
| 619 | * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this | ||
| 620 | * should return the ndev matching bssidx. | ||
| 621 | */ | ||
| 622 | static s32 | ||
| 623 | brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev) | ||
| 624 | { | ||
| 625 | return 0; | ||
| 626 | } | ||
| 627 | |||
| 628 | static void brcmf_set_mpc(struct net_device *ndev, int mpc) | 517 | static void brcmf_set_mpc(struct net_device *ndev, int mpc) |
| 629 | { | 518 | { |
| 519 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 630 | s32 err = 0; | 520 | s32 err = 0; |
| 631 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
| 632 | 521 | ||
| 633 | if (test_bit(WL_STATUS_READY, &cfg->status)) { | 522 | if (check_vif_up(ifp->vif)) { |
| 634 | err = brcmf_dev_intvar_set(ndev, "mpc", mpc); | 523 | err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc); |
| 635 | if (err) { | 524 | if (err) { |
| 636 | WL_ERR("fail to set mpc\n"); | 525 | WL_ERR("fail to set mpc\n"); |
| 637 | return; | 526 | return; |
| @@ -643,7 +532,7 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc) · 5 unmodified lines | |||
| 643 | static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, | 532 | static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, |
| 644 | struct brcmf_ssid *ssid) | 533 | struct brcmf_ssid *ssid) |
| 645 | { | 534 | { |
| 646 | memcpy(params_le->bssid, ether_bcast, ETH_ALEN); | 535 | memset(params_le->bssid, 0xFF, ETH_ALEN); |
| 647 | params_le->bss_type = DOT11_BSSTYPE_ANY; | 536 | params_le->bss_type = DOT11_BSSTYPE_ANY; |
| 648 | params_le->scan_type = 0; | 537 | params_le->scan_type = 0; |
| 649 | params_le->channel_num = 0; | 538 | params_le->channel_num = 0; |
| @@ -657,30 +546,6 @@ static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, · 7 unmodified lines | |||
| 657 | } | 546 | } |
| 658 | } | 547 | } |
| 659 | 548 | ||
| 660 | static s32 | ||
| 661 | brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param, | ||
| 662 | s32 paramlen, void *bufptr, s32 buflen) | ||
| 663 | { | ||
| 664 | s32 iolen; | ||
| 665 | |||
| 666 | iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen); | ||
| 667 | BUG_ON(!iolen); | ||
| 668 | |||
| 669 | return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen); | ||
| 670 | } | ||
| 671 | |||
| 672 | static s32 | ||
| 673 | brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param, | ||
| 674 | s32 paramlen, void *bufptr, s32 buflen) | ||
| 675 | { | ||
| 676 | s32 iolen; | ||
| 677 | |||
| 678 | iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen); | ||
| 679 | BUG_ON(!iolen); | ||
| 680 | |||
| 681 | return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen); | ||
| 682 | } | ||
| 683 | |||
| 684 | static s32 | 549 | static s32 |
| 685 | brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, | 550 | brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, |
| 686 | struct brcmf_ssid *ssid, u16 action) | 551 | struct brcmf_ssid *ssid, u16 action) |
| @@ -703,8 +568,8 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, · 16 unmodified lines | |||
| 703 | params->action = cpu_to_le16(action); | 568 | params->action = cpu_to_le16(action); |
| 704 | params->scan_duration = cpu_to_le16(0); | 569 | params->scan_duration = cpu_to_le16(0); |
| 705 | 570 | ||
| 706 | err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size, | 571 | err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan", |
| 707 | iscan->dcmd_buf, BRCMF_DCMD_SMLEN); | 572 | params, params_size); |
| 708 | if (err) { | 573 | if (err) { |
| 709 | if (err == -EBUSY) | 574 | if (err == -EBUSY) |
| 710 | WL_INFO("system busy : iscan canceled\n"); | 575 | WL_INFO("system busy : iscan canceled\n"); |
| @@ -721,7 +586,7 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) · 10 unmodified lines | |||
| 721 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | 586 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); |
| 722 | struct net_device *ndev = cfg_to_ndev(cfg); | 587 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 723 | struct brcmf_ssid ssid; | 588 | struct brcmf_ssid ssid; |
| 724 | __le32 passive_scan; | 589 | u32 passive_scan; |
| 725 | s32 err = 0; | 590 | s32 err = 0; |
| 726 | 591 | ||
| 727 | /* Broadcast scan by default */ | 592 | /* Broadcast scan by default */ |
| @@ -729,9 +594,9 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) · 1 unmodified line | |||
| 729 | 594 | ||
| 730 | iscan->state = WL_ISCAN_STATE_SCANING; | 595 | iscan->state = WL_ISCAN_STATE_SCANING; |
| 731 | 596 | ||
| 732 | passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); | 597 | passive_scan = cfg->active_scan ? 0 : 1; |
| 733 | err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN, | 598 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), |
| 734 | &passive_scan, sizeof(passive_scan)); | 599 | BRCMF_C_SET_PASSIVE_SCAN, passive_scan); |
| 735 | if (err) { | 600 | if (err) { |
| 736 | WL_ERR("error (%d)\n", err); | 601 | WL_ERR("error (%d)\n", err); |
| 737 | return err; | 602 | return err; |
| @@ -754,27 +619,27 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, · 16 unmodified lines | |||
| 754 | struct cfg80211_scan_request *request, | 619 | struct cfg80211_scan_request *request, |
| 755 | struct cfg80211_ssid *this_ssid) | 620 | struct cfg80211_ssid *this_ssid) |
| 756 | { | 621 | { |
| 622 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 757 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 623 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); |
| 758 | struct cfg80211_ssid *ssids; | 624 | struct cfg80211_ssid *ssids; |
| 759 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | 625 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; |
| 760 | __le32 passive_scan; | 626 | u32 passive_scan; |
| 761 | bool iscan_req; | 627 | bool iscan_req; |
| 762 | bool spec_scan; | 628 | bool spec_scan; |
| 763 | s32 err = 0; | 629 | s32 err = 0; |
| 764 | u32 SSID_len; | 630 | u32 SSID_len; |
| 765 | 631 | ||
| 766 | if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { | 632 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 767 | WL_ERR("Scanning already : status (%lu)\n", cfg->status); | 633 | WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); |
| 768 | return -EAGAIN; | 634 | return -EAGAIN; |
| 769 | } | 635 | } |
| 770 | if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { | 636 | if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { |
| 771 | WL_ERR("Scanning being aborted : status (%lu)\n", | 637 | WL_ERR("Scanning being aborted: status (%lu)\n", |
| 772 | cfg->status); | 638 | cfg->scan_status); |
| 773 | return -EAGAIN; | 639 | return -EAGAIN; |
| 774 | } | 640 | } |
| 775 | if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { | 641 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { |
| 776 | WL_ERR("Connecting : status (%lu)\n", | 642 | WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); |
| 777 | cfg->status); | ||
| 778 | return -EAGAIN; | 643 | return -EAGAIN; |
| 779 | } | 644 | } |
| 780 | 645 | ||
| @@ -792,7 +657,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, · 11 unmodified lines | |||
| 792 | } | 657 | } |
| 793 | 658 | ||
| 794 | cfg->scan_request = request; | 659 | cfg->scan_request = request; |
| 795 | set_bit(WL_STATUS_SCANNING, &cfg->status); | 660 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 796 | if (iscan_req) { | 661 | if (iscan_req) { |
| 797 | err = brcmf_do_iscan(cfg); | 662 | err = brcmf_do_iscan(cfg); |
| 798 | if (!err) | 663 | if (!err) |
| @@ -813,16 +678,16 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, · 14 unmodified lines | |||
| 813 | WL_SCAN("Broadcast scan\n"); | 678 | WL_SCAN("Broadcast scan\n"); |
| 814 | } | 679 | } |
| 815 | 680 | ||
| 816 | passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); | 681 | passive_scan = cfg->active_scan ? 0 : 1; |
| 817 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, | 682 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, |
| 818 | &passive_scan, sizeof(passive_scan)); | 683 | passive_scan); |
| 819 | if (err) { | 684 | if (err) { |
| 820 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); | 685 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); |
| 821 | goto scan_out; | 686 | goto scan_out; |
| 822 | } | 687 | } |
| 823 | brcmf_set_mpc(ndev, 0); | 688 | brcmf_set_mpc(ndev, 0); |
| 824 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le, | 689 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, |
| 825 | sizeof(sr->ssid_le)); | 690 | &sr->ssid_le, sizeof(sr->ssid_le)); |
| 826 | if (err) { | 691 | if (err) { |
| 827 | if (err == -EBUSY) | 692 | if (err == -EBUSY) |
| 828 | WL_INFO("system busy : scan for \"%s\" " | 693 | WL_INFO("system busy : scan for \"%s\" " |
| @@ -838,7 +703,7 @@ brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, · 9 unmodified lines | |||
| 838 | return 0; | 703 | return 0; |
| 839 | 704 | ||
| 840 | scan_out: | 705 | scan_out: |
| 841 | clear_bit(WL_STATUS_SCANNING, &cfg->status); | 706 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 842 | cfg->scan_request = NULL; | 707 | cfg->scan_request = NULL; |
| 843 | return err; | 708 | return err; |
| 844 | } | 709 | } |
| @@ -851,12 +716,10 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, · 6 unmodified lines | |||
| 851 | s32 i; | 716 | s32 i; |
| 852 | s32 offset; | 717 | s32 offset; |
| 853 | u16 chanspec; | 718 | u16 chanspec; |
| 854 | u16 channel; | ||
| 855 | struct ieee80211_channel *req_channel; | ||
| 856 | char *ptr; | 719 | char *ptr; |
| 857 | struct brcmf_ssid_le ssid_le; | 720 | struct brcmf_ssid_le ssid_le; |
| 858 | 721 | ||
| 859 | memcpy(params_le->bssid, ether_bcast, ETH_ALEN); | 722 | memset(params_le->bssid, 0xFF, ETH_ALEN); |
| 860 | params_le->bss_type = DOT11_BSSTYPE_ANY; | 723 | params_le->bss_type = DOT11_BSSTYPE_ANY; |
| 861 | params_le->scan_type = 0; | 724 | params_le->scan_type = 0; |
| 862 | params_le->channel_num = 0; | 725 | params_le->channel_num = 0; |
| @@ -876,30 +739,9 @@ static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, · 13 unmodified lines | |||
| 876 | WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels); | 739 | WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels); |
| 877 | if (n_channels > 0) { | 740 | if (n_channels > 0) { |
| 878 | for (i = 0; i < n_channels; i++) { | 741 | for (i = 0; i < n_channels; i++) { |
| 879 | chanspec = 0; | 742 | chanspec = channel_to_chanspec(request->channels[i]); |
| 880 | req_channel = request->channels[i]; | ||
| 881 | channel = ieee80211_frequency_to_channel( | ||
| 882 | req_channel->center_freq); | ||
| 883 | if (req_channel->band == IEEE80211_BAND_2GHZ) | ||
| 884 | chanspec |= WL_CHANSPEC_BAND_2G; | ||
| 885 | else | ||
| 886 | chanspec |= WL_CHANSPEC_BAND_5G; | ||
| 887 | |||
| 888 | if (req_channel->flags & IEEE80211_CHAN_NO_HT40) { | ||
| 889 | chanspec |= WL_CHANSPEC_BW_20; | ||
| 890 | chanspec |= WL_CHANSPEC_CTL_SB_NONE; | ||
| 891 | } else { | ||
| 892 | chanspec |= WL_CHANSPEC_BW_40; | ||
| 893 | if (req_channel->flags & | ||
| 894 | IEEE80211_CHAN_NO_HT40PLUS) | ||
| 895 | chanspec |= WL_CHANSPEC_CTL_SB_LOWER; | ||
| 896 | else | ||
| 897 | chanspec |= WL_CHANSPEC_CTL_SB_UPPER; | ||
| 898 | } | ||
| 899 | |||
| 900 | chanspec |= (channel & WL_CHANSPEC_CHAN_MASK); | ||
| 901 | WL_SCAN("Chan : %d, Channel spec: %x\n", | 743 | WL_SCAN("Chan : %d, Channel spec: %x\n", |
| 902 | channel, chanspec); | 744 | request->channels[i]->hw_value, chanspec); |
| 903 | params_le->channel_list[i] = cpu_to_le16(chanspec); | 745 | params_le->channel_list[i] = cpu_to_le16(chanspec); |
| 904 | } | 746 | } |
| 905 | } else { | 747 | } else { |
| @@ -966,7 +808,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 60 unmodified lines | |||
| 966 | /* Do a scan abort to stop the driver's scan engine */ | 808 | /* Do a scan abort to stop the driver's scan engine */ |
| 967 | WL_SCAN("ABORT scan in firmware\n"); | 809 | WL_SCAN("ABORT scan in firmware\n"); |
| 968 | memset(¶ms_le, 0, sizeof(params_le)); | 810 | memset(¶ms_le, 0, sizeof(params_le)); |
| 969 | memcpy(params_le.bssid, ether_bcast, ETH_ALEN); | 811 | memset(params_le.bssid, 0xFF, ETH_ALEN); |
| 970 | params_le.bss_type = DOT11_BSSTYPE_ANY; | 812 | params_le.bss_type = DOT11_BSSTYPE_ANY; |
| 971 | params_le.scan_type = 0; | 813 | params_le.scan_type = 0; |
| 972 | params_le.channel_num = cpu_to_le32(1); | 814 | params_le.channel_num = cpu_to_le32(1); |
| @@ -977,8 +819,8 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 4 unmodified lines | |||
| 977 | /* Scan is aborted by setting channel_list[0] to -1 */ | 819 | /* Scan is aborted by setting channel_list[0] to -1 */ |
| 978 | params_le.channel_list[0] = cpu_to_le16(-1); | 820 | params_le.channel_list[0] = cpu_to_le16(-1); |
| 979 | /* E-Scan (or anyother type) can be aborted by SCAN */ | 821 | /* E-Scan (or anyother type) can be aborted by SCAN */ |
| 980 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, ¶ms_le, | 822 | err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN, |
| 981 | sizeof(params_le)); | 823 | ¶ms_le, sizeof(params_le)); |
| 982 | if (err) | 824 | if (err) |
| 983 | WL_ERR("Scan abort failed\n"); | 825 | WL_ERR("Scan abort failed\n"); |
| 984 | } | 826 | } |
| @@ -998,7 +840,7 @@ brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 13 unmodified lines | |||
| 998 | cfg80211_scan_done(scan_request, aborted); | 840 | cfg80211_scan_done(scan_request, aborted); |
| 999 | brcmf_set_mpc(ndev, 1); | 841 | brcmf_set_mpc(ndev, 1); |
| 1000 | } | 842 | } |
| 1001 | if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { | 843 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 1002 | WL_ERR("Scan complete while device not scanning\n"); | 844 | WL_ERR("Scan complete while device not scanning\n"); |
| 1003 | return -EPERM; | 845 | return -EPERM; |
| 1004 | } | 846 | } |
| @@ -1036,8 +878,8 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev, · 31 unmodified lines | |||
| 1036 | params->action = cpu_to_le16(action); | 878 | params->action = cpu_to_le16(action); |
| 1037 | params->sync_id = cpu_to_le16(0x1234); | 879 | params->sync_id = cpu_to_le16(0x1234); |
| 1038 | 880 | ||
| 1039 | err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size, | 881 | err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan", |
| 1040 | cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN); | 882 | params, params_size); |
| 1041 | if (err) { | 883 | if (err) { |
| 1042 | if (err == -EBUSY) | 884 | if (err == -EBUSY) |
| 1043 | WL_INFO("system busy : escan canceled\n"); | 885 | WL_INFO("system busy : escan canceled\n"); |
| @@ -1055,16 +897,16 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, · 11 unmodified lines | |||
| 1055 | struct net_device *ndev, struct cfg80211_scan_request *request) | 897 | struct net_device *ndev, struct cfg80211_scan_request *request) |
| 1056 | { | 898 | { |
| 1057 | s32 err; | 899 | s32 err; |
| 1058 | __le32 passive_scan; | 900 | u32 passive_scan; |
| 1059 | struct brcmf_scan_results *results; | 901 | struct brcmf_scan_results *results; |
| 1060 | 902 | ||
| 1061 | WL_SCAN("Enter\n"); | 903 | WL_SCAN("Enter\n"); |
| 1062 | cfg->escan_info.ndev = ndev; | 904 | cfg->escan_info.ndev = ndev; |
| 1063 | cfg->escan_info.wiphy = wiphy; | 905 | cfg->escan_info.wiphy = wiphy; |
| 1064 | cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; | 906 | cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING; |
| 1065 | passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); | 907 | passive_scan = cfg->active_scan ? 0 : 1; |
| 1066 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, | 908 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN, |
| 1067 | &passive_scan, sizeof(passive_scan)); | 909 | passive_scan); |
| 1068 | if (err) { | 910 | if (err) { |
| 1069 | WL_ERR("error (%d)\n", err); | 911 | WL_ERR("error (%d)\n", err); |
| 1070 | return err; | 912 | return err; |
| @@ -1086,10 +928,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, · 15 unmodified lines | |||
| 1086 | struct cfg80211_scan_request *request, | 928 | struct cfg80211_scan_request *request, |
| 1087 | struct cfg80211_ssid *this_ssid) | 929 | struct cfg80211_ssid *this_ssid) |
| 1088 | { | 930 | { |
| 931 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 1089 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 932 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); |
| 1090 | struct cfg80211_ssid *ssids; | 933 | struct cfg80211_ssid *ssids; |
| 1091 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | 934 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; |
| 1092 | __le32 passive_scan; | 935 | u32 passive_scan; |
| 1093 | bool escan_req; | 936 | bool escan_req; |
| 1094 | bool spec_scan; | 937 | bool spec_scan; |
| 1095 | s32 err; | 938 | s32 err; |
| @@ -1097,18 +940,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 1097 | 940 | ||
| 1098 | WL_SCAN("START ESCAN\n"); | 941 | WL_SCAN("START ESCAN\n"); |
| 1099 | 942 | ||
| 1100 | if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { | 943 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 1101 | WL_ERR("Scanning already : status (%lu)\n", cfg->status); | 944 | WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); |
| 1102 | return -EAGAIN; | 945 | return -EAGAIN; |
| 1103 | } | 946 | } |
| 1104 | if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) { | 947 | if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { |
| 1105 | WL_ERR("Scanning being aborted : status (%lu)\n", | 948 | WL_ERR("Scanning being aborted: status (%lu)\n", |
| 1106 | cfg->status); | 949 | cfg->scan_status); |
| 1107 | return -EAGAIN; | 950 | return -EAGAIN; |
| 1108 | } | 951 | } |
| 1109 | if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) { | 952 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { |
| 1110 | WL_ERR("Connecting : status (%lu)\n", | 953 | WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); |
| 1111 | cfg->status); | ||
| 1112 | return -EAGAIN; | 954 | return -EAGAIN; |
| 1113 | } | 955 | } |
| 1114 | 956 | ||
| @@ -1128,7 +970,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, · 13 unmodified lines | |||
| 1128 | } | 970 | } |
| 1129 | 971 | ||
| 1130 | cfg->scan_request = request; | 972 | cfg->scan_request = request; |
| 1131 | set_bit(WL_STATUS_SCANNING, &cfg->status); | 973 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 1132 | if (escan_req) { | 974 | if (escan_req) { |
| 1133 | err = brcmf_do_escan(cfg, wiphy, ndev, request); | 975 | err = brcmf_do_escan(cfg, wiphy, ndev, request); |
| 1134 | if (!err) | 976 | if (!err) |
| @@ -1149,16 +991,16 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, · 14 unmodified lines | |||
| 1149 | } else | 991 | } else |
| 1150 | WL_SCAN("Broadcast scan\n"); | 992 | WL_SCAN("Broadcast scan\n"); |
| 1151 | 993 | ||
| 1152 | passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1); | 994 | passive_scan = cfg->active_scan ? 0 : 1; |
| 1153 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, | 995 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, |
| 1154 | &passive_scan, sizeof(passive_scan)); | 996 | passive_scan); |
| 1155 | if (err) { | 997 | if (err) { |
| 1156 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); | 998 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); |
| 1157 | goto scan_out; | 999 | goto scan_out; |
| 1158 | } | 1000 | } |
| 1159 | brcmf_set_mpc(ndev, 0); | 1001 | brcmf_set_mpc(ndev, 0); |
| 1160 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le, | 1002 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, |
| 1161 | sizeof(sr->ssid_le)); | 1003 | &sr->ssid_le, sizeof(sr->ssid_le)); |
| 1162 | if (err) { | 1004 | if (err) { |
| 1163 | if (err == -EBUSY) | 1005 | if (err == -EBUSY) |
| 1164 | WL_INFO("BUSY: scan for \"%s\" canceled\n", | 1006 | WL_INFO("BUSY: scan for \"%s\" canceled\n", |
| @@ -1174,7 +1016,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, · 9 unmodified lines | |||
| 1174 | return 0; | 1016 | return 0; |
| 1175 | 1017 | ||
| 1176 | scan_out: | 1018 | scan_out: |
| 1177 | clear_bit(WL_STATUS_SCANNING, &cfg->status); | 1019 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 1178 | if (timer_pending(&cfg->escan_timeout)) | 1020 | if (timer_pending(&cfg->escan_timeout)) |
| 1179 | del_timer_sync(&cfg->escan_timeout); | 1021 | del_timer_sync(&cfg->escan_timeout); |
| 1180 | cfg->scan_request = NULL; | 1022 | cfg->scan_request = NULL; |
| @@ -1182,8 +1024,7 @@ scan_out: · 1 unmodified line | |||
| 1182 | } | 1024 | } |
| 1183 | 1025 | ||
| 1184 | static s32 | 1026 | static s32 |
| 1185 | brcmf_cfg80211_scan(struct wiphy *wiphy, | 1027 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
| 1186 | struct cfg80211_scan_request *request) | ||
| 1187 | { | 1028 | { |
| 1188 | struct net_device *ndev = request->wdev->netdev; | 1029 | struct net_device *ndev = request->wdev->netdev; |
| 1189 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1030 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); |
| @@ -1191,7 +1032,8 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, · 1 unmodified line | |||
| 1191 | 1032 | ||
| 1192 | WL_TRACE("Enter\n"); | 1033 | WL_TRACE("Enter\n"); |
| 1193 | 1034 | ||
| 1194 | if (!check_sys_up(wiphy)) | 1035 | if (!check_vif_up(container_of(request->wdev, |
| 1036 | struct brcmf_cfg80211_vif, wdev))) | ||
| 1195 | return -EIO; | 1037 | return -EIO; |
| 1196 | 1038 | ||
| 1197 | if (cfg->iscan_on) | 1039 | if (cfg->iscan_on) |
| @@ -1210,7 +1052,8 @@ static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) · 12 unmodified lines | |||
| 1210 | { | 1052 | { |
| 1211 | s32 err = 0; | 1053 | s32 err = 0; |
| 1212 | 1054 | ||
| 1213 | err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold); | 1055 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh", |
| 1056 | rts_threshold); | ||
| 1214 | if (err) | 1057 | if (err) |
| 1215 | WL_ERR("Error (%d)\n", err); | 1058 | WL_ERR("Error (%d)\n", err); |
| 1216 | 1059 | ||
| @@ -1221,7 +1064,8 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) · 4 unmodified lines | |||
| 1221 | { | 1064 | { |
| 1222 | s32 err = 0; | 1065 | s32 err = 0; |
| 1223 | 1066 | ||
| 1224 | err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold); | 1067 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh", |
| 1068 | frag_threshold); | ||
| 1225 | if (err) | 1069 | if (err) |
| 1226 | WL_ERR("Error (%d)\n", err); | 1070 | WL_ERR("Error (%d)\n", err); |
| 1227 | 1071 | ||
| @@ -1233,7 +1077,7 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) · 5 unmodified lines | |||
| 1233 | s32 err = 0; | 1077 | s32 err = 0; |
| 1234 | u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); | 1078 | u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); |
| 1235 | 1079 | ||
| 1236 | err = brcmf_exec_dcmd_u32(ndev, cmd, &retry); | 1080 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); |
| 1237 | if (err) { | 1081 | if (err) { |
| 1238 | WL_ERR("cmd (%d) , error (%d)\n", cmd, err); | 1082 | WL_ERR("cmd (%d) , error (%d)\n", cmd, err); |
| 1239 | return err; | 1083 | return err; |
| @@ -1245,10 +1089,11 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) · 5 unmodified lines | |||
| 1245 | { | 1089 | { |
| 1246 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1090 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1247 | struct net_device *ndev = cfg_to_ndev(cfg); | 1091 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 1092 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 1248 | s32 err = 0; | 1093 | s32 err = 0; |
| 1249 | 1094 | ||
| 1250 | WL_TRACE("Enter\n"); | 1095 | WL_TRACE("Enter\n"); |
| 1251 | if (!check_sys_up(wiphy)) | 1096 | if (!check_vif_up(ifp->vif)) |
| 1252 | return -EIO; | 1097 | return -EIO; |
| 1253 | 1098 | ||
| 1254 | if (changed & WIPHY_PARAM_RTS_THRESHOLD && | 1099 | if (changed & WIPHY_PARAM_RTS_THRESHOLD && |
| @@ -1327,7 +1172,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_info *cfg) · 72 unmodified lines | |||
| 1327 | if (cfg->link_up) { | 1172 | if (cfg->link_up) { |
| 1328 | ndev = cfg_to_ndev(cfg); | 1173 | ndev = cfg_to_ndev(cfg); |
| 1329 | WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); | 1174 | WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); |
| 1330 | err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0); | 1175 | err = brcmf_fil_cmd_data_set(netdev_priv(ndev), |
| 1176 | BRCMF_C_DISASSOC, NULL, 0); | ||
| 1331 | if (err) | 1177 | if (err) |
| 1332 | WL_ERR("WLC_DISASSOC failed (%d)\n", err); | 1178 | WL_ERR("WLC_DISASSOC failed (%d)\n", err); |
| 1333 | cfg->link_up = false; | 1179 | cfg->link_up = false; |
| @@ -1340,7 +1186,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 6 unmodified lines | |||
| 1340 | struct cfg80211_ibss_params *params) | 1186 | struct cfg80211_ibss_params *params) |
| 1341 | { | 1187 | { |
| 1342 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1188 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1343 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 1189 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 1190 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 1344 | struct brcmf_join_params join_params; | 1191 | struct brcmf_join_params join_params; |
| 1345 | size_t join_params_size = 0; | 1192 | size_t join_params_size = 0; |
| 1346 | s32 err = 0; | 1193 | s32 err = 0; |
| @@ -1348,7 +1195,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 1348 | s32 bcnprd; | 1195 | s32 bcnprd; |
| 1349 | 1196 | ||
| 1350 | WL_TRACE("Enter\n"); | 1197 | WL_TRACE("Enter\n"); |
| 1351 | if (!check_sys_up(wiphy)) | 1198 | if (!check_vif_up(ifp->vif)) |
| 1352 | return -EIO; | 1199 | return -EIO; |
| 1353 | 1200 | ||
| 1354 | if (params->ssid) | 1201 | if (params->ssid) |
| @@ -1358,7 +1205,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 1358 | return -EOPNOTSUPP; | 1205 | return -EOPNOTSUPP; |
| 1359 | } | 1206 | } |
| 1360 | 1207 | ||
| 1361 | set_bit(WL_STATUS_CONNECTING, &cfg->status); | 1208 | set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); |
| 1362 | 1209 | ||
| 1363 | if (params->bssid) | 1210 | if (params->bssid) |
| 1364 | WL_CONN("BSSID: %pM\n", params->bssid); | 1211 | WL_CONN("BSSID: %pM\n", params->bssid); |
| @@ -1399,7 +1246,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 34 unmodified lines | |||
| 1399 | if (params->privacy) | 1246 | if (params->privacy) |
| 1400 | wsec |= WEP_ENABLED; | 1247 | wsec |= WEP_ENABLED; |
| 1401 | 1248 | ||
| 1402 | err = brcmf_dev_intvar_set(ndev, "wsec", wsec); | 1249 | err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec); |
| 1403 | if (err) { | 1250 | if (err) { |
| 1404 | WL_ERR("wsec failed (%d)\n", err); | 1251 | WL_ERR("wsec failed (%d)\n", err); |
| 1405 | goto done; | 1252 | goto done; |
| @@ -1411,7 +1258,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 1411 | else | 1258 | else |
| 1412 | bcnprd = 100; | 1259 | bcnprd = 100; |
| 1413 | 1260 | ||
| 1414 | err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd); | 1261 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd); |
| 1415 | if (err) { | 1262 | if (err) { |
| 1416 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); | 1263 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); |
| 1417 | goto done; | 1264 | goto done; |
| @@ -1434,7 +1281,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 16 unmodified lines | |||
| 1434 | BRCMF_ASSOC_PARAMS_FIXED_SIZE; | 1281 | BRCMF_ASSOC_PARAMS_FIXED_SIZE; |
| 1435 | memcpy(profile->bssid, params->bssid, ETH_ALEN); | 1282 | memcpy(profile->bssid, params->bssid, ETH_ALEN); |
| 1436 | } else { | 1283 | } else { |
| 1437 | memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); | 1284 | memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); |
| 1438 | memset(profile->bssid, 0, ETH_ALEN); | 1285 | memset(profile->bssid, 0, ETH_ALEN); |
| 1439 | } | 1286 | } |
| 1440 | 1287 | ||
| @@ -1453,8 +1300,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 12 unmodified lines | |||
| 1453 | 1300 | ||
| 1454 | /* set channel for starter */ | 1301 | /* set channel for starter */ |
| 1455 | target_channel = cfg->channel; | 1302 | target_channel = cfg->channel; |
| 1456 | err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL, | 1303 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL, |
| 1457 | &target_channel); | 1304 | target_channel); |
| 1458 | if (err) { | 1305 | if (err) { |
| 1459 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); | 1306 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); |
| 1460 | goto done; | 1307 | goto done; |
| @@ -1465,8 +1312,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 4 unmodified lines | |||
| 1465 | cfg->ibss_starter = false; | 1312 | cfg->ibss_starter = false; |
| 1466 | 1313 | ||
| 1467 | 1314 | ||
| 1468 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, | 1315 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, |
| 1469 | &join_params, join_params_size); | 1316 | &join_params, join_params_size); |
| 1470 | if (err) { | 1317 | if (err) { |
| 1471 | WL_ERR("WLC_SET_SSID failed (%d)\n", err); | 1318 | WL_ERR("WLC_SET_SSID failed (%d)\n", err); |
| 1472 | goto done; | 1319 | goto done; |
| @@ -1474,7 +1321,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 1474 | 1321 | ||
| 1475 | done: | 1322 | done: |
| 1476 | if (err) | 1323 | if (err) |
| 1477 | clear_bit(WL_STATUS_CONNECTING, &cfg->status); | 1324 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); |
| 1478 | WL_TRACE("Exit\n"); | 1325 | WL_TRACE("Exit\n"); |
| 1479 | return err; | 1326 | return err; |
| 1480 | } | 1327 | } |
| @@ -1483,10 +1330,11 @@ static s32 · 2 unmodified lines | |||
| 1483 | brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) | 1330 | brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) |
| 1484 | { | 1331 | { |
| 1485 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1332 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1333 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 1486 | s32 err = 0; | 1334 | s32 err = 0; |
| 1487 | 1335 | ||
| 1488 | WL_TRACE("Enter\n"); | 1336 | WL_TRACE("Enter\n"); |
| 1489 | if (!check_sys_up(wiphy)) | 1337 | if (!check_vif_up(ifp->vif)) |
| 1490 | return -EIO; | 1338 | return -EIO; |
| 1491 | 1339 | ||
| 1492 | brcmf_link_down(cfg); | 1340 | brcmf_link_down(cfg); |
| @@ -1499,8 +1347,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) · 6 unmodified lines | |||
| 1499 | static s32 brcmf_set_wpa_version(struct net_device *ndev, | 1347 | static s32 brcmf_set_wpa_version(struct net_device *ndev, |
| 1500 | struct cfg80211_connect_params *sme) | 1348 | struct cfg80211_connect_params *sme) |
| 1501 | { | 1349 | { |
| 1502 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1350 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
| 1503 | struct brcmf_cfg80211_profile *profile = cfg->profile; | ||
| 1504 | struct brcmf_cfg80211_security *sec; | 1351 | struct brcmf_cfg80211_security *sec; |
| 1505 | s32 val = 0; | 1352 | s32 val = 0; |
| 1506 | s32 err = 0; | 1353 | s32 err = 0; |
| @@ -1512,7 +1359,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev, · 5 unmodified lines | |||
| 1512 | else | 1359 | else |
| 1513 | val = WPA_AUTH_DISABLED; | 1360 | val = WPA_AUTH_DISABLED; |
| 1514 | WL_CONN("setting wpa_auth to 0x%0x\n", val); | 1361 | WL_CONN("setting wpa_auth to 0x%0x\n", val); |
| 1515 | err = brcmf_dev_intvar_set(ndev, "wpa_auth", val); | 1362 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val); |
| 1516 | if (err) { | 1363 | if (err) { |
| 1517 | WL_ERR("set wpa_auth failed (%d)\n", err); | 1364 | WL_ERR("set wpa_auth failed (%d)\n", err); |
| 1518 | return err; | 1365 | return err; |
| @@ -1525,8 +1372,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev, · 6 unmodified lines | |||
| 1525 | static s32 brcmf_set_auth_type(struct net_device *ndev, | 1372 | static s32 brcmf_set_auth_type(struct net_device *ndev, |
| 1526 | struct cfg80211_connect_params *sme) | 1373 | struct cfg80211_connect_params *sme) |
| 1527 | { | 1374 | { |
| 1528 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1375 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
| 1529 | struct brcmf_cfg80211_profile *profile = cfg->profile; | ||
| 1530 | struct brcmf_cfg80211_security *sec; | 1376 | struct brcmf_cfg80211_security *sec; |
| 1531 | s32 val = 0; | 1377 | s32 val = 0; |
| 1532 | s32 err = 0; | 1378 | s32 err = 0; |
| @@ -1552,7 +1398,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev, · 19 unmodified lines | |||
| 1552 | break; | 1398 | break; |
| 1553 | } | 1399 | } |
| 1554 | 1400 | ||
| 1555 | err = brcmf_dev_intvar_set(ndev, "auth", val); | 1401 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val); |
| 1556 | if (err) { | 1402 | if (err) { |
| 1557 | WL_ERR("set auth failed (%d)\n", err); | 1403 | WL_ERR("set auth failed (%d)\n", err); |
| 1558 | return err; | 1404 | return err; |
| @@ -1566,8 +1412,7 @@ static s32 · 7 unmodified lines | |||
| 1566 | brcmf_set_set_cipher(struct net_device *ndev, | 1412 | brcmf_set_set_cipher(struct net_device *ndev, |
| 1567 | struct cfg80211_connect_params *sme) | 1413 | struct cfg80211_connect_params *sme) |
| 1568 | { | 1414 | { |
| 1569 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1415 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
| 1570 | struct brcmf_cfg80211_profile *profile = cfg->profile; | ||
| 1571 | struct brcmf_cfg80211_security *sec; | 1416 | struct brcmf_cfg80211_security *sec; |
| 1572 | s32 pval = 0; | 1417 | s32 pval = 0; |
| 1573 | s32 gval = 0; | 1418 | s32 gval = 0; |
| @@ -1617,7 +1462,7 @@ brcmf_set_set_cipher(struct net_device *ndev, · 43 unmodified lines | |||
| 1617 | } | 1462 | } |
| 1618 | 1463 | ||
| 1619 | WL_CONN("pval (%d) gval (%d)\n", pval, gval); | 1464 | WL_CONN("pval (%d) gval (%d)\n", pval, gval); |
| 1620 | err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval); | 1465 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval); |
| 1621 | if (err) { | 1466 | if (err) { |
| 1622 | WL_ERR("error (%d)\n", err); | 1467 | WL_ERR("error (%d)\n", err); |
| 1623 | return err; | 1468 | return err; |
| @@ -1633,14 +1478,14 @@ brcmf_set_set_cipher(struct net_device *ndev, · 9 unmodified lines | |||
| 1633 | static s32 | 1478 | static s32 |
| 1634 | brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) | 1479 | brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) |
| 1635 | { | 1480 | { |
| 1636 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1481 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
| 1637 | struct brcmf_cfg80211_profile *profile = cfg->profile; | ||
| 1638 | struct brcmf_cfg80211_security *sec; | 1482 | struct brcmf_cfg80211_security *sec; |
| 1639 | s32 val = 0; | 1483 | s32 val = 0; |
| 1640 | s32 err = 0; | 1484 | s32 err = 0; |
| 1641 | 1485 | ||
| 1642 | if (sme->crypto.n_akm_suites) { | 1486 | if (sme->crypto.n_akm_suites) { |
| 1643 | err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val); | 1487 | err = brcmf_fil_iovar_int_get(netdev_priv(ndev), |
| 1488 | "wpa_auth", &val); | ||
| 1644 | if (err) { | 1489 | if (err) { |
| 1645 | WL_ERR("could not get wpa_auth (%d)\n", err); | 1490 | WL_ERR("could not get wpa_auth (%d)\n", err); |
| 1646 | return err; | 1491 | return err; |
| @@ -1674,7 +1519,8 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) · 27 unmodified lines | |||
| 1674 | } | 1519 | } |
| 1675 | 1520 | ||
| 1676 | WL_CONN("setting wpa_auth to %d\n", val); | 1521 | WL_CONN("setting wpa_auth to %d\n", val); |
| 1677 | err = brcmf_dev_intvar_set(ndev, "wpa_auth", val); | 1522 | err = brcmf_fil_iovar_int_set(netdev_priv(ndev), |
| 1523 | "wpa_auth", val); | ||
| 1678 | if (err) { | 1524 | if (err) { |
| 1679 | WL_ERR("could not set wpa_auth (%d)\n", err); | 1525 | WL_ERR("could not set wpa_auth (%d)\n", err); |
| 1680 | return err; | 1526 | return err; |
| @@ -1690,13 +1536,11 @@ static s32 · 9 unmodified lines | |||
| 1690 | brcmf_set_sharedkey(struct net_device *ndev, | 1536 | brcmf_set_sharedkey(struct net_device *ndev, |
| 1691 | struct cfg80211_connect_params *sme) | 1537 | struct cfg80211_connect_params *sme) |
| 1692 | { | 1538 | { |
| 1693 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 1539 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); |
| 1694 | struct brcmf_cfg80211_profile *profile = cfg->profile; | ||
| 1695 | struct brcmf_cfg80211_security *sec; | 1540 | struct brcmf_cfg80211_security *sec; |
| 1696 | struct brcmf_wsec_key key; | 1541 | struct brcmf_wsec_key key; |
| 1697 | s32 val; | 1542 | s32 val; |
| 1698 | s32 err = 0; | 1543 | s32 err = 0; |
| 1699 | s32 bssidx; | ||
| 1700 | 1544 | ||
| 1701 | WL_CONN("key len (%d)\n", sme->key_len); | 1545 | WL_CONN("key len (%d)\n", sme->key_len); |
| 1702 | 1546 | ||
| @@ -1739,15 +1583,14 @@ brcmf_set_sharedkey(struct net_device *ndev, · 36 unmodified lines | |||
| 1739 | WL_CONN("key length (%d) key index (%d) algo (%d)\n", | 1583 | WL_CONN("key length (%d) key index (%d) algo (%d)\n", |
| 1740 | key.len, key.index, key.algo); | 1584 | key.len, key.index, key.algo); |
| 1741 | WL_CONN("key \"%s\"\n", key.data); | 1585 | WL_CONN("key \"%s\"\n", key.data); |
| 1742 | bssidx = brcmf_find_bssidx(cfg, ndev); | 1586 | err = send_key_to_dongle(ndev, &key); |
| 1743 | err = send_key_to_dongle(cfg, bssidx, ndev, &key); | ||
| 1744 | if (err) | 1587 | if (err) |
| 1745 | return err; | 1588 | return err; |
| 1746 | 1589 | ||
| 1747 | if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { | 1590 | if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { |
| 1748 | WL_CONN("set auth_type to shared key\n"); | 1591 | WL_CONN("set auth_type to shared key\n"); |
| 1749 | val = WL_AUTH_SHARED_KEY; /* shared key */ | 1592 | val = WL_AUTH_SHARED_KEY; /* shared key */ |
| 1750 | err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx); | 1593 | err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val); |
| 1751 | if (err) | 1594 | if (err) |
| 1752 | WL_ERR("set auth failed (%d)\n", err); | 1595 | WL_ERR("set auth failed (%d)\n", err); |
| 1753 | } | 1596 | } |
| @@ -1759,7 +1602,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 1759 | struct cfg80211_connect_params *sme) | 1602 | struct cfg80211_connect_params *sme) |
| 1760 | { | 1603 | { |
| 1761 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1604 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1762 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 1605 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 1606 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 1763 | struct ieee80211_channel *chan = sme->channel; | 1607 | struct ieee80211_channel *chan = sme->channel; |
| 1764 | struct brcmf_join_params join_params; | 1608 | struct brcmf_join_params join_params; |
| 1765 | size_t join_params_size; | 1609 | size_t join_params_size; |
| @@ -1768,7 +1612,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, · 2 unmodified lines | |||
| 1768 | s32 err = 0; | 1612 | s32 err = 0; |
| 1769 | 1613 | ||
| 1770 | WL_TRACE("Enter\n"); | 1614 | WL_TRACE("Enter\n"); |
| 1771 | if (!check_sys_up(wiphy)) | 1615 | if (!check_vif_up(ifp->vif)) |
| 1772 | return -EIO; | 1616 | return -EIO; |
| 1773 | 1617 | ||
| 1774 | if (!sme->ssid) { | 1618 | if (!sme->ssid) { |
| @@ -1776,7 +1620,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 1776 | return -EOPNOTSUPP; | 1620 | return -EOPNOTSUPP; |
| 1777 | } | 1621 | } |
| 1778 | 1622 | ||
| 1779 | set_bit(WL_STATUS_CONNECTING, &cfg->status); | 1623 | set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); |
| 1780 | 1624 | ||
| 1781 | if (chan) { | 1625 | if (chan) { |
| 1782 | cfg->channel = | 1626 | cfg->channel = |
| @@ -1827,7 +1671,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, · 44 unmodified lines | |||
| 1827 | memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len); | 1671 | memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len); |
| 1828 | join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); | 1672 | join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len); |
| 1829 | 1673 | ||
| 1830 | memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); | 1674 | memset(join_params.params_le.bssid, 0xFF, ETH_ALEN); |
| 1831 | 1675 | ||
| 1832 | if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) | 1676 | if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) |
| 1833 | WL_CONN("ssid \"%s\", len (%d)\n", | 1677 | WL_CONN("ssid \"%s\", len (%d)\n", |
| @@ -1835,14 +1679,14 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 1835 | 1679 | ||
| 1836 | brcmf_ch_to_chanspec(cfg->channel, | 1680 | brcmf_ch_to_chanspec(cfg->channel, |
| 1837 | &join_params, &join_params_size); | 1681 | &join_params, &join_params_size); |
| 1838 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, | 1682 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, |
| 1839 | &join_params, join_params_size); | 1683 | &join_params, join_params_size); |
| 1840 | if (err) | 1684 | if (err) |
| 1841 | WL_ERR("WLC_SET_SSID failed (%d)\n", err); | 1685 | WL_ERR("WLC_SET_SSID failed (%d)\n", err); |
| 1842 | 1686 | ||
| 1843 | done: | 1687 | done: |
| 1844 | if (err) | 1688 | if (err) |
| 1845 | clear_bit(WL_STATUS_CONNECTING, &cfg->status); | 1689 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); |
| 1846 | WL_TRACE("Exit\n"); | 1690 | WL_TRACE("Exit\n"); |
| 1847 | return err; | 1691 | return err; |
| 1848 | } | 1692 | } |
| @@ -1852,20 +1696,21 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 1852 | u16 reason_code) | 1696 | u16 reason_code) |
| 1853 | { | 1697 | { |
| 1854 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1698 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1855 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 1699 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 1700 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 1856 | struct brcmf_scb_val_le scbval; | 1701 | struct brcmf_scb_val_le scbval; |
| 1857 | s32 err = 0; | 1702 | s32 err = 0; |
| 1858 | 1703 | ||
| 1859 | WL_TRACE("Enter. Reason code = %d\n", reason_code); | 1704 | WL_TRACE("Enter. Reason code = %d\n", reason_code); |
| 1860 | if (!check_sys_up(wiphy)) | 1705 | if (!check_vif_up(ifp->vif)) |
| 1861 | return -EIO; | 1706 | return -EIO; |
| 1862 | 1707 | ||
| 1863 | clear_bit(WL_STATUS_CONNECTED, &cfg->status); | 1708 | clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); |
| 1864 | 1709 | ||
| 1865 | memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); | 1710 | memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); |
| 1866 | scbval.val = cpu_to_le32(reason_code); | 1711 | scbval.val = cpu_to_le32(reason_code); |
| 1867 | err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval, | 1712 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC, |
| 1868 | sizeof(struct brcmf_scb_val_le)); | 1713 | &scbval, sizeof(scbval)); |
| 1869 | if (err) | 1714 | if (err) |
| 1870 | WL_ERR("error (%d)\n", err); | 1715 | WL_ERR("error (%d)\n", err); |
| 1871 | 1716 | ||
| @@ -1882,13 +1727,14 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, · 10 unmodified lines | |||
| 1882 | 1727 | ||
| 1883 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1728 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1884 | struct net_device *ndev = cfg_to_ndev(cfg); | 1729 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 1730 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 1885 | u16 txpwrmw; | 1731 | u16 txpwrmw; |
| 1886 | s32 err = 0; | 1732 | s32 err = 0; |
| 1887 | s32 disable = 0; | 1733 | s32 disable = 0; |
| 1888 | s32 dbm = MBM_TO_DBM(mbm); | 1734 | s32 dbm = MBM_TO_DBM(mbm); |
| 1889 | 1735 | ||
| 1890 | WL_TRACE("Enter\n"); | 1736 | WL_TRACE("Enter\n"); |
| 1891 | if (!check_sys_up(wiphy)) | 1737 | if (!check_vif_up(ifp->vif)) |
| 1892 | return -EIO; | 1738 | return -EIO; |
| 1893 | 1739 | ||
| 1894 | switch (type) { | 1740 | switch (type) { |
| @@ -1905,7 +1751,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, · 10 unmodified lines | |||
| 1905 | } | 1751 | } |
| 1906 | /* Make sure radio is off or on as far as software is concerned */ | 1752 | /* Make sure radio is off or on as far as software is concerned */ |
| 1907 | disable = WL_RADIO_SW_DISABLE << 16; | 1753 | disable = WL_RADIO_SW_DISABLE << 16; |
| 1908 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable); | 1754 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable); |
| 1909 | if (err) | 1755 | if (err) |
| 1910 | WL_ERR("WLC_SET_RADIO error (%d)\n", err); | 1756 | WL_ERR("WLC_SET_RADIO error (%d)\n", err); |
| 1911 | 1757 | ||
| @@ -1913,8 +1759,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, · 1 unmodified line | |||
| 1913 | txpwrmw = 0xffff; | 1759 | txpwrmw = 0xffff; |
| 1914 | else | 1760 | else |
| 1915 | txpwrmw = (u16) dbm; | 1761 | txpwrmw = (u16) dbm; |
| 1916 | err = brcmf_dev_intvar_set(ndev, "qtxpower", | 1762 | err = brcmf_fil_iovar_int_set(ifp, "qtxpower", |
| 1917 | (s32) (brcmf_mw_to_qdbm(txpwrmw))); | 1763 | (s32)brcmf_mw_to_qdbm(txpwrmw)); |
| 1918 | if (err) | 1764 | if (err) |
| 1919 | WL_ERR("qtxpower error (%d)\n", err); | 1765 | WL_ERR("qtxpower error (%d)\n", err); |
| 1920 | cfg->conf->tx_power = dbm; | 1766 | cfg->conf->tx_power = dbm; |
| @@ -1927,16 +1773,16 @@ done: · 6 unmodified lines | |||
| 1927 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) | 1773 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) |
| 1928 | { | 1774 | { |
| 1929 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1775 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1930 | struct net_device *ndev = cfg_to_ndev(cfg); | 1776 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
| 1931 | s32 txpwrdbm; | 1777 | s32 txpwrdbm; |
| 1932 | u8 result; | 1778 | u8 result; |
| 1933 | s32 err = 0; | 1779 | s32 err = 0; |
| 1934 | 1780 | ||
| 1935 | WL_TRACE("Enter\n"); | 1781 | WL_TRACE("Enter\n"); |
| 1936 | if (!check_sys_up(wiphy)) | 1782 | if (!check_vif_up(ifp->vif)) |
| 1937 | return -EIO; | 1783 | return -EIO; |
| 1938 | 1784 | ||
| 1939 | err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); | 1785 | err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm); |
| 1940 | if (err) { | 1786 | if (err) { |
| 1941 | WL_ERR("error (%d)\n", err); | 1787 | WL_ERR("error (%d)\n", err); |
| 1942 | goto done; | 1788 | goto done; |
| @@ -1954,19 +1800,17 @@ static s32 · 11 unmodified lines | |||
| 1954 | brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, | 1800 | brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, |
| 1955 | u8 key_idx, bool unicast, bool multicast) | 1801 | u8 key_idx, bool unicast, bool multicast) |
| 1956 | { | 1802 | { |
| 1957 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1803 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 1958 | u32 index; | 1804 | u32 index; |
| 1959 | u32 wsec; | 1805 | u32 wsec; |
| 1960 | s32 err = 0; | 1806 | s32 err = 0; |
| 1961 | s32 bssidx; | ||
| 1962 | 1807 | ||
| 1963 | WL_TRACE("Enter\n"); | 1808 | WL_TRACE("Enter\n"); |
| 1964 | WL_CONN("key index (%d)\n", key_idx); | 1809 | WL_CONN("key index (%d)\n", key_idx); |
| 1965 | if (!check_sys_up(wiphy)) | 1810 | if (!check_vif_up(ifp->vif)) |
| 1966 | return -EIO; | 1811 | return -EIO; |
| 1967 | 1812 | ||
| 1968 | bssidx = brcmf_find_bssidx(cfg, ndev); | 1813 | err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); |
| 1969 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); | ||
| 1970 | if (err) { | 1814 | if (err) { |
| 1971 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); | 1815 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); |
| 1972 | goto done; | 1816 | goto done; |
| @@ -1975,8 +1819,8 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, · 2 unmodified lines | |||
| 1975 | if (wsec & WEP_ENABLED) { | 1819 | if (wsec & WEP_ENABLED) { |
| 1976 | /* Just select a new current key */ | 1820 | /* Just select a new current key */ |
| 1977 | index = key_idx; | 1821 | index = key_idx; |
| 1978 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY, | 1822 | err = brcmf_fil_cmd_int_set(ifp, |
| 1979 | &index); | 1823 | BRCMF_C_SET_KEY_PRIMARY, index); |
| 1980 | if (err) | 1824 | if (err) |
| 1981 | WL_ERR("error (%d)\n", err); | 1825 | WL_ERR("error (%d)\n", err); |
| 1982 | } | 1826 | } |
| @@ -1989,11 +1833,8 @@ static s32 · 6 unmodified lines | |||
| 1989 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, | 1833 | brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, |
| 1990 | u8 key_idx, const u8 *mac_addr, struct key_params *params) | 1834 | u8 key_idx, const u8 *mac_addr, struct key_params *params) |
| 1991 | { | 1835 | { |
| 1992 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
| 1993 | struct brcmf_wsec_key key; | 1836 | struct brcmf_wsec_key key; |
| 1994 | struct brcmf_wsec_key_le key_le; | ||
| 1995 | s32 err = 0; | 1837 | s32 err = 0; |
| 1996 | s32 bssidx; | ||
| 1997 | 1838 | ||
| 1998 | memset(&key, 0, sizeof(key)); | 1839 | memset(&key, 0, sizeof(key)); |
| 1999 | key.index = (u32) key_idx; | 1840 | key.index = (u32) key_idx; |
| @@ -2002,11 +1843,10 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, · 2 unmodified lines | |||
| 2002 | if (!is_multicast_ether_addr(mac_addr)) | 1843 | if (!is_multicast_ether_addr(mac_addr)) |
| 2003 | memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); | 1844 | memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); |
| 2004 | key.len = (u32) params->key_len; | 1845 | key.len = (u32) params->key_len; |
| 2005 | bssidx = brcmf_find_bssidx(cfg, ndev); | ||
| 2006 | /* check for key index change */ | 1846 | /* check for key index change */ |
| 2007 | if (key.len == 0) { | 1847 | if (key.len == 0) { |
| 2008 | /* key delete */ | 1848 | /* key delete */ |
| 2009 | err = send_key_to_dongle(cfg, bssidx, ndev, &key); | 1849 | err = send_key_to_dongle(ndev, &key); |
| 2010 | if (err) | 1850 | if (err) |
| 2011 | WL_ERR("key delete error (%d)\n", err); | 1851 | WL_ERR("key delete error (%d)\n", err); |
| 2012 | } else { | 1852 | } else { |
| @@ -2061,13 +1901,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, · 48 unmodified lines | |||
| 2061 | WL_ERR("Invalid cipher (0x%x)\n", params->cipher); | 1901 | WL_ERR("Invalid cipher (0x%x)\n", params->cipher); |
| 2062 | return -EINVAL; | 1902 | return -EINVAL; |
| 2063 | } | 1903 | } |
| 2064 | convert_key_from_CPU(&key, &key_le); | 1904 | err = send_key_to_dongle(ndev, &key); |
| 2065 | |||
| 2066 | brcmf_netdev_wait_pend8021x(ndev); | ||
| 2067 | err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le, | ||
| 2068 | sizeof(key_le), | ||
| 2069 | cfg->extra_buf, | ||
| 2070 | WL_EXTRA_BUF_MAX, bssidx); | ||
| 2071 | if (err) | 1905 | if (err) |
| 2072 | WL_ERR("wsec_key error (%d)\n", err); | 1906 | WL_ERR("wsec_key error (%d)\n", err); |
| 2073 | } | 1907 | } |
| @@ -2080,16 +1914,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, · 6 unmodified lines | |||
| 2080 | struct key_params *params) | 1914 | struct key_params *params) |
| 2081 | { | 1915 | { |
| 2082 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1916 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 1917 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 2083 | struct brcmf_wsec_key key; | 1918 | struct brcmf_wsec_key key; |
| 2084 | s32 val; | 1919 | s32 val; |
| 2085 | s32 wsec; | 1920 | s32 wsec; |
| 2086 | s32 err = 0; | 1921 | s32 err = 0; |
| 2087 | u8 keybuf[8]; | 1922 | u8 keybuf[8]; |
| 2088 | s32 bssidx; | ||
| 2089 | 1923 | ||
| 2090 | WL_TRACE("Enter\n"); | 1924 | WL_TRACE("Enter\n"); |
| 2091 | WL_CONN("key index (%d)\n", key_idx); | 1925 | WL_CONN("key index (%d)\n", key_idx); |
| 2092 | if (!check_sys_up(wiphy)) | 1926 | if (!check_vif_up(ifp->vif)) |
| 2093 | return -EIO; | 1927 | return -EIO; |
| 2094 | 1928 | ||
| 2095 | if (mac_addr) { | 1929 | if (mac_addr) { |
| @@ -2147,18 +1981,17 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, · 51 unmodified lines | |||
| 2147 | goto done; | 1981 | goto done; |
| 2148 | } | 1982 | } |
| 2149 | 1983 | ||
| 2150 | bssidx = brcmf_find_bssidx(cfg, ndev); | 1984 | err = send_key_to_dongle(ndev, &key); |
| 2151 | err = send_key_to_dongle(cfg, bssidx, ndev, &key); | ||
| 2152 | if (err) | 1985 | if (err) |
| 2153 | goto done; | 1986 | goto done; |
| 2154 | 1987 | ||
| 2155 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); | 1988 | err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); |
| 2156 | if (err) { | 1989 | if (err) { |
| 2157 | WL_ERR("get wsec error (%d)\n", err); | 1990 | WL_ERR("get wsec error (%d)\n", err); |
| 2158 | goto done; | 1991 | goto done; |
| 2159 | } | 1992 | } |
| 2160 | wsec |= val; | 1993 | wsec |= val; |
| 2161 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx); | 1994 | err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); |
| 2162 | if (err) { | 1995 | if (err) { |
| 2163 | WL_ERR("set wsec error (%d)\n", err); | 1996 | WL_ERR("set wsec error (%d)\n", err); |
| 2164 | goto done; | 1997 | goto done; |
| @@ -2173,13 +2006,12 @@ static s32 · 8 unmodified lines | |||
| 2173 | brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | 2006 | brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, |
| 2174 | u8 key_idx, bool pairwise, const u8 *mac_addr) | 2007 | u8 key_idx, bool pairwise, const u8 *mac_addr) |
| 2175 | { | 2008 | { |
| 2176 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2009 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 2177 | struct brcmf_wsec_key key; | 2010 | struct brcmf_wsec_key key; |
| 2178 | s32 err = 0; | 2011 | s32 err = 0; |
| 2179 | s32 bssidx; | ||
| 2180 | 2012 | ||
| 2181 | WL_TRACE("Enter\n"); | 2013 | WL_TRACE("Enter\n"); |
| 2182 | if (!check_sys_up(wiphy)) | 2014 | if (!check_vif_up(ifp->vif)) |
| 2183 | return -EIO; | 2015 | return -EIO; |
| 2184 | 2016 | ||
| 2185 | memset(&key, 0, sizeof(key)); | 2017 | memset(&key, 0, sizeof(key)); |
| @@ -2191,8 +2023,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 2191 | WL_CONN("key index (%d)\n", key_idx); | 2023 | WL_CONN("key index (%d)\n", key_idx); |
| 2192 | 2024 | ||
| 2193 | /* Set the new key/index */ | 2025 | /* Set the new key/index */ |
| 2194 | bssidx = brcmf_find_bssidx(cfg, ndev); | 2026 | err = send_key_to_dongle(ndev, &key); |
| 2195 | err = send_key_to_dongle(cfg, bssidx, ndev, &key); | ||
| 2196 | if (err) { | 2027 | if (err) { |
| 2197 | if (err == -EINVAL) { | 2028 | if (err == -EINVAL) { |
| 2198 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) | 2029 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) |
| @@ -2213,22 +2044,20 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, · 14 unmodified lines | |||
| 2213 | void (*callback) (void *cookie, struct key_params * params)) | 2044 | void (*callback) (void *cookie, struct key_params * params)) |
| 2214 | { | 2045 | { |
| 2215 | struct key_params params; | 2046 | struct key_params params; |
| 2216 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2047 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 2217 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 2048 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; |
| 2218 | struct brcmf_cfg80211_security *sec; | 2049 | struct brcmf_cfg80211_security *sec; |
| 2219 | s32 wsec; | 2050 | s32 wsec; |
| 2220 | s32 err = 0; | 2051 | s32 err = 0; |
| 2221 | s32 bssidx; | ||
| 2222 | 2052 | ||
| 2223 | WL_TRACE("Enter\n"); | 2053 | WL_TRACE("Enter\n"); |
| 2224 | WL_CONN("key index (%d)\n", key_idx); | 2054 | WL_CONN("key index (%d)\n", key_idx); |
| 2225 | if (!check_sys_up(wiphy)) | 2055 | if (!check_vif_up(ifp->vif)) |
| 2226 | return -EIO; | 2056 | return -EIO; |
| 2227 | 2057 | ||
| 2228 | memset(¶ms, 0, sizeof(params)); | 2058 | memset(¶ms, 0, sizeof(params)); |
| 2229 | 2059 | ||
| 2230 | bssidx = brcmf_find_bssidx(cfg, ndev); | 2060 | err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); |
| 2231 | err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx); | ||
| 2232 | if (err) { | 2061 | if (err) { |
| 2233 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); | 2062 | WL_ERR("WLC_GET_WSEC error (%d)\n", err); |
| 2234 | /* Ignore this error, may happen during DISASSOC */ | 2063 | /* Ignore this error, may happen during DISASSOC */ |
| @@ -2280,33 +2109,33 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, · 45 unmodified lines | |||
| 2280 | u8 *mac, struct station_info *sinfo) | 2109 | u8 *mac, struct station_info *sinfo) |
| 2281 | { | 2110 | { |
| 2282 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2111 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 2283 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 2112 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 2113 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 2284 | struct brcmf_scb_val_le scb_val; | 2114 | struct brcmf_scb_val_le scb_val; |
| 2285 | int rssi; | 2115 | int rssi; |
| 2286 | s32 rate; | 2116 | s32 rate; |
| 2287 | s32 err = 0; | 2117 | s32 err = 0; |
| 2288 | u8 *bssid = profile->bssid; | 2118 | u8 *bssid = profile->bssid; |
| 2289 | struct brcmf_sta_info_le *sta_info_le; | 2119 | struct brcmf_sta_info_le sta_info_le; |
| 2290 | 2120 | ||
| 2291 | WL_TRACE("Enter, MAC %pM\n", mac); | 2121 | WL_TRACE("Enter, MAC %pM\n", mac); |
| 2292 | if (!check_sys_up(wiphy)) | 2122 | if (!check_vif_up(ifp->vif)) |
| 2293 | return -EIO; | 2123 | return -EIO; |
| 2294 | 2124 | ||
| 2295 | if (cfg->conf->mode == WL_MODE_AP) { | 2125 | if (cfg->conf->mode == WL_MODE_AP) { |
| 2296 | err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN, | 2126 | memcpy(&sta_info_le, mac, ETH_ALEN); |
| 2297 | cfg->dcmd_buf, | 2127 | err = brcmf_fil_iovar_data_get(ifp, "sta_info", |
| 2298 | WL_DCMD_LEN_MAX); | 2128 | &sta_info_le, |
| 2129 | sizeof(sta_info_le)); | ||
| 2299 | if (err < 0) { | 2130 | if (err < 0) { |
| 2300 | WL_ERR("GET STA INFO failed, %d\n", err); | 2131 | WL_ERR("GET STA INFO failed, %d\n", err); |
| 2301 | goto done; | 2132 | goto done; |
| 2302 | } | 2133 | } |
| 2303 | sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf; | ||
| 2304 | |||
| 2305 | sinfo->filled = STATION_INFO_INACTIVE_TIME; | 2134 | sinfo->filled = STATION_INFO_INACTIVE_TIME; |
| 2306 | sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000; | 2135 | sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; |
| 2307 | if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) { | 2136 | if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { |
| 2308 | sinfo->filled |= STATION_INFO_CONNECTED_TIME; | 2137 | sinfo->filled |= STATION_INFO_CONNECTED_TIME; |
| 2309 | sinfo->connected_time = le32_to_cpu(sta_info_le->in); | 2138 | sinfo->connected_time = le32_to_cpu(sta_info_le.in); |
| 2310 | } | 2139 | } |
| 2311 | WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", | 2140 | WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", |
| 2312 | sinfo->inactive_time, sinfo->connected_time); | 2141 | sinfo->inactive_time, sinfo->connected_time); |
| @@ -2318,7 +2147,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 2318 | goto done; | 2147 | goto done; |
| 2319 | } | 2148 | } |
| 2320 | /* Report the current tx rate */ | 2149 | /* Report the current tx rate */ |
| 2321 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate); | 2150 | err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); |
| 2322 | if (err) { | 2151 | if (err) { |
| 2323 | WL_ERR("Could not get rate (%d)\n", err); | 2152 | WL_ERR("Could not get rate (%d)\n", err); |
| 2324 | goto done; | 2153 | goto done; |
| @@ -2328,10 +2157,11 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 2328 | WL_CONN("Rate %d Mbps\n", rate / 2); | 2157 | WL_CONN("Rate %d Mbps\n", rate / 2); |
| 2329 | } | 2158 | } |
| 2330 | 2159 | ||
| 2331 | if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) { | 2160 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, |
| 2161 | &ifp->vif->sme_state)) { | ||
| 2332 | memset(&scb_val, 0, sizeof(scb_val)); | 2162 | memset(&scb_val, 0, sizeof(scb_val)); |
| 2333 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, | 2163 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, |
| 2334 | sizeof(scb_val)); | 2164 | &scb_val, sizeof(scb_val)); |
| 2335 | if (err) { | 2165 | if (err) { |
| 2336 | WL_ERR("Could not get rssi (%d)\n", err); | 2166 | WL_ERR("Could not get rssi (%d)\n", err); |
| 2337 | goto done; | 2167 | goto done; |
| @@ -2356,6 +2186,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, · 18 unmodified lines | |||
| 2356 | s32 pm; | 2186 | s32 pm; |
| 2357 | s32 err = 0; | 2187 | s32 err = 0; |
| 2358 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2188 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 2189 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 2359 | 2190 | ||
| 2360 | WL_TRACE("Enter\n"); | 2191 | WL_TRACE("Enter\n"); |
| 2361 | 2192 | ||
| @@ -2367,7 +2198,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, · 5 unmodified lines | |||
| 2367 | * FW later while initializing the dongle | 2198 | * FW later while initializing the dongle |
| 2368 | */ | 2199 | */ |
| 2369 | cfg->pwr_save = enabled; | 2200 | cfg->pwr_save = enabled; |
| 2370 | if (!test_bit(WL_STATUS_READY, &cfg->status)) { | 2201 | if (!check_vif_up(ifp->vif)) { |
| 2371 | 2202 | ||
| 2372 | WL_INFO("Device is not ready, storing the value in cfg_info struct\n"); | 2203 | WL_INFO("Device is not ready, storing the value in cfg_info struct\n"); |
| 2373 | goto done; | 2204 | goto done; |
| @@ -2376,7 +2207,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, · 2 unmodified lines | |||
| 2376 | pm = enabled ? PM_FAST : PM_OFF; | 2207 | pm = enabled ? PM_FAST : PM_OFF; |
| 2377 | WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); | 2208 | WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); |
| 2378 | 2209 | ||
| 2379 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm); | 2210 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); |
| 2380 | if (err) { | 2211 | if (err) { |
| 2381 | if (err == -ENODEV) | 2212 | if (err == -ENODEV) |
| 2382 | WL_ERR("net_device is not ready yet\n"); | 2213 | WL_ERR("net_device is not ready yet\n"); |
| @@ -2393,6 +2224,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, · 10 unmodified lines | |||
| 2393 | const u8 *addr, | 2224 | const u8 *addr, |
| 2394 | const struct cfg80211_bitrate_mask *mask) | 2225 | const struct cfg80211_bitrate_mask *mask) |
| 2395 | { | 2226 | { |
| 2227 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 2396 | struct brcm_rateset_le rateset_le; | 2228 | struct brcm_rateset_le rateset_le; |
| 2397 | s32 rate; | 2229 | s32 rate; |
| 2398 | s32 val; | 2230 | s32 val; |
| @@ -2402,13 +2234,13 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 2402 | s32 err = 0; | 2234 | s32 err = 0; |
| 2403 | 2235 | ||
| 2404 | WL_TRACE("Enter\n"); | 2236 | WL_TRACE("Enter\n"); |
| 2405 | if (!check_sys_up(wiphy)) | 2237 | if (!check_vif_up(ifp->vif)) |
| 2406 | return -EIO; | 2238 | return -EIO; |
| 2407 | 2239 | ||
| 2408 | /* addr param is always NULL. ignore it */ | 2240 | /* addr param is always NULL. ignore it */ |
| 2409 | /* Get current rateset */ | 2241 | /* Get current rateset */ |
| 2410 | err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le, | 2242 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET, |
| 2411 | sizeof(rateset_le)); | 2243 | &rateset_le, sizeof(rateset_le)); |
| 2412 | if (err) { | 2244 | if (err) { |
| 2413 | WL_ERR("could not get current rateset (%d)\n", err); | 2245 | WL_ERR("could not get current rateset (%d)\n", err); |
| 2414 | goto done; | 2246 | goto done; |
| @@ -2435,8 +2267,8 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, · 20 unmodified lines | |||
| 2435 | * Set rate override, | 2267 | * Set rate override, |
| 2436 | * Since the is a/b/g-blind, both a/bg_rate are enforced. | 2268 | * Since the is a/b/g-blind, both a/bg_rate are enforced. |
| 2437 | */ | 2269 | */ |
| 2438 | err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate); | 2270 | err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate); |
| 2439 | err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate); | 2271 | err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate); |
| 2440 | if (err_bg && err_a) { | 2272 | if (err_bg && err_a) { |
| 2441 | WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); | 2273 | WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); |
| 2442 | err = err_bg | err_a; | 2274 | err = err_bg | err_a; |
| @@ -2565,7 +2397,8 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, · 122 unmodified lines | |||
| 2565 | 2397 | ||
| 2566 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); | 2398 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); |
| 2567 | 2399 | ||
| 2568 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); | 2400 | err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO, |
| 2401 | buf, WL_BSS_INFO_MAX); | ||
| 2569 | if (err) { | 2402 | if (err) { |
| 2570 | WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err); | 2403 | WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err); |
| 2571 | goto CleanUp; | 2404 | goto CleanUp; |
| @@ -2674,12 +2507,12 @@ brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, · 102 unmodified lines | |||
| 2674 | return false; | 2507 | return false; |
| 2675 | } | 2508 | } |
| 2676 | 2509 | ||
| 2677 | struct brcmf_vs_tlv * | 2510 | static struct brcmf_vs_tlv * |
| 2678 | brcmf_find_wpaie(u8 *parse, u32 len) | 2511 | brcmf_find_wpaie(u8 *parse, u32 len) |
| 2679 | { | 2512 | { |
| 2680 | struct brcmf_tlv *ie; | 2513 | struct brcmf_tlv *ie; |
| 2681 | 2514 | ||
| 2682 | while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) { | 2515 | while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) { |
| 2683 | if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len, | 2516 | if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len, |
| 2684 | WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE)) | 2517 | WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE)) |
| 2685 | return (struct brcmf_vs_tlv *)ie; | 2518 | return (struct brcmf_vs_tlv *)ie; |
| @@ -2689,7 +2522,9 @@ brcmf_find_wpaie(u8 *parse, u32 len) · 3 unmodified lines | |||
| 2689 | 2522 | ||
| 2690 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) | 2523 | static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) |
| 2691 | { | 2524 | { |
| 2692 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 2525 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 2526 | struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); | ||
| 2527 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 2693 | struct brcmf_bss_info_le *bi; | 2528 | struct brcmf_bss_info_le *bi; |
| 2694 | struct brcmf_ssid *ssid; | 2529 | struct brcmf_ssid *ssid; |
| 2695 | struct brcmf_tlv *tim; | 2530 | struct brcmf_tlv *tim; |
| @@ -2706,8 +2541,8 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) · 10 unmodified lines | |||
| 2706 | ssid = &profile->ssid; | 2541 | ssid = &profile->ssid; |
| 2707 | 2542 | ||
| 2708 | *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); | 2543 | *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); |
| 2709 | err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO, | 2544 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, |
| 2710 | cfg->extra_buf, WL_EXTRA_BUF_MAX); | 2545 | cfg->extra_buf, WL_EXTRA_BUF_MAX); |
| 2711 | if (err) { | 2546 | if (err) { |
| 2712 | WL_ERR("Could not get bss info %d\n", err); | 2547 | WL_ERR("Could not get bss info %d\n", err); |
| 2713 | goto update_bss_info_out; | 2548 | goto update_bss_info_out; |
| @@ -2732,8 +2567,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) · 18 unmodified lines | |||
| 2732 | * so we speficially query dtim information to dongle. | 2567 | * so we speficially query dtim information to dongle. |
| 2733 | */ | 2568 | */ |
| 2734 | u32 var; | 2569 | u32 var; |
| 2735 | err = brcmf_dev_intvar_get(cfg_to_ndev(cfg), | 2570 | err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var); |
| 2736 | "dtim_assoc", &var); | ||
| 2737 | if (err) { | 2571 | if (err) { |
| 2738 | WL_ERR("wl dtim_assoc failed (%d)\n", err); | 2572 | WL_ERR("wl dtim_assoc failed (%d)\n", err); |
| 2739 | goto update_bss_info_out; | 2573 | goto update_bss_info_out; |
| @@ -2741,9 +2575,6 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) · 1 unmodified line | |||
| 2741 | dtim_period = (u8)var; | 2575 | dtim_period = (u8)var; |
| 2742 | } | 2576 | } |
| 2743 | 2577 | ||
| 2744 | profile->beacon_interval = beacon_interval; | ||
| 2745 | profile->dtim_period = dtim_period; | ||
| 2746 | |||
| 2747 | update_bss_info_out: | 2578 | update_bss_info_out: |
| 2748 | WL_TRACE("Exit"); | 2579 | WL_TRACE("Exit"); |
| 2749 | return err; | 2580 | return err; |
| @@ -2755,7 +2586,7 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) · 5 unmodified lines | |||
| 2755 | struct escan_info *escan = &cfg->escan_info; | 2586 | struct escan_info *escan = &cfg->escan_info; |
| 2756 | struct brcmf_ssid ssid; | 2587 | struct brcmf_ssid ssid; |
| 2757 | 2588 | ||
| 2758 | set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); | 2589 | set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
| 2759 | if (cfg->iscan_on) { | 2590 | if (cfg->iscan_on) { |
| 2760 | iscan->state = WL_ISCAN_STATE_IDLE; | 2591 | iscan->state = WL_ISCAN_STATE_IDLE; |
| 2761 | 2592 | ||
| @@ -2781,8 +2612,8 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) · 19 unmodified lines | |||
| 2781 | escan->escan_state = WL_ESCAN_STATE_IDLE; | 2612 | escan->escan_state = WL_ESCAN_STATE_IDLE; |
| 2782 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); | 2613 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); |
| 2783 | } | 2614 | } |
| 2784 | clear_bit(WL_STATUS_SCANNING, &cfg->status); | 2615 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 2785 | clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status); | 2616 | clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
| 2786 | } | 2617 | } |
| 2787 | 2618 | ||
| 2788 | static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, | 2619 | static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, |
| @@ -2791,7 +2622,7 @@ static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, · 2 unmodified lines | |||
| 2791 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); | 2622 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); |
| 2792 | struct net_device *ndev = cfg_to_ndev(cfg); | 2623 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 2793 | 2624 | ||
| 2794 | if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { | 2625 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 2795 | WL_ERR("Scan complete while device not scanning\n"); | 2626 | WL_ERR("Scan complete while device not scanning\n"); |
| 2796 | return; | 2627 | return; |
| 2797 | } | 2628 | } |
| @@ -2820,7 +2651,6 @@ static s32 · 22 unmodified lines | |||
| 2820 | brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, | 2651 | brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, |
| 2821 | struct brcmf_scan_results **bss_list) | 2652 | struct brcmf_scan_results **bss_list) |
| 2822 | { | 2653 | { |
| 2823 | struct brcmf_iscan_results list; | ||
| 2824 | struct brcmf_scan_results *results; | 2654 | struct brcmf_scan_results *results; |
| 2825 | struct brcmf_scan_results_le *results_le; | 2655 | struct brcmf_scan_results_le *results_le; |
| 2826 | struct brcmf_iscan_results *list_buf; | 2656 | struct brcmf_iscan_results *list_buf; |
| @@ -2830,15 +2660,13 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, · 3 unmodified lines | |||
| 2830 | list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; | 2660 | list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; |
| 2831 | results = &list_buf->results; | 2661 | results = &list_buf->results; |
| 2832 | results_le = &list_buf->results_le; | 2662 | results_le = &list_buf->results_le; |
| 2833 | results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE; | 2663 | results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf)); |
| 2834 | results->version = 0; | 2664 | results_le->version = 0; |
| 2835 | results->count = 0; | 2665 | results_le->count = 0; |
| 2836 | 2666 | ||
| 2837 | memset(&list, 0, sizeof(list)); | 2667 | err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults", |
| 2838 | list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX); | 2668 | iscan->scan_buf, |
| 2839 | err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list, | 2669 | sizeof(iscan->scan_buf)); |
| 2840 | BRCMF_ISCAN_RESULTS_FIXED_SIZE, | ||
| 2841 | iscan->scan_buf, WL_ISCAN_BUF_MAX); | ||
| 2842 | if (err) { | 2670 | if (err) { |
| 2843 | WL_ERR("error (%d)\n", err); | 2671 | WL_ERR("error (%d)\n", err); |
| 2844 | return err; | 2672 | return err; |
| @@ -3052,10 +2880,10 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, · 207 unmodified lines | |||
| 3052 | status = be32_to_cpu(e->status); | 2880 | status = be32_to_cpu(e->status); |
| 3053 | 2881 | ||
| 3054 | if (!ndev || !cfg->escan_on || | 2882 | if (!ndev || !cfg->escan_on || |
| 3055 | !test_bit(WL_STATUS_SCANNING, &cfg->status)) { | 2883 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 3056 | WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", | 2884 | WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", |
| 3057 | ndev, cfg->escan_on, | 2885 | ndev, cfg->escan_on, |
| 3058 | !test_bit(WL_STATUS_SCANNING, &cfg->status)); | 2886 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); |
| 3059 | return -EPERM; | 2887 | return -EPERM; |
| 3060 | } | 2888 | } |
| 3061 | 2889 | ||
| @@ -3159,16 +2987,17 @@ static __always_inline void brcmf_delay(u32 ms) · 97 unmodified lines | |||
| 3159 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) | 2987 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) |
| 3160 | { | 2988 | { |
| 3161 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 2989 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 2990 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
| 3162 | 2991 | ||
| 3163 | /* | 2992 | /* |
| 3164 | * Check for WL_STATUS_READY before any function call which | 2993 | * Check for BRCMF_VIF_STATUS_READY before any function call which |
| 3165 | * could result is bus access. Don't block the resume for | 2994 | * could result is bus access. Don't block the resume for |
| 3166 | * any driver error conditions | 2995 | * any driver error conditions |
| 3167 | */ | 2996 | */ |
| 3168 | WL_TRACE("Enter\n"); | 2997 | WL_TRACE("Enter\n"); |
| 3169 | 2998 | ||
| 3170 | if (test_bit(WL_STATUS_READY, &cfg->status)) | 2999 | if (check_vif_up(ifp->vif)) |
| 3171 | brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); | 3000 | brcmf_invoke_iscan(cfg); |
| 3172 | 3001 | ||
| 3173 | WL_TRACE("Exit\n"); | 3002 | WL_TRACE("Exit\n"); |
| 3174 | return 0; | 3003 | return 0; |
| @@ -3179,84 +3008,52 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, · 4 unmodified lines | |||
| 3179 | { | 3008 | { |
| 3180 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3009 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 3181 | struct net_device *ndev = cfg_to_ndev(cfg); | 3010 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 3011 | struct brcmf_cfg80211_vif *vif; | ||
| 3182 | 3012 | ||
| 3183 | WL_TRACE("Enter\n"); | 3013 | WL_TRACE("Enter\n"); |
| 3184 | 3014 | ||
| 3185 | /* | 3015 | /* |
| 3186 | * Check for WL_STATUS_READY before any function call which | 3016 | * if the primary net_device is not READY there is nothing |
| 3187 | * could result is bus access. Don't block the suspend for | 3017 | * we can do but pray resume goes smoothly. |
| 3188 | * any driver error conditions | ||
| 3189 | */ | ||
| 3190 | |||
| 3191 | /* | ||
| 3192 | * While going to suspend if associated with AP disassociate | ||
| 3193 | * from AP to save power while system is in suspended state | ||
| 3194 | */ | 3018 | */ |
| 3195 | if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || | 3019 | vif = ((struct brcmf_if *)netdev_priv(ndev))->vif; |
| 3196 | test_bit(WL_STATUS_CONNECTING, &cfg->status)) && | 3020 | if (!check_vif_up(vif)) |
| 3197 | test_bit(WL_STATUS_READY, &cfg->status)) { | 3021 | goto exit; |
| 3198 | WL_INFO("Disassociating from AP" | ||
| 3199 | " while entering suspend state\n"); | ||
| 3200 | brcmf_link_down(cfg); | ||
| 3201 | 3022 | ||
| 3023 | list_for_each_entry(vif, &cfg->vif_list, list) { | ||
| 3024 | if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) | ||
| 3025 | continue; | ||
| 3202 | /* | 3026 | /* |
| 3203 | * Make sure WPA_Supplicant receives all the event | 3027 | * While going to suspend if associated with AP disassociate |
| 3204 | * generated due to DISASSOC call to the fw to keep | 3028 | * from AP to save power while system is in suspended state |
| 3205 | * the state fw and WPA_Supplicant state consistent | ||
| 3206 | */ | 3029 | */ |
| 3207 | brcmf_delay(500); | 3030 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) || |
| 3031 | test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { | ||
| 3032 | WL_INFO("Disassociating from AP before suspend\n"); | ||
| 3033 | brcmf_link_down(cfg); | ||
| 3034 | |||
| 3035 | /* Make sure WPA_Supplicant receives all the event | ||
| 3036 | * generated due to DISASSOC call to the fw to keep | ||
| 3037 | * the state fw and WPA_Supplicant state consistent | ||
| 3038 | */ | ||
| 3039 | brcmf_delay(500); | ||
| 3040 | } | ||
| 3208 | } | 3041 | } |
| 3209 | 3042 | ||
| 3210 | if (test_bit(WL_STATUS_READY, &cfg->status)) | 3043 | /* end any scanning */ |
| 3044 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) | ||
| 3211 | brcmf_abort_scanning(cfg); | 3045 | brcmf_abort_scanning(cfg); |
| 3212 | else | ||
| 3213 | clear_bit(WL_STATUS_SCANNING, &cfg->status); | ||
| 3214 | 3046 | ||
| 3215 | /* Turn off watchdog timer */ | 3047 | /* Turn off watchdog timer */ |
| 3216 | if (test_bit(WL_STATUS_READY, &cfg->status)) | 3048 | brcmf_set_mpc(ndev, 1); |
| 3217 | brcmf_set_mpc(ndev, 1); | ||
| 3218 | 3049 | ||
| 3050 | exit: | ||
| 3219 | WL_TRACE("Exit\n"); | 3051 | WL_TRACE("Exit\n"); |
| 3220 | 3052 | /* clear any scanning activity */ | |
| 3053 | cfg->scan_status = 0; | ||
| 3221 | return 0; | 3054 | return 0; |
| 3222 | } | 3055 | } |
| 3223 | 3056 | ||
| 3224 | static __used s32 | ||
| 3225 | brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len) | ||
| 3226 | { | ||
| 3227 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
| 3228 | u32 buflen; | ||
| 3229 | |||
| 3230 | buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf, | ||
| 3231 | WL_DCMD_LEN_MAX); | ||
| 3232 | BUG_ON(!buflen); | ||
| 3233 | |||
| 3234 | return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf, | ||
| 3235 | buflen); | ||
| 3236 | } | ||
| 3237 | |||
| 3238 | static s32 | ||
| 3239 | brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf, | ||
| 3240 | s32 buf_len) | ||
| 3241 | { | ||
| 3242 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
| 3243 | u32 len; | ||
| 3244 | s32 err = 0; | ||
| 3245 | |||
| 3246 | len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf, | ||
| 3247 | WL_DCMD_LEN_MAX); | ||
| 3248 | BUG_ON(!len); | ||
| 3249 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf, | ||
| 3250 | WL_DCMD_LEN_MAX); | ||
| 3251 | if (err) { | ||
| 3252 | WL_ERR("error (%d)\n", err); | ||
| 3253 | return err; | ||
| 3254 | } | ||
| 3255 | memcpy(buf, cfg->dcmd_buf, buf_len); | ||
| 3256 | |||
| 3257 | return err; | ||
| 3258 | } | ||
| 3259 | |||
| 3260 | static __used s32 | 3057 | static __used s32 |
| 3261 | brcmf_update_pmklist(struct net_device *ndev, | 3058 | brcmf_update_pmklist(struct net_device *ndev, |
| 3262 | struct brcmf_cfg80211_pmk_list *pmk_list, s32 err) | 3059 | struct brcmf_cfg80211_pmk_list *pmk_list, s32 err) |
| @@ -3275,8 +3072,8 @@ brcmf_update_pmklist(struct net_device *ndev, · 12 unmodified lines | |||
| 3275 | } | 3072 | } |
| 3276 | 3073 | ||
| 3277 | if (!err) | 3074 | if (!err) |
| 3278 | brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list, | 3075 | brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info", |
| 3279 | sizeof(*pmk_list)); | 3076 | (char *)pmk_list, sizeof(*pmk_list)); |
| 3280 | 3077 | ||
| 3281 | return err; | 3078 | return err; |
| 3282 | } | 3079 | } |
| @@ -3286,13 +3083,14 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 3286 | struct cfg80211_pmksa *pmksa) | 3083 | struct cfg80211_pmksa *pmksa) |
| 3287 | { | 3084 | { |
| 3288 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3085 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 3086 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3289 | struct pmkid_list *pmkids = &cfg->pmk_list->pmkids; | 3087 | struct pmkid_list *pmkids = &cfg->pmk_list->pmkids; |
| 3290 | s32 err = 0; | 3088 | s32 err = 0; |
| 3291 | int i; | 3089 | int i; |
| 3292 | int pmkid_len; | 3090 | int pmkid_len; |
| 3293 | 3091 | ||
| 3294 | WL_TRACE("Enter\n"); | 3092 | WL_TRACE("Enter\n"); |
| 3295 | if (!check_sys_up(wiphy)) | 3093 | if (!check_vif_up(ifp->vif)) |
| 3296 | return -EIO; | 3094 | return -EIO; |
| 3297 | 3095 | ||
| 3298 | pmkid_len = le32_to_cpu(pmkids->npmkid); | 3096 | pmkid_len = le32_to_cpu(pmkids->npmkid); |
| @@ -3325,12 +3123,13 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, · 26 unmodified lines | |||
| 3325 | struct cfg80211_pmksa *pmksa) | 3123 | struct cfg80211_pmksa *pmksa) |
| 3326 | { | 3124 | { |
| 3327 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3125 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 3126 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3328 | struct pmkid_list pmkid; | 3127 | struct pmkid_list pmkid; |
| 3329 | s32 err = 0; | 3128 | s32 err = 0; |
| 3330 | int i, pmkid_len; | 3129 | int i, pmkid_len; |
| 3331 | 3130 | ||
| 3332 | WL_TRACE("Enter\n"); | 3131 | WL_TRACE("Enter\n"); |
| 3333 | if (!check_sys_up(wiphy)) | 3132 | if (!check_vif_up(ifp->vif)) |
| 3334 | return -EIO; | 3133 | return -EIO; |
| 3335 | 3134 | ||
| 3336 | memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); | 3135 | memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); |
| @@ -3375,10 +3174,11 @@ static s32 · 38 unmodified lines | |||
| 3375 | brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) | 3174 | brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) |
| 3376 | { | 3175 | { |
| 3377 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3176 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 3177 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3378 | s32 err = 0; | 3178 | s32 err = 0; |
| 3379 | 3179 | ||
| 3380 | WL_TRACE("Enter\n"); | 3180 | WL_TRACE("Enter\n"); |
| 3381 | if (!check_sys_up(wiphy)) | 3181 | if (!check_vif_up(ifp->vif)) |
| 3382 | return -EIO; | 3182 | return -EIO; |
| 3383 | 3183 | ||
| 3384 | memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list)); | 3184 | memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list)); |
| @@ -3478,15 +3278,15 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, · 93 unmodified lines | |||
| 3478 | if (request->n_ssids) | 3278 | if (request->n_ssids) |
| 3479 | request->ssids = &ssid[0]; | 3279 | request->ssids = &ssid[0]; |
| 3480 | 3280 | ||
| 3481 | if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { | 3281 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 3482 | /* Abort any on-going scan */ | 3282 | /* Abort any on-going scan */ |
| 3483 | brcmf_abort_scanning(cfg); | 3283 | brcmf_abort_scanning(cfg); |
| 3484 | } | 3284 | } |
| 3485 | 3285 | ||
| 3486 | set_bit(WL_STATUS_SCANNING, &cfg->status); | 3286 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 3487 | err = brcmf_do_escan(cfg, wiphy, ndev, request); | 3287 | err = brcmf_do_escan(cfg, wiphy, ndev, request); |
| 3488 | if (err) { | 3288 | if (err) { |
| 3489 | clear_bit(WL_STATUS_SCANNING, &cfg->status); | 3289 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
| 3490 | goto out_err; | 3290 | goto out_err; |
| 3491 | } | 3291 | } |
| 3492 | cfg->sched_escan = true; | 3292 | cfg->sched_escan = true; |
| @@ -3512,15 +3312,14 @@ out_err: · 19 unmodified lines | |||
| 3512 | #ifndef CONFIG_BRCMISCAN | 3312 | #ifndef CONFIG_BRCMISCAN |
| 3513 | static int brcmf_dev_pno_clean(struct net_device *ndev) | 3313 | static int brcmf_dev_pno_clean(struct net_device *ndev) |
| 3514 | { | 3314 | { |
| 3515 | char iovbuf[128]; | ||
| 3516 | int ret; | 3315 | int ret; |
| 3517 | 3316 | ||
| 3518 | /* Disable pfn */ | 3317 | /* Disable pfn */ |
| 3519 | ret = brcmf_dev_intvar_set(ndev, "pfn", 0); | 3318 | ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0); |
| 3520 | if (ret == 0) { | 3319 | if (ret == 0) { |
| 3521 | /* clear pfn */ | 3320 | /* clear pfn */ |
| 3522 | ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0, | 3321 | ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear", |
| 3523 | iovbuf, sizeof(iovbuf)); | 3322 | NULL, 0); |
| 3524 | } | 3323 | } |
| 3525 | if (ret < 0) | 3324 | if (ret < 0) |
| 3526 | WL_ERR("failed code %d\n", ret); | 3325 | WL_ERR("failed code %d\n", ret); |
| @@ -3531,7 +3330,6 @@ static int brcmf_dev_pno_clean(struct net_device *ndev) · 4 unmodified lines | |||
| 3531 | static int brcmf_dev_pno_config(struct net_device *ndev) | 3330 | static int brcmf_dev_pno_config(struct net_device *ndev) |
| 3532 | { | 3331 | { |
| 3533 | struct brcmf_pno_param_le pfn_param; | 3332 | struct brcmf_pno_param_le pfn_param; |
| 3534 | char iovbuf[128]; | ||
| 3535 | 3333 | ||
| 3536 | memset(&pfn_param, 0, sizeof(pfn_param)); | 3334 | memset(&pfn_param, 0, sizeof(pfn_param)); |
| 3537 | pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); | 3335 | pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION); |
| @@ -3544,9 +3342,8 @@ static int brcmf_dev_pno_config(struct net_device *ndev) · 6 unmodified lines | |||
| 3544 | /* set up pno scan fr */ | 3342 | /* set up pno scan fr */ |
| 3545 | pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); | 3343 | pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME); |
| 3546 | 3344 | ||
| 3547 | return brcmf_dev_iovar_setbuf(ndev, "pfn_set", | 3345 | return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set", |
| 3548 | &pfn_param, sizeof(pfn_param), | 3346 | &pfn_param, sizeof(pfn_param)); |
| 3549 | iovbuf, sizeof(iovbuf)); | ||
| 3550 | } | 3347 | } |
| 3551 | 3348 | ||
| 3552 | static int | 3349 | static int |
| @@ -3554,7 +3351,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, · 1 unmodified line | |||
| 3554 | struct net_device *ndev, | 3351 | struct net_device *ndev, |
| 3555 | struct cfg80211_sched_scan_request *request) | 3352 | struct cfg80211_sched_scan_request *request) |
| 3556 | { | 3353 | { |
| 3557 | char iovbuf[128]; | 3354 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 3558 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); | 3355 | struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); |
| 3559 | struct brcmf_pno_net_param_le pfn; | 3356 | struct brcmf_pno_net_param_le pfn; |
| 3560 | int i; | 3357 | int i; |
| @@ -3562,8 +3359,8 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, · 1 unmodified line | |||
| 3562 | 3359 | ||
| 3563 | WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n", | 3360 | WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n", |
| 3564 | request->n_match_sets, request->n_ssids); | 3361 | request->n_match_sets, request->n_ssids); |
| 3565 | if (test_bit(WL_STATUS_SCANNING, &cfg->status)) { | 3362 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 3566 | WL_ERR("Scanning already : status (%lu)\n", cfg->status); | 3363 | WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); |
| 3567 | return -EAGAIN; | 3364 | return -EAGAIN; |
| 3568 | } | 3365 | } |
| 3569 | 3366 | ||
| @@ -3620,15 +3417,14 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, · 50 unmodified lines | |||
| 3620 | pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); | 3417 | pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT); |
| 3621 | pfn.ssid.SSID_len = cpu_to_le32(ssid_len); | 3418 | pfn.ssid.SSID_len = cpu_to_le32(ssid_len); |
| 3622 | memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len); | 3419 | memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len); |
| 3623 | ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add", | 3420 | ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, |
| 3624 | &pfn, sizeof(pfn), | 3421 | sizeof(pfn)); |
| 3625 | iovbuf, sizeof(iovbuf)); | ||
| 3626 | WL_SCAN(">>> PNO filter %s for ssid (%s)\n", | 3422 | WL_SCAN(">>> PNO filter %s for ssid (%s)\n", |
| 3627 | ret == 0 ? "set" : "failed", | 3423 | ret == 0 ? "set" : "failed", |
| 3628 | ssid->ssid); | 3424 | ssid->ssid); |
| 3629 | } | 3425 | } |
| 3630 | /* Enable the PNO */ | 3426 | /* Enable the PNO */ |
| 3631 | if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) { | 3427 | if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) { |
| 3632 | WL_ERR("PNO enable failed!! ret=%d\n", ret); | 3428 | WL_ERR("PNO enable failed!! ret=%d\n", ret); |
| 3633 | return -EINVAL; | 3429 | return -EINVAL; |
| 3634 | } | 3430 | } |
| @@ -3656,12 +3452,20 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, · 21 unmodified lines | |||
| 3656 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) | 3452 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) |
| 3657 | { | 3453 | { |
| 3658 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 3454 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 3659 | struct net_device *ndev = cfg->wdev->netdev; | 3455 | struct net_device *ndev = cfg_to_ndev(cfg); |
| 3660 | struct brcmf_dcmd *dcmd = data; | 3456 | struct brcmf_dcmd *dcmd = data; |
| 3661 | struct sk_buff *reply; | 3457 | struct sk_buff *reply; |
| 3662 | int ret; | 3458 | int ret; |
| 3663 | 3459 | ||
| 3664 | ret = brcmf_netlink_dcmd(ndev, dcmd); | 3460 | WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set, |
| 3461 | dcmd->buf, dcmd->len); | ||
| 3462 | |||
| 3463 | if (dcmd->set) | ||
| 3464 | ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd, | ||
| 3465 | dcmd->buf, dcmd->len); | ||
| 3466 | else | ||
| 3467 | ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd, | ||
| 3468 | dcmd->buf, dcmd->len); | ||
| 3665 | if (ret == 0) { | 3469 | if (ret == 0) { |
| 3666 | reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd)); | 3470 | reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd)); |
| 3667 | nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd); | 3471 | nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd); |
| @@ -3673,23 +3477,23 @@ static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) · 5 unmodified lines | |||
| 3673 | 3477 | ||
| 3674 | static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx) | 3478 | static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx) |
| 3675 | { | 3479 | { |
| 3480 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3676 | s32 err; | 3481 | s32 err; |
| 3677 | 3482 | ||
| 3678 | /* set auth */ | 3483 | /* set auth */ |
| 3679 | err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx); | 3484 | err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0); |
| 3680 | if (err < 0) { | 3485 | if (err < 0) { |
| 3681 | WL_ERR("auth error %d\n", err); | 3486 | WL_ERR("auth error %d\n", err); |
| 3682 | return err; | 3487 | return err; |
| 3683 | } | 3488 | } |
| 3684 | /* set wsec */ | 3489 | /* set wsec */ |
| 3685 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx); | 3490 | err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0); |
| 3686 | if (err < 0) { | 3491 | if (err < 0) { |
| 3687 | WL_ERR("wsec error %d\n", err); | 3492 | WL_ERR("wsec error %d\n", err); |
| 3688 | return err; | 3493 | return err; |
| 3689 | } | 3494 | } |
| 3690 | /* set upper-layer auth */ | 3495 | /* set upper-layer auth */ |
| 3691 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", | 3496 | err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE); |
| 3692 | WPA_AUTH_NONE, bssidx); | ||
| 3693 | if (err < 0) { | 3497 | if (err < 0) { |
| 3694 | WL_ERR("wpa_auth error %d\n", err); | 3498 | WL_ERR("wpa_auth error %d\n", err); |
| 3695 | return err; | 3499 | return err; |
| @@ -3710,6 +3514,7 @@ static s32 · 14 unmodified lines | |||
| 3710 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, | 3514 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, |
| 3711 | bool is_rsn_ie, s32 bssidx) | 3515 | bool is_rsn_ie, s32 bssidx) |
| 3712 | { | 3516 | { |
| 3517 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3713 | u32 auth = 0; /* d11 open authentication */ | 3518 | u32 auth = 0; /* d11 open authentication */ |
| 3714 | u16 count; | 3519 | u16 count; |
| 3715 | s32 err = 0; | 3520 | s32 err = 0; |
| @@ -3850,8 +3655,8 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, · 134 unmodified lines | |||
| 3850 | wme_bss_disable = 0; | 3655 | wme_bss_disable = 0; |
| 3851 | } | 3656 | } |
| 3852 | /* set wme_bss_disable to sync RSN Capabilities */ | 3657 | /* set wme_bss_disable to sync RSN Capabilities */ |
| 3853 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable", | 3658 | err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", |
| 3854 | wme_bss_disable, bssidx); | 3659 | wme_bss_disable); |
| 3855 | if (err < 0) { | 3660 | if (err < 0) { |
| 3856 | WL_ERR("wme_bss_disable error %d\n", err); | 3661 | WL_ERR("wme_bss_disable error %d\n", err); |
| 3857 | goto exit; | 3662 | goto exit; |
| @@ -3861,19 +3666,19 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, · 3 unmodified lines | |||
| 3861 | wsec = (pval | gval | SES_OW_ENABLED); | 3666 | wsec = (pval | gval | SES_OW_ENABLED); |
| 3862 | 3667 | ||
| 3863 | /* set auth */ | 3668 | /* set auth */ |
| 3864 | err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx); | 3669 | err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth); |
| 3865 | if (err < 0) { | 3670 | if (err < 0) { |
| 3866 | WL_ERR("auth error %d\n", err); | 3671 | WL_ERR("auth error %d\n", err); |
| 3867 | goto exit; | 3672 | goto exit; |
| 3868 | } | 3673 | } |
| 3869 | /* set wsec */ | 3674 | /* set wsec */ |
| 3870 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx); | 3675 | err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); |
| 3871 | if (err < 0) { | 3676 | if (err < 0) { |
| 3872 | WL_ERR("wsec error %d\n", err); | 3677 | WL_ERR("wsec error %d\n", err); |
| 3873 | goto exit; | 3678 | goto exit; |
| 3874 | } | 3679 | } |
| 3875 | /* set upper-layer auth */ | 3680 | /* set upper-layer auth */ |
| 3876 | err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx); | 3681 | err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); |
| 3877 | if (err < 0) { | 3682 | if (err < 0) { |
| 3878 | WL_ERR("wpa_auth error %d\n", err); | 3683 | WL_ERR("wpa_auth error %d\n", err); |
| 3879 | goto exit; | 3684 | goto exit; |
| @@ -3963,17 +3768,19 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) · 83 unmodified lines | |||
| 3963 | return ie_len + VNDR_IE_HDR_SIZE; | 3768 | return ie_len + VNDR_IE_HDR_SIZE; |
| 3964 | } | 3769 | } |
| 3965 | 3770 | ||
| 3966 | s32 | 3771 | static s32 |
| 3967 | brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | 3772 | brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, |
| 3968 | struct net_device *ndev, s32 bssidx, s32 pktflag, | 3773 | struct net_device *ndev, s32 pktflag, |
| 3969 | u8 *vndr_ie_buf, u32 vndr_ie_len) | 3774 | u8 *vndr_ie_buf, u32 vndr_ie_len) |
| 3970 | { | 3775 | { |
| 3776 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 3777 | struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie; | ||
| 3971 | s32 err = 0; | 3778 | s32 err = 0; |
| 3972 | u8 *iovar_ie_buf; | 3779 | u8 *iovar_ie_buf; |
| 3973 | u8 *curr_ie_buf; | 3780 | u8 *curr_ie_buf; |
| 3974 | u8 *mgmt_ie_buf = NULL; | 3781 | u8 *mgmt_ie_buf = NULL; |
| 3975 | int mgmt_ie_buf_len; | 3782 | int mgmt_ie_buf_len; |
| 3976 | u32 *mgmt_ie_len = 0; | 3783 | u32 *mgmt_ie_len; |
| 3977 | u32 del_add_ie_buf_len = 0; | 3784 | u32 del_add_ie_buf_len = 0; |
| 3978 | u32 total_ie_buf_len = 0; | 3785 | u32 total_ie_buf_len = 0; |
| 3979 | u32 parsed_ie_buf_len = 0; | 3786 | u32 parsed_ie_buf_len = 0; |
| @@ -3984,31 +3791,29 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, · 4 unmodified lines | |||
| 3984 | u8 *ptr; | 3791 | u8 *ptr; |
| 3985 | int remained_buf_len; | 3792 | int remained_buf_len; |
| 3986 | 3793 | ||
| 3987 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag); | 3794 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", |
| 3795 | brcmf_ndev_bssidx(ndev), pktflag); | ||
| 3988 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 3796 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
| 3989 | if (!iovar_ie_buf) | 3797 | if (!iovar_ie_buf) |
| 3990 | return -ENOMEM; | 3798 | return -ENOMEM; |
| 3991 | curr_ie_buf = iovar_ie_buf; | 3799 | curr_ie_buf = iovar_ie_buf; |
| 3992 | if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) || | 3800 | if (ifp->vif->mode == WL_MODE_AP) { |
| 3993 | test_bit(WL_STATUS_AP_CREATED, &cfg->status)) { | ||
| 3994 | switch (pktflag) { | 3801 | switch (pktflag) { |
| 3995 | case VNDR_IE_PRBRSP_FLAG: | 3802 | case VNDR_IE_PRBRSP_FLAG: |
| 3996 | mgmt_ie_buf = cfg->ap_info->probe_res_ie; | 3803 | mgmt_ie_buf = saved_ie->probe_res_ie; |
| 3997 | mgmt_ie_len = &cfg->ap_info->probe_res_ie_len; | 3804 | mgmt_ie_len = &saved_ie->probe_res_ie_len; |
| 3998 | mgmt_ie_buf_len = | 3805 | mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie); |
| 3999 | sizeof(cfg->ap_info->probe_res_ie); | ||
| 4000 | break; | 3806 | break; |
| 4001 | case VNDR_IE_BEACON_FLAG: | 3807 | case VNDR_IE_BEACON_FLAG: |
| 4002 | mgmt_ie_buf = cfg->ap_info->beacon_ie; | 3808 | mgmt_ie_buf = saved_ie->beacon_ie; |
| 4003 | mgmt_ie_len = &cfg->ap_info->beacon_ie_len; | 3809 | mgmt_ie_len = &saved_ie->beacon_ie_len; |
| 4004 | mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie); | 3810 | mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie); |
| 4005 | break; | 3811 | break; |
| 4006 | default: | 3812 | default: |
| 4007 | err = -EPERM; | 3813 | err = -EPERM; |
| 4008 | WL_ERR("not suitable type\n"); | 3814 | WL_ERR("not suitable type\n"); |
| 4009 | goto exit; | 3815 | goto exit; |
| 4010 | } | 3816 | } |
| 4011 | bssidx = 0; | ||
| 4012 | } else { | 3817 | } else { |
| 4013 | err = -EPERM; | 3818 | err = -EPERM; |
| 4014 | WL_ERR("not suitable type\n"); | 3819 | WL_ERR("not suitable type\n"); |
| @@ -4104,11 +3909,8 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, · 89 unmodified lines | |||
| 4104 | } | 3909 | } |
| 4105 | } | 3910 | } |
| 4106 | if (total_ie_buf_len) { | 3911 | if (total_ie_buf_len) { |
| 4107 | err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie", | 3912 | err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf, |
| 4108 | iovar_ie_buf, | 3913 | total_ie_buf_len); |
| 4109 | total_ie_buf_len, | ||
| 4110 | cfg->extra_buf, | ||
| 4111 | WL_EXTRA_BUF_MAX, bssidx); | ||
| 4112 | if (err) | 3914 | if (err) |
| 4113 | WL_ERR("vndr ie set error : %d\n", err); | 3915 | WL_ERR("vndr ie set error : %d\n", err); |
| 4114 | } | 3916 | } |
| @@ -4123,9 +3925,9 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 8 unmodified lines | |||
| 4123 | struct cfg80211_ap_settings *settings) | 3925 | struct cfg80211_ap_settings *settings) |
| 4124 | { | 3926 | { |
| 4125 | s32 ie_offset; | 3927 | s32 ie_offset; |
| 3928 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 4126 | struct brcmf_tlv *ssid_ie; | 3929 | struct brcmf_tlv *ssid_ie; |
| 4127 | struct brcmf_ssid_le ssid_le; | 3930 | struct brcmf_ssid_le ssid_le; |
| 4128 | s32 ioctl_value; | ||
| 4129 | s32 err = -EPERM; | 3931 | s32 err = -EPERM; |
| 4130 | struct brcmf_tlv *rsn_ie; | 3932 | struct brcmf_tlv *rsn_ie; |
| 4131 | struct brcmf_vs_tlv *wpa_ie; | 3933 | struct brcmf_vs_tlv *wpa_ie; |
| @@ -4140,7 +3942,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 8 unmodified lines | |||
| 4140 | settings->ssid, settings->ssid_len, settings->auth_type, | 3942 | settings->ssid, settings->ssid_len, settings->auth_type, |
| 4141 | settings->inactivity_timeout); | 3943 | settings->inactivity_timeout); |
| 4142 | 3944 | ||
| 4143 | if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) { | 3945 | if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) { |
| 4144 | WL_ERR("Not in AP creation mode\n"); | 3946 | WL_ERR("Not in AP creation mode\n"); |
| 4145 | return -EPERM; | 3947 | return -EPERM; |
| 4146 | } | 3948 | } |
| @@ -4164,20 +3966,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 17 unmodified lines | |||
| 4164 | } | 3966 | } |
| 4165 | 3967 | ||
| 4166 | brcmf_set_mpc(ndev, 0); | 3968 | brcmf_set_mpc(ndev, 0); |
| 4167 | ioctl_value = 1; | 3969 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); |
| 4168 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value); | ||
| 4169 | if (err < 0) { | 3970 | if (err < 0) { |
| 4170 | WL_ERR("BRCMF_C_DOWN error %d\n", err); | 3971 | WL_ERR("BRCMF_C_DOWN error %d\n", err); |
| 4171 | goto exit; | 3972 | goto exit; |
| 4172 | } | 3973 | } |
| 4173 | ioctl_value = 1; | 3974 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1); |
| 4174 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value); | ||
| 4175 | if (err < 0) { | 3975 | if (err < 0) { |
| 4176 | WL_ERR("SET INFRA error %d\n", err); | 3976 | WL_ERR("SET INFRA error %d\n", err); |
| 4177 | goto exit; | 3977 | goto exit; |
| 4178 | } | 3978 | } |
| 4179 | ioctl_value = 1; | 3979 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1); |
| 4180 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value); | ||
| 4181 | if (err < 0) { | 3980 | if (err < 0) { |
| 4182 | WL_ERR("setting AP mode failed %d\n", err); | 3981 | WL_ERR("setting AP mode failed %d\n", err); |
| 4183 | goto exit; | 3982 | goto exit; |
| @@ -4226,7 +4025,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 42 unmodified lines | |||
| 4226 | cfg->ap_info->security_mode = false; | 4025 | cfg->ap_info->security_mode = false; |
| 4227 | } | 4026 | } |
| 4228 | /* Set Beacon IEs to FW */ | 4027 | /* Set Beacon IEs to FW */ |
| 4229 | err = brcmf_set_management_ie(cfg, ndev, bssidx, | 4028 | err = brcmf_set_management_ie(cfg, ndev, |
| 4230 | VNDR_IE_BEACON_FLAG, | 4029 | VNDR_IE_BEACON_FLAG, |
| 4231 | (u8 *)settings->beacon.tail, | 4030 | (u8 *)settings->beacon.tail, |
| 4232 | settings->beacon.tail_len); | 4031 | settings->beacon.tail_len); |
| @@ -4236,7 +4035,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 4236 | WL_TRACE("Applied Vndr IEs for Beacon\n"); | 4035 | WL_TRACE("Applied Vndr IEs for Beacon\n"); |
| 4237 | 4036 | ||
| 4238 | /* Set Probe Response IEs to FW */ | 4037 | /* Set Probe Response IEs to FW */ |
| 4239 | err = brcmf_set_management_ie(cfg, ndev, bssidx, | 4038 | err = brcmf_set_management_ie(cfg, ndev, |
| 4240 | VNDR_IE_PRBRSP_FLAG, | 4039 | VNDR_IE_PRBRSP_FLAG, |
| 4241 | (u8 *)settings->beacon.proberesp_ies, | 4040 | (u8 *)settings->beacon.proberesp_ies, |
| 4242 | settings->beacon.proberesp_ies_len); | 4041 | settings->beacon.proberesp_ies_len); |
| @@ -4246,25 +4045,22 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 4246 | WL_TRACE("Applied Vndr IEs for Probe Resp\n"); | 4045 | WL_TRACE("Applied Vndr IEs for Probe Resp\n"); |
| 4247 | 4046 | ||
| 4248 | if (settings->beacon_interval) { | 4047 | if (settings->beacon_interval) { |
| 4249 | ioctl_value = settings->beacon_interval; | 4048 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, |
| 4250 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD, | 4049 | settings->beacon_interval); |
| 4251 | &ioctl_value); | ||
| 4252 | if (err < 0) { | 4050 | if (err < 0) { |
| 4253 | WL_ERR("Beacon Interval Set Error, %d\n", err); | 4051 | WL_ERR("Beacon Interval Set Error, %d\n", err); |
| 4254 | goto exit; | 4052 | goto exit; |
| 4255 | } | 4053 | } |
| 4256 | } | 4054 | } |
| 4257 | if (settings->dtim_period) { | 4055 | if (settings->dtim_period) { |
| 4258 | ioctl_value = settings->dtim_period; | 4056 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD, |
| 4259 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD, | 4057 | settings->dtim_period); |
| 4260 | &ioctl_value); | ||
| 4261 | if (err < 0) { | 4058 | if (err < 0) { |
| 4262 | WL_ERR("DTIM Interval Set Error, %d\n", err); | 4059 | WL_ERR("DTIM Interval Set Error, %d\n", err); |
| 4263 | goto exit; | 4060 | goto exit; |
| 4264 | } | 4061 | } |
| 4265 | } | 4062 | } |
| 4266 | ioctl_value = 1; | 4063 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); |
| 4267 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value); | ||
| 4268 | if (err < 0) { | 4064 | if (err < 0) { |
| 4269 | WL_ERR("BRCMF_C_UP error (%d)\n", err); | 4065 | WL_ERR("BRCMF_C_UP error (%d)\n", err); |
| 4270 | goto exit; | 4066 | goto exit; |
| @@ -4274,14 +4070,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 3 unmodified lines | |||
| 4274 | /* join parameters starts with ssid */ | 4070 | /* join parameters starts with ssid */ |
| 4275 | memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le)); | 4071 | memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le)); |
| 4276 | /* create softap */ | 4072 | /* create softap */ |
| 4277 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params, | 4073 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, |
| 4278 | sizeof(join_params)); | 4074 | &join_params, sizeof(join_params)); |
| 4279 | if (err < 0) { | 4075 | if (err < 0) { |
| 4280 | WL_ERR("SET SSID error (%d)\n", err); | 4076 | WL_ERR("SET SSID error (%d)\n", err); |
| 4281 | goto exit; | 4077 | goto exit; |
| 4282 | } | 4078 | } |
| 4283 | clear_bit(WL_STATUS_AP_CREATING, &cfg->status); | 4079 | clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
| 4284 | set_bit(WL_STATUS_AP_CREATED, &cfg->status); | 4080 | set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); |
| 4285 | 4081 | ||
| 4286 | exit: | 4082 | exit: |
| 4287 | if (err) | 4083 | if (err) |
| @@ -4291,8 +4087,8 @@ exit: · 3 unmodified lines | |||
| 4291 | 4087 | ||
| 4292 | static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) | 4088 | static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) |
| 4293 | { | 4089 | { |
| 4090 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 4294 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 4091 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
| 4295 | s32 ioctl_value; | ||
| 4296 | s32 err = -EPERM; | 4092 | s32 err = -EPERM; |
| 4297 | 4093 | ||
| 4298 | WL_TRACE("Enter\n"); | 4094 | WL_TRACE("Enter\n"); |
| @@ -4301,21 +4097,20 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) · 2 unmodified lines | |||
| 4301 | /* Due to most likely deauths outstanding we sleep */ | 4097 | /* Due to most likely deauths outstanding we sleep */ |
| 4302 | /* first to make sure they get processed by fw. */ | 4098 | /* first to make sure they get processed by fw. */ |
| 4303 | msleep(400); | 4099 | msleep(400); |
| 4304 | ioctl_value = 0; | 4100 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), |
| 4305 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value); | 4101 | BRCMF_C_SET_AP, 0); |
| 4306 | if (err < 0) { | 4102 | if (err < 0) { |
| 4307 | WL_ERR("setting AP mode failed %d\n", err); | 4103 | WL_ERR("setting AP mode failed %d\n", err); |
| 4308 | goto exit; | 4104 | goto exit; |
| 4309 | } | 4105 | } |
| 4310 | ioctl_value = 0; | 4106 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0); |
| 4311 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value); | ||
| 4312 | if (err < 0) { | 4107 | if (err < 0) { |
| 4313 | WL_ERR("BRCMF_C_UP error %d\n", err); | 4108 | WL_ERR("BRCMF_C_UP error %d\n", err); |
| 4314 | goto exit; | 4109 | goto exit; |
| 4315 | } | 4110 | } |
| 4316 | brcmf_set_mpc(ndev, 1); | 4111 | brcmf_set_mpc(ndev, 1); |
| 4317 | clear_bit(WL_STATUS_AP_CREATING, &cfg->status); | 4112 | clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
| 4318 | clear_bit(WL_STATUS_AP_CREATED, &cfg->status); | 4113 | clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); |
| 4319 | } | 4114 | } |
| 4320 | exit: | 4115 | exit: |
| 4321 | return err; | 4116 | return err; |
| @@ -4326,6 +4121,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, · 4 unmodified lines | |||
| 4326 | u8 *mac) | 4121 | u8 *mac) |
| 4327 | { | 4122 | { |
| 4328 | struct brcmf_scb_val_le scbval; | 4123 | struct brcmf_scb_val_le scbval; |
| 4124 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 4329 | s32 err; | 4125 | s32 err; |
| 4330 | 4126 | ||
| 4331 | if (!mac) | 4127 | if (!mac) |
| @@ -4333,13 +4129,13 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, · 1 unmodified line | |||
| 4333 | 4129 | ||
| 4334 | WL_TRACE("Enter %pM\n", mac); | 4130 | WL_TRACE("Enter %pM\n", mac); |
| 4335 | 4131 | ||
| 4336 | if (!check_sys_up(wiphy)) | 4132 | if (!check_vif_up(ifp->vif)) |
| 4337 | return -EIO; | 4133 | return -EIO; |
| 4338 | 4134 | ||
| 4339 | memcpy(&scbval.ea, mac, ETH_ALEN); | 4135 | memcpy(&scbval.ea, mac, ETH_ALEN); |
| 4340 | scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); | 4136 | scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); |
| 4341 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, | 4137 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, |
| 4342 | &scbval, sizeof(scbval)); | 4138 | &scbval, sizeof(scbval)); |
| 4343 | if (err) | 4139 | if (err) |
| 4344 | WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err); | 4140 | WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err); |
| 4345 | 4141 | ||
| @@ -4410,72 +4206,97 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy) · 64 unmodified lines | |||
| 4410 | #endif | 4206 | #endif |
| 4411 | } | 4207 | } |
| 4412 | 4208 | ||
| 4413 | static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev) | 4209 | static struct wiphy *brcmf_setup_wiphy(struct device *phydev) |
| 4414 | { | 4210 | { |
| 4415 | struct wireless_dev *wdev; | 4211 | struct wiphy *wiphy; |
| 4416 | s32 err = 0; | 4212 | s32 err = 0; |
| 4417 | 4213 | ||
| 4418 | wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); | 4214 | wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); |
| 4419 | if (!wdev) | 4215 | if (!wiphy) { |
| 4420 | return ERR_PTR(-ENOMEM); | ||
| 4421 | |||
| 4422 | wdev->wiphy = wiphy_new(&wl_cfg80211_ops, | ||
| 4423 | sizeof(struct brcmf_cfg80211_info)); | ||
| 4424 | if (!wdev->wiphy) { | ||
| 4425 | WL_ERR("Could not allocate wiphy device\n"); | 4216 | WL_ERR("Could not allocate wiphy device\n"); |
| 4426 | err = -ENOMEM; | 4217 | return ERR_PTR(-ENOMEM); |
| 4427 | goto wiphy_new_out; | 4218 | } |
| 4428 | } | 4219 | set_wiphy_dev(wiphy, phydev); |
| 4429 | set_wiphy_dev(wdev->wiphy, ndev); | 4220 | wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; |
| 4430 | wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; | 4221 | wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; |
| 4431 | wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; | 4222 | wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
| 4432 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 4223 | BIT(NL80211_IFTYPE_ADHOC) | |
| 4433 | BIT(NL80211_IFTYPE_ADHOC) | | 4224 | BIT(NL80211_IFTYPE_AP); |
| 4434 | BIT(NL80211_IFTYPE_AP); | 4225 | wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; |
| 4435 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; | 4226 | wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set |
| 4436 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set | ||
| 4437 | * it as 11a by default. | 4227 | * it as 11a by default. |
| 4438 | * This will be updated with | 4228 | * This will be updated with |
| 4439 | * 11n phy tables in | 4229 | * 11n phy tables in |
| 4440 | * "ifconfig up" | 4230 | * "ifconfig up" |
| 4441 | * if phy has 11n capability | 4231 | * if phy has 11n capability |
| 4442 | */ | 4232 | */ |
| 4443 | wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; | 4233 | wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; |
| 4444 | wdev->wiphy->cipher_suites = __wl_cipher_suites; | 4234 | wiphy->cipher_suites = __wl_cipher_suites; |
| 4445 | wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); | 4235 | wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); |
| 4446 | wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power | 4236 | wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power |
| 4447 | * save mode | 4237 | * save mode |
| 4448 | * by default | 4238 | * by default |
| 4449 | */ | 4239 | */ |
| 4450 | brcmf_wiphy_pno_params(wdev->wiphy); | 4240 | brcmf_wiphy_pno_params(wiphy); |
| 4451 | err = wiphy_register(wdev->wiphy); | 4241 | err = wiphy_register(wiphy); |
| 4452 | if (err < 0) { | 4242 | if (err < 0) { |
| 4453 | WL_ERR("Could not register wiphy device (%d)\n", err); | 4243 | WL_ERR("Could not register wiphy device (%d)\n", err); |
| 4454 | goto wiphy_register_out; | 4244 | wiphy_free(wiphy); |
| 4245 | return ERR_PTR(err); | ||
| 4246 | } | ||
| 4247 | return wiphy; | ||
| 4248 | } | ||
| 4249 | |||
| 4250 | static | ||
| 4251 | struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | ||
| 4252 | struct net_device *netdev, | ||
| 4253 | s32 mode, bool pm_block) | ||
| 4254 | { | ||
| 4255 | struct brcmf_cfg80211_vif *vif; | ||
| 4256 | |||
| 4257 | if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) | ||
| 4258 | return ERR_PTR(-ENOSPC); | ||
| 4259 | |||
| 4260 | vif = kzalloc(sizeof(*vif), GFP_KERNEL); | ||
| 4261 | if (!vif) | ||
| 4262 | return ERR_PTR(-ENOMEM); | ||
| 4263 | |||
| 4264 | vif->wdev.wiphy = cfg->wiphy; | ||
| 4265 | vif->wdev.netdev = netdev; | ||
| 4266 | vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode); | ||
| 4267 | |||
| 4268 | if (netdev) { | ||
| 4269 | vif->ifp = netdev_priv(netdev); | ||
| 4270 | netdev->ieee80211_ptr = &vif->wdev; | ||
| 4271 | SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy)); | ||
| 4455 | } | 4272 | } |
| 4456 | return wdev; | ||
| 4457 | 4273 | ||
| 4458 | wiphy_register_out: | 4274 | vif->mode = mode; |
| 4459 | wiphy_free(wdev->wiphy); | 4275 | vif->pm_block = pm_block; |
| 4276 | vif->roam_off = -1; | ||
| 4460 | 4277 | ||
| 4461 | wiphy_new_out: | 4278 | brcmf_init_prof(&vif->profile); |
| 4462 | kfree(wdev); | ||
| 4463 | 4279 | ||
| 4464 | return ERR_PTR(err); | 4280 | list_add_tail(&vif->list, &cfg->vif_list); |
| 4281 | cfg->vif_cnt++; | ||
| 4282 | return vif; | ||
| 4465 | } | 4283 | } |
| 4466 | 4284 | ||
| 4467 | static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg) | 4285 | static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) |
| 4468 | { | 4286 | { |
| 4469 | struct wireless_dev *wdev = cfg->wdev; | 4287 | struct brcmf_cfg80211_info *cfg; |
| 4288 | struct wiphy *wiphy; | ||
| 4470 | 4289 | ||
| 4471 | if (!wdev) { | 4290 | wiphy = vif->wdev.wiphy; |
| 4472 | WL_ERR("wdev is invalid\n"); | 4291 | cfg = wiphy_priv(wiphy); |
| 4473 | return; | 4292 | list_del(&vif->list); |
| 4293 | cfg->vif_cnt--; | ||
| 4294 | |||
| 4295 | kfree(vif); | ||
| 4296 | if (!cfg->vif_cnt) { | ||
| 4297 | wiphy_unregister(wiphy); | ||
| 4298 | wiphy_free(wiphy); | ||
| 4474 | } | 4299 | } |
| 4475 | wiphy_unregister(wdev->wiphy); | ||
| 4476 | wiphy_free(wdev->wiphy); | ||
| 4477 | kfree(wdev); | ||
| 4478 | cfg->wdev = NULL; | ||
| 4479 | } | 4300 | } |
| 4480 | 4301 | ||
| 4481 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, | 4302 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, |
| @@ -4541,7 +4362,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg) · 59 unmodified lines | |||
| 4541 | 4362 | ||
| 4542 | static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) | 4363 | static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) |
| 4543 | { | 4364 | { |
| 4544 | struct net_device *ndev = cfg_to_ndev(cfg); | 4365 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
| 4545 | struct brcmf_cfg80211_assoc_ielen_le *assoc_info; | 4366 | struct brcmf_cfg80211_assoc_ielen_le *assoc_info; |
| 4546 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); | 4367 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); |
| 4547 | u32 req_len; | 4368 | u32 req_len; |
| @@ -4550,8 +4371,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) · 2 unmodified lines | |||
| 4550 | 4371 | ||
| 4551 | brcmf_clear_assoc_ies(cfg); | 4372 | brcmf_clear_assoc_ies(cfg); |
| 4552 | 4373 | ||
| 4553 | err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf, | 4374 | err = brcmf_fil_iovar_data_get(ifp, "assoc_info", |
| 4554 | WL_ASSOC_INFO_MAX); | 4375 | cfg->extra_buf, WL_ASSOC_INFO_MAX); |
| 4555 | if (err) { | 4376 | if (err) { |
| 4556 | WL_ERR("could not get assoc info (%d)\n", err); | 4377 | WL_ERR("could not get assoc info (%d)\n", err); |
| 4557 | return err; | 4378 | return err; |
| @@ -4561,9 +4382,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) · 3 unmodified lines | |||
| 4561 | req_len = le32_to_cpu(assoc_info->req_len); | 4382 | req_len = le32_to_cpu(assoc_info->req_len); |
| 4562 | resp_len = le32_to_cpu(assoc_info->resp_len); | 4383 | resp_len = le32_to_cpu(assoc_info->resp_len); |
| 4563 | if (req_len) { | 4384 | if (req_len) { |
| 4564 | err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", | 4385 | err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies", |
| 4565 | cfg->extra_buf, | 4386 | cfg->extra_buf, |
| 4566 | WL_ASSOC_INFO_MAX); | 4387 | WL_ASSOC_INFO_MAX); |
| 4567 | if (err) { | 4388 | if (err) { |
| 4568 | WL_ERR("could not get assoc req (%d)\n", err); | 4389 | WL_ERR("could not get assoc req (%d)\n", err); |
| 4569 | return err; | 4390 | return err; |
| @@ -4577,9 +4398,9 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg) · 7 unmodified lines | |||
| 4577 | conn_info->req_ie = NULL; | 4398 | conn_info->req_ie = NULL; |
| 4578 | } | 4399 | } |
| 4579 | if (resp_len) { | 4400 | if (resp_len) { |
| 4580 | err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", | 4401 | err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies", |
| 4581 | cfg->extra_buf, | 4402 | cfg->extra_buf, |
| 4582 | WL_ASSOC_INFO_MAX); | 4403 | WL_ASSOC_INFO_MAX); |
| 4583 | if (err) { | 4404 | if (err) { |
| 4584 | WL_ERR("could not get assoc resp (%d)\n", err); | 4405 | WL_ERR("could not get assoc resp (%d)\n", err); |
| 4585 | return err; | 4406 | return err; |
| @@ -4603,7 +4424,8 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, · 17 unmodified lines | |||
| 4603 | struct net_device *ndev, | 4424 | struct net_device *ndev, |
| 4604 | const struct brcmf_event_msg *e) | 4425 | const struct brcmf_event_msg *e) |
| 4605 | { | 4426 | { |
| 4606 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 4427 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 4428 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 4607 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); | 4429 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); |
| 4608 | struct wiphy *wiphy = cfg_to_wiphy(cfg); | 4430 | struct wiphy *wiphy = cfg_to_wiphy(cfg); |
| 4609 | struct ieee80211_channel *notify_channel = NULL; | 4431 | struct ieee80211_channel *notify_channel = NULL; |
| @@ -4628,7 +4450,8 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, · 18 unmodified lines | |||
| 4628 | 4450 | ||
| 4629 | /* data sent to dongle has to be little endian */ | 4451 | /* data sent to dongle has to be little endian */ |
| 4630 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); | 4452 | *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); |
| 4631 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); | 4453 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, |
| 4454 | buf, WL_BSS_INFO_MAX); | ||
| 4632 | 4455 | ||
| 4633 | if (err) | 4456 | if (err) |
| 4634 | goto done; | 4457 | goto done; |
| @@ -4652,7 +4475,7 @@ done: · 17 unmodified lines | |||
| 4652 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); | 4475 | conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); |
| 4653 | WL_CONN("Report roaming result\n"); | 4476 | WL_CONN("Report roaming result\n"); |
| 4654 | 4477 | ||
| 4655 | set_bit(WL_STATUS_CONNECTED, &cfg->status); | 4478 | set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); |
| 4656 | WL_TRACE("Exit\n"); | 4479 | WL_TRACE("Exit\n"); |
| 4657 | return err; | 4480 | return err; |
| 4658 | } | 4481 | } |
| @@ -4662,13 +4485,15 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg, · 3 unmodified lines | |||
| 4662 | struct net_device *ndev, const struct brcmf_event_msg *e, | 4485 | struct net_device *ndev, const struct brcmf_event_msg *e, |
| 4663 | bool completed) | 4486 | bool completed) |
| 4664 | { | 4487 | { |
| 4665 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 4488 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 4489 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 4666 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); | 4490 | struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); |
| 4667 | s32 err = 0; | 4491 | s32 err = 0; |
| 4668 | 4492 | ||
| 4669 | WL_TRACE("Enter\n"); | 4493 | WL_TRACE("Enter\n"); |
| 4670 | 4494 | ||
| 4671 | if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) { | 4495 | if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING, |
| 4496 | &ifp->vif->sme_state)) { | ||
| 4672 | if (completed) { | 4497 | if (completed) { |
| 4673 | brcmf_get_assoc_ies(cfg); | 4498 | brcmf_get_assoc_ies(cfg); |
| 4674 | memcpy(profile->bssid, e->addr, ETH_ALEN); | 4499 | memcpy(profile->bssid, e->addr, ETH_ALEN); |
| @@ -4684,7 +4509,8 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg, · 9 unmodified lines | |||
| 4684 | WLAN_STATUS_AUTH_TIMEOUT, | 4509 | WLAN_STATUS_AUTH_TIMEOUT, |
| 4685 | GFP_KERNEL); | 4510 | GFP_KERNEL); |
| 4686 | if (completed) | 4511 | if (completed) |
| 4687 | set_bit(WL_STATUS_CONNECTED, &cfg->status); | 4512 | set_bit(BRCMF_VIF_STATUS_CONNECTED, |
| 4513 | &ifp->vif->sme_state); | ||
| 4688 | WL_CONN("Report connect result - connection %s\n", | 4514 | WL_CONN("Report connect result - connection %s\n", |
| 4689 | completed ? "succeeded" : "failed"); | 4515 | completed ? "succeeded" : "failed"); |
| 4690 | } | 4516 | } |
| @@ -4736,7 +4562,8 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, · 45 unmodified lines | |||
| 4736 | struct net_device *ndev, | 4562 | struct net_device *ndev, |
| 4737 | const struct brcmf_event_msg *e, void *data) | 4563 | const struct brcmf_event_msg *e, void *data) |
| 4738 | { | 4564 | { |
| 4739 | struct brcmf_cfg80211_profile *profile = cfg->profile; | 4565 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 4566 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | ||
| 4740 | s32 err = 0; | 4567 | s32 err = 0; |
| 4741 | 4568 | ||
| 4742 | if (cfg->conf->mode == WL_MODE_AP) { | 4569 | if (cfg->conf->mode == WL_MODE_AP) { |
| @@ -4747,30 +4574,34 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, · 4 unmodified lines | |||
| 4747 | memcpy(profile->bssid, e->addr, ETH_ALEN); | 4574 | memcpy(profile->bssid, e->addr, ETH_ALEN); |
| 4748 | wl_inform_ibss(cfg, ndev, e->addr); | 4575 | wl_inform_ibss(cfg, ndev, e->addr); |
| 4749 | cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); | 4576 | cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); |
| 4750 | clear_bit(WL_STATUS_CONNECTING, &cfg->status); | 4577 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, |
| 4751 | set_bit(WL_STATUS_CONNECTED, &cfg->status); | 4578 | &ifp->vif->sme_state); |
| 4579 | set_bit(BRCMF_VIF_STATUS_CONNECTED, | ||
| 4580 | &ifp->vif->sme_state); | ||
| 4752 | } else | 4581 | } else |
| 4753 | brcmf_bss_connect_done(cfg, ndev, e, true); | 4582 | brcmf_bss_connect_done(cfg, ndev, e, true); |
| 4754 | } else if (brcmf_is_linkdown(cfg, e)) { | 4583 | } else if (brcmf_is_linkdown(cfg, e)) { |
| 4755 | WL_CONN("Linkdown\n"); | 4584 | WL_CONN("Linkdown\n"); |
| 4756 | if (brcmf_is_ibssmode(cfg)) { | 4585 | if (brcmf_is_ibssmode(cfg)) { |
| 4757 | clear_bit(WL_STATUS_CONNECTING, &cfg->status); | 4586 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, |
| 4758 | if (test_and_clear_bit(WL_STATUS_CONNECTED, | 4587 | &ifp->vif->sme_state); |
| 4759 | &cfg->status)) | 4588 | if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, |
| 4589 | &ifp->vif->sme_state)) | ||
| 4760 | brcmf_link_down(cfg); | 4590 | brcmf_link_down(cfg); |
| 4761 | } else { | 4591 | } else { |
| 4762 | brcmf_bss_connect_done(cfg, ndev, e, false); | 4592 | brcmf_bss_connect_done(cfg, ndev, e, false); |
| 4763 | if (test_and_clear_bit(WL_STATUS_CONNECTED, | 4593 | if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, |
| 4764 | &cfg->status)) { | 4594 | &ifp->vif->sme_state)) { |
| 4765 | cfg80211_disconnected(ndev, 0, NULL, 0, | 4595 | cfg80211_disconnected(ndev, 0, NULL, 0, |
| 4766 | GFP_KERNEL); | 4596 | GFP_KERNEL); |
| 4767 | brcmf_link_down(cfg); | 4597 | brcmf_link_down(cfg); |
| 4768 | } | 4598 | } |
| 4769 | } | 4599 | } |
| 4770 | brcmf_init_prof(cfg->profile); | 4600 | brcmf_init_prof(ndev_to_prof(ndev)); |
| 4771 | } else if (brcmf_is_nonetwork(cfg, e)) { | 4601 | } else if (brcmf_is_nonetwork(cfg, e)) { |
| 4772 | if (brcmf_is_ibssmode(cfg)) | 4602 | if (brcmf_is_ibssmode(cfg)) |
| 4773 | clear_bit(WL_STATUS_CONNECTING, &cfg->status); | 4603 | clear_bit(BRCMF_VIF_STATUS_CONNECTING, |
| 4604 | &ifp->vif->sme_state); | ||
| 4774 | else | 4605 | else |
| 4775 | brcmf_bss_connect_done(cfg, ndev, e, false); | 4606 | brcmf_bss_connect_done(cfg, ndev, e, false); |
| 4776 | } | 4607 | } |
| @@ -4783,12 +4614,13 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, · 6 unmodified lines | |||
| 4783 | struct net_device *ndev, | 4614 | struct net_device *ndev, |
| 4784 | const struct brcmf_event_msg *e, void *data) | 4615 | const struct brcmf_event_msg *e, void *data) |
| 4785 | { | 4616 | { |
| 4617 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 4786 | s32 err = 0; | 4618 | s32 err = 0; |
| 4787 | u32 event = be32_to_cpu(e->event_type); | 4619 | u32 event = be32_to_cpu(e->event_type); |
| 4788 | u32 status = be32_to_cpu(e->status); | 4620 | u32 status = be32_to_cpu(e->status); |
| 4789 | 4621 | ||
| 4790 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { | 4622 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { |
| 4791 | if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) | 4623 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) |
| 4792 | brcmf_bss_roaming_done(cfg, ndev, e); | 4624 | brcmf_bss_roaming_done(cfg, ndev, e); |
| 4793 | else | 4625 | else |
| 4794 | brcmf_bss_connect_done(cfg, ndev, e, true); | 4626 | brcmf_bss_connect_done(cfg, ndev, e, true); |
| @@ -4821,6 +4653,7 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, · 26 unmodified lines | |||
| 4821 | struct net_device *ndev, | 4653 | struct net_device *ndev, |
| 4822 | const struct brcmf_event_msg *e, void *data) | 4654 | const struct brcmf_event_msg *e, void *data) |
| 4823 | { | 4655 | { |
| 4656 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 4824 | struct brcmf_channel_info_le channel_inform_le; | 4657 | struct brcmf_channel_info_le channel_inform_le; |
| 4825 | struct brcmf_scan_results_le *bss_list_le; | 4658 | struct brcmf_scan_results_le *bss_list_le; |
| 4826 | u32 len = WL_SCAN_BUF_MAX; | 4659 | u32 len = WL_SCAN_BUF_MAX; |
| @@ -4835,15 +4668,16 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, · 8 unmodified lines | |||
| 4835 | return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); | 4668 | return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); |
| 4836 | } | 4669 | } |
| 4837 | 4670 | ||
| 4838 | if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) { | 4671 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
| 4839 | WL_ERR("Scan complete while device not scanning\n"); | 4672 | WL_ERR("Scan complete while device not scanning\n"); |
| 4840 | scan_abort = true; | 4673 | scan_abort = true; |
| 4841 | err = -EINVAL; | 4674 | err = -EINVAL; |
| 4842 | goto scan_done_out; | 4675 | goto scan_done_out; |
| 4843 | } | 4676 | } |
| 4844 | 4677 | ||
| 4845 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le, | 4678 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, |
| 4846 | sizeof(channel_inform_le)); | 4679 | &channel_inform_le, |
| 4680 | sizeof(channel_inform_le)); | ||
| 4847 | if (err) { | 4681 | if (err) { |
| 4848 | WL_ERR("scan busy (%d)\n", err); | 4682 | WL_ERR("scan busy (%d)\n", err); |
| 4849 | scan_abort = true; | 4683 | scan_abort = true; |
| @@ -4857,8 +4691,8 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, · 7 unmodified lines | |||
| 4857 | 4691 | ||
| 4858 | memset(cfg->scan_results, 0, len); | 4692 | memset(cfg->scan_results, 0, len); |
| 4859 | bss_list_le->buflen = cpu_to_le32(len); | 4693 | bss_list_le->buflen = cpu_to_le32(len); |
| 4860 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS, | 4694 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS, |
| 4861 | cfg->scan_results, len); | 4695 | cfg->scan_results, len); |
| 4862 | if (err) { | 4696 | if (err) { |
| 4863 | WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); | 4697 | WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); |
| 4864 | err = -EINVAL; | 4698 | err = -EINVAL; |
| @@ -4920,8 +4754,6 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) · 55 unmodified lines | |||
| 4920 | cfg->bss_info = NULL; | 4754 | cfg->bss_info = NULL; |
| 4921 | kfree(cfg->conf); | 4755 | kfree(cfg->conf); |
| 4922 | cfg->conf = NULL; | 4756 | cfg->conf = NULL; |
| 4923 | kfree(cfg->profile); | ||
| 4924 | cfg->profile = NULL; | ||
| 4925 | kfree(cfg->scan_req_int); | 4757 | kfree(cfg->scan_req_int); |
| 4926 | cfg->scan_req_int = NULL; | 4758 | cfg->scan_req_int = NULL; |
| 4927 | kfree(cfg->escan_ioctl_buf); | 4759 | kfree(cfg->escan_ioctl_buf); |
| @@ -4950,9 +4782,6 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) · 22 unmodified lines | |||
| 4950 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); | 4782 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); |
| 4951 | if (!cfg->conf) | 4783 | if (!cfg->conf) |
| 4952 | goto init_priv_mem_out; | 4784 | goto init_priv_mem_out; |
| 4953 | cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL); | ||
| 4954 | if (!cfg->profile) | ||
| 4955 | goto init_priv_mem_out; | ||
| 4956 | cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); | 4785 | cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); |
| 4957 | if (!cfg->bss_info) | 4786 | if (!cfg->bss_info) |
| 4958 | goto init_priv_mem_out; | 4787 | goto init_priv_mem_out; |
| @@ -5129,7 +4958,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) · 170 unmodified lines | |||
| 5129 | return err; | 4958 | return err; |
| 5130 | brcmf_init_escan(cfg); | 4959 | brcmf_init_escan(cfg); |
| 5131 | brcmf_init_conf(cfg->conf); | 4960 | brcmf_init_conf(cfg->conf); |
| 5132 | brcmf_init_prof(cfg->profile); | ||
| 5133 | brcmf_link_down(cfg); | 4961 | brcmf_link_down(cfg); |
| 5134 | 4962 | ||
| 5135 | return err; | 4963 | return err; |
| @@ -5145,12 +4973,14 @@ static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) · 9 unmodified lines | |||
| 5145 | brcmf_deinit_priv_mem(cfg); | 4973 | brcmf_deinit_priv_mem(cfg); |
| 5146 | } | 4974 | } |
| 5147 | 4975 | ||
| 5148 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev, | 4976 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr) |
| 5149 | struct device *busdev, | ||
| 5150 | struct brcmf_pub *drvr) | ||
| 5151 | { | 4977 | { |
| 5152 | struct wireless_dev *wdev; | 4978 | struct net_device *ndev = drvr->iflist[0]->ndev; |
| 4979 | struct device *busdev = drvr->dev; | ||
| 5153 | struct brcmf_cfg80211_info *cfg; | 4980 | struct brcmf_cfg80211_info *cfg; |
| 4981 | struct wiphy *wiphy; | ||
| 4982 | struct brcmf_cfg80211_vif *vif; | ||
| 4983 | struct brcmf_if *ifp; | ||
| 5154 | s32 err = 0; | 4984 | s32 err = 0; |
| 5155 | 4985 | ||
| 5156 | if (!ndev) { | 4986 | if (!ndev) { |
| @@ -5158,35 +4988,45 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev, · 1 unmodified line | |||
| 5158 | return NULL; | 4988 | return NULL; |
| 5159 | } | 4989 | } |
| 5160 | 4990 | ||
| 5161 | wdev = brcmf_alloc_wdev(busdev); | 4991 | ifp = netdev_priv(ndev); |
| 5162 | if (IS_ERR(wdev)) { | 4992 | wiphy = brcmf_setup_wiphy(busdev); |
| 4993 | if (IS_ERR(wiphy)) | ||
| 5163 | return NULL; | 4994 | return NULL; |
| 5164 | } | ||
| 5165 | 4995 | ||
| 5166 | wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); | 4996 | cfg = wiphy_priv(wiphy); |
| 5167 | cfg = wdev_to_cfg(wdev); | 4997 | cfg->wiphy = wiphy; |
| 5168 | cfg->wdev = wdev; | ||
| 5169 | cfg->pub = drvr; | 4998 | cfg->pub = drvr; |
| 5170 | ndev->ieee80211_ptr = wdev; | 4999 | INIT_LIST_HEAD(&cfg->vif_list); |
| 5171 | SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); | 5000 | |
| 5172 | wdev->netdev = ndev; | 5001 | vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false); |
| 5002 | if (IS_ERR(vif)) { | ||
| 5003 | wiphy_free(wiphy); | ||
| 5004 | return NULL; | ||
| 5005 | } | ||
| 5006 | |||
| 5173 | err = wl_init_priv(cfg); | 5007 | err = wl_init_priv(cfg); |
| 5174 | if (err) { | 5008 | if (err) { |
| 5175 | WL_ERR("Failed to init iwm_priv (%d)\n", err); | 5009 | WL_ERR("Failed to init iwm_priv (%d)\n", err); |
| 5176 | goto cfg80211_attach_out; | 5010 | goto cfg80211_attach_out; |
| 5177 | } | 5011 | } |
| 5178 | 5012 | ||
| 5013 | ifp->vif = vif; | ||
| 5179 | return cfg; | 5014 | return cfg; |
| 5180 | 5015 | ||
| 5181 | cfg80211_attach_out: | 5016 | cfg80211_attach_out: |
| 5182 | brcmf_free_wdev(cfg); | 5017 | brcmf_free_vif(vif); |
| 5183 | return NULL; | 5018 | return NULL; |
| 5184 | } | 5019 | } |
| 5185 | 5020 | ||
| 5186 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | 5021 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) |
| 5187 | { | 5022 | { |
| 5023 | struct brcmf_cfg80211_vif *vif; | ||
| 5024 | struct brcmf_cfg80211_vif *tmp; | ||
| 5025 | |||
| 5188 | wl_deinit_priv(cfg); | 5026 | wl_deinit_priv(cfg); |
| 5189 | brcmf_free_wdev(cfg); | 5027 | list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { |
| 5028 | brcmf_free_vif(vif); | ||
| 5029 | } | ||
| 5190 | } | 5030 | } |
| 5191 | 5031 | ||
| 5192 | void | 5032 | void |
| @@ -5202,22 +5042,18 @@ brcmf_cfg80211_event(struct net_device *ndev, · 9 unmodified lines | |||
| 5202 | 5042 | ||
| 5203 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) | 5043 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) |
| 5204 | { | 5044 | { |
| 5205 | /* Room for "event_msgs" + '\0' + bitvec */ | ||
| 5206 | s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; | ||
| 5207 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | 5045 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; |
| 5208 | s32 err = 0; | 5046 | s32 err = 0; |
| 5209 | 5047 | ||
| 5210 | WL_TRACE("Enter\n"); | 5048 | WL_TRACE("Enter\n"); |
| 5211 | 5049 | ||
| 5212 | /* Setup event_msgs */ | 5050 | /* Setup event_msgs */ |
| 5213 | brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, | 5051 | err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs", |
| 5214 | iovbuf, sizeof(iovbuf)); | 5052 | eventmask, BRCMF_EVENTING_MASK_LEN); |
| 5215 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf)); | ||
| 5216 | if (err) { | 5053 | if (err) { |
| 5217 | WL_ERR("Get event_msgs error (%d)\n", err); | 5054 | WL_ERR("Get event_msgs error (%d)\n", err); |
| 5218 | goto dongle_eventmsg_out; | 5055 | goto dongle_eventmsg_out; |
| 5219 | } | 5056 | } |
| 5220 | memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); | ||
| 5221 | 5057 | ||
| 5222 | setbit(eventmask, BRCMF_E_SET_SSID); | 5058 | setbit(eventmask, BRCMF_E_SET_SSID); |
| 5223 | setbit(eventmask, BRCMF_E_ROAM); | 5059 | setbit(eventmask, BRCMF_E_ROAM); |
| @@ -5241,9 +5077,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev) · 17 unmodified lines | |||
| 5241 | setbit(eventmask, BRCMF_E_ESCAN_RESULT); | 5077 | setbit(eventmask, BRCMF_E_ESCAN_RESULT); |
| 5242 | setbit(eventmask, BRCMF_E_PFN_NET_FOUND); | 5078 | setbit(eventmask, BRCMF_E_PFN_NET_FOUND); |
| 5243 | 5079 | ||
| 5244 | brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, | 5080 | err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs", |
| 5245 | iovbuf, sizeof(iovbuf)); | 5081 | eventmask, BRCMF_EVENTING_MASK_LEN); |
| 5246 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); | ||
| 5247 | if (err) { | 5082 | if (err) { |
| 5248 | WL_ERR("Set event_msgs error (%d)\n", err); | 5083 | WL_ERR("Set event_msgs error (%d)\n", err); |
| 5249 | goto dongle_eventmsg_out; | 5084 | goto dongle_eventmsg_out; |
| @@ -5257,23 +5092,17 @@ dongle_eventmsg_out: · 7 unmodified lines | |||
| 5257 | static s32 | 5092 | static s32 |
| 5258 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) | 5093 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) |
| 5259 | { | 5094 | { |
| 5260 | s8 iovbuf[32]; | 5095 | struct brcmf_if *ifp = netdev_priv(ndev); |
| 5261 | s32 err = 0; | 5096 | s32 err = 0; |
| 5262 | __le32 roamtrigger[2]; | 5097 | __le32 roamtrigger[2]; |
| 5263 | __le32 roam_delta[2]; | 5098 | __le32 roam_delta[2]; |
| 5264 | __le32 bcn_to_le; | ||
| 5265 | __le32 roamvar_le; | ||
| 5266 | 5099 | ||
| 5267 | /* | 5100 | /* |
| 5268 | * Setup timeout if Beacons are lost and roam is | 5101 | * Setup timeout if Beacons are lost and roam is |
| 5269 | * off to report link down | 5102 | * off to report link down |
| 5270 | */ | 5103 | */ |
| 5271 | if (roamvar) { | 5104 | if (roamvar) { |
| 5272 | bcn_to_le = cpu_to_le32(bcn_timeout); | 5105 | err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); |
| 5273 | brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le, | ||
| 5274 | sizeof(bcn_to_le), iovbuf, sizeof(iovbuf)); | ||
| 5275 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, | ||
| 5276 | iovbuf, sizeof(iovbuf)); | ||
| 5277 | if (err) { | 5106 | if (err) { |
| 5278 | WL_ERR("bcn_timeout error (%d)\n", err); | 5107 | WL_ERR("bcn_timeout error (%d)\n", err); |
| 5279 | goto dongle_rom_out; | 5108 | goto dongle_rom_out; |
| @@ -5285,10 +5114,7 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) · 5 unmodified lines | |||
| 5285 | * to take care of roaming | 5114 | * to take care of roaming |
| 5286 | */ | 5115 | */ |
| 5287 | WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On"); | 5116 | WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On"); |
| 5288 | roamvar_le = cpu_to_le32(roamvar); | 5117 | err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar); |
| 5289 | brcmf_c_mkiovar("roam_off", (char *)&roamvar_le, | ||
| 5290 | sizeof(roamvar_le), iovbuf, sizeof(iovbuf)); | ||
| 5291 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); | ||
| 5292 | if (err) { | 5118 | if (err) { |
| 5293 | WL_ERR("roam_off error (%d)\n", err); | 5119 | WL_ERR("roam_off error (%d)\n", err); |
| 5294 | goto dongle_rom_out; | 5120 | goto dongle_rom_out; |
| @@ -5296,8 +5122,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) · 1 unmodified line | |||
| 5296 | 5122 | ||
| 5297 | roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL); | 5123 | roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL); |
| 5298 | roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL); | 5124 | roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL); |
| 5299 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER, | 5125 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER, |
| 5300 | (void *)roamtrigger, sizeof(roamtrigger)); | 5126 | (void *)roamtrigger, sizeof(roamtrigger)); |
| 5301 | if (err) { | 5127 | if (err) { |
| 5302 | WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err); | 5128 | WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err); |
| 5303 | goto dongle_rom_out; | 5129 | goto dongle_rom_out; |
| @@ -5305,8 +5131,8 @@ brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) · 1 unmodified line | |||
| 5305 | 5131 | ||
| 5306 | roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA); | 5132 | roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA); |
| 5307 | roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL); | 5133 | roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL); |
| 5308 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA, | 5134 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA, |
| 5309 | (void *)roam_delta, sizeof(roam_delta)); | 5135 | (void *)roam_delta, sizeof(roam_delta)); |
| 5310 | if (err) { | 5136 | if (err) { |
| 5311 | WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err); | 5137 | WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err); |
| 5312 | goto dongle_rom_out; | 5138 | goto dongle_rom_out; |
| @@ -5320,13 +5146,11 @@ static s32 · 7 unmodified lines | |||
| 5320 | brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, | 5146 | brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, |
| 5321 | s32 scan_unassoc_time, s32 scan_passive_time) | 5147 | s32 scan_unassoc_time, s32 scan_passive_time) |
| 5322 | { | 5148 | { |
| 5149 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 5323 | s32 err = 0; | 5150 | s32 err = 0; |
| 5324 | __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time); | ||
| 5325 | __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time); | ||
| 5326 | __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time); | ||
| 5327 | 5151 | ||
| 5328 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME, | 5152 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, |
| 5329 | &scan_assoc_tm_le, sizeof(scan_assoc_tm_le)); | 5153 | scan_assoc_time); |
| 5330 | if (err) { | 5154 | if (err) { |
| 5331 | if (err == -EOPNOTSUPP) | 5155 | if (err == -EOPNOTSUPP) |
| 5332 | WL_INFO("Scan assoc time is not supported\n"); | 5156 | WL_INFO("Scan assoc time is not supported\n"); |
| @@ -5334,8 +5158,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, · 1 unmodified line | |||
| 5334 | WL_ERR("Scan assoc time error (%d)\n", err); | 5158 | WL_ERR("Scan assoc time error (%d)\n", err); |
| 5335 | goto dongle_scantime_out; | 5159 | goto dongle_scantime_out; |
| 5336 | } | 5160 | } |
| 5337 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME, | 5161 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, |
| 5338 | &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le)); | 5162 | scan_unassoc_time); |
| 5339 | if (err) { | 5163 | if (err) { |
| 5340 | if (err == -EOPNOTSUPP) | 5164 | if (err == -EOPNOTSUPP) |
| 5341 | WL_INFO("Scan unassoc time is not supported\n"); | 5165 | WL_INFO("Scan unassoc time is not supported\n"); |
| @@ -5344,8 +5168,8 @@ brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, · 2 unmodified lines | |||
| 5344 | goto dongle_scantime_out; | 5168 | goto dongle_scantime_out; |
| 5345 | } | 5169 | } |
| 5346 | 5170 | ||
| 5347 | err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME, | 5171 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME, |
| 5348 | &scan_passive_tm_le, sizeof(scan_passive_tm_le)); | 5172 | scan_passive_time); |
| 5349 | if (err) { | 5173 | if (err) { |
| 5350 | if (err == -EOPNOTSUPP) | 5174 | if (err == -EOPNOTSUPP) |
| 5351 | WL_INFO("Scan passive time is not supported\n"); | 5175 | WL_INFO("Scan passive time is not supported\n"); |
| @@ -5360,13 +5184,14 @@ dongle_scantime_out: · 8 unmodified lines | |||
| 5360 | 5184 | ||
| 5361 | static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) | 5185 | static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) |
| 5362 | { | 5186 | { |
| 5187 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
| 5363 | struct wiphy *wiphy; | 5188 | struct wiphy *wiphy; |
| 5364 | s32 phy_list; | 5189 | s32 phy_list; |
| 5365 | s8 phy; | 5190 | s8 phy; |
| 5366 | s32 err = 0; | 5191 | s32 err = 0; |
| 5367 | 5192 | ||
| 5368 | err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST, | 5193 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST, |
| 5369 | &phy_list, sizeof(phy_list)); | 5194 | &phy_list, sizeof(phy_list)); |
| 5370 | if (err) { | 5195 | if (err) { |
| 5371 | WL_ERR("error (%d)\n", err); | 5196 | WL_ERR("error (%d)\n", err); |
| 5372 | return err; | 5197 | return err; |
| @@ -5408,7 +5233,8 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) · 35 unmodified lines | |||
| 5408 | goto default_conf_out; | 5233 | goto default_conf_out; |
| 5409 | 5234 | ||
| 5410 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; | 5235 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; |
| 5411 | err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode); | 5236 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, |
| 5237 | power_mode); | ||
| 5412 | if (err) | 5238 | if (err) |
| 5413 | goto default_conf_out; | 5239 | goto default_conf_out; |
| 5414 | WL_INFO("power save set to %s\n", | 5240 | WL_INFO("power save set to %s\n", |
| @@ -5436,47 +5262,12 @@ default_conf_out: · 21 unmodified lines | |||
| 5436 | 5262 | ||
| 5437 | } | 5263 | } |
| 5438 | 5264 | ||
| 5439 | static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg) | ||
| 5440 | { | ||
| 5441 | char buf[10+IFNAMSIZ]; | ||
| 5442 | struct dentry *fd; | ||
| 5443 | s32 err = 0; | ||
| 5444 | |||
| 5445 | sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name); | ||
| 5446 | cfg->debugfsdir = debugfs_create_dir(buf, | ||
| 5447 | cfg_to_wiphy(cfg)->debugfsdir); | ||
| 5448 | |||
| 5449 | fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir, | ||
| 5450 | (u16 *)&cfg->profile->beacon_interval); | ||
| 5451 | if (!fd) { | ||
| 5452 | err = -ENOMEM; | ||
| 5453 | goto err_out; | ||
| 5454 | } | ||
| 5455 | |||
| 5456 | fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir, | ||
| 5457 | (u8 *)&cfg->profile->dtim_period); | ||
| 5458 | if (!fd) { | ||
| 5459 | err = -ENOMEM; | ||
| 5460 | goto err_out; | ||
| 5461 | } | ||
| 5462 | |||
| 5463 | err_out: | ||
| 5464 | return err; | ||
| 5465 | } | ||
| 5466 | |||
| 5467 | static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg) | ||
| 5468 | { | ||
| 5469 | debugfs_remove_recursive(cfg->debugfsdir); | ||
| 5470 | cfg->debugfsdir = NULL; | ||
| 5471 | } | ||
| 5472 | |||
| 5473 | static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) | 5265 | static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) |
| 5474 | { | 5266 | { |
| 5267 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
| 5475 | s32 err = 0; | 5268 | s32 err = 0; |
| 5476 | 5269 | ||
| 5477 | set_bit(WL_STATUS_READY, &cfg->status); | 5270 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); |
| 5478 | |||
| 5479 | brcmf_debugfs_add_netdev_params(cfg); | ||
| 5480 | 5271 | ||
| 5481 | err = brcmf_config_dongle(cfg); | 5272 | err = brcmf_config_dongle(cfg); |
| 5482 | if (err) | 5273 | if (err) |
| @@ -5489,13 +5280,16 @@ static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) · 6 unmodified lines | |||
| 5489 | 5280 | ||
| 5490 | static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | 5281 | static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) |
| 5491 | { | 5282 | { |
| 5283 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
| 5284 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
| 5285 | |||
| 5492 | /* | 5286 | /* |
| 5493 | * While going down, if associated with AP disassociate | 5287 | * While going down, if associated with AP disassociate |
| 5494 | * from AP to save power | 5288 | * from AP to save power |
| 5495 | */ | 5289 | */ |
| 5496 | if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) || | 5290 | if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) || |
| 5497 | test_bit(WL_STATUS_CONNECTING, &cfg->status)) && | 5291 | test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) && |
| 5498 | test_bit(WL_STATUS_READY, &cfg->status)) { | 5292 | check_vif_up(ifp->vif)) { |
| 5499 | WL_INFO("Disassociating from AP"); | 5293 | WL_INFO("Disassociating from AP"); |
| 5500 | brcmf_link_down(cfg); | 5294 | brcmf_link_down(cfg); |
| 5501 | 5295 | ||
| @@ -5507,9 +5301,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) · 5 unmodified lines | |||
| 5507 | } | 5301 | } |
| 5508 | 5302 | ||
| 5509 | brcmf_abort_scanning(cfg); | 5303 | brcmf_abort_scanning(cfg); |
| 5510 | clear_bit(WL_STATUS_READY, &cfg->status); | 5304 | clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); |
| 5511 | |||
| 5512 | brcmf_debugfs_remove_netdev(cfg); | ||
| 5513 | 5305 | ||
| 5514 | return 0; | 5306 | return 0; |
| 5515 | } | 5307 | } |
| @@ -127,15 +127,15 @@ do { \ · 126 unmodified lines | |||
| 127 | #define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ | 127 | #define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ |
| 128 | #define IE_MAX_LEN 512 | 128 | #define IE_MAX_LEN 512 |
| 129 | 129 | ||
| 130 | /* dongle status */ | 130 | /** |
| 131 | enum wl_status { | 131 | * enum brcmf_scan_status - dongle scan status |
| 132 | WL_STATUS_READY, | 132 | * |
| 133 | WL_STATUS_SCANNING, | 133 | * @BRCMF_SCAN_STATUS_BUSY: scanning in progress on dongle. |
| 134 | WL_STATUS_SCAN_ABORTING, | 134 | * @BRCMF_SCAN_STATUS_ABORT: scan being aborted on dongle. |
| 135 | WL_STATUS_CONNECTING, | 135 | */ |
| 136 | WL_STATUS_CONNECTED, | 136 | enum brcmf_scan_status { |
| 137 | WL_STATUS_AP_CREATING, | 137 | BRCMF_SCAN_STATUS_BUSY, |
| 138 | WL_STATUS_AP_CREATED | 138 | BRCMF_SCAN_STATUS_ABORT, |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | /* wi-fi mode */ | 141 | /* wi-fi mode */ |
| @@ -145,19 +145,6 @@ enum wl_mode { · 3 unmodified lines | |||
| 145 | WL_MODE_AP | 145 | WL_MODE_AP |
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | /* dongle profile list */ | ||
| 149 | enum wl_prof_list { | ||
| 150 | WL_PROF_MODE, | ||
| 151 | WL_PROF_SSID, | ||
| 152 | WL_PROF_SEC, | ||
| 153 | WL_PROF_IBSS, | ||
| 154 | WL_PROF_BAND, | ||
| 155 | WL_PROF_BSSID, | ||
| 156 | WL_PROF_ACT, | ||
| 157 | WL_PROF_BEACONINT, | ||
| 158 | WL_PROF_DTIMPERIOD | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* dongle iscan state */ | 148 | /* dongle iscan state */ |
| 162 | enum wl_iscan_state { | 149 | enum wl_iscan_state { |
| 163 | WL_ISCAN_STATE_IDLE, | 150 | WL_ISCAN_STATE_IDLE, |
| @@ -214,25 +201,73 @@ struct brcmf_cfg80211_security { · 50 unmodified lines | |||
| 214 | u32 wpa_auth; | 201 | u32 wpa_auth; |
| 215 | }; | 202 | }; |
| 216 | 203 | ||
| 217 | /* ibss information for currently joined ibss network */ | 204 | /** |
| 218 | struct brcmf_cfg80211_ibss { | 205 | * struct brcmf_cfg80211_profile - profile information. |
| 219 | u8 beacon_interval; /* in millisecond */ | 206 | * |
| 220 | u8 atim; /* in millisecond */ | 207 | * @ssid: ssid of associated/associating ap. |
| 221 | s8 join_only; | 208 | * @bssid: bssid of joined/joining ibss. |
| 222 | u8 band; | 209 | * @sec: security information. |
| 223 | u8 channel; | 210 | */ |
| 224 | }; | ||
| 225 | |||
| 226 | /* dongle profile */ | ||
| 227 | struct brcmf_cfg80211_profile { | 211 | struct brcmf_cfg80211_profile { |
| 228 | u32 mode; | ||
| 229 | struct brcmf_ssid ssid; | 212 | struct brcmf_ssid ssid; |
| 230 | u8 bssid[ETH_ALEN]; | 213 | u8 bssid[ETH_ALEN]; |
| 231 | u16 beacon_interval; | ||
| 232 | u8 dtim_period; | ||
| 233 | struct brcmf_cfg80211_security sec; | 214 | struct brcmf_cfg80211_security sec; |
| 234 | struct brcmf_cfg80211_ibss ibss; | 215 | }; |
| 235 | s32 band; | 216 | |
| 217 | /** | ||
| 218 | * enum brcmf_vif_status - bit indices for vif status. | ||
| 219 | * | ||
| 220 | * @BRCMF_VIF_STATUS_READY: ready for operation. | ||
| 221 | * @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress. | ||
| 222 | * @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully. | ||
| 223 | * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation. | ||
| 224 | * @BRCMF_VIF_STATUS_AP_CREATED: AP operation started. | ||
| 225 | */ | ||
| 226 | enum brcmf_vif_status { | ||
| 227 | BRCMF_VIF_STATUS_READY, | ||
| 228 | BRCMF_VIF_STATUS_CONNECTING, | ||
| 229 | BRCMF_VIF_STATUS_CONNECTED, | ||
| 230 | BRCMF_VIF_STATUS_AP_CREATING, | ||
| 231 | BRCMF_VIF_STATUS_AP_CREATED | ||
| 232 | }; | ||
| 233 | |||
| 234 | /** | ||
| 235 | * struct vif_saved_ie - holds saved IEs for a virtual interface. | ||
| 236 | * | ||
| 237 | * @probe_res_ie: IE info for probe response. | ||
| 238 | * @beacon_ie: IE info for beacon frame. | ||
| 239 | * @probe_res_ie_len: IE info length for probe response. | ||
| 240 | * @beacon_ie_len: IE info length for beacon frame. | ||
| 241 | */ | ||
| 242 | struct vif_saved_ie { | ||
| 243 | u8 probe_res_ie[IE_MAX_LEN]; | ||
| 244 | u8 beacon_ie[IE_MAX_LEN]; | ||
| 245 | u32 probe_res_ie_len; | ||
| 246 | u32 beacon_ie_len; | ||
| 247 | }; | ||
| 248 | |||
| 249 | /** | ||
| 250 | * struct brcmf_cfg80211_vif - virtual interface specific information. | ||
| 251 | * | ||
| 252 | * @ifp: lower layer interface pointer | ||
| 253 | * @wdev: wireless device. | ||
| 254 | * @profile: profile information. | ||
| 255 | * @mode: operating mode. | ||
| 256 | * @roam_off: roaming state. | ||
| 257 | * @sme_state: SME state using enum brcmf_vif_status bits. | ||
| 258 | * @pm_block: power-management blocked. | ||
| 259 | * @list: linked list. | ||
| 260 | */ | ||
| 261 | struct brcmf_cfg80211_vif { | ||
| 262 | struct brcmf_if *ifp; | ||
| 263 | struct wireless_dev wdev; | ||
| 264 | struct brcmf_cfg80211_profile profile; | ||
| 265 | s32 mode; | ||
| 266 | s32 roam_off; | ||
| 267 | unsigned long sme_state; | ||
| 268 | bool pm_block; | ||
| 269 | struct vif_saved_ie saved_ie; | ||
| 270 | struct list_head list; | ||
| 236 | }; | 271 | }; |
| 237 | 272 | ||
| 238 | /* dongle iscan event loop */ | 273 | /* dongle iscan event loop */ |
| @@ -383,7 +418,7 @@ struct brcmf_pno_scanresults_le { · 144 unmodified lines | |||
| 383 | /** | 418 | /** |
| 384 | * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface | 419 | * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface |
| 385 | * | 420 | * |
| 386 | * @wdev: representing wl cfg80211 device. | 421 | * @wiphy: wiphy object for cfg80211 interface. |
| 387 | * @conf: dongle configuration. | 422 | * @conf: dongle configuration. |
| 388 | * @scan_request: cfg80211 scan request object. | 423 | * @scan_request: cfg80211 scan request object. |
| 389 | * @el: main event loop. | 424 | * @el: main event loop. |
| @@ -395,12 +430,11 @@ struct brcmf_pno_scanresults_le { · 5 unmodified lines | |||
| 395 | * @scan_req_int: internal scan request object. | 430 | * @scan_req_int: internal scan request object. |
| 396 | * @bss_info: bss information for cfg80211 layer. | 431 | * @bss_info: bss information for cfg80211 layer. |
| 397 | * @ie: information element object for internal purpose. | 432 | * @ie: information element object for internal purpose. |
| 398 | * @profile: holding dongle profile. | ||
| 399 | * @iscan: iscan controller information. | 433 | * @iscan: iscan controller information. |
| 400 | * @conn_info: association info. | 434 | * @conn_info: association info. |
| 401 | * @pmk_list: wpa2 pmk list. | 435 | * @pmk_list: wpa2 pmk list. |
| 402 | * @event_work: event handler work struct. | 436 | * @event_work: event handler work struct. |
| 403 | * @status: current dongle status. | 437 | * @scan_status: scan activity on the dongle. |
| 404 | * @pub: common driver information. | 438 | * @pub: common driver information. |
| 405 | * @channel: current channel. | 439 | * @channel: current channel. |
| 406 | * @iscan_on: iscan on/off switch. | 440 | * @iscan_on: iscan on/off switch. |
| @@ -422,10 +456,11 @@ struct brcmf_pno_scanresults_le { · 15 unmodified lines | |||
| 422 | * @escan_timeout_work: scan timeout worker. | 456 | * @escan_timeout_work: scan timeout worker. |
| 423 | * @escan_ioctl_buf: dongle command buffer for escan commands. | 457 | * @escan_ioctl_buf: dongle command buffer for escan commands. |
| 424 | * @ap_info: host ap information. | 458 | * @ap_info: host ap information. |
| 425 | * @ci: used to link this structure to netdev private data. | 459 | * @vif_list: linked list of vif instances. |
| 460 | * @vif_cnt: number of vif instances. | ||
| 426 | */ | 461 | */ |
| 427 | struct brcmf_cfg80211_info { | 462 | struct brcmf_cfg80211_info { |
| 428 | struct wireless_dev *wdev; | 463 | struct wiphy *wiphy; |
| 429 | struct brcmf_cfg80211_conf *conf; | 464 | struct brcmf_cfg80211_conf *conf; |
| 430 | struct cfg80211_scan_request *scan_request; | 465 | struct cfg80211_scan_request *scan_request; |
| 431 | struct brcmf_cfg80211_event_loop el; | 466 | struct brcmf_cfg80211_event_loop el; |
| @@ -437,12 +472,11 @@ struct brcmf_cfg80211_info { · 5 unmodified lines | |||
| 437 | struct brcmf_cfg80211_scan_req *scan_req_int; | 472 | struct brcmf_cfg80211_scan_req *scan_req_int; |
| 438 | struct wl_cfg80211_bss_info *bss_info; | 473 | struct wl_cfg80211_bss_info *bss_info; |
| 439 | struct brcmf_cfg80211_ie ie; | 474 | struct brcmf_cfg80211_ie ie; |
| 440 | struct brcmf_cfg80211_profile *profile; | ||
| 441 | struct brcmf_cfg80211_iscan_ctrl *iscan; | 475 | struct brcmf_cfg80211_iscan_ctrl *iscan; |
| 442 | struct brcmf_cfg80211_connect_info conn_info; | 476 | struct brcmf_cfg80211_connect_info conn_info; |
| 443 | struct brcmf_cfg80211_pmk_list *pmk_list; | 477 | struct brcmf_cfg80211_pmk_list *pmk_list; |
| 444 | struct work_struct event_work; | 478 | struct work_struct event_work; |
| 445 | unsigned long status; | 479 | unsigned long scan_status; |
| 446 | struct brcmf_pub *pub; | 480 | struct brcmf_pub *pub; |
| 447 | u32 channel; | 481 | u32 channel; |
| 448 | bool iscan_on; | 482 | bool iscan_on; |
| @@ -464,11 +498,13 @@ struct brcmf_cfg80211_info { · 15 unmodified lines | |||
| 464 | struct work_struct escan_timeout_work; | 498 | struct work_struct escan_timeout_work; |
| 465 | u8 *escan_ioctl_buf; | 499 | u8 *escan_ioctl_buf; |
| 466 | struct ap_info *ap_info; | 500 | struct ap_info *ap_info; |
| 501 | struct list_head vif_list; | ||
| 502 | u8 vif_cnt; | ||
| 467 | }; | 503 | }; |
| 468 | 504 | ||
| 469 | static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w) | 505 | static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg) |
| 470 | { | 506 | { |
| 471 | return w->wdev->wiphy; | 507 | return cfg->wiphy; |
| 472 | } | 508 | } |
| 473 | 509 | ||
| 474 | static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) | 510 | static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) |
| @@ -481,9 +517,12 @@ static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) · 6 unmodified lines | |||
| 481 | return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); | 517 | return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); |
| 482 | } | 518 | } |
| 483 | 519 | ||
| 484 | static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) | 520 | static inline |
| 521 | struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) | ||
| 485 | { | 522 | { |
| 486 | return cfg->wdev->netdev; | 523 | struct brcmf_cfg80211_vif *vif; |
| 524 | vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list); | ||
| 525 | return vif->wdev.netdev; | ||
| 487 | } | 526 | } |
| 488 | 527 | ||
| 489 | static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) | 528 | static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) |
| @@ -491,6 +530,12 @@ static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) · 1 unmodified line | |||
| 491 | return wdev_to_cfg(ndev->ieee80211_ptr); | 530 | return wdev_to_cfg(ndev->ieee80211_ptr); |
| 492 | } | 531 | } |
| 493 | 532 | ||
| 533 | static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd) | ||
| 534 | { | ||
| 535 | struct brcmf_if *ifp = netdev_priv(nd); | ||
| 536 | return &ifp->vif->profile; | ||
| 537 | } | ||
| 538 | |||
| 494 | #define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) | 539 | #define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) |
| 495 | #define cfg_to_iscan(w) (w->iscan) | 540 | #define cfg_to_iscan(w) (w->iscan) |
| 496 | 541 | ||
| @@ -500,9 +545,7 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) · 3 unmodified lines | |||
| 500 | return &cfg->conn_info; | 545 | return &cfg->conn_info; |
| 501 | } | 546 | } |
| 502 | 547 | ||
| 503 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev, | 548 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); |
| 504 | struct device *busdev, | ||
| 505 | struct brcmf_pub *drvr); | ||
| 506 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | 549 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); |
| 507 | 550 | ||
| 508 | /* event handler from dongle */ | 551 | /* event handler from dongle */ |
| @@ -692,7 +692,7 @@ void ai_pci_up(struct si_pub *sih) · 691 unmodified lines | |||
| 692 | sii = container_of(sih, struct si_info, pub); | 692 | sii = container_of(sih, struct si_info, pub); |
| 693 | 693 | ||
| 694 | if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) | 694 | if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) |
| 695 | bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true); | 695 | bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true); |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | /* Unconfigure and/or apply various WARs when going down */ | 698 | /* Unconfigure and/or apply various WARs when going down */ |
| @@ -703,7 +703,7 @@ void ai_pci_down(struct si_pub *sih) · 4 unmodified lines | |||
| 703 | sii = container_of(sih, struct si_info, pub); | 703 | sii = container_of(sih, struct si_info, pub); |
| 704 | 704 | ||
| 705 | if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) | 705 | if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI) |
| 706 | bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false); | 706 | bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | /* Enable BT-COEX & Ex-PA for 4313 */ | 709 | /* Enable BT-COEX & Ex-PA for 4313 */ |
| @@ -5077,7 +5077,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) · 5076 unmodified lines | |||
| 5077 | * Configure pci/pcmcia here instead of in brcms_c_attach() | 5077 | * Configure pci/pcmcia here instead of in brcms_c_attach() |
| 5078 | * to allow mfg hotswap: down, hotswap (chip power cycle), up. | 5078 | * to allow mfg hotswap: down, hotswap (chip power cycle), up. |
| 5079 | */ | 5079 | */ |
| 5080 | bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core, | 5080 | bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, |
| 5081 | true); | 5081 | true); |
| 5082 | 5082 | ||
| 5083 | /* | 5083 | /* |
| @@ -415,7 +415,7 @@ static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb, · 414 unmodified lines | |||
| 415 | ssid = pos + 2; | 415 | ssid = pos + 2; |
| 416 | ssid_len = pos[1]; | 416 | ssid_len = pos[1]; |
| 417 | break; | 417 | break; |
| 418 | case WLAN_EID_GENERIC: | 418 | case WLAN_EID_VENDOR_SPECIFIC: |
| 419 | if (pos[1] >= 4 && | 419 | if (pos[1] >= 4 && |
| 420 | pos[2] == 0x00 && pos[3] == 0x50 && | 420 | pos[2] == 0x00 && pos[3] == 0x50 && |
| 421 | pos[4] == 0xf2 && pos[5] == 1) { | 421 | pos[4] == 0xf2 && pos[5] == 1) { |
| @@ -1108,7 +1108,7 @@ static const char *get_info_element_string(u16 id) · 1107 unmodified lines | |||
| 1108 | MFIE_STRING(ERP_INFO); | 1108 | MFIE_STRING(ERP_INFO); |
| 1109 | MFIE_STRING(RSN); | 1109 | MFIE_STRING(RSN); |
| 1110 | MFIE_STRING(EXT_SUPP_RATES); | 1110 | MFIE_STRING(EXT_SUPP_RATES); |
| 1111 | MFIE_STRING(GENERIC); | 1111 | MFIE_STRING(VENDOR_SPECIFIC); |
| 1112 | MFIE_STRING(QOS_PARAMETER); | 1112 | MFIE_STRING(QOS_PARAMETER); |
| 1113 | default: | 1113 | default: |
| 1114 | return "UNKNOWN"; | 1114 | return "UNKNOWN"; |
| @@ -1248,8 +1248,8 @@ static int libipw_parse_info_param(struct libipw_info_element · 133 unmodified lines | |||
| 1248 | LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n"); | 1248 | LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n"); |
| 1249 | break; | 1249 | break; |
| 1250 | 1250 | ||
| 1251 | case WLAN_EID_GENERIC: | 1251 | case WLAN_EID_VENDOR_SPECIFIC: |
| 1252 | LIBIPW_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n", | 1252 | LIBIPW_DEBUG_MGMT("WLAN_EID_VENDOR_SPECIFIC: %d bytes\n", |
| 1253 | info_element->len); | 1253 | info_element->len); |
| 1254 | if (!libipw_parse_qos_info_param_IE(info_element, | 1254 | if (!libipw_parse_qos_info_param_IE(info_element, |
| 1255 | network)) | 1255 | network)) |
| @@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv) · 1190 unmodified lines | |||
| 1191 | 1191 | ||
| 1192 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | 1192 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) |
| 1193 | { | 1193 | { |
| 1194 | u16 radio_cfg; | ||
| 1195 | |||
| 1196 | priv->eeprom_data->sku = priv->eeprom_data->sku; | 1194 | priv->eeprom_data->sku = priv->eeprom_data->sku; |
| 1197 | 1195 | ||
| 1198 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && | 1196 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && |
| @@ -1208,8 +1206,6 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) · 9 unmodified lines | |||
| 1208 | 1206 | ||
| 1209 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); | 1207 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); |
| 1210 | 1208 | ||
| 1211 | radio_cfg = priv->eeprom_data->radio_cfg; | ||
| 1212 | |||
| 1213 | priv->hw_params.tx_chains_num = | 1209 | priv->hw_params.tx_chains_num = |
| 1214 | num_of_ant(priv->eeprom_data->valid_tx_ant); | 1210 | num_of_ant(priv->eeprom_data->valid_tx_ant); |
| 1215 | if (priv->cfg->rx_with_siso_diversity) | 1211 | if (priv->cfg->rx_with_siso_diversity) |
| @@ -1334,6 +1330,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, · 118 unmodified lines | |||
| 1334 | /* Configure transport layer */ | 1330 | /* Configure transport layer */ |
| 1335 | iwl_trans_configure(priv->trans, &trans_cfg); | 1331 | iwl_trans_configure(priv->trans, &trans_cfg); |
| 1336 | 1332 | ||
| 1333 | trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; | ||
| 1334 | trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); | ||
| 1335 | |||
| 1337 | /* At this point both hw and priv are allocated. */ | 1336 | /* At this point both hw and priv are allocated. */ |
| 1338 | 1337 | ||
| 1339 | SET_IEEE80211_DEV(priv->hw, priv->trans->dev); | 1338 | SET_IEEE80211_DEV(priv->hw, priv->trans->dev); |
| @@ -2152,8 +2151,6 @@ static int __init iwl_init(void) · 812 unmodified lines | |||
| 2152 | { | 2151 | { |
| 2153 | 2152 | ||
| 2154 | int ret; | 2153 | int ret; |
| 2155 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||
| 2156 | pr_info(DRV_COPYRIGHT "\n"); | ||
| 2157 | 2154 | ||
| 2158 | ret = iwlagn_rate_control_register(); | 2155 | ret = iwlagn_rate_control_register(); |
| 2159 | if (ret) { | 2156 | if (ret) { |
| @@ -25,6 +25,39 @@ · 24 unmodified lines | |||
| 25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
| 26 | 26 | ||
| 27 | #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) | 27 | #if !defined(__IWLWIFI_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) |
| 28 | #include <linux/skbuff.h> | ||
| 29 | #include <linux/ieee80211.h> | ||
| 30 | #include <net/cfg80211.h> | ||
| 31 | #include "iwl-trans.h" | ||
| 32 | #if !defined(__IWLWIFI_DEVICE_TRACE) | ||
| 33 | static inline bool iwl_trace_data(struct sk_buff *skb) | ||
| 34 | { | ||
| 35 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
| 36 | |||
| 37 | if (ieee80211_is_data(hdr->frame_control)) | ||
| 38 | return skb->protocol != cpu_to_be16(ETH_P_PAE); | ||
| 39 | return false; | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, | ||
| 43 | void *rxbuf, size_t len) | ||
| 44 | { | ||
| 45 | struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32)); | ||
| 46 | struct ieee80211_hdr *hdr; | ||
| 47 | |||
| 48 | if (cmd->cmd != trans->rx_mpdu_cmd) | ||
| 49 | return len; | ||
| 50 | |||
| 51 | hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) + | ||
| 52 | trans->rx_mpdu_cmd_hdr_size); | ||
| 53 | if (!ieee80211_is_data(hdr->frame_control)) | ||
| 54 | return len; | ||
| 55 | /* maybe try to identify EAPOL frames? */ | ||
| 56 | return sizeof(__le32) + sizeof(*cmd) + trans->rx_mpdu_cmd_hdr_size + | ||
| 57 | ieee80211_hdrlen(hdr->frame_control); | ||
| 58 | } | ||
| 59 | #endif | ||
| 60 | |||
| 28 | #define __IWLWIFI_DEVICE_TRACE | 61 | #define __IWLWIFI_DEVICE_TRACE |
| 29 | 62 | ||
| 30 | #include <linux/tracepoint.h> | 63 | #include <linux/tracepoint.h> |
| @@ -234,6 +267,48 @@ TRACE_EVENT(iwlwifi_dbg, · 203 unmodified lines | |||
| 234 | TP_printk("%s", (char *)__get_dynamic_array(msg)) | 267 | TP_printk("%s", (char *)__get_dynamic_array(msg)) |
| 235 | ); | 268 | ); |
| 236 | 269 | ||
| 270 | #undef TRACE_SYSTEM | ||
| 271 | #define TRACE_SYSTEM iwlwifi_data | ||
| 272 | |||
| 273 | TRACE_EVENT(iwlwifi_dev_tx_data, | ||
| 274 | TP_PROTO(const struct device *dev, | ||
| 275 | struct sk_buff *skb, | ||
| 276 | void *data, size_t data_len), | ||
| 277 | TP_ARGS(dev, skb, data, data_len), | ||
| 278 | TP_STRUCT__entry( | ||
| 279 | DEV_ENTRY | ||
| 280 | |||
| 281 | __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0) | ||
| 282 | ), | ||
| 283 | TP_fast_assign( | ||
| 284 | DEV_ASSIGN; | ||
| 285 | if (iwl_trace_data(skb)) | ||
| 286 | memcpy(__get_dynamic_array(data), data, data_len); | ||
| 287 | ), | ||
| 288 | TP_printk("[%s] TX frame data", __get_str(dev)) | ||
| 289 | ); | ||
| 290 | |||
| 291 | TRACE_EVENT(iwlwifi_dev_rx_data, | ||
| 292 | TP_PROTO(const struct device *dev, | ||
| 293 | const struct iwl_trans *trans, | ||
| 294 | void *rxbuf, size_t len), | ||
| 295 | TP_ARGS(dev, trans, rxbuf, len), | ||
| 296 | TP_STRUCT__entry( | ||
| 297 | DEV_ENTRY | ||
| 298 | |||
| 299 | __dynamic_array(u8, data, | ||
| 300 | len - iwl_rx_trace_len(trans, rxbuf, len)) | ||
| 301 | ), | ||
| 302 | TP_fast_assign( | ||
| 303 | size_t offs = iwl_rx_trace_len(trans, rxbuf, len); | ||
| 304 | DEV_ASSIGN; | ||
| 305 | if (offs < len) | ||
| 306 | memcpy(__get_dynamic_array(data), | ||
| 307 | ((u8 *)rxbuf) + offs, len - offs); | ||
| 308 | ), | ||
| 309 | TP_printk("[%s] TX frame data", __get_str(dev)) | ||
| 310 | ); | ||
| 311 | |||
| 237 | #undef TRACE_SYSTEM | 312 | #undef TRACE_SYSTEM |
| 238 | #define TRACE_SYSTEM iwlwifi | 313 | #define TRACE_SYSTEM iwlwifi |
| 239 | 314 | ||
| @@ -270,25 +345,28 @@ TRACE_EVENT(iwlwifi_dev_hcmd, · 30 unmodified lines | |||
| 270 | ); | 345 | ); |
| 271 | 346 | ||
| 272 | TRACE_EVENT(iwlwifi_dev_rx, | 347 | TRACE_EVENT(iwlwifi_dev_rx, |
| 273 | TP_PROTO(const struct device *dev, void *rxbuf, size_t len), | 348 | TP_PROTO(const struct device *dev, const struct iwl_trans *trans, |
| 274 | TP_ARGS(dev, rxbuf, len), | 349 | void *rxbuf, size_t len), |
| 350 | TP_ARGS(dev, trans, rxbuf, len), | ||
| 275 | TP_STRUCT__entry( | 351 | TP_STRUCT__entry( |
| 276 | DEV_ENTRY | 352 | DEV_ENTRY |
| 277 | __dynamic_array(u8, rxbuf, len) | 353 | __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, rxbuf, len)) |
| 278 | ), | 354 | ), |
| 279 | TP_fast_assign( | 355 | TP_fast_assign( |
| 280 | DEV_ASSIGN; | 356 | DEV_ASSIGN; |
| 281 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); | 357 | memcpy(__get_dynamic_array(rxbuf), rxbuf, |
| 358 | iwl_rx_trace_len(trans, rxbuf, len)); | ||
| 282 | ), | 359 | ), |
| 283 | TP_printk("[%s] RX cmd %#.2x", | 360 | TP_printk("[%s] RX cmd %#.2x", |
| 284 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) | 361 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) |
| 285 | ); | 362 | ); |
| 286 | 363 | ||
| 287 | TRACE_EVENT(iwlwifi_dev_tx, | 364 | TRACE_EVENT(iwlwifi_dev_tx, |
| 288 | TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, | 365 | TP_PROTO(const struct device *dev, struct sk_buff *skb, |
| 366 | void *tfd, size_t tfdlen, | ||
| 289 | void *buf0, size_t buf0_len, | 367 | void *buf0, size_t buf0_len, |
| 290 | void *buf1, size_t buf1_len), | 368 | void *buf1, size_t buf1_len), |
| 291 | TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 369 | TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
| 292 | TP_STRUCT__entry( | 370 | TP_STRUCT__entry( |
| 293 | DEV_ENTRY | 371 | DEV_ENTRY |
| 294 | 372 | ||
| @@ -301,14 +379,15 @@ TRACE_EVENT(iwlwifi_dev_tx, · 6 unmodified lines | |||
| 301 | * for the possible padding). | 379 | * for the possible padding). |
| 302 | */ | 380 | */ |
| 303 | __dynamic_array(u8, buf0, buf0_len) | 381 | __dynamic_array(u8, buf0, buf0_len) |
| 304 | __dynamic_array(u8, buf1, buf1_len) | 382 | __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len) |
| 305 | ), | 383 | ), |
| 306 | TP_fast_assign( | 384 | TP_fast_assign( |
| 307 | DEV_ASSIGN; | 385 | DEV_ASSIGN; |
| 308 | __entry->framelen = buf0_len + buf1_len; | 386 | __entry->framelen = buf0_len + buf1_len; |
| 309 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); | 387 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); |
| 310 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); | 388 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); |
| 311 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); | 389 | if (!iwl_trace_data(skb)) |
| 390 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); | ||
| 312 | ), | 391 | ), |
| 313 | TP_printk("[%s] TX %.2x (%zu bytes)", | 392 | TP_printk("[%s] TX %.2x (%zu bytes)", |
| 314 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], | 393 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], |
| @@ -327,11 +327,11 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) · 326 unmodified lines | |||
| 327 | EXPORT_SYMBOL_GPL(iwl_read_targ_mem); | 327 | EXPORT_SYMBOL_GPL(iwl_read_targ_mem); |
| 328 | 328 | ||
| 329 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | 329 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, |
| 330 | void *buf, int dwords) | 330 | const void *buf, int dwords) |
| 331 | { | 331 | { |
| 332 | unsigned long flags; | 332 | unsigned long flags; |
| 333 | int offs, result = 0; | 333 | int offs, result = 0; |
| 334 | u32 *vals = buf; | 334 | const u32 *vals = buf; |
| 335 | 335 | ||
| 336 | spin_lock_irqsave(&trans->reg_lock, flags); | 336 | spin_lock_irqsave(&trans->reg_lock, flags); |
| 337 | if (likely(iwl_grab_nic_access(trans))) { | 337 | if (likely(iwl_grab_nic_access(trans))) { |
| @@ -87,7 +87,7 @@ void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr, · 86 unmodified lines | |||
| 87 | } while (0) | 87 | } while (0) |
| 88 | 88 | ||
| 89 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, | 89 | int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr, |
| 90 | void *buf, int dwords); | 90 | const void *buf, int dwords); |
| 91 | 91 | ||
| 92 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); | 92 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); |
| 93 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); | 93 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); |
| @@ -213,6 +213,9 @@ · 212 unmodified lines | |||
| 213 | #define SCD_CONTEXT_QUEUE_OFFSET(x)\ | 213 | #define SCD_CONTEXT_QUEUE_OFFSET(x)\ |
| 214 | (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) | 214 | (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8)) |
| 215 | 215 | ||
| 216 | #define SCD_TX_STTS_QUEUE_OFFSET(x)\ | ||
| 217 | (SCD_TX_STTS_MEM_LOWER_BOUND + ((x) * 16)) | ||
| 218 | |||
| 216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ | 219 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ |
| 217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) | 220 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) |
| 218 | 221 | ||
| @@ -444,6 +444,10 @@ enum iwl_trans_state { · 443 unmodified lines | |||
| 444 | * @dev_cmd_headroom: room needed for the transport's private use before the | 444 | * @dev_cmd_headroom: room needed for the transport's private use before the |
| 445 | * device_cmd for Tx - for internal use only | 445 | * device_cmd for Tx - for internal use only |
| 446 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | 446 | * The user should use iwl_trans_{alloc,free}_tx_cmd. |
| 447 | * @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before | ||
| 448 | * starting the firmware, used for tracing | ||
| 449 | * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the | ||
| 450 | * start of the 802.11 header in the @rx_mpdu_cmd | ||
| 447 | */ | 451 | */ |
| 448 | struct iwl_trans { | 452 | struct iwl_trans { |
| 449 | const struct iwl_trans_ops *ops; | 453 | const struct iwl_trans_ops *ops; |
| @@ -457,6 +461,8 @@ struct iwl_trans { · 7 unmodified lines | |||
| 457 | u32 hw_id; | 461 | u32 hw_id; |
| 458 | char hw_id_str[52]; | 462 | char hw_id_str[52]; |
| 459 | 463 | ||
| 464 | u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; | ||
| 465 | |||
| 460 | bool pm_support; | 466 | bool pm_support; |
| 461 | 467 | ||
| 462 | wait_queue_head_t wait_command_queue; | 468 | wait_queue_head_t wait_command_queue; |
| @@ -516,6 +522,8 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, · 53 unmodified lines | |||
| 516 | { | 522 | { |
| 517 | might_sleep(); | 523 | might_sleep(); |
| 518 | 524 | ||
| 525 | WARN_ON_ONCE(!trans->rx_mpdu_cmd); | ||
| 526 | |||
| 519 | return trans->ops->start_fw(trans, fw); | 527 | return trans->ops->start_fw(trans, fw); |
| 520 | } | 528 | } |
| 521 | 529 | ||
| @@ -411,7 +411,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, · 410 unmodified lines | |||
| 411 | 411 | ||
| 412 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 412 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
| 413 | len += sizeof(u32); /* account for status word */ | 413 | len += sizeof(u32); /* account for status word */ |
| 414 | trace_iwlwifi_dev_rx(trans->dev, pkt, len); | 414 | trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len); |
| 415 | trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len); | ||
| 415 | 416 | ||
| 416 | /* Reclaim a command buffer only if this packet is a response | 417 | /* Reclaim a command buffer only if this packet is a response |
| 417 | * to a (driver-originated) command. | 418 | * to a (driver-originated) command. |
| @@ -300,7 +300,7 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) · 299 unmodified lines | |||
| 300 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; | 300 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; |
| 301 | struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); | 301 | struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); |
| 302 | u32 scd_sram_addr = trans_pcie->scd_base_addr + | 302 | u32 scd_sram_addr = trans_pcie->scd_base_addr + |
| 303 | SCD_TX_STTS_MEM_LOWER_BOUND + (16 * txq->q.id); | 303 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); |
| 304 | u8 buf[16]; | 304 | u8 buf[16]; |
| 305 | int i; | 305 | int i; |
| 306 | 306 | ||
| @@ -1385,11 +1385,13 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, · 1078 unmodified lines | |||
| 1385 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | 1385 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
| 1386 | DMA_BIDIRECTIONAL); | 1386 | DMA_BIDIRECTIONAL); |
| 1387 | 1387 | ||
| 1388 | trace_iwlwifi_dev_tx(trans->dev, | 1388 | trace_iwlwifi_dev_tx(trans->dev, skb, |
| 1389 | &txq->tfds[txq->q.write_ptr], | 1389 | &txq->tfds[txq->q.write_ptr], |
| 1390 | sizeof(struct iwl_tfd), | 1390 | sizeof(struct iwl_tfd), |
| 1391 | &dev_cmd->hdr, firstlen, | 1391 | &dev_cmd->hdr, firstlen, |
| 1392 | skb->data + hdr_len, secondlen); | 1392 | skb->data + hdr_len, secondlen); |
| 1393 | trace_iwlwifi_dev_tx_data(trans->dev, skb, | ||
| 1394 | skb->data + hdr_len, secondlen); | ||
| 1393 | 1395 | ||
| 1394 | /* start timer if queue currently empty */ | 1396 | /* start timer if queue currently empty */ |
| 1395 | if (txq->need_update && q->read_ptr == q->write_ptr && | 1397 | if (txq->need_update && q->read_ptr == q->write_ptr && |
| @@ -1514,14 +1516,13 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, · 118 unmodified lines | |||
| 1514 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 1516 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
| 1515 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ | 1517 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ |
| 1516 | int tfd_num = ssn & (txq->q.n_bd - 1); | 1518 | int tfd_num = ssn & (txq->q.n_bd - 1); |
| 1517 | int freed = 0; | ||
| 1518 | 1519 | ||
| 1519 | spin_lock(&txq->lock); | 1520 | spin_lock(&txq->lock); |
| 1520 | 1521 | ||
| 1521 | if (txq->q.read_ptr != tfd_num) { | 1522 | if (txq->q.read_ptr != tfd_num) { |
| 1522 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", | 1523 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", |
| 1523 | txq_id, txq->q.read_ptr, tfd_num, ssn); | 1524 | txq_id, txq->q.read_ptr, tfd_num, ssn); |
| 1524 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1525 | iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
| 1525 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) | 1526 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) |
| 1526 | iwl_wake_queue(trans, txq); | 1527 | iwl_wake_queue(trans, txq); |
| 1527 | } | 1528 | } |
| @@ -480,21 +480,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, · 479 unmodified lines | |||
| 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | 480 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
| 481 | { | 481 | { |
| 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
| 483 | u16 rd_ptr, wr_ptr; | 483 | u32 stts_addr = trans_pcie->scd_base_addr + |
| 484 | int n_bd = trans_pcie->txq[txq_id].q.n_bd; | 484 | SCD_TX_STTS_QUEUE_OFFSET(txq_id); |
| 485 | static const u32 zero_val[4] = {}; | ||
| 485 | 486 | ||
| 486 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { | 487 | if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { |
| 487 | WARN_ONCE(1, "queue %d not used", txq_id); | 488 | WARN_ONCE(1, "queue %d not used", txq_id); |
| 488 | return; | 489 | return; |
| 489 | } | 490 | } |
| 490 | 491 | ||
| 491 | rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); | 492 | iwl_txq_set_inactive(trans, txq_id); |
| 492 | wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); | ||
| 493 | 493 | ||
| 494 | WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", | 494 | _iwl_write_targ_mem_dwords(trans, stts_addr, |
| 495 | txq_id, rd_ptr, wr_ptr); | 495 | zero_val, ARRAY_SIZE(zero_val)); |
| 496 | 496 | ||
| 497 | iwl_txq_set_inactive(trans, txq_id); | ||
| 498 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 497 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
| 499 | } | 498 | } |
| 500 | 499 | ||
| @@ -549,7 +548,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) · 48 unmodified lines | |||
| 549 | * allocated into separate TFDs, then we will need to | 548 | * allocated into separate TFDs, then we will need to |
| 550 | * increase the size of the buffers. | 549 | * increase the size of the buffers. |
| 551 | */ | 550 | */ |
| 552 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) | 551 | if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, |
| 552 | "Command %s (%#x) is too large (%d bytes)\n", | ||
| 553 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), | ||
| 554 | cmd->id, copy_size)) | ||
| 553 | return -EINVAL; | 555 | return -EINVAL; |
| 554 | 556 | ||
| 555 | spin_lock_bh(&txq->lock); | 557 | spin_lock_bh(&txq->lock); |
| @@ -101,7 +101,7 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, · 100 unmodified lines | |||
| 101 | 101 | ||
| 102 | switch (action) { | 102 | switch (action) { |
| 103 | case CMD_ACT_MESH_CONFIG_START: | 103 | case CMD_ACT_MESH_CONFIG_START: |
| 104 | ie->id = WLAN_EID_GENERIC; | 104 | ie->id = WLAN_EID_VENDOR_SPECIFIC; |
| 105 | ie->val.oui[0] = 0x00; | 105 | ie->val.oui[0] = 0x00; |
| 106 | ie->val.oui[1] = 0x50; | 106 | ie->val.oui[1] = 0x50; |
| 107 | ie->val.oui[2] = 0x43; | 107 | ie->val.oui[2] = 0x43; |
| @@ -58,8 +58,7 @@ mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, · 57 unmodified lines | |||
| 58 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) | 58 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) |
| 59 | mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); | 59 | mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); |
| 60 | else | 60 | else |
| 61 | mwifiex_process_rx_packet(priv->adapter, | 61 | mwifiex_process_rx_packet(priv, rx_tmp_ptr); |
| 62 | rx_tmp_ptr); | ||
| 63 | } | 62 | } |
| 64 | } | 63 | } |
| 65 | 64 | ||
| @@ -106,7 +105,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, · 40 unmodified lines | |||
| 106 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) | 105 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) |
| 107 | mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); | 106 | mwifiex_handle_uap_rx_forward(priv, rx_tmp_ptr); |
| 108 | else | 107 | else |
| 109 | mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); | 108 | mwifiex_process_rx_packet(priv, rx_tmp_ptr); |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); | 111 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); |
| @@ -442,8 +441,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, · 329 unmodified lines | |||
| 442 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) | 441 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) |
| 443 | mwifiex_handle_uap_rx_forward(priv, payload); | 442 | mwifiex_handle_uap_rx_forward(priv, payload); |
| 444 | else | 443 | else |
| 445 | mwifiex_process_rx_packet(priv->adapter, | 444 | mwifiex_process_rx_packet(priv, payload); |
| 446 | payload); | ||
| 447 | } | 445 | } |
| 448 | return 0; | 446 | return 0; |
| 449 | } | 447 | } |
| @@ -471,13 +471,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) · 470 unmodified lines | |||
| 471 | flag = 1; | 471 | flag = 1; |
| 472 | first_chan = (u32) ch->hw_value; | 472 | first_chan = (u32) ch->hw_value; |
| 473 | next_chan = first_chan; | 473 | next_chan = first_chan; |
| 474 | max_pwr = ch->max_reg_power; | 474 | max_pwr = ch->max_power; |
| 475 | no_of_parsed_chan = 1; | 475 | no_of_parsed_chan = 1; |
| 476 | continue; | 476 | continue; |
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | if (ch->hw_value == next_chan + 1 && | 479 | if (ch->hw_value == next_chan + 1 && |
| 480 | ch->max_reg_power == max_pwr) { | 480 | ch->max_power == max_pwr) { |
| 481 | next_chan++; | 481 | next_chan++; |
| 482 | no_of_parsed_chan++; | 482 | no_of_parsed_chan++; |
| 483 | } else { | 483 | } else { |
| @@ -488,7 +488,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) · 4 unmodified lines | |||
| 488 | no_of_triplet++; | 488 | no_of_triplet++; |
| 489 | first_chan = (u32) ch->hw_value; | 489 | first_chan = (u32) ch->hw_value; |
| 490 | next_chan = first_chan; | 490 | next_chan = first_chan; |
| 491 | max_pwr = ch->max_reg_power; | 491 | max_pwr = ch->max_power; |
| 492 | no_of_parsed_chan = 1; | 492 | no_of_parsed_chan = 1; |
| 493 | } | 493 | } |
| 494 | } | 494 | } |
| @@ -1819,12 +1819,18 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, · 1324 unmodified lines | |||
| 1819 | 1819 | ||
| 1820 | wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); | 1820 | wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); |
| 1821 | 1821 | ||
| 1822 | if (atomic_read(&priv->wmm.tx_pkts_queued) >= | 1822 | if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && |
| 1823 | atomic_read(&priv->wmm.tx_pkts_queued) >= | ||
| 1823 | MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) { | 1824 | MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) { |
| 1824 | dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n"); | 1825 | dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n"); |
| 1825 | return -EBUSY; | 1826 | return -EBUSY; |
| 1826 | } | 1827 | } |
| 1827 | 1828 | ||
| 1829 | if (priv->user_scan_cfg) { | ||
| 1830 | dev_err(priv->adapter->dev, "cmd: Scan already in process..\n"); | ||
| 1831 | return -EBUSY; | ||
| 1832 | } | ||
| 1833 | |||
| 1828 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), | 1834 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), |
| 1829 | GFP_KERNEL); | 1835 | GFP_KERNEL); |
| 1830 | if (!priv->user_scan_cfg) { | 1836 | if (!priv->user_scan_cfg) { |
| @@ -2116,7 +2122,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, · 285 unmodified lines | |||
| 2116 | } | 2122 | } |
| 2117 | 2123 | ||
| 2118 | sema_init(&priv->async_sem, 1); | 2124 | sema_init(&priv->async_sem, 1); |
| 2119 | priv->scan_pending_on_block = false; | ||
| 2120 | 2125 | ||
| 2121 | dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); | 2126 | dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); |
| 2122 | 2127 | ||
| @@ -2253,8 +2258,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) · 130 unmodified lines | |||
| 2253 | wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; | 2258 | wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; |
| 2254 | wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; | 2259 | wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; |
| 2255 | 2260 | ||
| 2256 | wiphy->features = NL80211_FEATURE_HT_IBSS | | 2261 | wiphy->features |= NL80211_FEATURE_HT_IBSS | |
| 2257 | NL80211_FEATURE_INACTIVITY_TIMER; | 2262 | NL80211_FEATURE_INACTIVITY_TIMER | |
| 2263 | NL80211_FEATURE_LOW_PRIORITY_SCAN; | ||
| 2258 | 2264 | ||
| 2259 | /* Reserve space for mwifiex specific private data for BSS */ | 2265 | /* Reserve space for mwifiex specific private data for BSS */ |
| 2260 | wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); | 2266 | wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); |
| @@ -917,21 +917,24 @@ mwifiex_cmd_timeout_func(unsigned long function_context) · 916 unmodified lines | |||
| 917 | 917 | ||
| 918 | dev_err(adapter->dev, "last_cmd_index = %d\n", | 918 | dev_err(adapter->dev, "last_cmd_index = %d\n", |
| 919 | adapter->dbg.last_cmd_index); | 919 | adapter->dbg.last_cmd_index); |
| 920 | print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, | 920 | dev_err(adapter->dev, "last_cmd_id: %*ph\n", |
| 921 | adapter->dbg.last_cmd_id, DBG_CMD_NUM); | 921 | (int)sizeof(adapter->dbg.last_cmd_id), |
| 922 | print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, | 922 | adapter->dbg.last_cmd_id); |
| 923 | adapter->dbg.last_cmd_act, DBG_CMD_NUM); | 923 | dev_err(adapter->dev, "last_cmd_act: %*ph\n", |
| 924 | (int)sizeof(adapter->dbg.last_cmd_act), | ||
| 925 | adapter->dbg.last_cmd_act); | ||
| 924 | 926 | ||
| 925 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", | 927 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", |
| 926 | adapter->dbg.last_cmd_resp_index); | 928 | adapter->dbg.last_cmd_resp_index); |
| 927 | print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, | 929 | dev_err(adapter->dev, "last_cmd_resp_id: %*ph\n", |
| 928 | adapter->dbg.last_cmd_resp_id, | 930 | (int)sizeof(adapter->dbg.last_cmd_resp_id), |
| 929 | DBG_CMD_NUM); | 931 | adapter->dbg.last_cmd_resp_id); |
| 930 | 932 | ||
| 931 | dev_err(adapter->dev, "last_event_index = %d\n", | 933 | dev_err(adapter->dev, "last_event_index = %d\n", |
| 932 | adapter->dbg.last_event_index); | 934 | adapter->dbg.last_event_index); |
| 933 | print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, | 935 | dev_err(adapter->dev, "last_event: %*ph\n", |
| 934 | adapter->dbg.last_event, DBG_CMD_NUM); | 936 | (int)sizeof(adapter->dbg.last_event), |
| 937 | adapter->dbg.last_event); | ||
| 935 | 938 | ||
| 936 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", | 939 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", |
| 937 | adapter->data_sent, adapter->cmd_sent); | 940 | adapter->data_sent, adapter->cmd_sent); |
| @@ -84,18 +84,19 @@ static void scan_delay_timer_fn(unsigned long data) · 83 unmodified lines | |||
| 84 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 84 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
| 85 | 85 | ||
| 86 | if (priv->user_scan_cfg) { | 86 | if (priv->user_scan_cfg) { |
| 87 | dev_dbg(priv->adapter->dev, | 87 | if (priv->scan_request) { |
| 88 | "info: %s: scan aborted\n", __func__); | 88 | dev_dbg(priv->adapter->dev, |
| 89 | cfg80211_scan_done(priv->scan_request, 1); | 89 | "info: aborting scan\n"); |
| 90 | priv->scan_request = NULL; | 90 | cfg80211_scan_done(priv->scan_request, 1); |
| 91 | priv->scan_request = NULL; | ||
| 92 | } else { | ||
| 93 | dev_dbg(priv->adapter->dev, | ||
| 94 | "info: scan already aborted\n"); | ||
| 95 | } | ||
| 96 | |||
| 91 | kfree(priv->user_scan_cfg); | 97 | kfree(priv->user_scan_cfg); |
| 92 | priv->user_scan_cfg = NULL; | 98 | priv->user_scan_cfg = NULL; |
| 93 | } | 99 | } |
| 94 | |||
| 95 | if (priv->scan_pending_on_block) { | ||
| 96 | priv->scan_pending_on_block = false; | ||
| 97 | up(&priv->async_sem); | ||
| 98 | } | ||
| 99 | goto done; | 100 | goto done; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| @@ -472,6 +472,14 @@ mwifiex_open(struct net_device *dev) · 471 unmodified lines | |||
| 472 | static int | 472 | static int |
| 473 | mwifiex_close(struct net_device *dev) | 473 | mwifiex_close(struct net_device *dev) |
| 474 | { | 474 | { |
| 475 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | ||
| 476 | |||
| 477 | if (priv->scan_request) { | ||
| 478 | dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n"); | ||
| 479 | cfg80211_scan_done(priv->scan_request, 1); | ||
| 480 | priv->scan_request = NULL; | ||
| 481 | } | ||
| 482 | |||
| 475 | return 0; | 483 | return 0; |
| 476 | } | 484 | } |
| 477 | 485 | ||
| @@ -115,8 +115,6 @@ enum { · 114 unmodified lines | |||
| 115 | #define MWIFIEX_TYPE_DATA 0 | 115 | #define MWIFIEX_TYPE_DATA 0 |
| 116 | #define MWIFIEX_TYPE_EVENT 3 | 116 | #define MWIFIEX_TYPE_EVENT 3 |
| 117 | 117 | ||
| 118 | #define DBG_CMD_NUM 5 | ||
| 119 | |||
| 120 | #define MAX_BITMAP_RATES_SIZE 10 | 118 | #define MAX_BITMAP_RATES_SIZE 10 |
| 121 | 119 | ||
| 122 | #define MAX_CHANNEL_BAND_BG 14 | 120 | #define MAX_CHANNEL_BAND_BG 14 |
| @@ -484,7 +482,6 @@ struct mwifiex_private { · 361 unmodified lines | |||
| 484 | u8 nick_name[16]; | 482 | u8 nick_name[16]; |
| 485 | u16 current_key_index; | 483 | u16 current_key_index; |
| 486 | struct semaphore async_sem; | 484 | struct semaphore async_sem; |
| 487 | u8 scan_pending_on_block; | ||
| 488 | u8 report_scan_result; | 485 | u8 report_scan_result; |
| 489 | struct cfg80211_scan_request *scan_request; | 486 | struct cfg80211_scan_request *scan_request; |
| 490 | struct mwifiex_user_scan_cfg *user_scan_cfg; | 487 | struct mwifiex_user_scan_cfg *user_scan_cfg; |
| @@ -750,9 +747,9 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter); · 259 unmodified lines | |||
| 750 | 747 | ||
| 751 | int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); | 748 | int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); |
| 752 | 749 | ||
| 753 | int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); | 750 | int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb); |
| 754 | 751 | ||
| 755 | int mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter, | 752 | int mwifiex_process_mgmt_packet(struct mwifiex_private *priv, |
| 756 | struct sk_buff *skb); | 753 | struct sk_buff *skb); |
| 757 | 754 | ||
| 758 | int mwifiex_process_event(struct mwifiex_adapter *adapter); | 755 | int mwifiex_process_event(struct mwifiex_adapter *adapter); |
| @@ -809,7 +806,7 @@ void mwifiex_hs_activated_event(struct mwifiex_private *priv, · 50 unmodified lines | |||
| 809 | u8 activated); | 806 | u8 activated); |
| 810 | int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | 807 | int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, |
| 811 | struct host_cmd_ds_command *resp); | 808 | struct host_cmd_ds_command *resp); |
| 812 | int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, | 809 | int mwifiex_process_rx_packet(struct mwifiex_private *priv, |
| 813 | struct sk_buff *skb); | 810 | struct sk_buff *skb); |
| 814 | int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, | 811 | int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no, |
| 815 | u16 cmd_action, u32 cmd_oid, | 812 | u16 cmd_action, u32 cmd_oid, |
| @@ -819,9 +816,9 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, · 3 unmodified lines | |||
| 819 | void *data_buf, void *cmd_buf); | 816 | void *data_buf, void *cmd_buf); |
| 820 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, | 817 | int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no, |
| 821 | struct host_cmd_ds_command *resp); | 818 | struct host_cmd_ds_command *resp); |
| 822 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *, | 819 | int mwifiex_process_sta_rx_packet(struct mwifiex_private *, |
| 823 | struct sk_buff *skb); | 820 | struct sk_buff *skb); |
| 824 | int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, | 821 | int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, |
| 825 | struct sk_buff *skb); | 822 | struct sk_buff *skb); |
| 826 | int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, | 823 | int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, |
| 827 | struct sk_buff *skb); | 824 | struct sk_buff *skb); |
| @@ -153,7 +153,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) · 152 unmodified lines | |||
| 153 | 153 | ||
| 154 | if (((bss_desc->bcn_wpa_ie) && | 154 | if (((bss_desc->bcn_wpa_ie) && |
| 155 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == | 155 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == |
| 156 | WLAN_EID_WPA))) { | 156 | WLAN_EID_VENDOR_SPECIFIC))) { |
| 157 | iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; | 157 | iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; |
| 158 | oui = &mwifiex_wpa_oui[cipher][0]; | 158 | oui = &mwifiex_wpa_oui[cipher][0]; |
| 159 | ret = mwifiex_search_oui_in_ie(iebody, oui); | 159 | ret = mwifiex_search_oui_in_ie(iebody, oui); |
| @@ -202,7 +202,7 @@ mwifiex_is_bss_no_sec(struct mwifiex_private *priv, · 42 unmodified lines | |||
| 202 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 202 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
| 203 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 203 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || |
| 204 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != | 204 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != |
| 205 | WLAN_EID_WPA)) && | 205 | WLAN_EID_VENDOR_SPECIFIC)) && |
| 206 | ((!bss_desc->bcn_rsn_ie) || | 206 | ((!bss_desc->bcn_rsn_ie) || |
| 207 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != | 207 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != |
| 208 | WLAN_EID_RSN)) && | 208 | WLAN_EID_RSN)) && |
| @@ -237,7 +237,8 @@ mwifiex_is_bss_wpa(struct mwifiex_private *priv, · 28 unmodified lines | |||
| 237 | { | 237 | { |
| 238 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && | 238 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && |
| 239 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && | 239 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && |
| 240 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == WLAN_EID_WPA)) | 240 | ((*(bss_desc->bcn_wpa_ie)). |
| 241 | vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)) | ||
| 241 | /* | 242 | /* |
| 242 | * Privacy bit may NOT be set in some APs like | 243 | * Privacy bit may NOT be set in some APs like |
| 243 | * LinkSys WRT54G && bss_desc->privacy | 244 | * LinkSys WRT54G && bss_desc->privacy |
| @@ -309,7 +310,8 @@ mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, · 65 unmodified lines | |||
| 309 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 310 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
| 310 | !priv->sec_info.wpa2_enabled && | 311 | !priv->sec_info.wpa2_enabled && |
| 311 | ((!bss_desc->bcn_wpa_ie) || | 312 | ((!bss_desc->bcn_wpa_ie) || |
| 312 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && | 313 | ((*(bss_desc->bcn_wpa_ie)). |
| 314 | vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) && | ||
| 313 | ((!bss_desc->bcn_rsn_ie) || | 315 | ((!bss_desc->bcn_rsn_ie) || |
| 314 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && | 316 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
| 315 | !priv->sec_info.encryption_mode && bss_desc->privacy) { | 317 | !priv->sec_info.encryption_mode && bss_desc->privacy) { |
| @@ -329,7 +331,8 @@ mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, · 13 unmodified lines | |||
| 329 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 331 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
| 330 | !priv->sec_info.wpa2_enabled && | 332 | !priv->sec_info.wpa2_enabled && |
| 331 | ((!bss_desc->bcn_wpa_ie) || | 333 | ((!bss_desc->bcn_wpa_ie) || |
| 332 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && | 334 | ((*(bss_desc->bcn_wpa_ie)). |
| 335 | vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) && | ||
| 333 | ((!bss_desc->bcn_rsn_ie) || | 336 | ((!bss_desc->bcn_rsn_ie) || |
| 334 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && | 337 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
| 335 | priv->sec_info.encryption_mode && bss_desc->privacy) { | 338 | priv->sec_info.encryption_mode && bss_desc->privacy) { |
| @@ -938,6 +941,11 @@ mwifiex_config_scan(struct mwifiex_private *priv, · 602 unmodified lines | |||
| 938 | chan_idx)->chan_scan_mode_bitmap | 941 | chan_idx)->chan_scan_mode_bitmap |
| 939 | &= ~MWIFIEX_PASSIVE_SCAN; | 942 | &= ~MWIFIEX_PASSIVE_SCAN; |
| 940 | 943 | ||
| 944 | if (*filtered_scan) | ||
| 945 | (scan_chan_list + | ||
| 946 | chan_idx)->chan_scan_mode_bitmap | ||
| 947 | |= MWIFIEX_DISABLE_CHAN_FILT; | ||
| 948 | |||
| 941 | if (user_scan_in->chan_list[chan_idx].scan_time) { | 949 | if (user_scan_in->chan_list[chan_idx].scan_time) { |
| 942 | scan_dur = (u16) user_scan_in-> | 950 | scan_dur = (u16) user_scan_in-> |
| 943 | chan_list[chan_idx].scan_time; | 951 | chan_list[chan_idx].scan_time; |
| @@ -1759,26 +1767,39 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, · 815 unmodified lines | |||
| 1759 | } | 1767 | } |
| 1760 | if (priv->report_scan_result) | 1768 | if (priv->report_scan_result) |
| 1761 | priv->report_scan_result = false; | 1769 | priv->report_scan_result = false; |
| 1762 | if (priv->scan_pending_on_block) { | ||
| 1763 | priv->scan_pending_on_block = false; | ||
| 1764 | up(&priv->async_sem); | ||
| 1765 | } | ||
| 1766 | 1770 | ||
| 1767 | if (priv->user_scan_cfg) { | 1771 | if (priv->user_scan_cfg) { |
| 1768 | dev_dbg(priv->adapter->dev, | 1772 | if (priv->scan_request) { |
| 1769 | "info: %s: sending scan results\n", __func__); | 1773 | dev_dbg(priv->adapter->dev, |
| 1770 | cfg80211_scan_done(priv->scan_request, 0); | 1774 | "info: notifying scan done\n"); |
| 1771 | priv->scan_request = NULL; | 1775 | cfg80211_scan_done(priv->scan_request, 0); |
| 1776 | priv->scan_request = NULL; | ||
| 1777 | } else { | ||
| 1778 | dev_dbg(priv->adapter->dev, | ||
| 1779 | "info: scan already aborted\n"); | ||
| 1780 | } | ||
| 1781 | |||
| 1772 | kfree(priv->user_scan_cfg); | 1782 | kfree(priv->user_scan_cfg); |
| 1773 | priv->user_scan_cfg = NULL; | 1783 | priv->user_scan_cfg = NULL; |
| 1774 | } | 1784 | } |
| 1775 | } else { | 1785 | } else { |
| 1776 | if (!mwifiex_wmm_lists_empty(adapter)) { | 1786 | if (priv->user_scan_cfg && !priv->scan_request) { |
| 1787 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | ||
| 1788 | flags); | ||
| 1789 | adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT; | ||
| 1790 | mod_timer(&priv->scan_delay_timer, jiffies); | ||
| 1791 | dev_dbg(priv->adapter->dev, | ||
| 1792 | "info: %s: triggerring scan abort\n", __func__); | ||
| 1793 | } else if (!mwifiex_wmm_lists_empty(adapter) && | ||
| 1794 | (priv->scan_request && (priv->scan_request->flags & | ||
| 1795 | NL80211_SCAN_FLAG_LOW_PRIORITY))) { | ||
| 1777 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1796 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
| 1778 | flags); | 1797 | flags); |
| 1779 | adapter->scan_delay_cnt = 1; | 1798 | adapter->scan_delay_cnt = 1; |
| 1780 | mod_timer(&priv->scan_delay_timer, jiffies + | 1799 | mod_timer(&priv->scan_delay_timer, jiffies + |
| 1781 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); | 1800 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); |
| 1801 | dev_dbg(priv->adapter->dev, | ||
| 1802 | "info: %s: deferring scan\n", __func__); | ||
| 1782 | } else { | 1803 | } else { |
| 1783 | /* Get scan command from scan_pending_q and put to | 1804 | /* Get scan command from scan_pending_q and put to |
| 1784 | cmd_pending_q */ | 1805 | cmd_pending_q */ |
| @@ -1891,7 +1912,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv, · 106 unmodified lines | |||
| 1891 | __func__); | 1912 | __func__); |
| 1892 | return -1; | 1913 | return -1; |
| 1893 | } | 1914 | } |
| 1894 | priv->scan_pending_on_block = true; | ||
| 1895 | 1915 | ||
| 1896 | priv->adapter->scan_wait_q_woken = false; | 1916 | priv->adapter->scan_wait_q_woken = false; |
| 1897 | 1917 | ||
| @@ -1905,10 +1925,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv, · 7 unmodified lines | |||
| 1905 | if (!ret) | 1925 | if (!ret) |
| 1906 | ret = mwifiex_wait_queue_complete(priv->adapter); | 1926 | ret = mwifiex_wait_queue_complete(priv->adapter); |
| 1907 | 1927 | ||
| 1908 | if (ret == -1) { | 1928 | up(&priv->async_sem); |
| 1909 | priv->scan_pending_on_block = false; | ||
| 1910 | up(&priv->async_sem); | ||
| 1911 | } | ||
| 1912 | 1929 | ||
| 1913 | return ret; | 1930 | return ret; |
| 1914 | } | 1931 | } |
| @@ -85,10 +85,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, · 84 unmodified lines | |||
| 85 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 85 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
| 86 | if (priv->report_scan_result) | 86 | if (priv->report_scan_result) |
| 87 | priv->report_scan_result = false; | 87 | priv->report_scan_result = false; |
| 88 | if (priv->scan_pending_on_block) { | ||
| 89 | priv->scan_pending_on_block = false; | ||
| 90 | up(&priv->async_sem); | ||
| 91 | } | ||
| 92 | break; | 88 | break; |
| 93 | 89 | ||
| 94 | case HostCmd_CMD_MAC_CONTROL: | 90 | case HostCmd_CMD_MAC_CONTROL: |
| @@ -713,7 +713,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, · 712 unmodified lines | |||
| 713 | dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", | 713 | dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", |
| 714 | priv->wpa_ie_len, priv->wpa_ie[0]); | 714 | priv->wpa_ie_len, priv->wpa_ie[0]); |
| 715 | 715 | ||
| 716 | if (priv->wpa_ie[0] == WLAN_EID_WPA) { | 716 | if (priv->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) { |
| 717 | priv->sec_info.wpa_enabled = true; | 717 | priv->sec_info.wpa_enabled = true; |
| 718 | } else if (priv->wpa_ie[0] == WLAN_EID_RSN) { | 718 | } else if (priv->wpa_ie[0] == WLAN_EID_RSN) { |
| 719 | priv->sec_info.wpa2_enabled = true; | 719 | priv->sec_info.wpa2_enabled = true; |
| @@ -1253,7 +1253,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, · 533 unmodified lines | |||
| 1253 | } | 1253 | } |
| 1254 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; | 1254 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; |
| 1255 | /* Test to see if it is a WPA IE, if not, then it is a gen IE */ | 1255 | /* Test to see if it is a WPA IE, if not, then it is a gen IE */ |
| 1256 | if (((pvendor_ie->element_id == WLAN_EID_WPA) && | 1256 | if (((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && |
| 1257 | (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || | 1257 | (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || |
| 1258 | (pvendor_ie->element_id == WLAN_EID_RSN)) { | 1258 | (pvendor_ie->element_id == WLAN_EID_RSN)) { |
| 1259 | 1259 | ||
| @@ -38,14 +38,10 @@ · 37 unmodified lines | |||
| 38 | * | 38 | * |
| 39 | * The completion callback is called after processing in complete. | 39 | * The completion callback is called after processing in complete. |
| 40 | */ | 40 | */ |
| 41 | int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, | 41 | int mwifiex_process_rx_packet(struct mwifiex_private *priv, |
| 42 | struct sk_buff *skb) | 42 | struct sk_buff *skb) |
| 43 | { | 43 | { |
| 44 | int ret; | 44 | int ret; |
| 45 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); | ||
| 46 | struct mwifiex_private *priv = | ||
| 47 | mwifiex_get_priv_by_id(adapter, rx_info->bss_num, | ||
| 48 | rx_info->bss_type); | ||
| 49 | struct rx_packet_hdr *rx_pkt_hdr; | 45 | struct rx_packet_hdr *rx_pkt_hdr; |
| 50 | struct rxpd *local_rx_pd; | 46 | struct rxpd *local_rx_pd; |
| 51 | int hdr_chop; | 47 | int hdr_chop; |
| @@ -98,9 +94,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, · 46 unmodified lines | |||
| 98 | 94 | ||
| 99 | priv->rxpd_htinfo = local_rx_pd->ht_info; | 95 | priv->rxpd_htinfo = local_rx_pd->ht_info; |
| 100 | 96 | ||
| 101 | ret = mwifiex_recv_packet(adapter, skb); | 97 | ret = mwifiex_recv_packet(priv, skb); |
| 102 | if (ret == -1) | 98 | if (ret == -1) |
| 103 | dev_err(adapter->dev, "recv packet failed\n"); | 99 | dev_err(priv->adapter->dev, "recv packet failed\n"); |
| 104 | 100 | ||
| 105 | return ret; | 101 | return ret; |
| 106 | } | 102 | } |
| @@ -117,21 +113,15 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, · 10 unmodified lines | |||
| 117 | * | 113 | * |
| 118 | * The completion callback is called after processing in complete. | 114 | * The completion callback is called after processing in complete. |
| 119 | */ | 115 | */ |
| 120 | int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | 116 | int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv, |
| 121 | struct sk_buff *skb) | 117 | struct sk_buff *skb) |
| 122 | { | 118 | { |
| 119 | struct mwifiex_adapter *adapter = priv->adapter; | ||
| 123 | int ret = 0; | 120 | int ret = 0; |
| 124 | struct rxpd *local_rx_pd; | 121 | struct rxpd *local_rx_pd; |
| 125 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); | ||
| 126 | struct rx_packet_hdr *rx_pkt_hdr; | 122 | struct rx_packet_hdr *rx_pkt_hdr; |
| 127 | u8 ta[ETH_ALEN]; | 123 | u8 ta[ETH_ALEN]; |
| 128 | u16 rx_pkt_type, rx_pkt_offset, rx_pkt_length, seq_num; | 124 | u16 rx_pkt_type, rx_pkt_offset, rx_pkt_length, seq_num; |
| 129 | struct mwifiex_private *priv = | ||
| 130 | mwifiex_get_priv_by_id(adapter, rx_info->bss_num, | ||
| 131 | rx_info->bss_type); | ||
| 132 | |||
| 133 | if (!priv) | ||
| 134 | return -1; | ||
| 135 | 125 | ||
| 136 | local_rx_pd = (struct rxpd *) (skb->data); | 126 | local_rx_pd = (struct rxpd *) (skb->data); |
| 137 | rx_pkt_type = le16_to_cpu(local_rx_pd->rx_pkt_type); | 127 | rx_pkt_type = le16_to_cpu(local_rx_pd->rx_pkt_type); |
| @@ -169,13 +159,13 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, · 31 unmodified lines | |||
| 169 | 159 | ||
| 170 | while (!skb_queue_empty(&list)) { | 160 | while (!skb_queue_empty(&list)) { |
| 171 | rx_skb = __skb_dequeue(&list); | 161 | rx_skb = __skb_dequeue(&list); |
| 172 | ret = mwifiex_recv_packet(adapter, rx_skb); | 162 | ret = mwifiex_recv_packet(priv, rx_skb); |
| 173 | if (ret == -1) | 163 | if (ret == -1) |
| 174 | dev_err(adapter->dev, "Rx of A-MSDU failed"); | 164 | dev_err(adapter->dev, "Rx of A-MSDU failed"); |
| 175 | } | 165 | } |
| 176 | return 0; | 166 | return 0; |
| 177 | } else if (rx_pkt_type == PKT_TYPE_MGMT) { | 167 | } else if (rx_pkt_type == PKT_TYPE_MGMT) { |
| 178 | ret = mwifiex_process_mgmt_packet(adapter, skb); | 168 | ret = mwifiex_process_mgmt_packet(priv, skb); |
| 179 | if (ret) | 169 | if (ret) |
| 180 | dev_err(adapter->dev, "Rx of mgmt packet failed"); | 170 | dev_err(adapter->dev, "Rx of mgmt packet failed"); |
| 181 | dev_kfree_skb_any(skb); | 171 | dev_kfree_skb_any(skb); |
| @@ -188,7 +178,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, · 6 unmodified lines | |||
| 188 | */ | 178 | */ |
| 189 | if (!IS_11N_ENABLED(priv) || | 179 | if (!IS_11N_ENABLED(priv) || |
| 190 | memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) { | 180 | memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) { |
| 191 | mwifiex_process_rx_packet(adapter, skb); | 181 | mwifiex_process_rx_packet(priv, skb); |
| 192 | return ret; | 182 | return ret; |
| 193 | } | 183 | } |
| 194 | 184 | ||
| @@ -48,13 +48,19 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, · 47 unmodified lines | |||
| 48 | if (!priv) | 48 | if (!priv) |
| 49 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 49 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
| 50 | 50 | ||
| 51 | if (!priv) { | ||
| 52 | dev_err(adapter->dev, "data: priv not found. Drop RX packet\n"); | ||
| 53 | dev_kfree_skb_any(skb); | ||
| 54 | return -1; | ||
| 55 | } | ||
| 56 | |||
| 51 | rx_info->bss_num = priv->bss_num; | 57 | rx_info->bss_num = priv->bss_num; |
| 52 | rx_info->bss_type = priv->bss_type; | 58 | rx_info->bss_type = priv->bss_type; |
| 53 | 59 | ||
| 54 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) | 60 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) |
| 55 | return mwifiex_process_uap_rx_packet(adapter, skb); | 61 | return mwifiex_process_uap_rx_packet(priv, skb); |
| 56 | 62 | ||
| 57 | return mwifiex_process_sta_rx_packet(adapter, skb); | 63 | return mwifiex_process_sta_rx_packet(priv, skb); |
| 58 | } | 64 | } |
| 59 | EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); | 65 | EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet); |
| 60 | 66 | ||
| @@ -188,10 +188,19 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, · 187 unmodified lines | |||
| 188 | int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); | 188 | int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable); |
| 189 | const u8 *var_pos = params->beacon.head + var_offset; | 189 | const u8 *var_pos = params->beacon.head + var_offset; |
| 190 | int len = params->beacon.head_len - var_offset; | 190 | int len = params->beacon.head_len - var_offset; |
| 191 | u8 rate_len = 0; | ||
| 191 | 192 | ||
| 192 | rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); | 193 | rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len); |
| 193 | if (rate_ie) | 194 | if (rate_ie) { |
| 194 | memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len); | 195 | memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len); |
| 196 | rate_len = rate_ie->len; | ||
| 197 | } | ||
| 198 | |||
| 199 | rate_ie = (void *)cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, | ||
| 200 | params->beacon.tail, | ||
| 201 | params->beacon.tail_len); | ||
| 202 | if (rate_ie) | ||
| 203 | memcpy(bss_cfg->rates + rate_len, rate_ie + 1, rate_ie->len); | ||
| 195 | 204 | ||
| 196 | return; | 205 | return; |
| 197 | } | 206 | } |
| @@ -146,7 +146,7 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, · 145 unmodified lines | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | /* Forward unicat/Inter-BSS packets to kernel. */ | 148 | /* Forward unicat/Inter-BSS packets to kernel. */ |
| 149 | return mwifiex_process_rx_packet(adapter, skb); | 149 | return mwifiex_process_rx_packet(priv, skb); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | /* | 152 | /* |
| @@ -159,24 +159,17 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, · 6 unmodified lines | |||
| 159 | * | 159 | * |
| 160 | * The completion callback is called after processing is complete. | 160 | * The completion callback is called after processing is complete. |
| 161 | */ | 161 | */ |
| 162 | int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, | 162 | int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, |
| 163 | struct sk_buff *skb) | 163 | struct sk_buff *skb) |
| 164 | { | 164 | { |
| 165 | struct mwifiex_adapter *adapter = priv->adapter; | ||
| 165 | int ret; | 166 | int ret; |
| 166 | struct uap_rxpd *uap_rx_pd; | 167 | struct uap_rxpd *uap_rx_pd; |
| 167 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); | ||
| 168 | struct rx_packet_hdr *rx_pkt_hdr; | 168 | struct rx_packet_hdr *rx_pkt_hdr; |
| 169 | u16 rx_pkt_type; | 169 | u16 rx_pkt_type; |
| 170 | u8 ta[ETH_ALEN], pkt_type; | 170 | u8 ta[ETH_ALEN], pkt_type; |
| 171 | struct mwifiex_sta_node *node; | 171 | struct mwifiex_sta_node *node; |
| 172 | 172 | ||
| 173 | struct mwifiex_private *priv = | ||
| 174 | mwifiex_get_priv_by_id(adapter, rx_info->bss_num, | ||
| 175 | rx_info->bss_type); | ||
| 176 | |||
| 177 | if (!priv) | ||
| 178 | return -1; | ||
| 179 | |||
| 180 | uap_rx_pd = (struct uap_rxpd *)(skb->data); | 173 | uap_rx_pd = (struct uap_rxpd *)(skb->data); |
| 181 | rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); | 174 | rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); |
| 182 | rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); | 175 | rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); |
| @@ -210,7 +203,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, · 27 unmodified lines | |||
| 210 | 203 | ||
| 211 | while (!skb_queue_empty(&list)) { | 204 | while (!skb_queue_empty(&list)) { |
| 212 | rx_skb = __skb_dequeue(&list); | 205 | rx_skb = __skb_dequeue(&list); |
| 213 | ret = mwifiex_recv_packet(adapter, rx_skb); | 206 | ret = mwifiex_recv_packet(priv, rx_skb); |
| 214 | if (ret) | 207 | if (ret) |
| 215 | dev_err(adapter->dev, | 208 | dev_err(adapter->dev, |
| 216 | "AP:Rx A-MSDU failed"); | 209 | "AP:Rx A-MSDU failed"); |
| @@ -218,7 +211,7 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter, · 1 unmodified line | |||
| 218 | 211 | ||
| 219 | return 0; | 212 | return 0; |
| 220 | } else if (rx_pkt_type == PKT_TYPE_MGMT) { | 213 | } else if (rx_pkt_type == PKT_TYPE_MGMT) { |
| 221 | ret = mwifiex_process_mgmt_packet(adapter, skb); | 214 | ret = mwifiex_process_mgmt_packet(priv, skb); |
| 222 | if (ret) | 215 | if (ret) |
| 223 | dev_err(adapter->dev, "Rx of mgmt packet failed"); | 216 | dev_err(adapter->dev, "Rx of mgmt packet failed"); |
| 224 | dev_kfree_skb_any(skb); | 217 | dev_kfree_skb_any(skb); |
| @@ -146,20 +146,16 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, · 145 unmodified lines | |||
| 146 | * to the kernel. | 146 | * to the kernel. |
| 147 | */ | 147 | */ |
| 148 | int | 148 | int |
| 149 | mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter, | 149 | mwifiex_process_mgmt_packet(struct mwifiex_private *priv, |
| 150 | struct sk_buff *skb) | 150 | struct sk_buff *skb) |
| 151 | { | 151 | { |
| 152 | struct rxpd *rx_pd; | 152 | struct rxpd *rx_pd; |
| 153 | struct mwifiex_private *priv; | ||
| 154 | u16 pkt_len; | 153 | u16 pkt_len; |
| 155 | 154 | ||
| 156 | if (!skb) | 155 | if (!skb) |
| 157 | return -1; | 156 | return -1; |
| 158 | 157 | ||
| 159 | rx_pd = (struct rxpd *)skb->data; | 158 | rx_pd = (struct rxpd *)skb->data; |
| 160 | priv = mwifiex_get_priv_by_id(adapter, rx_pd->bss_num, rx_pd->bss_type); | ||
| 161 | if (!priv) | ||
| 162 | return -1; | ||
| 163 | 159 | ||
| 164 | skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); | 160 | skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); |
| 165 | skb_pull(skb, sizeof(pkt_len)); | 161 | skb_pull(skb, sizeof(pkt_len)); |
| @@ -190,20 +186,11 @@ mwifiex_process_mgmt_packet(struct mwifiex_adapter *adapter, · 24 unmodified lines | |||
| 190 | * the function creates a blank SKB, fills it with the data from the | 186 | * the function creates a blank SKB, fills it with the data from the |
| 191 | * received buffer and then sends this new SKB to the kernel. | 187 | * received buffer and then sends this new SKB to the kernel. |
| 192 | */ | 188 | */ |
| 193 | int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) | 189 | int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) |
| 194 | { | 190 | { |
| 195 | struct mwifiex_rxinfo *rx_info; | ||
| 196 | struct mwifiex_private *priv; | ||
| 197 | |||
| 198 | if (!skb) | 191 | if (!skb) |
| 199 | return -1; | 192 | return -1; |
| 200 | 193 | ||
| 201 | rx_info = MWIFIEX_SKB_RXCB(skb); | ||
| 202 | priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, | ||
| 203 | rx_info->bss_type); | ||
| 204 | if (!priv) | ||
| 205 | return -1; | ||
| 206 | |||
| 207 | skb->dev = priv->netdev; | 194 | skb->dev = priv->netdev; |
| 208 | skb->protocol = eth_type_trans(skb, priv->netdev); | 195 | skb->protocol = eth_type_trans(skb, priv->netdev); |
| 209 | skb->ip_summed = CHECKSUM_NONE; | 196 | skb->ip_summed = CHECKSUM_NONE; |
| @@ -225,7 +212,7 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) · 15 unmodified lines | |||
| 225 | * fragments. Currently we fail the Filesndl-ht.scr script | 212 | * fragments. Currently we fail the Filesndl-ht.scr script |
| 226 | * for UDP, hence this fix | 213 | * for UDP, hence this fix |
| 227 | */ | 214 | */ |
| 228 | if ((adapter->iface_type == MWIFIEX_USB) && | 215 | if ((priv->adapter->iface_type == MWIFIEX_USB) && |
| 229 | (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) | 216 | (skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE)) |
| 230 | skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); | 217 | skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); |
| 231 | 218 | ||
| @@ -39,7 +39,7 @@ static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len) · 38 unmodified lines | |||
| 39 | { | 39 | { |
| 40 | u8 *p = data; | 40 | u8 *p = data; |
| 41 | while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) { | 41 | while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) { |
| 42 | if ((p[0] == WLAN_EID_GENERIC) && | 42 | if ((p[0] == WLAN_EID_VENDOR_SPECIFIC) && |
| 43 | (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0)) | 43 | (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0)) |
| 44 | return p; | 44 | return p; |
| 45 | p += p[1] + 2; | 45 | p += p[1] + 2; |
| @@ -865,7 +865,7 @@ static int ezusb_firmware_download(struct ezusb_priv *upriv, · 864 unmodified lines | |||
| 865 | static int ezusb_access_ltv(struct ezusb_priv *upriv, | 865 | static int ezusb_access_ltv(struct ezusb_priv *upriv, |
| 866 | struct request_context *ctx, | 866 | struct request_context *ctx, |
| 867 | u16 length, const void *data, u16 frame_type, | 867 | u16 length, const void *data, u16 frame_type, |
| 868 | void *ans_buff, int ans_size, u16 *ans_length) | 868 | void *ans_buff, unsigned ans_size, u16 *ans_length) |
| 869 | { | 869 | { |
| 870 | int req_size; | 870 | int req_size; |
| 871 | int retval = 0; | 871 | int retval = 0; |
| @@ -933,7 +933,7 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, · 61 unmodified lines | |||
| 933 | } | 933 | } |
| 934 | if (ctx->in_rid) { | 934 | if (ctx->in_rid) { |
| 935 | struct ezusb_packet *ans = ctx->buf; | 935 | struct ezusb_packet *ans = ctx->buf; |
| 936 | int exp_len; | 936 | unsigned exp_len; |
| 937 | 937 | ||
| 938 | if (ans->hermes_len != 0) | 938 | if (ans->hermes_len != 0) |
| 939 | exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12; | 939 | exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12; |
| @@ -949,8 +949,7 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, · 9 unmodified lines | |||
| 949 | } | 949 | } |
| 950 | 950 | ||
| 951 | if (ans_buff) | 951 | if (ans_buff) |
| 952 | memcpy(ans_buff, ans->data, | 952 | memcpy(ans_buff, ans->data, min(exp_len, ans_size)); |
| 953 | min_t(int, exp_len, ans_size)); | ||
| 954 | if (ans_length) | 953 | if (ans_length) |
| 955 | *ans_length = le16_to_cpu(ans->hermes_len); | 954 | *ans_length = le16_to_cpu(ans->hermes_len); |
| 956 | } | 955 | } |
| @@ -995,7 +994,7 @@ static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid, · 38 unmodified lines | |||
| 995 | struct ezusb_priv *upriv = hw->priv; | 994 | struct ezusb_priv *upriv = hw->priv; |
| 996 | struct request_context *ctx; | 995 | struct request_context *ctx; |
| 997 | 996 | ||
| 998 | if ((bufsize < 0) || (bufsize % 2)) | 997 | if (bufsize % 2) |
| 999 | return -EINVAL; | 998 | return -EINVAL; |
| 1000 | 999 | ||
| 1001 | ctx = ezusb_alloc_ctx(upriv, rid, rid); | 1000 | ctx = ezusb_alloc_ctx(upriv, rid, rid); |
| @@ -2520,20 +2520,37 @@ static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, · 2519 unmodified lines | |||
| 2520 | return comp_value; | 2520 | return comp_value; |
| 2521 | } | 2521 | } |
| 2522 | 2522 | ||
| 2523 | static int rt2800_get_txpower_reg_delta(struct rt2x00_dev *rt2x00dev, | ||
| 2524 | int power_level, int max_power) | ||
| 2525 | { | ||
| 2526 | int delta; | ||
| 2527 | |||
| 2528 | if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) | ||
| 2529 | return 0; | ||
| 2530 | |||
| 2531 | /* | ||
| 2532 | * XXX: We don't know the maximum transmit power of our hardware since | ||
| 2533 | * the EEPROM doesn't expose it. We only know that we are calibrated | ||
| 2534 | * to 100% tx power. | ||
| 2535 | * | ||
| 2536 | * Hence, we assume the regulatory limit that cfg80211 calulated for | ||
| 2537 | * the current channel is our maximum and if we are requested to lower | ||
| 2538 | * the value we just reduce our tx power accordingly. | ||
| 2539 | */ | ||
| 2540 | delta = power_level - max_power; | ||
| 2541 | return min(delta, 0); | ||
| 2542 | } | ||
| 2543 | |||
| 2523 | static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, | 2544 | static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, |
| 2524 | enum ieee80211_band band, int power_level, | 2545 | enum ieee80211_band band, int power_level, |
| 2525 | u8 txpower, int delta) | 2546 | u8 txpower, int delta) |
| 2526 | { | 2547 | { |
| 2527 | u32 reg; | ||
| 2528 | u16 eeprom; | 2548 | u16 eeprom; |
| 2529 | u8 criterion; | 2549 | u8 criterion; |
| 2530 | u8 eirp_txpower; | 2550 | u8 eirp_txpower; |
| 2531 | u8 eirp_txpower_criterion; | 2551 | u8 eirp_txpower_criterion; |
| 2532 | u8 reg_limit; | 2552 | u8 reg_limit; |
| 2533 | 2553 | ||
| 2534 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) | ||
| 2535 | return txpower; | ||
| 2536 | |||
| 2537 | if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { | 2554 | if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { |
| 2538 | /* | 2555 | /* |
| 2539 | * Check if eirp txpower exceed txpower_limit. | 2556 | * Check if eirp txpower exceed txpower_limit. |
| @@ -2542,11 +2559,13 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, · 2 unmodified lines | |||
| 2542 | * .11b data rate need add additional 4dbm | 2559 | * .11b data rate need add additional 4dbm |
| 2543 | * when calculating eirp txpower. | 2560 | * when calculating eirp txpower. |
| 2544 | */ | 2561 | */ |
| 2545 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); | 2562 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + 1, |
| 2546 | criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); | 2563 | &eeprom); |
| 2564 | criterion = rt2x00_get_field16(eeprom, | ||
| 2565 | EEPROM_TXPOWER_BYRATE_RATE0); | ||
| 2547 | 2566 | ||
| 2548 | rt2x00_eeprom_read(rt2x00dev, | 2567 | rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, |
| 2549 | EEPROM_EIRP_MAX_TX_POWER, &eeprom); | 2568 | &eeprom); |
| 2550 | 2569 | ||
| 2551 | if (band == IEEE80211_BAND_2GHZ) | 2570 | if (band == IEEE80211_BAND_2GHZ) |
| 2552 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | 2571 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, |
| @@ -2563,36 +2582,71 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, · 10 unmodified lines | |||
| 2563 | } else | 2582 | } else |
| 2564 | reg_limit = 0; | 2583 | reg_limit = 0; |
| 2565 | 2584 | ||
| 2566 | return txpower + delta - reg_limit; | 2585 | txpower = max(0, txpower + delta - reg_limit); |
| 2586 | return min_t(u8, txpower, 0xc); | ||
| 2567 | } | 2587 | } |
| 2568 | 2588 | ||
| 2589 | /* | ||
| 2590 | * We configure transmit power using MAC TX_PWR_CFG_{0,...,N} registers and | ||
| 2591 | * BBP R1 register. TX_PWR_CFG_X allow to configure per rate TX power values, | ||
| 2592 | * 4 bits for each rate (tune from 0 to 15 dBm). BBP_R1 controls transmit power | ||
| 2593 | * for all rates, but allow to set only 4 discrete values: -12, -6, 0 and 6 dBm. | ||
| 2594 | * Reference per rate transmit power values are located in the EEPROM at | ||
| 2595 | * EEPROM_TXPOWER_BYRATE offset. We adjust them and BBP R1 settings according to | ||
| 2596 | * current conditions (i.e. band, bandwidth, temperature, user settings). | ||
| 2597 | */ | ||
| 2569 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 2598 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, |
| 2570 | enum ieee80211_band band, | 2599 | struct ieee80211_channel *chan, |
| 2571 | int power_level) | 2600 | int power_level) |
| 2572 | { | 2601 | { |
| 2573 | u8 txpower; | 2602 | u8 txpower, r1; |
| 2574 | u16 eeprom; | 2603 | u16 eeprom; |
| 2575 | int i, is_rate_b; | 2604 | u32 reg, offset; |
| 2576 | u32 reg; | 2605 | int i, is_rate_b, delta, power_ctrl; |
| 2577 | u8 r1; | 2606 | enum ieee80211_band band = chan->band; |
| 2578 | u32 offset; | ||
| 2579 | int delta; | ||
| 2580 | 2607 | ||
| 2581 | /* | 2608 | /* |
| 2582 | * Calculate HT40 compensation delta | 2609 | * Calculate HT40 compensation. For 40MHz we need to add or subtract |
| 2610 | * value read from EEPROM (different for 2GHz and for 5GHz). | ||
| 2583 | */ | 2611 | */ |
| 2584 | delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); | 2612 | delta = rt2800_get_txpower_bw_comp(rt2x00dev, band); |
| 2585 | 2613 | ||
| 2586 | /* | 2614 | /* |
| 2587 | * calculate temperature compensation delta | 2615 | * Calculate temperature compensation. Depends on measurement of current |
| 2616 | * TSSI (Transmitter Signal Strength Indication) we know TX power (due | ||
| 2617 | * to temperature or maybe other factors) is smaller or bigger than | ||
| 2618 | * expected. We adjust it, based on TSSI reference and boundaries values | ||
| 2619 | * provided in EEPROM. | ||
| 2588 | */ | 2620 | */ |
| 2589 | delta += rt2800_get_gain_calibration_delta(rt2x00dev); | 2621 | delta += rt2800_get_gain_calibration_delta(rt2x00dev); |
| 2590 | 2622 | ||
| 2591 | /* | 2623 | /* |
| 2592 | * set to normal bbp tx power control mode: +/- 0dBm | 2624 | * Decrease power according to user settings, on devices with unknown |
| 2625 | * maximum tx power. For other devices we take user power_level into | ||
| 2626 | * consideration on rt2800_compensate_txpower(). | ||
| 2627 | */ | ||
| 2628 | delta += rt2800_get_txpower_reg_delta(rt2x00dev, power_level, | ||
| 2629 | chan->max_power); | ||
| 2630 | |||
| 2631 | /* | ||
| 2632 | * BBP_R1 controls TX power for all rates, it allow to set the following | ||
| 2633 | * gains -12, -6, 0, +6 dBm by setting values 2, 1, 0, 3 respectively. | ||
| 2634 | * | ||
| 2635 | * TODO: we do not use +6 dBm option to do not increase power beyond | ||
| 2636 | * regulatory limit, however this could be utilized for devices with | ||
| 2637 | * CAPABILITY_POWER_LIMIT. | ||
| 2593 | */ | 2638 | */ |
| 2594 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 2639 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
| 2595 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); | 2640 | if (delta <= -12) { |
| 2641 | power_ctrl = 2; | ||
| 2642 | delta += 12; | ||
| 2643 | } else if (delta <= -6) { | ||
| 2644 | power_ctrl = 1; | ||
| 2645 | delta += 6; | ||
| 2646 | } else { | ||
| 2647 | power_ctrl = 0; | ||
| 2648 | } | ||
| 2649 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, power_ctrl); | ||
| 2596 | rt2800_bbp_write(rt2x00dev, 1, r1); | 2650 | rt2800_bbp_write(rt2x00dev, 1, r1); |
| 2597 | offset = TX_PWR_CFG_0; | 2651 | offset = TX_PWR_CFG_0; |
| 2598 | 2652 | ||
| @@ -2710,7 +2764,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, · 111 unmodified lines | |||
| 2710 | 2764 | ||
| 2711 | void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) | 2765 | void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) |
| 2712 | { | 2766 | { |
| 2713 | rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band, | 2767 | rt2800_config_txpower(rt2x00dev, rt2x00dev->hw->conf.channel, |
| 2714 | rt2x00dev->tx_power); | 2768 | rt2x00dev->tx_power); |
| 2715 | } | 2769 | } |
| 2716 | EXPORT_SYMBOL_GPL(rt2800_gain_calibration); | 2770 | EXPORT_SYMBOL_GPL(rt2800_gain_calibration); |
| @@ -2845,11 +2899,11 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, · 128 unmodified lines | |||
| 2845 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { | 2899 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 2846 | rt2800_config_channel(rt2x00dev, libconf->conf, | 2900 | rt2800_config_channel(rt2x00dev, libconf->conf, |
| 2847 | &libconf->rf, &libconf->channel); | 2901 | &libconf->rf, &libconf->channel); |
| 2848 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, | 2902 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel, |
| 2849 | libconf->conf->power_level); | 2903 | libconf->conf->power_level); |
| 2850 | } | 2904 | } |
| 2851 | if (flags & IEEE80211_CONF_CHANGE_POWER) | 2905 | if (flags & IEEE80211_CONF_CHANGE_POWER) |
| 2852 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band, | 2906 | rt2800_config_txpower(rt2x00dev, libconf->conf->channel, |
| 2853 | libconf->conf->power_level); | 2907 | libconf->conf->power_level); |
| 2854 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 2908 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
| 2855 | rt2800_config_retry_limit(rt2x00dev, libconf); | 2909 | rt2800_config_retry_limit(rt2x00dev, libconf); |
| @@ -52,11 +52,8 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, · 51 unmodified lines | |||
| 52 | u32 target_content = 0; | 52 | u32 target_content = 0; |
| 53 | u8 entry_i; | 53 | u8 entry_i; |
| 54 | 54 | ||
| 55 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | 55 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %6phC\n", |
| 56 | "key_cont_128:\n %x:%x:%x:%x:%x:%x\n", | 56 | key_cont_128); |
| 57 | key_cont_128[0], key_cont_128[1], | ||
| 58 | key_cont_128[2], key_cont_128[3], | ||
| 59 | key_cont_128[4], key_cont_128[5]); | ||
| 60 | 57 | ||
| 61 | for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { | 58 | for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { |
| 62 | target_command = entry_i + CAM_CONTENT_COUNT * entry_no; | 59 | target_command = entry_i + CAM_CONTENT_COUNT * entry_no; |
| @@ -43,8 +43,8 @@ · 42 unmodified lines | |||
| 43 | #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ | 43 | #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ |
| 44 | ((RTLPRIV(_priv))->mac80211.opmode == \ | 44 | ((RTLPRIV(_priv))->mac80211.opmode == \ |
| 45 | NL80211_IFTYPE_ADHOC) ? \ | 45 | NL80211_IFTYPE_ADHOC) ? \ |
| 46 | ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ | 46 | ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \ |
| 47 | ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) | 47 | ((RTLPRIV(_priv))->dm.undec_sm_pwdb) |
| 48 | 48 | ||
| 49 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | 49 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { |
| 50 | 0x7f8001fe, | 50 | 0x7f8001fe, |
| @@ -167,18 +167,18 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw) · 116 unmodified lines | |||
| 167 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 167 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
| 168 | dm_digtable->cur_igvalue = 0x20; | 168 | dm_digtable->cur_igvalue = 0x20; |
| 169 | dm_digtable->pre_igvalue = 0x0; | 169 | dm_digtable->pre_igvalue = 0x0; |
| 170 | dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; | 170 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; |
| 171 | dm_digtable->presta_connectstate = DIG_STA_DISCONNECT; | 171 | dm_digtable->presta_cstate = DIG_STA_DISCONNECT; |
| 172 | dm_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; | 172 | dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; |
| 173 | dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; | 173 | dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; |
| 174 | dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; | 174 | dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; |
| 175 | dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | 175 | dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; |
| 176 | dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | 176 | dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; |
| 177 | dm_digtable->rx_gain_range_max = DM_DIG_MAX; | 177 | dm_digtable->rx_gain_range_max = DM_DIG_MAX; |
| 178 | dm_digtable->rx_gain_range_min = DM_DIG_MIN; | 178 | dm_digtable->rx_gain_range_min = DM_DIG_MIN; |
| 179 | dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; | 179 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; |
| 180 | dm_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; | 180 | dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; |
| 181 | dm_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; | 181 | dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; |
| 182 | dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; | 182 | dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; |
| 183 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | 183 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; |
| 184 | } | 184 | } |
| @@ -189,22 +189,21 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 189 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 189 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
| 190 | long rssi_val_min = 0; | 190 | long rssi_val_min = 0; |
| 191 | 191 | ||
| 192 | if ((dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) && | 192 | if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && |
| 193 | (dm_digtable->cursta_connectstate == DIG_STA_CONNECT)) { | 193 | (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { |
| 194 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) | 194 | if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) |
| 195 | rssi_val_min = | 195 | rssi_val_min = |
| 196 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > | 196 | (rtlpriv->dm.entry_min_undec_sm_pwdb > |
| 197 | rtlpriv->dm.undecorated_smoothed_pwdb) ? | 197 | rtlpriv->dm.undec_sm_pwdb) ? |
| 198 | rtlpriv->dm.undecorated_smoothed_pwdb : | 198 | rtlpriv->dm.undec_sm_pwdb : |
| 199 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | 199 | rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 200 | else | 200 | else |
| 201 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | 201 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; |
| 202 | } else if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT || | 202 | } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || |
| 203 | dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT) { | 203 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { |
| 204 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | 204 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; |
| 205 | } else if (dm_digtable->curmultista_connectstate == | 205 | } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { |
| 206 | DIG_MULTISTA_CONNECT) { | 206 | rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 207 | rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | return (u8) rssi_val_min; | 209 | return (u8) rssi_val_min; |
| @@ -286,37 +285,33 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) · 75 unmodified lines | |||
| 286 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | 285 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) |
| 287 | { | 286 | { |
| 288 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 287 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 289 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 288 | struct dig_t *digtable = &rtlpriv->dm_digtable; |
| 290 | 289 | ||
| 291 | if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) { | 290 | if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { |
| 292 | if ((dm_digtable->backoff_val - 2) < | 291 | if ((digtable->back_val - 2) < digtable->back_range_min) |
| 293 | dm_digtable->backoff_val_range_min) | 292 | digtable->back_val = digtable->back_range_min; |
| 294 | dm_digtable->backoff_val = | ||
| 295 | dm_digtable->backoff_val_range_min; | ||
| 296 | else | 293 | else |
| 297 | dm_digtable->backoff_val -= 2; | 294 | digtable->back_val -= 2; |
| 298 | } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) { | 295 | } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { |
| 299 | if ((dm_digtable->backoff_val + 2) > | 296 | if ((digtable->back_val + 2) > digtable->back_range_max) |
| 300 | dm_digtable->backoff_val_range_max) | 297 | digtable->back_val = digtable->back_range_max; |
| 301 | dm_digtable->backoff_val = | ||
| 302 | dm_digtable->backoff_val_range_max; | ||
| 303 | else | 298 | else |
| 304 | dm_digtable->backoff_val += 2; | 299 | digtable->back_val += 2; |
| 305 | } | 300 | } |
| 306 | 301 | ||
| 307 | if ((dm_digtable->rssi_val_min + 10 - dm_digtable->backoff_val) > | 302 | if ((digtable->rssi_val_min + 10 - digtable->back_val) > |
| 308 | dm_digtable->rx_gain_range_max) | 303 | digtable->rx_gain_range_max) |
| 309 | dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_max; | 304 | digtable->cur_igvalue = digtable->rx_gain_range_max; |
| 310 | else if ((dm_digtable->rssi_val_min + 10 - | 305 | else if ((digtable->rssi_val_min + 10 - |
| 311 | dm_digtable->backoff_val) < dm_digtable->rx_gain_range_min) | 306 | digtable->back_val) < digtable->rx_gain_range_min) |
| 312 | dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_min; | 307 | digtable->cur_igvalue = digtable->rx_gain_range_min; |
| 313 | else | 308 | else |
| 314 | dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 - | 309 | digtable->cur_igvalue = digtable->rssi_val_min + 10 - |
| 315 | dm_digtable->backoff_val; | 310 | digtable->back_val; |
| 316 | 311 | ||
| 317 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | 312 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, |
| 318 | "rssi_val_min = %x backoff_val %x\n", | 313 | "rssi_val_min = %x back_val %x\n", |
| 319 | dm_digtable->rssi_val_min, dm_digtable->backoff_val); | 314 | digtable->rssi_val_min, digtable->back_val); |
| 320 | 315 | ||
| 321 | rtl92c_dm_write_dig(hw); | 316 | rtl92c_dm_write_dig(hw); |
| 322 | } | 317 | } |
| @@ -327,14 +322,14 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 327 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 322 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 328 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 323 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
| 329 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 324 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 330 | long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | 325 | long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 331 | bool multi_sta = false; | 326 | bool multi_sta = false; |
| 332 | 327 | ||
| 333 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | 328 | if (mac->opmode == NL80211_IFTYPE_ADHOC) |
| 334 | multi_sta = true; | 329 | multi_sta = true; |
| 335 | 330 | ||
| 336 | if (!multi_sta || | 331 | if (!multi_sta || |
| 337 | dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { | 332 | dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { |
| 338 | initialized = false; | 333 | initialized = false; |
| 339 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 334 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
| 340 | return; | 335 | return; |
| @@ -345,7 +340,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 345 | rtl92c_dm_write_dig(hw); | 340 | rtl92c_dm_write_dig(hw); |
| 346 | } | 341 | } |
| 347 | 342 | ||
| 348 | if (dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) { | 343 | if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { |
| 349 | if ((rssi_strength < dm_digtable->rssi_lowthresh) && | 344 | if ((rssi_strength < dm_digtable->rssi_lowthresh) && |
| 350 | (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { | 345 | (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { |
| 351 | 346 | ||
| @@ -367,8 +362,8 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) · 15 unmodified lines | |||
| 367 | } | 362 | } |
| 368 | 363 | ||
| 369 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | 364 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, |
| 370 | "curmultista_connectstate = %x dig_ext_port_stage %x\n", | 365 | "curmultista_cstate = %x dig_ext_port_stage %x\n", |
| 371 | dm_digtable->curmultista_connectstate, | 366 | dm_digtable->curmultista_cstate, |
| 372 | dm_digtable->dig_ext_port_stage); | 367 | dm_digtable->dig_ext_port_stage); |
| 373 | } | 368 | } |
| 374 | 369 | ||
| @@ -378,15 +373,14 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) · 3 unmodified lines | |||
| 378 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 373 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
| 379 | 374 | ||
| 380 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | 375 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, |
| 381 | "presta_connectstate = %x, cursta_connectstate = %x\n", | 376 | "presta_cstate = %x, cursta_cstate = %x\n", |
| 382 | dm_digtable->presta_connectstate, | 377 | dm_digtable->presta_cstate, dm_digtable->cursta_cstate); |
| 383 | dm_digtable->cursta_connectstate); | ||
| 384 | 378 | ||
| 385 | if (dm_digtable->presta_connectstate == dm_digtable->cursta_connectstate | 379 | if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || |
| 386 | || dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT | 380 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || |
| 387 | || dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { | 381 | dm_digtable->cursta_cstate == DIG_STA_CONNECT) { |
| 388 | 382 | ||
| 389 | if (dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { | 383 | if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { |
| 390 | dm_digtable->rssi_val_min = | 384 | dm_digtable->rssi_val_min = |
| 391 | rtl92c_dm_initial_gain_min_pwdb(hw); | 385 | rtl92c_dm_initial_gain_min_pwdb(hw); |
| 392 | rtl92c_dm_ctrl_initgain_by_rssi(hw); | 386 | rtl92c_dm_ctrl_initgain_by_rssi(hw); |
| @@ -394,7 +388,7 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) · 1 unmodified line | |||
| 394 | } else { | 388 | } else { |
| 395 | dm_digtable->rssi_val_min = 0; | 389 | dm_digtable->rssi_val_min = 0; |
| 396 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 390 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
| 397 | dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; | 391 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; |
| 398 | dm_digtable->cur_igvalue = 0x20; | 392 | dm_digtable->cur_igvalue = 0x20; |
| 399 | dm_digtable->pre_igvalue = 0; | 393 | dm_digtable->pre_igvalue = 0; |
| 400 | rtl92c_dm_write_dig(hw); | 394 | rtl92c_dm_write_dig(hw); |
| @@ -407,7 +401,7 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) · 6 unmodified lines | |||
| 407 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 401 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 408 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 402 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
| 409 | 403 | ||
| 410 | if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { | 404 | if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { |
| 411 | dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); | 405 | dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); |
| 412 | 406 | ||
| 413 | if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { | 407 | if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { |
| @@ -484,15 +478,15 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) · 70 unmodified lines | |||
| 484 | return; | 478 | return; |
| 485 | 479 | ||
| 486 | if (mac->link_state >= MAC80211_LINKED) | 480 | if (mac->link_state >= MAC80211_LINKED) |
| 487 | dm_digtable->cursta_connectstate = DIG_STA_CONNECT; | 481 | dm_digtable->cursta_cstate = DIG_STA_CONNECT; |
| 488 | else | 482 | else |
| 489 | dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; | 483 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; |
| 490 | 484 | ||
| 491 | rtl92c_dm_initial_gain_sta(hw); | 485 | rtl92c_dm_initial_gain_sta(hw); |
| 492 | rtl92c_dm_initial_gain_multi_sta(hw); | 486 | rtl92c_dm_initial_gain_multi_sta(hw); |
| 493 | rtl92c_dm_cck_packet_detection_thresh(hw); | 487 | rtl92c_dm_cck_packet_detection_thresh(hw); |
| 494 | 488 | ||
| 495 | dm_digtable->presta_connectstate = dm_digtable->cursta_connectstate; | 489 | dm_digtable->presta_cstate = dm_digtable->cursta_cstate; |
| 496 | 490 | ||
| 497 | } | 491 | } |
| 498 | 492 | ||
| @@ -526,9 +520,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) · 27 unmodified lines | |||
| 526 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | 520 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
| 527 | 521 | ||
| 528 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | 522 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, |
| 529 | "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", | 523 | "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", |
| 530 | dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, | 524 | dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, |
| 531 | dm_digtable->backoff_val); | 525 | dm_digtable->back_val); |
| 532 | 526 | ||
| 533 | dm_digtable->cur_igvalue += 2; | 527 | dm_digtable->cur_igvalue += 2; |
| 534 | if (dm_digtable->cur_igvalue > 0x3f) | 528 | if (dm_digtable->cur_igvalue > 0x3f) |
| @@ -555,20 +549,18 @@ static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) · 20 unmodified lines | |||
| 555 | return; | 549 | return; |
| 556 | 550 | ||
| 557 | if (tmpentry_max_pwdb != 0) { | 551 | if (tmpentry_max_pwdb != 0) { |
| 558 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = | 552 | rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; |
| 559 | tmpentry_max_pwdb; | ||
| 560 | } else { | 553 | } else { |
| 561 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; | 554 | rtlpriv->dm.entry_max_undec_sm_pwdb = 0; |
| 562 | } | 555 | } |
| 563 | 556 | ||
| 564 | if (tmpentry_min_pwdb != 0xff) { | 557 | if (tmpentry_min_pwdb != 0xff) { |
| 565 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = | 558 | rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; |
| 566 | tmpentry_min_pwdb; | ||
| 567 | } else { | 559 | } else { |
| 568 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; | 560 | rtlpriv->dm.entry_min_undec_sm_pwdb = 0; |
| 569 | } | 561 | } |
| 570 | 562 | ||
| 571 | h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); | 563 | h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); |
| 572 | h2c_parameter[0] = 0; | 564 | h2c_parameter[0] = 0; |
| 573 | 565 | ||
| 574 | rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); | 566 | rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); |
| @@ -1160,7 +1152,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) · 585 unmodified lines | |||
| 1160 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 1152 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 1161 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1153 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 1162 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | 1154 | struct rate_adaptive *p_ra = &(rtlpriv->ra); |
| 1163 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | 1155 | u32 low_rssi_thresh, high_rssi_thresh; |
| 1164 | struct ieee80211_sta *sta = NULL; | 1156 | struct ieee80211_sta *sta = NULL; |
| 1165 | 1157 | ||
| 1166 | if (is_hal_stop(rtlhal)) { | 1158 | if (is_hal_stop(rtlhal)) { |
| @@ -1179,35 +1171,33 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) · 12 unmodified lines | |||
| 1179 | mac->opmode == NL80211_IFTYPE_STATION) { | 1171 | mac->opmode == NL80211_IFTYPE_STATION) { |
| 1180 | switch (p_ra->pre_ratr_state) { | 1172 | switch (p_ra->pre_ratr_state) { |
| 1181 | case DM_RATR_STA_HIGH: | 1173 | case DM_RATR_STA_HIGH: |
| 1182 | high_rssithresh_for_ra = 50; | 1174 | high_rssi_thresh = 50; |
| 1183 | low_rssithresh_for_ra = 20; | 1175 | low_rssi_thresh = 20; |
| 1184 | break; | 1176 | break; |
| 1185 | case DM_RATR_STA_MIDDLE: | 1177 | case DM_RATR_STA_MIDDLE: |
| 1186 | high_rssithresh_for_ra = 55; | 1178 | high_rssi_thresh = 55; |
| 1187 | low_rssithresh_for_ra = 20; | 1179 | low_rssi_thresh = 20; |
| 1188 | break; | 1180 | break; |
| 1189 | case DM_RATR_STA_LOW: | 1181 | case DM_RATR_STA_LOW: |
| 1190 | high_rssithresh_for_ra = 50; | 1182 | high_rssi_thresh = 50; |
| 1191 | low_rssithresh_for_ra = 25; | 1183 | low_rssi_thresh = 25; |
| 1192 | break; | 1184 | break; |
| 1193 | default: | 1185 | default: |
| 1194 | high_rssithresh_for_ra = 50; | 1186 | high_rssi_thresh = 50; |
| 1195 | low_rssithresh_for_ra = 20; | 1187 | low_rssi_thresh = 20; |
| 1196 | break; | 1188 | break; |
| 1197 | } | 1189 | } |
| 1198 | 1190 | ||
| 1199 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | 1191 | if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) |
| 1200 | (long)high_rssithresh_for_ra) | ||
| 1201 | p_ra->ratr_state = DM_RATR_STA_HIGH; | 1192 | p_ra->ratr_state = DM_RATR_STA_HIGH; |
| 1202 | else if (rtlpriv->dm.undecorated_smoothed_pwdb > | 1193 | else if (rtlpriv->dm.undec_sm_pwdb > (long)low_rssi_thresh) |
| 1203 | (long)low_rssithresh_for_ra) | ||
| 1204 | p_ra->ratr_state = DM_RATR_STA_MIDDLE; | 1194 | p_ra->ratr_state = DM_RATR_STA_MIDDLE; |
| 1205 | else | 1195 | else |
| 1206 | p_ra->ratr_state = DM_RATR_STA_LOW; | 1196 | p_ra->ratr_state = DM_RATR_STA_LOW; |
| 1207 | 1197 | ||
| 1208 | if (p_ra->pre_ratr_state != p_ra->ratr_state) { | 1198 | if (p_ra->pre_ratr_state != p_ra->ratr_state) { |
| 1209 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", | 1199 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", |
| 1210 | rtlpriv->dm.undecorated_smoothed_pwdb); | 1200 | rtlpriv->dm.undec_sm_pwdb); |
| 1211 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | 1201 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, |
| 1212 | "RSSI_LEVEL = %d\n", p_ra->ratr_state); | 1202 | "RSSI_LEVEL = %d\n", p_ra->ratr_state); |
| 1213 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | 1203 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, |
| @@ -1315,7 +1305,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) · 101 unmodified lines | |||
| 1315 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 1305 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 1316 | 1306 | ||
| 1317 | if (((mac->link_state == MAC80211_NOLINK)) && | 1307 | if (((mac->link_state == MAC80211_NOLINK)) && |
| 1318 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | 1308 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { |
| 1319 | dm_pstable->rssi_val_min = 0; | 1309 | dm_pstable->rssi_val_min = 0; |
| 1320 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); | 1310 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); |
| 1321 | } | 1311 | } |
| @@ -1323,20 +1313,19 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) · 1 unmodified line | |||
| 1323 | if (mac->link_state == MAC80211_LINKED) { | 1313 | if (mac->link_state == MAC80211_LINKED) { |
| 1324 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 1314 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 1325 | dm_pstable->rssi_val_min = | 1315 | dm_pstable->rssi_val_min = |
| 1326 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | 1316 | rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 1327 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | 1317 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, |
| 1328 | "AP Client PWDB = 0x%lx\n", | 1318 | "AP Client PWDB = 0x%lx\n", |
| 1329 | dm_pstable->rssi_val_min); | 1319 | dm_pstable->rssi_val_min); |
| 1330 | } else { | 1320 | } else { |
| 1331 | dm_pstable->rssi_val_min = | 1321 | dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; |
| 1332 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 1333 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | 1322 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, |
| 1334 | "STA Default Port PWDB = 0x%lx\n", | 1323 | "STA Default Port PWDB = 0x%lx\n", |
| 1335 | dm_pstable->rssi_val_min); | 1324 | dm_pstable->rssi_val_min); |
| 1336 | } | 1325 | } |
| 1337 | } else { | 1326 | } else { |
| 1338 | dm_pstable->rssi_val_min = | 1327 | dm_pstable->rssi_val_min = |
| 1339 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | 1328 | rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 1340 | 1329 | ||
| 1341 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | 1330 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, |
| 1342 | "AP Ext Port PWDB = 0x%lx\n", | 1331 | "AP Ext Port PWDB = 0x%lx\n", |
| @@ -1368,7 +1357,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) · 25 unmodified lines | |||
| 1368 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1357 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1369 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 1358 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 1370 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1359 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 1371 | long undecorated_smoothed_pwdb; | 1360 | long undec_sm_pwdb; |
| 1372 | 1361 | ||
| 1373 | if (!rtlpriv->dm.dynamic_txpower_enable) | 1362 | if (!rtlpriv->dm.dynamic_txpower_enable) |
| 1374 | return; | 1363 | return; |
| @@ -1379,7 +1368,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 1379 | } | 1368 | } |
| 1380 | 1369 | ||
| 1381 | if ((mac->link_state < MAC80211_LINKED) && | 1370 | if ((mac->link_state < MAC80211_LINKED) && |
| 1382 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | 1371 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { |
| 1383 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 1372 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
| 1384 | "Not connected to any\n"); | 1373 | "Not connected to any\n"); |
| 1385 | 1374 | ||
| @@ -1391,41 +1380,35 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 1391 | 1380 | ||
| 1392 | if (mac->link_state >= MAC80211_LINKED) { | 1381 | if (mac->link_state >= MAC80211_LINKED) { |
| 1393 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 1382 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 1394 | undecorated_smoothed_pwdb = | 1383 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 1395 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 1396 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1384 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1397 | "AP Client PWDB = 0x%lx\n", | 1385 | "AP Client PWDB = 0x%lx\n", |
| 1398 | undecorated_smoothed_pwdb); | 1386 | undec_sm_pwdb); |
| 1399 | } else { | 1387 | } else { |
| 1400 | undecorated_smoothed_pwdb = | 1388 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 1401 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 1402 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1389 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1403 | "STA Default Port PWDB = 0x%lx\n", | 1390 | "STA Default Port PWDB = 0x%lx\n", |
| 1404 | undecorated_smoothed_pwdb); | 1391 | undec_sm_pwdb); |
| 1405 | } | 1392 | } |
| 1406 | } else { | 1393 | } else { |
| 1407 | undecorated_smoothed_pwdb = | 1394 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 1408 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 1409 | 1395 | ||
| 1410 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1396 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1411 | "AP Ext Port PWDB = 0x%lx\n", | 1397 | "AP Ext Port PWDB = 0x%lx\n", |
| 1412 | undecorated_smoothed_pwdb); | 1398 | undec_sm_pwdb); |
| 1413 | } | 1399 | } |
| 1414 | 1400 | ||
| 1415 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | 1401 | if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { |
| 1416 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 1402 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 1417 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1403 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1418 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | 1404 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); |
| 1419 | } else if ((undecorated_smoothed_pwdb < | 1405 | } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && |
| 1420 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | 1406 | (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { |
| 1421 | (undecorated_smoothed_pwdb >= | ||
| 1422 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
| 1423 | 1407 | ||
| 1424 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 1408 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 1425 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1409 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1426 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | 1410 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); |
| 1427 | } else if (undecorated_smoothed_pwdb < | 1411 | } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { |
| 1428 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
| 1429 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | 1412 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; |
| 1430 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 1413 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 1431 | "TXHIGHPWRLEVEL_NORMAL\n"); | 1414 | "TXHIGHPWRLEVEL_NORMAL\n"); |
| @@ -1473,48 +1456,46 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) · 41 unmodified lines | |||
| 1473 | { | 1456 | { |
| 1474 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1457 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1475 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | 1458 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); |
| 1476 | long undecorated_smoothed_pwdb; | 1459 | long undec_sm_pwdb; |
| 1477 | u8 curr_bt_rssi_state = 0x00; | 1460 | u8 curr_bt_rssi_state = 0x00; |
| 1478 | 1461 | ||
| 1479 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | 1462 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { |
| 1480 | undecorated_smoothed_pwdb = | 1463 | undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); |
| 1481 | GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); | ||
| 1482 | } else { | 1464 | } else { |
| 1483 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) | 1465 | if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0) |
| 1484 | undecorated_smoothed_pwdb = 100; | 1466 | undec_sm_pwdb = 100; |
| 1485 | else | 1467 | else |
| 1486 | undecorated_smoothed_pwdb = | 1468 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 1487 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 1488 | } | 1469 | } |
| 1489 | 1470 | ||
| 1490 | /* Check RSSI to determine HighPower/NormalPower state for | 1471 | /* Check RSSI to determine HighPower/NormalPower state for |
| 1491 | * BT coexistence. */ | 1472 | * BT coexistence. */ |
| 1492 | if (undecorated_smoothed_pwdb >= 67) | 1473 | if (undec_sm_pwdb >= 67) |
| 1493 | curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); | 1474 | curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); |
| 1494 | else if (undecorated_smoothed_pwdb < 62) | 1475 | else if (undec_sm_pwdb < 62) |
| 1495 | curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; | 1476 | curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; |
| 1496 | 1477 | ||
| 1497 | /* Check RSSI to determine AMPDU setting for BT coexistence. */ | 1478 | /* Check RSSI to determine AMPDU setting for BT coexistence. */ |
| 1498 | if (undecorated_smoothed_pwdb >= 40) | 1479 | if (undec_sm_pwdb >= 40) |
| 1499 | curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); | 1480 | curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); |
| 1500 | else if (undecorated_smoothed_pwdb <= 32) | 1481 | else if (undec_sm_pwdb <= 32) |
| 1501 | curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; | 1482 | curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; |
| 1502 | 1483 | ||
| 1503 | /* Marked RSSI state. It will be used to determine BT coexistence | 1484 | /* Marked RSSI state. It will be used to determine BT coexistence |
| 1504 | * setting later. */ | 1485 | * setting later. */ |
| 1505 | if (undecorated_smoothed_pwdb < 35) | 1486 | if (undec_sm_pwdb < 35) |
| 1506 | curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; | 1487 | curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; |
| 1507 | else | 1488 | else |
| 1508 | curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); | 1489 | curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); |
| 1509 | 1490 | ||
| 1510 | /* Set Tx Power according to BT status. */ | 1491 | /* Set Tx Power according to BT status. */ |
| 1511 | if (undecorated_smoothed_pwdb >= 30) | 1492 | if (undec_sm_pwdb >= 30) |
| 1512 | curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; | 1493 | curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; |
| 1513 | else if (undecorated_smoothed_pwdb < 25) | 1494 | else if (undec_sm_pwdb < 25) |
| 1514 | curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); | 1495 | curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); |
| 1515 | 1496 | ||
| 1516 | /* Check BT state related to BT_Idle in B/G mode. */ | 1497 | /* Check BT state related to BT_Idle in B/G mode. */ |
| 1517 | if (undecorated_smoothed_pwdb < 15) | 1498 | if (undec_sm_pwdb < 15) |
| 1518 | curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; | 1499 | curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; |
| 1519 | else | 1500 | else |
| 1520 | curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); | 1501 | curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); |
| @@ -34,9 +34,6 @@ · 33 unmodified lines | |||
| 34 | #include "dm_common.h" | 34 | #include "dm_common.h" |
| 35 | #include "phy_common.h" | 35 | #include "phy_common.h" |
| 36 | 36 | ||
| 37 | /* Define macro to shorten lines */ | ||
| 38 | #define MCS_TXPWR mcs_txpwrlevel_origoffset | ||
| 39 | |||
| 40 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | 37 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) |
| 41 | { | 38 | { |
| 42 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 39 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| @@ -138,13 +135,13 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, · 95 unmodified lines | |||
| 138 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | 135 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, |
| 139 | BIT(8)); | 136 | BIT(8)); |
| 140 | if (rfpi_enable) | 137 | if (rfpi_enable) |
| 141 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | 138 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, |
| 142 | BLSSIREADBACKDATA); | 139 | BLSSIREADBACKDATA); |
| 143 | else | 140 | else |
| 144 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | 141 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, |
| 145 | BLSSIREADBACKDATA); | 142 | BLSSIREADBACKDATA); |
| 146 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", | 143 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", |
| 147 | rfpath, pphyreg->rflssi_readback, retvalue); | 144 | rfpath, pphyreg->rf_rb, retvalue); |
| 148 | return retvalue; | 145 | return retvalue; |
| 149 | } | 146 | } |
| 150 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); | 147 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); |
| @@ -290,11 +287,11 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, · 139 unmodified lines | |||
| 290 | else | 287 | else |
| 291 | return; | 288 | return; |
| 292 | 289 | ||
| 293 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data; | 290 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; |
| 294 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 291 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
| 295 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", | 292 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", |
| 296 | rtlphy->pwrgroup_cnt, index, | 293 | rtlphy->pwrgroup_cnt, index, |
| 297 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]); | 294 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); |
| 298 | 295 | ||
| 299 | if (index == 13) | 296 | if (index == 13) |
| 300 | rtlphy->pwrgroup_cnt++; | 297 | rtlphy->pwrgroup_cnt++; |
| @@ -374,14 +371,10 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 73 unmodified lines | |||
| 374 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | 371 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; |
| 375 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | 372 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; |
| 376 | 373 | ||
| 377 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | 374 | rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 378 | RFPGA0_XAB_SWITCHCONTROL; | 375 | rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 379 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | 376 | rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 380 | RFPGA0_XAB_SWITCHCONTROL; | 377 | rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 381 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
| 382 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 383 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
| 384 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 385 | 378 | ||
| 386 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | 379 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; |
| 387 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | 380 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; |
| @@ -393,47 +386,33 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 393 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | 386 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; |
| 394 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | 387 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; |
| 395 | 388 | ||
| 396 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | 389 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; |
| 397 | ROFDM0_XARXIQIMBALANCE; | 390 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; |
| 398 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | 391 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; |
| 399 | ROFDM0_XBRXIQIMBALANCE; | 392 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; |
| 400 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
| 401 | ROFDM0_XCRXIQIMBANLANCE; | ||
| 402 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
| 403 | ROFDM0_XDRXIQIMBALANCE; | ||
| 404 | 393 | ||
| 405 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | 394 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; |
| 406 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | 395 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; |
| 407 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | 396 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; |
| 408 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | 397 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; |
| 409 | 398 | ||
| 410 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | 399 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; |
| 411 | ROFDM0_XATXIQIMBALANCE; | 400 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; |
| 412 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | 401 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; |
| 413 | ROFDM0_XBTXIQIMBALANCE; | 402 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; |
| 414 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
| 415 | ROFDM0_XCTXIQIMBALANCE; | ||
| 416 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
| 417 | ROFDM0_XDTXIQIMBALANCE; | ||
| 418 | 403 | ||
| 419 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | 404 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; |
| 420 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | 405 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; |
| 421 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | 406 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; |
| 422 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | 407 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; |
| 423 | 408 | ||
| 424 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | 409 | rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; |
| 425 | RFPGA0_XA_LSSIREADBACK; | 410 | rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; |
| 426 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | 411 | rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; |
| 427 | RFPGA0_XB_LSSIREADBACK; | 412 | rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; |
| 428 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
| 429 | RFPGA0_XC_LSSIREADBACK; | ||
| 430 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
| 431 | RFPGA0_XD_LSSIREADBACK; | ||
| 432 | 413 | ||
| 433 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | 414 | rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; |
| 434 | TRANSCEIVEA_HSPI_READBACK; | 415 | rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; |
| 435 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
| 436 | TRANSCEIVEB_HSPI_READBACK; | ||
| 437 | 416 | ||
| 438 | } | 417 | } |
| 439 | EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); | 418 | EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); |
| @@ -724,6 +703,26 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) · 284 unmodified lines | |||
| 724 | } | 703 | } |
| 725 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl); | 704 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl); |
| 726 | 705 | ||
| 706 | static void _rtl92c_phy_sw_rf_setting(struct ieee80211_hw *hw, u8 channel) | ||
| 707 | { | ||
| 708 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
| 709 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
| 710 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
| 711 | |||
| 712 | if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { | ||
| 713 | if (channel == 6 && rtlphy->current_chan_bw == | ||
| 714 | HT_CHANNEL_WIDTH_20) | ||
| 715 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, | ||
| 716 | 0x00255); | ||
| 717 | else{ | ||
| 718 | u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, | ||
| 719 | RF_RX_G1, RFREG_OFFSET_MASK); | ||
| 720 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, | ||
| 721 | backupRF0x1A); | ||
| 722 | } | ||
| 723 | } | ||
| 724 | } | ||
| 725 | |||
| 727 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | 726 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, |
| 728 | u32 cmdtableidx, u32 cmdtablesz, | 727 | u32 cmdtableidx, u32 cmdtablesz, |
| 729 | enum swchnlcmd_id cmdid, | 728 | enum swchnlcmd_id cmdid, |
| @@ -837,6 +836,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, · 107 unmodified lines | |||
| 837 | currentcmd->para1, | 836 | currentcmd->para1, |
| 838 | RFREG_OFFSET_MASK, | 837 | RFREG_OFFSET_MASK, |
| 839 | rtlphy->rfreg_chnlval[rfpath]); | 838 | rtlphy->rfreg_chnlval[rfpath]); |
| 839 | _rtl92c_phy_sw_rf_setting(hw, channel); | ||
| 840 | } | 840 | } |
| 841 | break; | 841 | break; |
| 842 | default: | 842 | default: |
| @@ -116,6 +116,9 @@ · 115 unmodified lines | |||
| 116 | LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) | 116 | LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) |
| 117 | 117 | ||
| 118 | #define CHIP_VER_B BIT(4) | 118 | #define CHIP_VER_B BIT(4) |
| 119 | #define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) | ||
| 120 | #define CHIP_BONDING_92C_1T2R 0x1 | ||
| 121 | #define RF_TYPE_1T2R BIT(1) | ||
| 119 | #define CHIP_92C_BITMASK BIT(0) | 122 | #define CHIP_92C_BITMASK BIT(0) |
| 120 | #define CHIP_UNKNOWN BIT(7) | 123 | #define CHIP_UNKNOWN BIT(7) |
| 121 | #define CHIP_92C_1T2R 0x03 | 124 | #define CHIP_92C_1T2R 0x03 |
| @@ -41,7 +41,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) · 40 unmodified lines | |||
| 41 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 41 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 43 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 43 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 44 | long undecorated_smoothed_pwdb; | 44 | long undec_sm_pwdb; |
| 45 | 45 | ||
| 46 | if (!rtlpriv->dm.dynamic_txpower_enable) | 46 | if (!rtlpriv->dm.dynamic_txpower_enable) |
| 47 | return; | 47 | return; |
| @@ -52,7 +52,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | if ((mac->link_state < MAC80211_LINKED) && | 54 | if ((mac->link_state < MAC80211_LINKED) && |
| 55 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | 55 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { |
| 56 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 56 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
| 57 | "Not connected to any\n"); | 57 | "Not connected to any\n"); |
| 58 | 58 | ||
| @@ -64,41 +64,35 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 64 | 64 | ||
| 65 | if (mac->link_state >= MAC80211_LINKED) { | 65 | if (mac->link_state >= MAC80211_LINKED) { |
| 66 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 66 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 67 | undecorated_smoothed_pwdb = | 67 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 68 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 69 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 68 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 70 | "AP Client PWDB = 0x%lx\n", | 69 | "AP Client PWDB = 0x%lx\n", |
| 71 | undecorated_smoothed_pwdb); | 70 | undec_sm_pwdb); |
| 72 | } else { | 71 | } else { |
| 73 | undecorated_smoothed_pwdb = | 72 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 74 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 75 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 73 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 76 | "STA Default Port PWDB = 0x%lx\n", | 74 | "STA Default Port PWDB = 0x%lx\n", |
| 77 | undecorated_smoothed_pwdb); | 75 | undec_sm_pwdb); |
| 78 | } | 76 | } |
| 79 | } else { | 77 | } else { |
| 80 | undecorated_smoothed_pwdb = | 78 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 81 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 82 | 79 | ||
| 83 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 80 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 84 | "AP Ext Port PWDB = 0x%lx\n", | 81 | "AP Ext Port PWDB = 0x%lx\n", |
| 85 | undecorated_smoothed_pwdb); | 82 | undec_sm_pwdb); |
| 86 | } | 83 | } |
| 87 | 84 | ||
| 88 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | 85 | if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { |
| 89 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 86 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 90 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 87 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 91 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | 88 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); |
| 92 | } else if ((undecorated_smoothed_pwdb < | 89 | } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && |
| 93 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | 90 | (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { |
| 94 | (undecorated_smoothed_pwdb >= | ||
| 95 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
| 96 | 91 | ||
| 97 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 92 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 98 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 93 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 99 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | 94 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); |
| 100 | } else if (undecorated_smoothed_pwdb < | 95 | } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { |
| 101 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
| 102 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | 96 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; |
| 103 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 97 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 104 | "TXHIGHPWRLEVEL_NORMAL\n"); | 98 | "TXHIGHPWRLEVEL_NORMAL\n"); |
| @@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) · 895 unmodified lines | |||
| 896 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 896 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 897 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 897 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| 898 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 898 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 899 | static bool iqk_initialized; /* initialized to false */ | ||
| 900 | bool rtstatus = true; | 899 | bool rtstatus = true; |
| 901 | bool is92c; | 900 | bool is92c; |
| 902 | int err; | 901 | int err; |
| @@ -921,9 +920,28 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) · 18 unmodified lines | |||
| 921 | 920 | ||
| 922 | rtlhal->last_hmeboxnum = 0; | 921 | rtlhal->last_hmeboxnum = 0; |
| 923 | rtl92c_phy_mac_config(hw); | 922 | rtl92c_phy_mac_config(hw); |
| 923 | /* because last function modify RCR, so we update | ||
| 924 | * rcr var here, or TP will unstable for receive_config | ||
| 925 | * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx | ||
| 926 | * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ | ||
| 927 | rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); | ||
| 928 | rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); | ||
| 929 | rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); | ||
| 924 | rtl92c_phy_bb_config(hw); | 930 | rtl92c_phy_bb_config(hw); |
| 925 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; | 931 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; |
| 926 | rtl92c_phy_rf_config(hw); | 932 | rtl92c_phy_rf_config(hw); |
| 933 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && | ||
| 934 | !IS_92C_SERIAL(rtlhal->version)) { | ||
| 935 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); | ||
| 936 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); | ||
| 937 | } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { | ||
| 938 | rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); | ||
| 939 | rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); | ||
| 940 | rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); | ||
| 941 | rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); | ||
| 942 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); | ||
| 943 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); | ||
| 944 | } | ||
| 927 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, | 945 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, |
| 928 | RF_CHNLBW, RFREG_OFFSET_MASK); | 946 | RF_CHNLBW, RFREG_OFFSET_MASK); |
| 929 | rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, | 947 | rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, |
| @@ -945,11 +963,11 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) · 15 unmodified lines | |||
| 945 | 963 | ||
| 946 | if (ppsc->rfpwr_state == ERFON) { | 964 | if (ppsc->rfpwr_state == ERFON) { |
| 947 | rtl92c_phy_set_rfpath_switch(hw, 1); | 965 | rtl92c_phy_set_rfpath_switch(hw, 1); |
| 948 | if (iqk_initialized) { | 966 | if (rtlphy->iqk_initialized) { |
| 949 | rtl92c_phy_iq_calibrate(hw, true); | 967 | rtl92c_phy_iq_calibrate(hw, true); |
| 950 | } else { | 968 | } else { |
| 951 | rtl92c_phy_iq_calibrate(hw, false); | 969 | rtl92c_phy_iq_calibrate(hw, false); |
| 952 | iqk_initialized = true; | 970 | rtlphy->iqk_initialized = true; |
| 953 | } | 971 | } |
| 954 | 972 | ||
| 955 | rtl92c_dm_check_txpower_tracking(hw); | 973 | rtl92c_dm_check_txpower_tracking(hw); |
| @@ -1004,6 +1022,13 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) · 48 unmodified lines | |||
| 1004 | ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | | 1022 | ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | |
| 1005 | CHIP_VENDOR_UMC)); | 1023 | CHIP_VENDOR_UMC)); |
| 1006 | } | 1024 | } |
| 1025 | if (IS_92C_SERIAL(version)) { | ||
| 1026 | value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); | ||
| 1027 | version = (enum version_8192c)(version | | ||
| 1028 | ((CHIP_BONDING_IDENTIFIER(value32) | ||
| 1029 | == CHIP_BONDING_92C_1T2R) ? | ||
| 1030 | RF_TYPE_1T2R : 0)); | ||
| 1031 | } | ||
| 1007 | } | 1032 | } |
| 1008 | 1033 | ||
| 1009 | switch (version) { | 1034 | switch (version) { |
| @@ -1019,12 +1044,30 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) · 9 unmodified lines | |||
| 1019 | case VERSION_A_CHIP_88C: | 1044 | case VERSION_A_CHIP_88C: |
| 1020 | versionid = "A_CHIP_88C"; | 1045 | versionid = "A_CHIP_88C"; |
| 1021 | break; | 1046 | break; |
| 1047 | case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: | ||
| 1048 | versionid = "A_CUT_92C_1T2R"; | ||
| 1049 | break; | ||
| 1050 | case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: | ||
| 1051 | versionid = "A_CUT_92C"; | ||
| 1052 | break; | ||
| 1053 | case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: | ||
| 1054 | versionid = "A_CUT_88C"; | ||
| 1055 | break; | ||
| 1056 | case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: | ||
| 1057 | versionid = "B_CUT_92C_1T2R"; | ||
| 1058 | break; | ||
| 1059 | case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: | ||
| 1060 | versionid = "B_CUT_92C"; | ||
| 1061 | break; | ||
| 1062 | case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: | ||
| 1063 | versionid = "B_CUT_88C"; | ||
| 1064 | break; | ||
| 1022 | default: | 1065 | default: |
| 1023 | versionid = "Unknown. Bug?"; | 1066 | versionid = "Unknown. Bug?"; |
| 1024 | break; | 1067 | break; |
| 1025 | } | 1068 | } |
| 1026 | 1069 | ||
| 1027 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 1070 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, |
| 1028 | "Chip Version ID: %s\n", versionid); | 1071 | "Chip Version ID: %s\n", versionid); |
| 1029 | 1072 | ||
| 1030 | switch (version & 0x3) { | 1073 | switch (version & 0x3) { |
| @@ -1197,6 +1240,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) · 166 unmodified lines | |||
| 1197 | { | 1240 | { |
| 1198 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1241 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1199 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | 1242 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); |
| 1243 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
| 1200 | u8 u1b_tmp; | 1244 | u8 u1b_tmp; |
| 1201 | u32 u4b_tmp; | 1245 | u32 u4b_tmp; |
| 1202 | 1246 | ||
| @@ -1225,7 +1269,8 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) · 22 unmodified lines | |||
| 1225 | rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); | 1269 | rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); |
| 1226 | rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); | 1270 | rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); |
| 1227 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); | 1271 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); |
| 1228 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); | 1272 | if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) |
| 1273 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); | ||
| 1229 | if (rtlpcipriv->bt_coexist.bt_coexistence) { | 1274 | if (rtlpcipriv->bt_coexist.bt_coexistence) { |
| 1230 | u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); | 1275 | u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); |
| 1231 | u4b_tmp |= 0x03824800; | 1276 | u4b_tmp |= 0x03824800; |
| @@ -1254,6 +1299,9 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw) · 22 unmodified lines | |||
| 1254 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); | 1299 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); |
| 1255 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 1300 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
| 1256 | _rtl92ce_poweroff_adapter(hw); | 1301 | _rtl92ce_poweroff_adapter(hw); |
| 1302 | |||
| 1303 | /* after power off we should do iqk again */ | ||
| 1304 | rtlpriv->phy.iqk_initialized = false; | ||
| 1257 | } | 1305 | } |
| 1258 | 1306 | ||
| 1259 | void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, | 1307 | void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, |
| @@ -1355,9 +1403,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, · 95 unmodified lines | |||
| 1355 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; | 1403 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; |
| 1356 | else | 1404 | else |
| 1357 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; | 1405 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; |
| 1358 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = | 1406 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = |
| 1359 | (tempval & 0xf); | 1407 | (tempval & 0xf); |
| 1360 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = | 1408 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = |
| 1361 | ((tempval & 0xf0) >> 4); | 1409 | ((tempval & 0xf0) >> 4); |
| 1362 | } | 1410 | } |
| 1363 | 1411 | ||
| @@ -1381,7 +1429,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, · 17 unmodified lines | |||
| 1381 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | 1429 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", |
| 1382 | rf_path, i, | 1430 | rf_path, i, |
| 1383 | rtlefuse-> | 1431 | rtlefuse-> |
| 1384 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); | 1432 | eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); |
| 1385 | 1433 | ||
| 1386 | for (rf_path = 0; rf_path < 2; rf_path++) { | 1434 | for (rf_path = 0; rf_path < 2; rf_path++) { |
| 1387 | for (i = 0; i < 14; i++) { | 1435 | for (i = 0; i < 14; i++) { |
| @@ -1396,14 +1444,14 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, · 8 unmodified lines | |||
| 1396 | if ((rtlefuse-> | 1444 | if ((rtlefuse-> |
| 1397 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - | 1445 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - |
| 1398 | rtlefuse-> | 1446 | rtlefuse-> |
| 1399 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) | 1447 | eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) |
| 1400 | > 0) { | 1448 | > 0) { |
| 1401 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | 1449 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = |
| 1402 | rtlefuse-> | 1450 | rtlefuse-> |
| 1403 | eeprom_chnlarea_txpwr_ht40_1s[rf_path] | 1451 | eeprom_chnlarea_txpwr_ht40_1s[rf_path] |
| 1404 | [index] - | 1452 | [index] - |
| 1405 | rtlefuse-> | 1453 | rtlefuse-> |
| 1406 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] | 1454 | eprom_chnl_txpwr_ht40_2sdf[rf_path] |
| 1407 | [index]; | 1455 | [index]; |
| 1408 | } else { | 1456 | } else { |
| 1409 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; | 1457 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; |
| @@ -1912,16 +1960,16 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, · 502 unmodified lines | |||
| 1912 | ratr_bitmap &= 0x0f0ff0ff; | 1960 | ratr_bitmap &= 0x0f0ff0ff; |
| 1913 | break; | 1961 | break; |
| 1914 | } | 1962 | } |
| 1963 | sta_entry->ratr_index = ratr_index; | ||
| 1964 | |||
| 1915 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 1965 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
| 1916 | "ratr_bitmap :%x\n", ratr_bitmap); | 1966 | "ratr_bitmap :%x\n", ratr_bitmap); |
| 1917 | *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | | 1967 | *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | |
| 1918 | (ratr_index << 28); | 1968 | (ratr_index << 28); |
| 1919 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | 1969 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
| 1920 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 1970 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
| 1921 | "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", | 1971 | "Rate_index:%x, ratr_val:%x, %5phC\n", |
| 1922 | ratr_index, ratr_bitmap, | 1972 | ratr_index, ratr_bitmap, rate_mask); |
| 1923 | rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], | ||
| 1924 | rate_mask[4]); | ||
| 1925 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | 1973 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); |
| 1926 | 1974 | ||
| 1927 | if (macid != 0) | 1975 | if (macid != 0) |
| @@ -2176,7 +2224,7 @@ static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) · 248 unmodified lines | |||
| 2176 | 2224 | ||
| 2177 | if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) | 2225 | if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) |
| 2178 | rtlpcipriv->bt_coexist.bt_ant_isolation = | 2226 | rtlpcipriv->bt_coexist.bt_ant_isolation = |
| 2179 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; | 2227 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isol; |
| 2180 | else | 2228 | else |
| 2181 | rtlpcipriv->bt_coexist.bt_ant_isolation = | 2229 | rtlpcipriv->bt_coexist.bt_ant_isolation = |
| 2182 | rtlpcipriv->bt_coexist.reg_bt_iso; | 2230 | rtlpcipriv->bt_coexist.reg_bt_iso; |
| @@ -2207,23 +2255,22 @@ void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, · 24 unmodified lines | |||
| 2207 | bool auto_load_fail, u8 *hwinfo) | 2255 | bool auto_load_fail, u8 *hwinfo) |
| 2208 | { | 2256 | { |
| 2209 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | 2257 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); |
| 2210 | u8 value; | 2258 | u8 val; |
| 2211 | 2259 | ||
| 2212 | if (!auto_load_fail) { | 2260 | if (!auto_load_fail) { |
| 2213 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = | 2261 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = |
| 2214 | ((hwinfo[RF_OPTION1] & 0xe0) >> 5); | 2262 | ((hwinfo[RF_OPTION1] & 0xe0) >> 5); |
| 2215 | value = hwinfo[RF_OPTION4]; | 2263 | val = hwinfo[RF_OPTION4]; |
| 2216 | rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1); | 2264 | rtlpcipriv->bt_coexist.eeprom_bt_type = ((val & 0xe) >> 1); |
| 2217 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); | 2265 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (val & 0x1); |
| 2218 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = | 2266 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = ((val & 0x10) >> 4); |
| 2219 | ((value & 0x10) >> 4); | ||
| 2220 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = | 2267 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = |
| 2221 | ((value & 0x20) >> 5); | 2268 | ((val & 0x20) >> 5); |
| 2222 | } else { | 2269 | } else { |
| 2223 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; | 2270 | rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; |
| 2224 | rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; | 2271 | rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; |
| 2225 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; | 2272 | rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; |
| 2226 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0; | 2273 | rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = 0; |
| 2227 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; | 2274 | rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; |
| 2228 | } | 2275 | } |
| 2229 | 2276 | ||
| @@ -82,6 +82,8 @@ bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) · 81 unmodified lines | |||
| 82 | 82 | ||
| 83 | if (is92c) | 83 | if (is92c) |
| 84 | rtl_write_byte(rtlpriv, 0x14, 0x71); | 84 | rtl_write_byte(rtlpriv, 0x14, 0x71); |
| 85 | else | ||
| 86 | rtl_write_byte(rtlpriv, 0x04CA, 0x0A); | ||
| 85 | return rtstatus; | 87 | return rtstatus; |
| 86 | } | 88 | } |
| 87 | 89 | ||
| @@ -97,15 +97,12 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, · 96 unmodified lines | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | if (rtlefuse->eeprom_regulatory == 0) { | 99 | if (rtlefuse->eeprom_regulatory == 0) { |
| 100 | tmpval = | 100 | tmpval = (rtlphy->mcs_offset[0][6]) + |
| 101 | (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + | 101 | (rtlphy->mcs_offset[0][7] << 8); |
| 102 | (rtlphy->mcs_txpwrlevel_origoffset[0][7] << | ||
| 103 | 8); | ||
| 104 | tx_agc[RF90_PATH_A] += tmpval; | 102 | tx_agc[RF90_PATH_A] += tmpval; |
| 105 | 103 | ||
| 106 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + | 104 | tmpval = (rtlphy->mcs_offset[0][14]) + |
| 107 | (rtlphy->mcs_txpwrlevel_origoffset[0][15] << | 105 | (rtlphy->mcs_offset[0][15] << 24); |
| 108 | 24); | ||
| 109 | tx_agc[RF90_PATH_B] += tmpval; | 106 | tx_agc[RF90_PATH_B] += tmpval; |
| 110 | } | 107 | } |
| 111 | } | 108 | } |
| @@ -209,8 +206,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 97 unmodified lines | |||
| 209 | case 0: | 206 | case 0: |
| 210 | chnlgroup = 0; | 207 | chnlgroup = 0; |
| 211 | 208 | ||
| 212 | writeVal = | 209 | writeVal = rtlphy->mcs_offset[chnlgroup][index + |
| 213 | rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + | ||
| 214 | (rf ? 8 : 0)] | 210 | (rf ? 8 : 0)] |
| 215 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | 211 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); |
| 216 | 212 | ||
| @@ -240,8 +236,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 23 unmodified lines | |||
| 240 | chnlgroup++; | 236 | chnlgroup++; |
| 241 | } | 237 | } |
| 242 | 238 | ||
| 243 | writeVal = | 239 | writeVal = rtlphy->mcs_offset[chnlgroup] |
| 244 | rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] | ||
| 245 | [index + (rf ? 8 : 0)] + ((index < 2) ? | 240 | [index + (rf ? 8 : 0)] + ((index < 2) ? |
| 246 | powerBase0[rf] : | 241 | powerBase0[rf] : |
| 247 | powerBase1[rf]); | 242 | powerBase1[rf]); |
| @@ -276,8 +271,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 28 unmodified lines | |||
| 276 | 1]); | 271 | 1]); |
| 277 | } | 272 | } |
| 278 | for (i = 0; i < 4; i++) { | 273 | for (i = 0; i < 4; i++) { |
| 279 | pwr_diff_limit[i] = | 274 | pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset |
| 280 | (u8) ((rtlphy->mcs_txpwrlevel_origoffset | ||
| 281 | [chnlgroup][index + | 275 | [chnlgroup][index + |
| 282 | (rf ? 8 : 0)] & (0x7f << (i * 8))) >> | 276 | (rf ? 8 : 0)] & (0x7f << (i * 8))) >> |
| 283 | (i * 8)); | 277 | (i * 8)); |
| @@ -317,8 +311,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 33 unmodified lines | |||
| 317 | break; | 311 | break; |
| 318 | default: | 312 | default: |
| 319 | chnlgroup = 0; | 313 | chnlgroup = 0; |
| 320 | writeVal = | 314 | writeVal = rtlphy->mcs_offset[chnlgroup] |
| 321 | rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] | ||
| 322 | [index + (rf ? 8 : 0)] | 315 | [index + (rf ? 8 : 0)] |
| 323 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | 316 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); |
| 324 | 317 | ||
| @@ -162,12 +162,10 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) · 161 unmodified lines | |||
| 162 | 162 | ||
| 163 | /* request fw */ | 163 | /* request fw */ |
| 164 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && | 164 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && |
| 165 | !IS_92C_SERIAL(rtlhal->version)) { | 165 | !IS_92C_SERIAL(rtlhal->version)) |
| 166 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; | 166 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; |
| 167 | } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { | 167 | else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) |
| 168 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; | 168 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; |
| 169 | pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n"); | ||
| 170 | } | ||
| 171 | 169 | ||
| 172 | rtlpriv->max_fw_size = 0x4000; | 170 | rtlpriv->max_fw_size = 0x4000; |
| 173 | pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); | 171 | pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); |
| @@ -127,11 +127,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, · 126 unmodified lines | |||
| 127 | { | 127 | { |
| 128 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 128 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 129 | struct phy_sts_cck_8192s_t *cck_buf; | 129 | struct phy_sts_cck_8192s_t *cck_buf; |
| 130 | struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); | ||
| 130 | s8 rx_pwr_all = 0, rx_pwr[4]; | 131 | s8 rx_pwr_all = 0, rx_pwr[4]; |
| 131 | u8 evm, pwdb_all, rf_rx_num = 0; | 132 | u8 evm, pwdb_all, rf_rx_num = 0; |
| 132 | u8 i, max_spatial_stream; | 133 | u8 i, max_spatial_stream; |
| 133 | u32 rssi, total_rssi = 0; | 134 | u32 rssi, total_rssi = 0; |
| 134 | bool in_powersavemode = false; | ||
| 135 | bool is_cck_rate; | 135 | bool is_cck_rate; |
| 136 | 136 | ||
| 137 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | 137 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); |
| @@ -140,14 +140,14 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, · 2 unmodified lines | |||
| 140 | pstats->is_cck = is_cck_rate; | 140 | pstats->is_cck = is_cck_rate; |
| 141 | pstats->packet_beacon = packet_beacon; | 141 | pstats->packet_beacon = packet_beacon; |
| 142 | pstats->is_cck = is_cck_rate; | 142 | pstats->is_cck = is_cck_rate; |
| 143 | pstats->rx_mimo_signalquality[0] = -1; | 143 | pstats->rx_mimo_sig_qual[0] = -1; |
| 144 | pstats->rx_mimo_signalquality[1] = -1; | 144 | pstats->rx_mimo_sig_qual[1] = -1; |
| 145 | 145 | ||
| 146 | if (is_cck_rate) { | 146 | if (is_cck_rate) { |
| 147 | u8 report, cck_highpwr; | 147 | u8 report, cck_highpwr; |
| 148 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; | 148 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; |
| 149 | 149 | ||
| 150 | if (!in_powersavemode) | 150 | if (ppsc->rfpwr_state == ERFON) |
| 151 | cck_highpwr = (u8) rtl_get_bbreg(hw, | 151 | cck_highpwr = (u8) rtl_get_bbreg(hw, |
| 152 | RFPGA0_XA_HSSIPARAMETER2, | 152 | RFPGA0_XA_HSSIPARAMETER2, |
| 153 | BIT(9)); | 153 | BIT(9)); |
| @@ -211,8 +211,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, · 57 unmodified lines | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | pstats->signalquality = sq; | 213 | pstats->signalquality = sq; |
| 214 | pstats->rx_mimo_signalquality[0] = sq; | 214 | pstats->rx_mimo_sig_qual[0] = sq; |
| 215 | pstats->rx_mimo_signalquality[1] = -1; | 215 | pstats->rx_mimo_sig_qual[1] = -1; |
| 216 | } | 216 | } |
| 217 | } else { | 217 | } else { |
| 218 | rtlpriv->dm.rfpath_rxenable[0] = | 218 | rtlpriv->dm.rfpath_rxenable[0] = |
| @@ -251,8 +251,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, · 32 unmodified lines | |||
| 251 | if (i == 0) | 251 | if (i == 0) |
| 252 | pstats->signalquality = | 252 | pstats->signalquality = |
| 253 | (u8) (evm & 0xff); | 253 | (u8) (evm & 0xff); |
| 254 | pstats->rx_mimo_signalquality[i] = | 254 | pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); |
| 255 | (u8) (evm & 0xff); | ||
| 256 | } | 255 | } |
| 257 | } | 256 | } |
| 258 | } | 257 | } |
| @@ -362,36 +361,31 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, · 103 unmodified lines | |||
| 362 | { | 361 | { |
| 363 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 362 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 364 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 363 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 365 | long undecorated_smoothed_pwdb; | 364 | long undec_sm_pwdb; |
| 366 | 365 | ||
| 367 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 366 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 368 | return; | 367 | return; |
| 369 | } else { | 368 | } else { |
| 370 | undecorated_smoothed_pwdb = | 369 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 371 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 372 | } | 370 | } |
| 373 | 371 | ||
| 374 | if (pstats->packet_toself || pstats->packet_beacon) { | 372 | if (pstats->packet_toself || pstats->packet_beacon) { |
| 375 | if (undecorated_smoothed_pwdb < 0) | 373 | if (undec_sm_pwdb < 0) |
| 376 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | 374 | undec_sm_pwdb = pstats->rx_pwdb_all; |
| 377 | 375 | ||
| 378 | if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { | 376 | if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { |
| 379 | undecorated_smoothed_pwdb = | 377 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 380 | (((undecorated_smoothed_pwdb) * | ||
| 381 | (RX_SMOOTH_FACTOR - 1)) + | 378 | (RX_SMOOTH_FACTOR - 1)) + |
| 382 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 379 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 383 | 380 | ||
| 384 | undecorated_smoothed_pwdb = undecorated_smoothed_pwdb | 381 | undec_sm_pwdb += 1; |
| 385 | + 1; | ||
| 386 | } else { | 382 | } else { |
| 387 | undecorated_smoothed_pwdb = | 383 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 388 | (((undecorated_smoothed_pwdb) * | ||
| 389 | (RX_SMOOTH_FACTOR - 1)) + | 384 | (RX_SMOOTH_FACTOR - 1)) + |
| 390 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 385 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 391 | } | 386 | } |
| 392 | 387 | ||
| 393 | rtlpriv->dm.undecorated_smoothed_pwdb = | 388 | rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; |
| 394 | undecorated_smoothed_pwdb; | ||
| 395 | _rtl92ce_update_rxsignalstatistics(hw, pstats); | 389 | _rtl92ce_update_rxsignalstatistics(hw, pstats); |
| 396 | } | 390 | } |
| 397 | } | 391 | } |
| @@ -438,15 +432,14 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, · 40 unmodified lines | |||
| 438 | for (n_spatialstream = 0; n_spatialstream < 2; | 432 | for (n_spatialstream = 0; n_spatialstream < 2; |
| 439 | n_spatialstream++) { | 433 | n_spatialstream++) { |
| 440 | if (pstats-> | 434 | if (pstats-> |
| 441 | rx_mimo_signalquality[n_spatialstream] != | 435 | rx_mimo_sig_qual[n_spatialstream] != -1) { |
| 442 | -1) { | ||
| 443 | if (rtlpriv->stats. | 436 | if (rtlpriv->stats. |
| 444 | rx_evm_percentage[n_spatialstream] | 437 | rx_evm_percentage[n_spatialstream] |
| 445 | == 0) { | 438 | == 0) { |
| 446 | rtlpriv->stats. | 439 | rtlpriv->stats. |
| 447 | rx_evm_percentage | 440 | rx_evm_percentage |
| 448 | [n_spatialstream] = | 441 | [n_spatialstream] = |
| 449 | pstats->rx_mimo_signalquality | 442 | pstats->rx_mimo_sig_qual |
| 450 | [n_spatialstream]; | 443 | [n_spatialstream]; |
| 451 | } | 444 | } |
| 452 | 445 | ||
| @@ -456,8 +449,7 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, · 3 unmodified lines | |||
| 456 | stats.rx_evm_percentage | 449 | stats.rx_evm_percentage |
| 457 | [n_spatialstream] * | 450 | [n_spatialstream] * |
| 458 | (RX_SMOOTH_FACTOR - 1)) + | 451 | (RX_SMOOTH_FACTOR - 1)) + |
| 459 | (pstats-> | 452 | (pstats->rx_mimo_sig_qual |
| 460 | rx_mimo_signalquality | ||
| 461 | [n_spatialstream] * 1)) / | 453 | [n_spatialstream] * 1)) / |
| 462 | (RX_SMOOTH_FACTOR); | 454 | (RX_SMOOTH_FACTOR); |
| 463 | } | 455 | } |
| @@ -39,7 +39,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) · 38 unmodified lines | |||
| 39 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 39 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 40 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 40 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 41 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 41 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 42 | long undecorated_smoothed_pwdb; | 42 | long undec_sm_pwdb; |
| 43 | 43 | ||
| 44 | if (!rtlpriv->dm.dynamic_txpower_enable) | 44 | if (!rtlpriv->dm.dynamic_txpower_enable) |
| 45 | return; | 45 | return; |
| @@ -50,7 +50,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | if ((mac->link_state < MAC80211_LINKED) && | 52 | if ((mac->link_state < MAC80211_LINKED) && |
| 53 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | 53 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { |
| 54 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 54 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
| 55 | "Not connected to any\n"); | 55 | "Not connected to any\n"); |
| 56 | 56 | ||
| @@ -62,41 +62,35 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 62 | 62 | ||
| 63 | if (mac->link_state >= MAC80211_LINKED) { | 63 | if (mac->link_state >= MAC80211_LINKED) { |
| 64 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 64 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 65 | undecorated_smoothed_pwdb = | 65 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 66 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 67 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 66 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 68 | "AP Client PWDB = 0x%lx\n", | 67 | "AP Client PWDB = 0x%lx\n", |
| 69 | undecorated_smoothed_pwdb); | 68 | undec_sm_pwdb); |
| 70 | } else { | 69 | } else { |
| 71 | undecorated_smoothed_pwdb = | 70 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 72 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 73 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 71 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 74 | "STA Default Port PWDB = 0x%lx\n", | 72 | "STA Default Port PWDB = 0x%lx\n", |
| 75 | undecorated_smoothed_pwdb); | 73 | undec_sm_pwdb); |
| 76 | } | 74 | } |
| 77 | } else { | 75 | } else { |
| 78 | undecorated_smoothed_pwdb = | 76 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 79 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 80 | 77 | ||
| 81 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 78 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 82 | "AP Ext Port PWDB = 0x%lx\n", | 79 | "AP Ext Port PWDB = 0x%lx\n", |
| 83 | undecorated_smoothed_pwdb); | 80 | undec_sm_pwdb); |
| 84 | } | 81 | } |
| 85 | 82 | ||
| 86 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | 83 | if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { |
| 87 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 84 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 88 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 85 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 89 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | 86 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); |
| 90 | } else if ((undecorated_smoothed_pwdb < | 87 | } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && |
| 91 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | 88 | (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { |
| 92 | (undecorated_smoothed_pwdb >= | ||
| 93 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
| 94 | 89 | ||
| 95 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | 90 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; |
| 96 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 91 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 97 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | 92 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); |
| 98 | } else if (undecorated_smoothed_pwdb < | 93 | } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { |
| 99 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
| 100 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | 94 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; |
| 101 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 95 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 102 | "TXHIGHPWRLEVEL_NORMAL\n"); | 96 | "TXHIGHPWRLEVEL_NORMAL\n"); |
| @@ -152,9 +152,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, · 151 unmodified lines | |||
| 152 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; | 152 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; |
| 153 | else | 153 | else |
| 154 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; | 154 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; |
| 155 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = | 155 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = |
| 156 | (tempval & 0xf); | 156 | (tempval & 0xf); |
| 157 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = | 157 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = |
| 158 | ((tempval & 0xf0) >> 4); | 158 | ((tempval & 0xf0) >> 4); |
| 159 | } | 159 | } |
| 160 | for (rf_path = 0; rf_path < 2; rf_path++) | 160 | 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, · 16 unmodified lines | |||
| 177 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | 177 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", |
| 178 | rf_path, i, | 178 | rf_path, i, |
| 179 | rtlefuse-> | 179 | rtlefuse-> |
| 180 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); | 180 | eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); |
| 181 | for (rf_path = 0; rf_path < 2; rf_path++) { | 181 | for (rf_path = 0; rf_path < 2; rf_path++) { |
| 182 | for (i = 0; i < 14; i++) { | 182 | for (i = 0; i < 14; i++) { |
| 183 | index = _rtl92c_get_chnl_group((u8) i); | 183 | index = _rtl92c_get_chnl_group((u8) i); |
| @@ -189,13 +189,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, · 5 unmodified lines | |||
| 189 | if ((rtlefuse-> | 189 | if ((rtlefuse-> |
| 190 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - | 190 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - |
| 191 | rtlefuse-> | 191 | rtlefuse-> |
| 192 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) | 192 | eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) |
| 193 | > 0) { | 193 | > 0) { |
| 194 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | 194 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = |
| 195 | rtlefuse-> | 195 | rtlefuse-> |
| 196 | eeprom_chnlarea_txpwr_ht40_1s[rf_path] | 196 | eeprom_chnlarea_txpwr_ht40_1s[rf_path] |
| 197 | [index] - rtlefuse-> | 197 | [index] - rtlefuse-> |
| 198 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] | 198 | eprom_chnl_txpwr_ht40_2sdf[rf_path] |
| 199 | [index]; | 199 | [index]; |
| 200 | } else { | 200 | } else { |
| 201 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; | 201 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; |
| @@ -2169,10 +2169,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) · 1967 unmodified lines | |||
| 2169 | ratr_index << 28); | 2169 | ratr_index << 28); |
| 2170 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | 2170 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
| 2171 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 2171 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
| 2172 | "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", | 2172 | "Rate_index:%x, ratr_val:%x, %5phC\n", |
| 2173 | ratr_index, ratr_bitmap, | 2173 | ratr_index, ratr_bitmap, rate_mask); |
| 2174 | rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], | ||
| 2175 | rate_mask[4]); | ||
| 2176 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | 2174 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); |
| 2177 | } | 2175 | } |
| 2178 | 2176 | ||
| @@ -46,7 +46,7 @@ · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | #define LINK_Q ui_link_quality | 47 | #define LINK_Q ui_link_quality |
| 48 | #define RX_EVM rx_evm_percentage | 48 | #define RX_EVM rx_evm_percentage |
| 49 | #define RX_SIGQ rx_mimo_signalquality | 49 | #define RX_SIGQ rx_mimo_sig_qual |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | void rtl92c_read_chip_version(struct ieee80211_hw *hw) | 52 | void rtl92c_read_chip_version(struct ieee80211_hw *hw) |
| @@ -982,32 +982,27 @@ static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, · 929 unmodified lines | |||
| 982 | { | 982 | { |
| 983 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 983 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 984 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 984 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 985 | long undecorated_smoothed_pwdb = 0; | 985 | long undec_sm_pwdb = 0; |
| 986 | 986 | ||
| 987 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 987 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 988 | return; | 988 | return; |
| 989 | } else { | 989 | } else { |
| 990 | undecorated_smoothed_pwdb = | 990 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 991 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 992 | } | 991 | } |
| 993 | if (pstats->packet_toself || pstats->packet_beacon) { | 992 | if (pstats->packet_toself || pstats->packet_beacon) { |
| 994 | if (undecorated_smoothed_pwdb < 0) | 993 | if (undec_sm_pwdb < 0) |
| 995 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | 994 | undec_sm_pwdb = pstats->rx_pwdb_all; |
| 996 | if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { | 995 | if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { |
| 997 | undecorated_smoothed_pwdb = | 996 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 998 | (((undecorated_smoothed_pwdb) * | ||
| 999 | (RX_SMOOTH_FACTOR - 1)) + | 997 | (RX_SMOOTH_FACTOR - 1)) + |
| 1000 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 998 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 1001 | undecorated_smoothed_pwdb = undecorated_smoothed_pwdb | 999 | undec_sm_pwdb += 1; |
| 1002 | + 1; | ||
| 1003 | } else { | 1000 | } else { |
| 1004 | undecorated_smoothed_pwdb = | 1001 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 1005 | (((undecorated_smoothed_pwdb) * | ||
| 1006 | (RX_SMOOTH_FACTOR - 1)) + | 1002 | (RX_SMOOTH_FACTOR - 1)) + |
| 1007 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 1003 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 1008 | } | 1004 | } |
| 1009 | rtlpriv->dm.undecorated_smoothed_pwdb = | 1005 | rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; |
| 1010 | undecorated_smoothed_pwdb; | ||
| 1011 | _rtl92c_update_rxsignalstatistics(hw, pstats); | 1006 | _rtl92c_update_rxsignalstatistics(hw, pstats); |
| 1012 | } | 1007 | } |
| 1013 | } | 1008 | } |
| @@ -115,15 +115,11 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, · 114 unmodified lines | |||
| 115 | (ppowerlevel[idx1] << 24); | 115 | (ppowerlevel[idx1] << 24); |
| 116 | } | 116 | } |
| 117 | if (rtlefuse->eeprom_regulatory == 0) { | 117 | if (rtlefuse->eeprom_regulatory == 0) { |
| 118 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset | 118 | tmpval = (rtlphy->mcs_offset[0][6]) + |
| 119 | [0][6]) + | 119 | (rtlphy->mcs_offset[0][7] << 8); |
| 120 | (rtlphy->mcs_txpwrlevel_origoffset | ||
| 121 | [0][7] << 8); | ||
| 122 | tx_agc[RF90_PATH_A] += tmpval; | 120 | tx_agc[RF90_PATH_A] += tmpval; |
| 123 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset | 121 | tmpval = (rtlphy->mcs_offset[0][14]) + |
| 124 | [0][14]) + | 122 | (rtlphy->mcs_offset[0][15] << 24); |
| 125 | (rtlphy->mcs_txpwrlevel_origoffset | ||
| 126 | [0][15] << 24); | ||
| 127 | tx_agc[RF90_PATH_B] += tmpval; | 123 | tx_agc[RF90_PATH_B] += tmpval; |
| 128 | } | 124 | } |
| 129 | } | 125 | } |
| @@ -215,7 +211,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 85 unmodified lines | |||
| 215 | switch (rtlefuse->eeprom_regulatory) { | 211 | switch (rtlefuse->eeprom_regulatory) { |
| 216 | case 0: | 212 | case 0: |
| 217 | chnlgroup = 0; | 213 | chnlgroup = 0; |
| 218 | writeVal = rtlphy->mcs_txpwrlevel_origoffset | 214 | writeVal = rtlphy->mcs_offset |
| 219 | [chnlgroup][index + (rf ? 8 : 0)] | 215 | [chnlgroup][index + (rf ? 8 : 0)] |
| 220 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | 216 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); |
| 221 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | 217 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, |
| @@ -238,8 +234,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 16 unmodified lines | |||
| 238 | else | 234 | else |
| 239 | chnlgroup += 4; | 235 | chnlgroup += 4; |
| 240 | } | 236 | } |
| 241 | writeVal = rtlphy->mcs_txpwrlevel_origoffset | 237 | writeVal = rtlphy->mcs_offset[chnlgroup][index + |
| 242 | [chnlgroup][index + | ||
| 243 | (rf ? 8 : 0)] + | 238 | (rf ? 8 : 0)] + |
| 244 | ((index < 2) ? powerBase0[rf] : | 239 | ((index < 2) ? powerBase0[rf] : |
| 245 | powerBase1[rf]); | 240 | powerBase1[rf]); |
| @@ -271,8 +266,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 25 unmodified lines | |||
| 271 | [channel - 1]); | 266 | [channel - 1]); |
| 272 | } | 267 | } |
| 273 | for (i = 0; i < 4; i++) { | 268 | for (i = 0; i < 4; i++) { |
| 274 | pwr_diff_limit[i] = | 269 | pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset |
| 275 | (u8) ((rtlphy->mcs_txpwrlevel_origoffset | ||
| 276 | [chnlgroup][index + (rf ? 8 : 0)] | 270 | [chnlgroup][index + (rf ? 8 : 0)] |
| 277 | & (0x7f << (i * 8))) >> (i * 8)); | 271 | & (0x7f << (i * 8))) >> (i * 8)); |
| 278 | if (rtlphy->current_chan_bw == | 272 | if (rtlphy->current_chan_bw == |
| @@ -306,7 +300,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 27 unmodified lines | |||
| 306 | break; | 300 | break; |
| 307 | default: | 301 | default: |
| 308 | chnlgroup = 0; | 302 | chnlgroup = 0; |
| 309 | writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] | 303 | writeVal = rtlphy->mcs_offset[chnlgroup] |
| 310 | [index + (rf ? 8 : 0)] + ((index < 2) ? | 304 | [index + (rf ? 8 : 0)] + ((index < 2) ? |
| 311 | powerBase0[rf] : powerBase1[rf]); | 305 | powerBase0[rf] : powerBase1[rf]); |
| 312 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | 306 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, |
| @@ -35,7 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include "dm.h" | 35 | #include "dm.h" |
| 36 | #include "fw.h" | 36 | #include "fw.h" |
| 37 | 37 | ||
| 38 | #define UNDEC_SM_PWDB entry_min_undecoratedsmoothed_pwdb | 38 | #define UNDEC_SM_PWDB entry_min_undec_sm_pwdb |
| 39 | 39 | ||
| 40 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { | 40 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { |
| 41 | 0x7f8001fe, /* 0, +6.0dB */ | 41 | 0x7f8001fe, /* 0, +6.0dB */ |
| @@ -164,18 +164,18 @@ static void rtl92d_dm_diginit(struct ieee80211_hw *hw) · 122 unmodified lines | |||
| 164 | de_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 164 | de_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
| 165 | de_digtable->cur_igvalue = 0x20; | 165 | de_digtable->cur_igvalue = 0x20; |
| 166 | de_digtable->pre_igvalue = 0x0; | 166 | de_digtable->pre_igvalue = 0x0; |
| 167 | de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; | 167 | de_digtable->cursta_cstate = DIG_STA_DISCONNECT; |
| 168 | de_digtable->presta_connectstate = DIG_STA_DISCONNECT; | 168 | de_digtable->presta_cstate = DIG_STA_DISCONNECT; |
| 169 | de_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; | 169 | de_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; |
| 170 | de_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; | 170 | de_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; |
| 171 | de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; | 171 | de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; |
| 172 | de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | 172 | de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; |
| 173 | de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | 173 | de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; |
| 174 | de_digtable->rx_gain_range_max = DM_DIG_FA_UPPER; | 174 | de_digtable->rx_gain_range_max = DM_DIG_FA_UPPER; |
| 175 | de_digtable->rx_gain_range_min = DM_DIG_FA_LOWER; | 175 | de_digtable->rx_gain_range_min = DM_DIG_FA_LOWER; |
| 176 | de_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; | 176 | de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; |
| 177 | de_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; | 177 | de_digtable->back_range_max = DM_DIG_BACKOFF_MAX; |
| 178 | de_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; | 178 | de_digtable->back_range_min = DM_DIG_BACKOFF_MIN; |
| 179 | de_digtable->pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; | 179 | de_digtable->pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; |
| 180 | de_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | 180 | de_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; |
| 181 | de_digtable->large_fa_hit = 0; | 181 | de_digtable->large_fa_hit = 0; |
| @@ -273,35 +273,34 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) · 91 unmodified lines | |||
| 273 | /* Determine the minimum RSSI */ | 273 | /* Determine the minimum RSSI */ |
| 274 | if ((mac->link_state < MAC80211_LINKED) && | 274 | if ((mac->link_state < MAC80211_LINKED) && |
| 275 | (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { | 275 | (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { |
| 276 | de_digtable->min_undecorated_pwdb_for_dm = 0; | 276 | de_digtable->min_undec_pwdb_for_dm = 0; |
| 277 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, | 277 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, |
| 278 | "Not connected to any\n"); | 278 | "Not connected to any\n"); |
| 279 | } | 279 | } |
| 280 | if (mac->link_state >= MAC80211_LINKED) { | 280 | if (mac->link_state >= MAC80211_LINKED) { |
| 281 | if (mac->opmode == NL80211_IFTYPE_AP || | 281 | if (mac->opmode == NL80211_IFTYPE_AP || |
| 282 | mac->opmode == NL80211_IFTYPE_ADHOC) { | 282 | mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 283 | de_digtable->min_undecorated_pwdb_for_dm = | 283 | de_digtable->min_undec_pwdb_for_dm = |
| 284 | rtlpriv->dm.UNDEC_SM_PWDB; | 284 | rtlpriv->dm.UNDEC_SM_PWDB; |
| 285 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, | 285 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, |
| 286 | "AP Client PWDB = 0x%lx\n", | 286 | "AP Client PWDB = 0x%lx\n", |
| 287 | rtlpriv->dm.UNDEC_SM_PWDB); | 287 | rtlpriv->dm.UNDEC_SM_PWDB); |
| 288 | } else { | 288 | } else { |
| 289 | de_digtable->min_undecorated_pwdb_for_dm = | 289 | de_digtable->min_undec_pwdb_for_dm = |
| 290 | rtlpriv->dm.undecorated_smoothed_pwdb; | 290 | rtlpriv->dm.undec_sm_pwdb; |
| 291 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, | 291 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, |
| 292 | "STA Default Port PWDB = 0x%x\n", | 292 | "STA Default Port PWDB = 0x%x\n", |
| 293 | de_digtable->min_undecorated_pwdb_for_dm); | 293 | de_digtable->min_undec_pwdb_for_dm); |
| 294 | } | 294 | } |
| 295 | } else { | 295 | } else { |
| 296 | de_digtable->min_undecorated_pwdb_for_dm = | 296 | de_digtable->min_undec_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; |
| 297 | rtlpriv->dm.UNDEC_SM_PWDB; | ||
| 298 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, | 297 | RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, |
| 299 | "AP Ext Port or disconnect PWDB = 0x%x\n", | 298 | "AP Ext Port or disconnect PWDB = 0x%x\n", |
| 300 | de_digtable->min_undecorated_pwdb_for_dm); | 299 | de_digtable->min_undec_pwdb_for_dm); |
| 301 | } | 300 | } |
| 302 | 301 | ||
| 303 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", | 302 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", |
| 304 | de_digtable->min_undecorated_pwdb_for_dm); | 303 | de_digtable->min_undec_pwdb_for_dm); |
| 305 | } | 304 | } |
| 306 | 305 | ||
| 307 | static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) | 306 | static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) |
| @@ -310,16 +309,16 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 310 | struct dig_t *de_digtable = &rtlpriv->dm_digtable; | 309 | struct dig_t *de_digtable = &rtlpriv->dm_digtable; |
| 311 | unsigned long flag = 0; | 310 | unsigned long flag = 0; |
| 312 | 311 | ||
| 313 | if (de_digtable->cursta_connectstate == DIG_STA_CONNECT) { | 312 | if (de_digtable->cursta_cstate == DIG_STA_CONNECT) { |
| 314 | if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { | 313 | if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { |
| 315 | if (de_digtable->min_undecorated_pwdb_for_dm <= 25) | 314 | if (de_digtable->min_undec_pwdb_for_dm <= 25) |
| 316 | de_digtable->cur_cck_pd_state = | 315 | de_digtable->cur_cck_pd_state = |
| 317 | CCK_PD_STAGE_LOWRSSI; | 316 | CCK_PD_STAGE_LOWRSSI; |
| 318 | else | 317 | else |
| 319 | de_digtable->cur_cck_pd_state = | 318 | de_digtable->cur_cck_pd_state = |
| 320 | CCK_PD_STAGE_HIGHRSSI; | 319 | CCK_PD_STAGE_HIGHRSSI; |
| 321 | } else { | 320 | } else { |
| 322 | if (de_digtable->min_undecorated_pwdb_for_dm <= 20) | 321 | if (de_digtable->min_undec_pwdb_for_dm <= 20) |
| 323 | de_digtable->cur_cck_pd_state = | 322 | de_digtable->cur_cck_pd_state = |
| 324 | CCK_PD_STAGE_LOWRSSI; | 323 | CCK_PD_STAGE_LOWRSSI; |
| 325 | else | 324 | else |
| @@ -342,7 +341,7 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) · 16 unmodified lines | |||
| 342 | de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; | 341 | de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; |
| 343 | } | 342 | } |
| 344 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", | 343 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", |
| 345 | de_digtable->cursta_connectstate == DIG_STA_CONNECT ? | 344 | de_digtable->cursta_cstate == DIG_STA_CONNECT ? |
| 346 | "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); | 345 | "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); |
| 347 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", | 346 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", |
| 348 | de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? | 347 | de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? |
| @@ -358,9 +357,9 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) · 9 unmodified lines | |||
| 358 | struct dig_t *de_digtable = &rtlpriv->dm_digtable; | 357 | struct dig_t *de_digtable = &rtlpriv->dm_digtable; |
| 359 | 358 | ||
| 360 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | 359 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, |
| 361 | "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", | 360 | "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", |
| 362 | de_digtable->cur_igvalue, de_digtable->pre_igvalue, | 361 | de_digtable->cur_igvalue, de_digtable->pre_igvalue, |
| 363 | de_digtable->backoff_val); | 362 | de_digtable->back_val); |
| 364 | if (de_digtable->dig_enable_flag == false) { | 363 | if (de_digtable->dig_enable_flag == false) { |
| 365 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); | 364 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); |
| 366 | de_digtable->pre_igvalue = 0x17; | 365 | de_digtable->pre_igvalue = 0x17; |
| @@ -382,13 +381,13 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) · 15 unmodified lines | |||
| 382 | if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && | 381 | if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && |
| 383 | (rtlpriv->mac80211.vendor == PEER_CISCO)) { | 382 | (rtlpriv->mac80211.vendor == PEER_CISCO)) { |
| 384 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); | 383 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); |
| 385 | if (de_digtable->last_min_undecorated_pwdb_for_dm >= 50 | 384 | if (de_digtable->last_min_undec_pwdb_for_dm >= 50 |
| 386 | && de_digtable->min_undecorated_pwdb_for_dm < 50) { | 385 | && de_digtable->min_undec_pwdb_for_dm < 50) { |
| 387 | rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); | 386 | rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); |
| 388 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | 387 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, |
| 389 | "Early Mode Off\n"); | 388 | "Early Mode Off\n"); |
| 390 | } else if (de_digtable->last_min_undecorated_pwdb_for_dm <= 55 && | 389 | } else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 && |
| 391 | de_digtable->min_undecorated_pwdb_for_dm > 55) { | 390 | de_digtable->min_undec_pwdb_for_dm > 55) { |
| 392 | rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); | 391 | rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); |
| 393 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | 392 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, |
| 394 | "Early Mode On\n"); | 393 | "Early Mode On\n"); |
| @@ -409,8 +408,8 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) · 14 unmodified lines | |||
| 409 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); | 408 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); |
| 410 | if (rtlpriv->rtlhal.earlymode_enable) { | 409 | if (rtlpriv->rtlhal.earlymode_enable) { |
| 411 | rtl92d_early_mode_enabled(rtlpriv); | 410 | rtl92d_early_mode_enabled(rtlpriv); |
| 412 | de_digtable->last_min_undecorated_pwdb_for_dm = | 411 | de_digtable->last_min_undec_pwdb_for_dm = |
| 413 | de_digtable->min_undecorated_pwdb_for_dm; | 412 | de_digtable->min_undec_pwdb_for_dm; |
| 414 | } | 413 | } |
| 415 | if (!rtlpriv->dm.dm_initialgain_enable) | 414 | if (!rtlpriv->dm.dm_initialgain_enable) |
| 416 | return; | 415 | return; |
| @@ -428,9 +427,9 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) · 11 unmodified lines | |||
| 428 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); | 427 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); |
| 429 | /* Decide the current status and if modify initial gain or not */ | 428 | /* Decide the current status and if modify initial gain or not */ |
| 430 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) | 429 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) |
| 431 | de_digtable->cursta_connectstate = DIG_STA_CONNECT; | 430 | de_digtable->cursta_cstate = DIG_STA_CONNECT; |
| 432 | else | 431 | else |
| 433 | de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; | 432 | de_digtable->cursta_cstate = DIG_STA_DISCONNECT; |
| 434 | 433 | ||
| 435 | /* adjust initial gain according to false alarm counter */ | 434 | /* adjust initial gain according to false alarm counter */ |
| 436 | if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) | 435 | if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) |
| @@ -522,7 +521,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) · 85 unmodified lines | |||
| 522 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 521 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 523 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 522 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
| 524 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 523 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 525 | long undecorated_smoothed_pwdb; | 524 | long undec_sm_pwdb; |
| 526 | 525 | ||
| 527 | if ((!rtlpriv->dm.dynamic_txpower_enable) | 526 | if ((!rtlpriv->dm.dynamic_txpower_enable) |
| 528 | || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | 527 | || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { |
| @@ -539,62 +538,62 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) · 10 unmodified lines | |||
| 539 | } | 538 | } |
| 540 | if (mac->link_state >= MAC80211_LINKED) { | 539 | if (mac->link_state >= MAC80211_LINKED) { |
| 541 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 540 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 542 | undecorated_smoothed_pwdb = | 541 | undec_sm_pwdb = |
| 543 | rtlpriv->dm.UNDEC_SM_PWDB; | 542 | rtlpriv->dm.UNDEC_SM_PWDB; |
| 544 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 543 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 545 | "IBSS Client PWDB = 0x%lx\n", | 544 | "IBSS Client PWDB = 0x%lx\n", |
| 546 | undecorated_smoothed_pwdb); | 545 | undec_sm_pwdb); |
| 547 | } else { | 546 | } else { |
| 548 | undecorated_smoothed_pwdb = | 547 | undec_sm_pwdb = |
| 549 | rtlpriv->dm.undecorated_smoothed_pwdb; | 548 | rtlpriv->dm.undec_sm_pwdb; |
| 550 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 549 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 551 | "STA Default Port PWDB = 0x%lx\n", | 550 | "STA Default Port PWDB = 0x%lx\n", |
| 552 | undecorated_smoothed_pwdb); | 551 | undec_sm_pwdb); |
| 553 | } | 552 | } |
| 554 | } else { | 553 | } else { |
| 555 | undecorated_smoothed_pwdb = | 554 | undec_sm_pwdb = |
| 556 | rtlpriv->dm.UNDEC_SM_PWDB; | 555 | rtlpriv->dm.UNDEC_SM_PWDB; |
| 557 | 556 | ||
| 558 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 557 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 559 | "AP Ext Port PWDB = 0x%lx\n", | 558 | "AP Ext Port PWDB = 0x%lx\n", |
| 560 | undecorated_smoothed_pwdb); | 559 | undec_sm_pwdb); |
| 561 | } | 560 | } |
| 562 | if (rtlhal->current_bandtype == BAND_ON_5G) { | 561 | if (rtlhal->current_bandtype == BAND_ON_5G) { |
| 563 | if (undecorated_smoothed_pwdb >= 0x33) { | 562 | if (undec_sm_pwdb >= 0x33) { |
| 564 | rtlpriv->dm.dynamic_txhighpower_lvl = | 563 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 565 | TXHIGHPWRLEVEL_LEVEL2; | 564 | TXHIGHPWRLEVEL_LEVEL2; |
| 566 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, | 565 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, |
| 567 | "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); | 566 | "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); |
| 568 | } else if ((undecorated_smoothed_pwdb < 0x33) | 567 | } else if ((undec_sm_pwdb < 0x33) |
| 569 | && (undecorated_smoothed_pwdb >= 0x2b)) { | 568 | && (undec_sm_pwdb >= 0x2b)) { |
| 570 | rtlpriv->dm.dynamic_txhighpower_lvl = | 569 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 571 | TXHIGHPWRLEVEL_LEVEL1; | 570 | TXHIGHPWRLEVEL_LEVEL1; |
| 572 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, | 571 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, |
| 573 | "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); | 572 | "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); |
| 574 | } else if (undecorated_smoothed_pwdb < 0x2b) { | 573 | } else if (undec_sm_pwdb < 0x2b) { |
| 575 | rtlpriv->dm.dynamic_txhighpower_lvl = | 574 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 576 | TXHIGHPWRLEVEL_NORMAL; | 575 | TXHIGHPWRLEVEL_NORMAL; |
| 577 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, | 576 | RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, |
| 578 | "5G:TxHighPwrLevel_Normal\n"); | 577 | "5G:TxHighPwrLevel_Normal\n"); |
| 579 | } | 578 | } |
| 580 | } else { | 579 | } else { |
| 581 | if (undecorated_smoothed_pwdb >= | 580 | if (undec_sm_pwdb >= |
| 582 | TX_POWER_NEAR_FIELD_THRESH_LVL2) { | 581 | TX_POWER_NEAR_FIELD_THRESH_LVL2) { |
| 583 | rtlpriv->dm.dynamic_txhighpower_lvl = | 582 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 584 | TXHIGHPWRLEVEL_LEVEL2; | 583 | TXHIGHPWRLEVEL_LEVEL2; |
| 585 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 584 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 586 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | 585 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); |
| 587 | } else | 586 | } else |
| 588 | if ((undecorated_smoothed_pwdb < | 587 | if ((undec_sm_pwdb < |
| 589 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) | 588 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) |
| 590 | && (undecorated_smoothed_pwdb >= | 589 | && (undec_sm_pwdb >= |
| 591 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | 590 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { |
| 592 | 591 | ||
| 593 | rtlpriv->dm.dynamic_txhighpower_lvl = | 592 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 594 | TXHIGHPWRLEVEL_LEVEL1; | 593 | TXHIGHPWRLEVEL_LEVEL1; |
| 595 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 594 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 596 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | 595 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); |
| 597 | } else if (undecorated_smoothed_pwdb < | 596 | } else if (undec_sm_pwdb < |
| 598 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | 597 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { |
| 599 | rtlpriv->dm.dynamic_txhighpower_lvl = | 598 | rtlpriv->dm.dynamic_txhighpower_lvl = |
| 600 | TXHIGHPWRLEVEL_NORMAL; | 599 | TXHIGHPWRLEVEL_NORMAL; |
| @@ -620,7 +619,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) · 19 unmodified lines | |||
| 620 | return; | 619 | return; |
| 621 | /* Indicate Rx signal strength to FW. */ | 620 | /* Indicate Rx signal strength to FW. */ |
| 622 | if (rtlpriv->dm.useramask) { | 621 | if (rtlpriv->dm.useramask) { |
| 623 | u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb; | 622 | u32 temp = rtlpriv->dm.undec_sm_pwdb; |
| 624 | 623 | ||
| 625 | temp <<= 16; | 624 | temp <<= 16; |
| 626 | temp |= 0x100; | 625 | temp |= 0x100; |
| @@ -629,7 +628,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 629 | rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); | 628 | rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); |
| 630 | } else { | 629 | } else { |
| 631 | rtl_write_byte(rtlpriv, 0x4fe, | 630 | rtl_write_byte(rtlpriv, 0x4fe, |
| 632 | (u8) rtlpriv->dm.undecorated_smoothed_pwdb); | 631 | (u8) rtlpriv->dm.undec_sm_pwdb); |
| 633 | } | 632 | } |
| 634 | } | 633 | } |
| 635 | 634 | ||
| @@ -298,13 +298,13 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, · 297 unmodified lines | |||
| 298 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | 298 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, |
| 299 | BIT(8)); | 299 | BIT(8)); |
| 300 | if (rfpi_enable) | 300 | if (rfpi_enable) |
| 301 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | 301 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, |
| 302 | BLSSIREADBACKDATA); | 302 | BLSSIREADBACKDATA); |
| 303 | else | 303 | else |
| 304 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | 304 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, |
| 305 | BLSSIREADBACKDATA); | 305 | BLSSIREADBACKDATA); |
| 306 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", | 306 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", |
| 307 | rfpath, pphyreg->rflssi_readback, retvalue); | 307 | rfpath, pphyreg->rf_rb, retvalue); |
| 308 | return retvalue; | 308 | return retvalue; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| @@ -478,14 +478,10 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 167 unmodified lines | |||
| 478 | 478 | ||
| 479 | /* RF switch Control */ | 479 | /* RF switch Control */ |
| 480 | /* TR/Ant switch control */ | 480 | /* TR/Ant switch control */ |
| 481 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | 481 | rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 482 | RFPGA0_XAB_SWITCHCONTROL; | 482 | rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 483 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | 483 | rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 484 | RFPGA0_XAB_SWITCHCONTROL; | 484 | rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 485 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
| 486 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 487 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
| 488 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 489 | 485 | ||
| 490 | /* AGC control 1 */ | 486 | /* AGC control 1 */ |
| 491 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | 487 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; |
| @@ -500,14 +496,10 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 8 unmodified lines | |||
| 500 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | 496 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; |
| 501 | 497 | ||
| 502 | /* RX AFE control 1 */ | 498 | /* RX AFE control 1 */ |
| 503 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | 499 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; |
| 504 | ROFDM0_XARXIQIMBALANCE; | 500 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; |
| 505 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | 501 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; |
| 506 | ROFDM0_XBRXIQIMBALANCE; | 502 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; |
| 507 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
| 508 | ROFDM0_XCRXIQIMBALANCE; | ||
| 509 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
| 510 | ROFDM0_XDRXIQIMBALANCE; | ||
| 511 | 503 | ||
| 512 | /*RX AFE control 1 */ | 504 | /*RX AFE control 1 */ |
| 513 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | 505 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; |
| @@ -516,14 +508,10 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 516 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | 508 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; |
| 517 | 509 | ||
| 518 | /* Tx AFE control 1 */ | 510 | /* Tx AFE control 1 */ |
| 519 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | 511 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATxIQIMBALANCE; |
| 520 | ROFDM0_XATxIQIMBALANCE; | 512 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTxIQIMBALANCE; |
| 521 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | 513 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTxIQIMBALANCE; |
| 522 | ROFDM0_XBTxIQIMBALANCE; | 514 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTxIQIMBALANCE; |
| 523 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
| 524 | ROFDM0_XCTxIQIMBALANCE; | ||
| 525 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
| 526 | ROFDM0_XDTxIQIMBALANCE; | ||
| 527 | 515 | ||
| 528 | /* Tx AFE control 2 */ | 516 | /* Tx AFE control 2 */ |
| 529 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE; | 517 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE; |
| @@ -532,20 +520,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 532 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE; | 520 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE; |
| 533 | 521 | ||
| 534 | /* Tranceiver LSSI Readback SI mode */ | 522 | /* Tranceiver LSSI Readback SI mode */ |
| 535 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | 523 | rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; |
| 536 | RFPGA0_XA_LSSIREADBACK; | 524 | rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; |
| 537 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | 525 | rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; |
| 538 | RFPGA0_XB_LSSIREADBACK; | 526 | rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; |
| 539 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
| 540 | RFPGA0_XC_LSSIREADBACK; | ||
| 541 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
| 542 | RFPGA0_XD_LSSIREADBACK; | ||
| 543 | 527 | ||
| 544 | /* Tranceiver LSSI Readback PI mode */ | 528 | /* Tranceiver LSSI Readback PI mode */ |
| 545 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | 529 | rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; |
| 546 | TRANSCEIVERA_HSPI_READBACK; | 530 | rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; |
| 547 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
| 548 | TRANSCEIVERB_HSPI_READBACK; | ||
| 549 | } | 531 | } |
| 550 | 532 | ||
| 551 | static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 533 | static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
| @@ -702,12 +684,11 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, · 150 unmodified lines | |||
| 702 | else | 684 | else |
| 703 | return; | 685 | return; |
| 704 | 686 | ||
| 705 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; | 687 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; |
| 706 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 688 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
| 707 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", | 689 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", |
| 708 | rtlphy->pwrgroup_cnt, index, | 690 | rtlphy->pwrgroup_cnt, index, |
| 709 | rtlphy->mcs_txpwrlevel_origoffset | 691 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); |
| 710 | [rtlphy->pwrgroup_cnt][index]); | ||
| 711 | if (index == 13) | 692 | if (index == 13) |
| 712 | rtlphy->pwrgroup_cnt++; | 693 | rtlphy->pwrgroup_cnt++; |
| 713 | } | 694 | } |
| @@ -106,11 +106,11 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, · 105 unmodified lines | |||
| 106 | (ppowerlevel[idx1] << 24); | 106 | (ppowerlevel[idx1] << 24); |
| 107 | } | 107 | } |
| 108 | if (rtlefuse->eeprom_regulatory == 0) { | 108 | if (rtlefuse->eeprom_regulatory == 0) { |
| 109 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + | 109 | tmpval = (rtlphy->mcs_offset[0][6]) + |
| 110 | (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8); | 110 | (rtlphy->mcs_offset[0][7] << 8); |
| 111 | tx_agc[RF90_PATH_A] += tmpval; | 111 | tx_agc[RF90_PATH_A] += tmpval; |
| 112 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + | 112 | tmpval = (rtlphy->mcs_offset[0][14]) + |
| 113 | (rtlphy->mcs_txpwrlevel_origoffset[0][15] << 24); | 113 | (rtlphy->mcs_offset[0][15] << 24); |
| 114 | tx_agc[RF90_PATH_B] += tmpval; | 114 | tx_agc[RF90_PATH_B] += tmpval; |
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| @@ -227,7 +227,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 110 unmodified lines | |||
| 227 | switch (rtlefuse->eeprom_regulatory) { | 227 | switch (rtlefuse->eeprom_regulatory) { |
| 228 | case 0: | 228 | case 0: |
| 229 | chnlgroup = 0; | 229 | chnlgroup = 0; |
| 230 | writeval = rtlphy->mcs_txpwrlevel_origoffset | 230 | writeval = rtlphy->mcs_offset |
| 231 | [chnlgroup][index + | 231 | [chnlgroup][index + |
| 232 | (rf ? 8 : 0)] + ((index < 2) ? | 232 | (rf ? 8 : 0)] + ((index < 2) ? |
| 233 | powerbase0[rf] : | 233 | powerbase0[rf] : |
| @@ -247,7 +247,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 13 unmodified lines | |||
| 247 | chnlgroup++; | 247 | chnlgroup++; |
| 248 | else | 248 | else |
| 249 | chnlgroup += 4; | 249 | chnlgroup += 4; |
| 250 | writeval = rtlphy->mcs_txpwrlevel_origoffset | 250 | writeval = rtlphy->mcs_offset |
| 251 | [chnlgroup][index + | 251 | [chnlgroup][index + |
| 252 | (rf ? 8 : 0)] + ((index < 2) ? | 252 | (rf ? 8 : 0)] + ((index < 2) ? |
| 253 | powerbase0[rf] : | 253 | powerbase0[rf] : |
| @@ -280,8 +280,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 26 unmodified lines | |||
| 280 | [channel - 1]); | 280 | [channel - 1]); |
| 281 | } | 281 | } |
| 282 | for (i = 0; i < 4; i++) { | 282 | for (i = 0; i < 4; i++) { |
| 283 | pwr_diff_limit[i] = | 283 | pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset |
| 284 | (u8)((rtlphy->mcs_txpwrlevel_origoffset | ||
| 285 | [chnlgroup][index + (rf ? 8 : 0)] & | 284 | [chnlgroup][index + (rf ? 8 : 0)] & |
| 286 | (0x7f << (i * 8))) >> (i * 8)); | 285 | (0x7f << (i * 8))) >> (i * 8)); |
| 287 | if (rtlphy->current_chan_bw == | 286 | if (rtlphy->current_chan_bw == |
| @@ -316,8 +315,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, · 28 unmodified lines | |||
| 316 | break; | 315 | break; |
| 317 | default: | 316 | default: |
| 318 | chnlgroup = 0; | 317 | chnlgroup = 0; |
| 319 | writeval = rtlphy->mcs_txpwrlevel_origoffset | 318 | writeval = rtlphy->mcs_offset[chnlgroup][index + |
| 320 | [chnlgroup][index + | ||
| 321 | (rf ? 8 : 0)] + ((index < 2) ? | 319 | (rf ? 8 : 0)] + ((index < 2) ? |
| 322 | powerbase0[rf] : powerbase1[rf]); | 320 | powerbase0[rf] : powerbase1[rf]); |
| 323 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | 321 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, |
| @@ -132,8 +132,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, · 131 unmodified lines | |||
| 132 | pstats->packet_toself = packet_toself; | 132 | pstats->packet_toself = packet_toself; |
| 133 | pstats->packet_beacon = packet_beacon; | 133 | pstats->packet_beacon = packet_beacon; |
| 134 | pstats->is_cck = is_cck_rate; | 134 | pstats->is_cck = is_cck_rate; |
| 135 | pstats->rx_mimo_signalquality[0] = -1; | 135 | pstats->rx_mimo_sig_qual[0] = -1; |
| 136 | pstats->rx_mimo_signalquality[1] = -1; | 136 | pstats->rx_mimo_sig_qual[1] = -1; |
| 137 | 137 | ||
| 138 | if (is_cck_rate) { | 138 | if (is_cck_rate) { |
| 139 | u8 report, cck_highpwr; | 139 | u8 report, cck_highpwr; |
| @@ -212,8 +212,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, · 72 unmodified lines | |||
| 212 | sq = ((64 - sq) * 100) / 44; | 212 | sq = ((64 - sq) * 100) / 44; |
| 213 | } | 213 | } |
| 214 | pstats->signalquality = sq; | 214 | pstats->signalquality = sq; |
| 215 | pstats->rx_mimo_signalquality[0] = sq; | 215 | pstats->rx_mimo_sig_qual[0] = sq; |
| 216 | pstats->rx_mimo_signalquality[1] = -1; | 216 | pstats->rx_mimo_sig_qual[1] = -1; |
| 217 | } | 217 | } |
| 218 | } else { | 218 | } else { |
| 219 | rtlpriv->dm.rfpath_rxenable[0] = true; | 219 | rtlpriv->dm.rfpath_rxenable[0] = true; |
| @@ -246,7 +246,7 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, · 26 unmodified lines | |||
| 246 | if (i == 0) | 246 | if (i == 0) |
| 247 | pstats->signalquality = | 247 | pstats->signalquality = |
| 248 | (u8)(evm & 0xff); | 248 | (u8)(evm & 0xff); |
| 249 | pstats->rx_mimo_signalquality[i] = | 249 | pstats->rx_mimo_sig_qual[i] = |
| 250 | (u8)(evm & 0xff); | 250 | (u8)(evm & 0xff); |
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| @@ -345,33 +345,28 @@ static void _rtl92de_process_pwdb(struct ieee80211_hw *hw, · 92 unmodified lines | |||
| 345 | { | 345 | { |
| 346 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 346 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 347 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 347 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 348 | long undecorated_smoothed_pwdb; | 348 | long undec_sm_pwdb; |
| 349 | 349 | ||
| 350 | if (mac->opmode == NL80211_IFTYPE_ADHOC || | 350 | if (mac->opmode == NL80211_IFTYPE_ADHOC || |
| 351 | mac->opmode == NL80211_IFTYPE_AP) | 351 | mac->opmode == NL80211_IFTYPE_AP) |
| 352 | return; | 352 | return; |
| 353 | else | 353 | else |
| 354 | undecorated_smoothed_pwdb = | 354 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 355 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 356 | 355 | ||
| 357 | if (pstats->packet_toself || pstats->packet_beacon) { | 356 | if (pstats->packet_toself || pstats->packet_beacon) { |
| 358 | if (undecorated_smoothed_pwdb < 0) | 357 | if (undec_sm_pwdb < 0) |
| 359 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | 358 | undec_sm_pwdb = pstats->rx_pwdb_all; |
| 360 | if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { | 359 | if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { |
| 361 | undecorated_smoothed_pwdb = | 360 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 362 | (((undecorated_smoothed_pwdb) * | ||
| 363 | (RX_SMOOTH_FACTOR - 1)) + | 361 | (RX_SMOOTH_FACTOR - 1)) + |
| 364 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 362 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 365 | undecorated_smoothed_pwdb = | 363 | undec_sm_pwdb = undec_sm_pwdb + 1; |
| 366 | undecorated_smoothed_pwdb + 1; | ||
| 367 | } else { | 364 | } else { |
| 368 | undecorated_smoothed_pwdb = | 365 | undec_sm_pwdb = (((undec_sm_pwdb) * |
| 369 | (((undecorated_smoothed_pwdb) * | ||
| 370 | (RX_SMOOTH_FACTOR - 1)) + | 366 | (RX_SMOOTH_FACTOR - 1)) + |
| 371 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | 367 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); |
| 372 | } | 368 | } |
| 373 | rtlpriv->dm.undecorated_smoothed_pwdb = | 369 | rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; |
| 374 | undecorated_smoothed_pwdb; | ||
| 375 | _rtl92de_update_rxsignalstatistics(hw, pstats); | 370 | _rtl92de_update_rxsignalstatistics(hw, pstats); |
| 376 | } | 371 | } |
| 377 | } | 372 | } |
| @@ -383,15 +378,15 @@ static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, · 5 unmodified lines | |||
| 383 | int stream; | 378 | int stream; |
| 384 | 379 | ||
| 385 | for (stream = 0; stream < 2; stream++) { | 380 | for (stream = 0; stream < 2; stream++) { |
| 386 | if (pstats->rx_mimo_signalquality[stream] != -1) { | 381 | if (pstats->rx_mimo_sig_qual[stream] != -1) { |
| 387 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { | 382 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { |
| 388 | rtlpriv->stats.rx_evm_percentage[stream] = | 383 | rtlpriv->stats.rx_evm_percentage[stream] = |
| 389 | pstats->rx_mimo_signalquality[stream]; | 384 | pstats->rx_mimo_sig_qual[stream]; |
| 390 | } | 385 | } |
| 391 | rtlpriv->stats.rx_evm_percentage[stream] = | 386 | rtlpriv->stats.rx_evm_percentage[stream] = |
| 392 | ((rtlpriv->stats.rx_evm_percentage[stream] | 387 | ((rtlpriv->stats.rx_evm_percentage[stream] |
| 393 | * (RX_SMOOTH_FACTOR - 1)) + | 388 | * (RX_SMOOTH_FACTOR - 1)) + |
| 394 | (pstats->rx_mimo_signalquality[stream] * 1)) / | 389 | (pstats->rx_mimo_sig_qual[stream] * 1)) / |
| 395 | (RX_SMOOTH_FACTOR); | 390 | (RX_SMOOTH_FACTOR); |
| 396 | } | 391 | } |
| 397 | } | 392 | } |
| @@ -267,13 +267,12 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) · 266 unmodified lines | |||
| 267 | break; | 267 | break; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | 270 | if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) { |
| 271 | (long)high_rssi_thresh) { | ||
| 272 | ra->ratr_state = DM_RATR_STA_HIGH; | 271 | ra->ratr_state = DM_RATR_STA_HIGH; |
| 273 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | 272 | } else if (rtlpriv->dm.undec_sm_pwdb > |
| 274 | (long)middle_rssi_thresh) { | 273 | (long)middle_rssi_thresh) { |
| 275 | ra->ratr_state = DM_RATR_STA_LOW; | 274 | ra->ratr_state = DM_RATR_STA_LOW; |
| 276 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | 275 | } else if (rtlpriv->dm.undec_sm_pwdb > |
| 277 | (long)low_rssi_thresh) { | 276 | (long)low_rssi_thresh) { |
| 278 | ra->ratr_state = DM_RATR_STA_LOW; | 277 | ra->ratr_state = DM_RATR_STA_LOW; |
| 279 | } else { | 278 | } else { |
| @@ -283,8 +282,7 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) · 3 unmodified lines | |||
| 283 | if (ra->pre_ratr_state != ra->ratr_state) { | 282 | if (ra->pre_ratr_state != ra->ratr_state) { |
| 284 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | 283 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, |
| 285 | "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", | 284 | "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", |
| 286 | rtlpriv->dm.undecorated_smoothed_pwdb, | 285 | rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, |
| 287 | ra->ratr_state, | ||
| 288 | ra->pre_ratr_state, ra->ratr_state); | 286 | ra->pre_ratr_state, ra->ratr_state); |
| 289 | 287 | ||
| 290 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | 288 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, |
| @@ -316,7 +314,7 @@ static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) · 25 unmodified lines | |||
| 316 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); | 314 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); |
| 317 | 315 | ||
| 318 | if (mac->link_state >= MAC80211_LINKED) { | 316 | if (mac->link_state >= MAC80211_LINKED) { |
| 319 | if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) { | 317 | if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) { |
| 320 | rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; | 318 | rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; |
| 321 | rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; | 319 | rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; |
| 322 | } | 320 | } |
| @@ -424,18 +422,18 @@ static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw) · 101 unmodified lines | |||
| 424 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | 422 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); |
| 425 | 423 | ||
| 426 | if (falsealm_cnt->cnt_all > digtable->fa_highthresh) { | 424 | if (falsealm_cnt->cnt_all > digtable->fa_highthresh) { |
| 427 | if ((digtable->backoff_val - 6) < | 425 | if ((digtable->back_val - 6) < |
| 428 | digtable->backoffval_range_min) | 426 | digtable->backoffval_range_min) |
| 429 | digtable->backoff_val = digtable->backoffval_range_min; | 427 | digtable->back_val = digtable->backoffval_range_min; |
| 430 | else | 428 | else |
| 431 | digtable->backoff_val -= 6; | 429 | digtable->back_val -= 6; |
| 432 | } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) { | 430 | } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) { |
| 433 | if ((digtable->backoff_val + 6) > | 431 | if ((digtable->back_val + 6) > |
| 434 | digtable->backoffval_range_max) | 432 | digtable->backoffval_range_max) |
| 435 | digtable->backoff_val = | 433 | digtable->back_val = |
| 436 | digtable->backoffval_range_max; | 434 | digtable->backoffval_range_max; |
| 437 | else | 435 | else |
| 438 | digtable->backoff_val += 6; | 436 | digtable->back_val += 6; |
| 439 | } | 437 | } |
| 440 | } | 438 | } |
| 441 | 439 | ||
| @@ -447,28 +445,28 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 447 | static u8 initialized, force_write; | 445 | static u8 initialized, force_write; |
| 448 | u8 initial_gain = 0; | 446 | u8 initial_gain = 0; |
| 449 | 447 | ||
| 450 | if ((digtable->pre_sta_connectstate == digtable->cur_sta_connectstate) || | 448 | if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) || |
| 451 | (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) { | 449 | (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) { |
| 452 | if (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) { | 450 | if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) { |
| 453 | if (rtlpriv->psc.rfpwr_state != ERFON) | 451 | if (rtlpriv->psc.rfpwr_state != ERFON) |
| 454 | return; | 452 | return; |
| 455 | 453 | ||
| 456 | if (digtable->backoff_enable_flag) | 454 | if (digtable->backoff_enable_flag) |
| 457 | rtl92s_backoff_enable_flag(hw); | 455 | rtl92s_backoff_enable_flag(hw); |
| 458 | else | 456 | else |
| 459 | digtable->backoff_val = DM_DIG_BACKOFF; | 457 | digtable->back_val = DM_DIG_BACKOFF; |
| 460 | 458 | ||
| 461 | if ((digtable->rssi_val + 10 - digtable->backoff_val) > | 459 | if ((digtable->rssi_val + 10 - digtable->back_val) > |
| 462 | digtable->rx_gain_range_max) | 460 | digtable->rx_gain_range_max) |
| 463 | digtable->cur_igvalue = | 461 | digtable->cur_igvalue = |
| 464 | digtable->rx_gain_range_max; | 462 | digtable->rx_gain_range_max; |
| 465 | else if ((digtable->rssi_val + 10 - digtable->backoff_val) | 463 | else if ((digtable->rssi_val + 10 - digtable->back_val) |
| 466 | < digtable->rx_gain_range_min) | 464 | < digtable->rx_gain_range_min) |
| 467 | digtable->cur_igvalue = | 465 | digtable->cur_igvalue = |
| 468 | digtable->rx_gain_range_min; | 466 | digtable->rx_gain_range_min; |
| 469 | else | 467 | else |
| 470 | digtable->cur_igvalue = digtable->rssi_val + 10 - | 468 | digtable->cur_igvalue = digtable->rssi_val + 10 - |
| 471 | digtable->backoff_val; | 469 | digtable->back_val; |
| 472 | 470 | ||
| 473 | if (falsealm_cnt->cnt_all > 10000) | 471 | if (falsealm_cnt->cnt_all > 10000) |
| 474 | digtable->cur_igvalue = | 472 | digtable->cur_igvalue = |
| @@ -490,7 +488,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) · 15 unmodified lines | |||
| 490 | digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | 488 | digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; |
| 491 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); | 489 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); |
| 492 | 490 | ||
| 493 | digtable->backoff_val = DM_DIG_BACKOFF; | 491 | digtable->back_val = DM_DIG_BACKOFF; |
| 494 | digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; | 492 | digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; |
| 495 | digtable->pre_igvalue = 0; | 493 | digtable->pre_igvalue = 0; |
| 496 | return; | 494 | return; |
| @@ -528,14 +526,14 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) · 31 unmodified lines | |||
| 528 | /* Decide the current status and if modify initial gain or not */ | 526 | /* Decide the current status and if modify initial gain or not */ |
| 529 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || | 527 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || |
| 530 | rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) | 528 | rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) |
| 531 | digtable->cur_sta_connectstate = DIG_STA_CONNECT; | 529 | digtable->cur_sta_cstate = DIG_STA_CONNECT; |
| 532 | else | 530 | else |
| 533 | digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; | 531 | digtable->cur_sta_cstate = DIG_STA_DISCONNECT; |
| 534 | 532 | ||
| 535 | digtable->rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb; | 533 | digtable->rssi_val = rtlpriv->dm.undec_sm_pwdb; |
| 536 | 534 | ||
| 537 | /* Change dig mode to rssi */ | 535 | /* Change dig mode to rssi */ |
| 538 | if (digtable->cur_sta_connectstate != DIG_STA_DISCONNECT) { | 536 | if (digtable->cur_sta_cstate != DIG_STA_DISCONNECT) { |
| 539 | if (digtable->dig_twoport_algorithm == | 537 | if (digtable->dig_twoport_algorithm == |
| 540 | DIG_TWO_PORT_ALGO_FALSE_ALARM) { | 538 | DIG_TWO_PORT_ALGO_FALSE_ALARM) { |
| 541 | digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; | 539 | digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; |
| @@ -546,7 +544,7 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) · 4 unmodified lines | |||
| 546 | _rtl92s_dm_false_alarm_counter_statistics(hw); | 544 | _rtl92s_dm_false_alarm_counter_statistics(hw); |
| 547 | _rtl92s_dm_initial_gain_sta_beforeconnect(hw); | 545 | _rtl92s_dm_initial_gain_sta_beforeconnect(hw); |
| 548 | 546 | ||
| 549 | digtable->pre_sta_connectstate = digtable->cur_sta_connectstate; | 547 | digtable->pre_sta_cstate = digtable->cur_sta_cstate; |
| 550 | } | 548 | } |
| 551 | 549 | ||
| 552 | static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) | 550 | static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) |
| @@ -573,7 +571,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) · 20 unmodified lines | |||
| 573 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 571 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 574 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 572 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 575 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 573 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 576 | long undecorated_smoothed_pwdb; | 574 | long undec_sm_pwdb; |
| 577 | long txpwr_threshold_lv1, txpwr_threshold_lv2; | 575 | long txpwr_threshold_lv1, txpwr_threshold_lv2; |
| 578 | 576 | ||
| 579 | /* 2T2R TP issue */ | 577 | /* 2T2R TP issue */ |
| @@ -587,7 +585,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) · 7 unmodified lines | |||
| 587 | } | 585 | } |
| 588 | 586 | ||
| 589 | if ((mac->link_state < MAC80211_LINKED) && | 587 | if ((mac->link_state < MAC80211_LINKED) && |
| 590 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | 588 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { |
| 591 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | 589 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, |
| 592 | "Not connected to any\n"); | 590 | "Not connected to any\n"); |
| 593 | 591 | ||
| @@ -599,25 +597,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) · 5 unmodified lines | |||
| 599 | 597 | ||
| 600 | if (mac->link_state >= MAC80211_LINKED) { | 598 | if (mac->link_state >= MAC80211_LINKED) { |
| 601 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 599 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
| 602 | undecorated_smoothed_pwdb = | 600 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 603 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 604 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 601 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 605 | "AP Client PWDB = 0x%lx\n", | 602 | "AP Client PWDB = 0x%lx\n", |
| 606 | undecorated_smoothed_pwdb); | 603 | undec_sm_pwdb); |
| 607 | } else { | 604 | } else { |
| 608 | undecorated_smoothed_pwdb = | 605 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; |
| 609 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
| 610 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 606 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 611 | "STA Default Port PWDB = 0x%lx\n", | 607 | "STA Default Port PWDB = 0x%lx\n", |
| 612 | undecorated_smoothed_pwdb); | 608 | undec_sm_pwdb); |
| 613 | } | 609 | } |
| 614 | } else { | 610 | } else { |
| 615 | undecorated_smoothed_pwdb = | 611 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; |
| 616 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
| 617 | 612 | ||
| 618 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 613 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 619 | "AP Ext Port PWDB = 0x%lx\n", | 614 | "AP Ext Port PWDB = 0x%lx\n", |
| 620 | undecorated_smoothed_pwdb); | 615 | undec_sm_pwdb); |
| 621 | } | 616 | } |
| 622 | 617 | ||
| 623 | txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; | 618 | txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; |
| @@ -625,12 +620,12 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) · 1 unmodified line | |||
| 625 | 620 | ||
| 626 | if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) | 621 | if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) |
| 627 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | 622 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; |
| 628 | else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2) | 623 | else if (undec_sm_pwdb >= txpwr_threshold_lv2) |
| 629 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; | 624 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; |
| 630 | else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) && | 625 | else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) && |
| 631 | (undecorated_smoothed_pwdb >= txpwr_threshold_lv1)) | 626 | (undec_sm_pwdb >= txpwr_threshold_lv1)) |
| 632 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; | 627 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; |
| 633 | else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3)) | 628 | else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3)) |
| 634 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | 629 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; |
| 635 | 630 | ||
| 636 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) | 631 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) |
| @@ -665,10 +660,10 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) · 28 unmodified lines | |||
| 665 | digtable->dig_state = DM_STA_DIG_MAX; | 660 | digtable->dig_state = DM_STA_DIG_MAX; |
| 666 | digtable->dig_highpwrstate = DM_STA_DIG_MAX; | 661 | digtable->dig_highpwrstate = DM_STA_DIG_MAX; |
| 667 | 662 | ||
| 668 | digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; | 663 | digtable->cur_sta_cstate = DIG_STA_DISCONNECT; |
| 669 | digtable->pre_sta_connectstate = DIG_STA_DISCONNECT; | 664 | digtable->pre_sta_cstate = DIG_STA_DISCONNECT; |
| 670 | digtable->cur_ap_connectstate = DIG_AP_DISCONNECT; | 665 | digtable->cur_ap_cstate = DIG_AP_DISCONNECT; |
| 671 | digtable->pre_ap_connectstate = DIG_AP_DISCONNECT; | 666 | digtable->pre_ap_cstate = DIG_AP_DISCONNECT; |
| 672 | 667 | ||
| 673 | digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; | 668 | digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; |
| 674 | digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; | 669 | digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; |
| @@ -681,7 +676,7 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) · 6 unmodified lines | |||
| 681 | 676 | ||
| 682 | /* for dig debug rssi value */ | 677 | /* for dig debug rssi value */ |
| 683 | digtable->rssi_val = 50; | 678 | digtable->rssi_val = 50; |
| 684 | digtable->backoff_val = DM_DIG_BACKOFF; | 679 | digtable->back_val = DM_DIG_BACKOFF; |
| 685 | digtable->rx_gain_range_max = DM_DIG_MAX; | 680 | digtable->rx_gain_range_max = DM_DIG_MAX; |
| 686 | 681 | ||
| 687 | digtable->rx_gain_range_min = DM_DIG_MIN; | 682 | digtable->rx_gain_range_min = DM_DIG_MIN; |
| @@ -709,7 +704,7 @@ void rtl92s_dm_init(struct ieee80211_hw *hw) · 21 unmodified lines | |||
| 709 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 704 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 710 | 705 | ||
| 711 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | 706 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; |
| 712 | rtlpriv->dm.undecorated_smoothed_pwdb = -1; | 707 | rtlpriv->dm.undec_sm_pwdb = -1; |
| 713 | 708 | ||
| 714 | _rtl92s_dm_init_dynamic_txpower(hw); | 709 | _rtl92s_dm_init_dynamic_txpower(hw); |
| 715 | rtl92s_dm_init_edca_turbo(hw); | 710 | rtl92s_dm_init_edca_turbo(hw); |
| @@ -1697,7 +1697,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) · 1696 unmodified lines | |||
| 1697 | hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; | 1697 | hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; |
| 1698 | 1698 | ||
| 1699 | /* Read OFDM RF A & B Tx power for 2T */ | 1699 | /* Read OFDM RF A & B Tx power for 2T */ |
| 1700 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i] | 1700 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] |
| 1701 | = hwinfo[EEPROM_TXPOWERBASE + 12 + | 1701 | = hwinfo[EEPROM_TXPOWERBASE + 12 + |
| 1702 | rf_path * 3 + i]; | 1702 | rf_path * 3 + i]; |
| 1703 | } | 1703 | } |
| @@ -1722,7 +1722,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) · 18 unmodified lines | |||
| 1722 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | 1722 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, |
| 1723 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | 1723 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", |
| 1724 | rf_path, i, | 1724 | rf_path, i, |
| 1725 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif | 1725 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf |
| 1726 | [rf_path][i]); | 1726 | [rf_path][i]); |
| 1727 | 1727 | ||
| 1728 | for (rf_path = 0; rf_path < 2; rf_path++) { | 1728 | for (rf_path = 0; rf_path < 2; rf_path++) { |
| @@ -1748,7 +1748,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) · 19 unmodified lines | |||
| 1748 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | 1748 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s |
| 1749 | [rf_path][index]; | 1749 | [rf_path][index]; |
| 1750 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | 1750 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = |
| 1751 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif | 1751 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf |
| 1752 | [rf_path][index]; | 1752 | [rf_path][index]; |
| 1753 | } | 1753 | } |
| 1754 | 1754 | ||
| @@ -139,17 +139,17 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, · 138 unmodified lines | |||
| 139 | BIT(8)); | 139 | BIT(8)); |
| 140 | 140 | ||
| 141 | if (rfpi_enable) | 141 | if (rfpi_enable) |
| 142 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | 142 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, |
| 143 | BLSSI_READBACK_DATA); | 143 | BLSSI_READBACK_DATA); |
| 144 | else | 144 | else |
| 145 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | 145 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, |
| 146 | BLSSI_READBACK_DATA); | 146 | BLSSI_READBACK_DATA); |
| 147 | 147 | ||
| 148 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | 148 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, |
| 149 | BLSSI_READBACK_DATA); | 149 | BLSSI_READBACK_DATA); |
| 150 | 150 | ||
| 151 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", | 151 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", |
| 152 | rfpath, pphyreg->rflssi_readback, retvalue); | 152 | rfpath, pphyreg->rf_rb, retvalue); |
| 153 | 153 | ||
| 154 | return retvalue; | 154 | return retvalue; |
| 155 | 155 | ||
| @@ -696,7 +696,7 @@ static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, · 540 unmodified lines | |||
| 696 | else | 696 | else |
| 697 | return; | 697 | return; |
| 698 | 698 | ||
| 699 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; | 699 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; |
| 700 | if (index == 5) | 700 | if (index == 5) |
| 701 | rtlphy->pwrgroup_cnt++; | 701 | rtlphy->pwrgroup_cnt++; |
| 702 | } | 702 | } |
| @@ -765,14 +765,10 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) · 62 unmodified lines | |||
| 765 | rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; | 765 | rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; |
| 766 | 766 | ||
| 767 | /* RF switch Control */ | 767 | /* RF switch Control */ |
| 768 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | 768 | rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 769 | RFPGA0_XAB_SWITCHCONTROL; | 769 | rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
| 770 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | 770 | rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 771 | RFPGA0_XAB_SWITCHCONTROL; | 771 | rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; |
| 772 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
| 773 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 774 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
| 775 | RFPGA0_XCD_SWITCHCONTROL; | ||
| 776 | 772 | ||
| 777 | /* AGC control 1 */ | 773 | /* AGC control 1 */ |
| 778 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | 774 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; |
| @@ -787,14 +783,10 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) · 8 unmodified lines | |||
| 787 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | 783 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; |
| 788 | 784 | ||
| 789 | /* RX AFE control 1 */ | 785 | /* RX AFE control 1 */ |
| 790 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | 786 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; |
| 791 | ROFDM0_XARXIQIMBALANCE; | 787 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; |
| 792 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | 788 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; |
| 793 | ROFDM0_XBRXIQIMBALANCE; | 789 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; |
| 794 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
| 795 | ROFDM0_XCRXIQIMBALANCE; | ||
| 796 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
| 797 | ROFDM0_XDRXIQIMBALANCE; | ||
| 798 | 790 | ||
| 799 | /* RX AFE control 1 */ | 791 | /* RX AFE control 1 */ |
| 800 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | 792 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; |
| @@ -803,14 +795,10 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 803 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | 795 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; |
| 804 | 796 | ||
| 805 | /* Tx AFE control 1 */ | 797 | /* Tx AFE control 1 */ |
| 806 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | 798 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; |
| 807 | ROFDM0_XATXIQIMBALANCE; | 799 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; |
| 808 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | 800 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; |
| 809 | ROFDM0_XBTXIQIMBALANCE; | 801 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; |
| 810 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
| 811 | ROFDM0_XCTXIQIMBALANCE; | ||
| 812 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
| 813 | ROFDM0_XDTXIQIMBALANCE; | ||
| 814 | 802 | ||
| 815 | /* Tx AFE control 2 */ | 803 | /* Tx AFE control 2 */ |
| 816 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | 804 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; |
| @@ -819,20 +807,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) · 2 unmodified lines | |||
| 819 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | 807 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; |
| 820 | 808 | ||
| 821 | /* Tranceiver LSSI Readback */ | 809 | /* Tranceiver LSSI Readback */ |
| 822 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | 810 | rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; |
| 823 | RFPGA0_XA_LSSIREADBACK; | 811 | rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; |
| 824 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | 812 | rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; |
| 825 | RFPGA0_XB_LSSIREADBACK; | 813 | rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; |
| 826 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
| 827 | RFPGA0_XC_LSSIREADBACK; | ||
| 828 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
| 829 | RFPGA0_XD_LSSIREADBACK; | ||
| 830 | 814 | ||
| 831 | /* Tranceiver LSSI Readback PI mode */ | 815 | /* Tranceiver LSSI Readback PI mode */ |
| 832 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | 816 | rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; |
| 833 | TRANSCEIVERA_HSPI_READBACK; | 817 | rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; |
| 834 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
| 835 | TRANSCEIVERB_HSPI_READBACK; | ||
| 836 | } | 818 | } |
| 837 | 819 | ||
| 838 | 820 | ||
| @@ -192,8 +192,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, · 191 unmodified lines | |||
| 192 | * defined by Realtek for large power */ | 192 | * defined by Realtek for large power */ |
| 193 | chnlgroup = 0; | 193 | chnlgroup = 0; |
| 194 | 194 | ||
| 195 | writeval = rtlphy->mcs_txpwrlevel_origoffset | 195 | writeval = rtlphy->mcs_offset[chnlgroup][index] + |
| 196 | [chnlgroup][index] + | ||
| 197 | ((index < 2) ? pwrbase0 : pwrbase1); | 196 | ((index < 2) ? pwrbase0 : pwrbase1); |
| 198 | 197 | ||
| 199 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 198 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| @@ -223,8 +222,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, · 23 unmodified lines | |||
| 223 | chnlgroup++; | 222 | chnlgroup++; |
| 224 | } | 223 | } |
| 225 | 224 | ||
| 226 | writeval = rtlphy->mcs_txpwrlevel_origoffset | 225 | writeval = rtlphy->mcs_offset[chnlgroup][index] |
| 227 | [chnlgroup][index] | ||
| 228 | + ((index < 2) ? | 226 | + ((index < 2) ? |
| 229 | pwrbase0 : pwrbase1); | 227 | pwrbase0 : pwrbase1); |
| 230 | 228 | ||
| @@ -257,8 +255,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, · 26 unmodified lines | |||
| 257 | } | 255 | } |
| 258 | 256 | ||
| 259 | for (i = 0; i < 4; i++) { | 257 | for (i = 0; i < 4; i++) { |
| 260 | pwrdiff_limit[i] = | 258 | pwrdiff_limit[i] = (u8)((rtlphy->mcs_offset |
| 261 | (u8)((rtlphy->mcs_txpwrlevel_origoffset | ||
| 262 | [chnlgroup][index] & (0x7f << (i * 8))) | 259 | [chnlgroup][index] & (0x7f << (i * 8))) |
| 263 | >> (i * 8)); | 260 | >> (i * 8)); |
| 264 | 261 | ||
| @@ -296,7 +293,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, · 31 unmodified lines | |||
| 296 | break; | 293 | break; |
| 297 | default: | 294 | default: |
| 298 | chnlgroup = 0; | 295 | chnlgroup = 0; |
| 299 | writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + | 296 | writeval = rtlphy->mcs_offset[chnlgroup][index] + |
| 300 | ((index < 2) ? pwrbase0 : pwrbase1); | 297 | ((index < 2) ? pwrbase0 : pwrbase1); |
| 301 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | 298 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, |
| 302 | "RTK better performance, writeval = 0x%x\n", writeval); | 299 | "RTK better performance, writeval = 0x%x\n", writeval); |
| @@ -129,8 +129,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, · 128 unmodified lines | |||
| 129 | pstats->packet_matchbssid = packet_match_bssid; | 129 | pstats->packet_matchbssid = packet_match_bssid; |
| 130 | pstats->packet_toself = packet_toself; | 130 | pstats->packet_toself = packet_toself; |
| 131 | pstats->packet_beacon = packet_beacon; | 131 | pstats->packet_beacon = packet_beacon; |
| 132 | pstats->rx_mimo_signalquality[0] = -1; | 132 | pstats->rx_mimo_sig_qual[0] = -1; |
| 133 | pstats->rx_mimo_signalquality[1] = -1; | 133 | pstats->rx_mimo_sig_qual[1] = -1; |
| 134 | 134 | ||
| 135 | if (is_cck) { | 135 | if (is_cck) { |
| 136 | u8 report, cck_highpwr; | 136 | u8 report, cck_highpwr; |
| @@ -216,8 +216,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, · 79 unmodified lines | |||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | pstats->signalquality = sq; | 218 | pstats->signalquality = sq; |
| 219 | pstats->rx_mimo_signalquality[0] = sq; | 219 | pstats->rx_mimo_sig_qual[0] = sq; |
| 220 | pstats->rx_mimo_signalquality[1] = -1; | 220 | pstats->rx_mimo_sig_qual[1] = -1; |
| 221 | } | 221 | } |
| 222 | } else { | 222 | } else { |
| 223 | rtlpriv->dm.rfpath_rxenable[0] = | 223 | rtlpriv->dm.rfpath_rxenable[0] = |
| @@ -256,8 +256,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, · 32 unmodified lines | |||
| 256 | if (i == 0) | 256 | if (i == 0) |
| 257 | pstats->signalquality = (u8)(evm & | 257 | pstats->signalquality = (u8)(evm & |
| 258 | 0xff); | 258 | 0xff); |
| 259 | pstats->rx_mimo_signalquality[i] = | 259 | pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); |
| 260 | (u8) (evm & 0xff); | ||
| 261 | } | 260 | } |
| 262 | } | 261 | } |
| 263 | } | 262 | } |
| @@ -366,7 +365,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, · 102 unmodified lines | |||
| 366 | return; | 365 | return; |
| 367 | } else { | 366 | } else { |
| 368 | undec_sm_pwdb = | 367 | undec_sm_pwdb = |
| 369 | rtlpriv->dm.undecorated_smoothed_pwdb; | 368 | rtlpriv->dm.undec_sm_pwdb; |
| 370 | } | 369 | } |
| 371 | 370 | ||
| 372 | if (pstats->packet_toself || pstats->packet_beacon) { | 371 | if (pstats->packet_toself || pstats->packet_beacon) { |
| @@ -386,7 +385,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, · 13 unmodified lines | |||
| 386 | (RX_SMOOTH_FACTOR); | 385 | (RX_SMOOTH_FACTOR); |
| 387 | } | 386 | } |
| 388 | 387 | ||
| 389 | rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb; | 388 | rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; |
| 390 | _rtl92se_update_rxsignalstatistics(hw, pstats); | 389 | _rtl92se_update_rxsignalstatistics(hw, pstats); |
| 391 | } | 390 | } |
| 392 | } | 391 | } |
| @@ -398,16 +397,16 @@ static void rtl_92s_process_streams(struct ieee80211_hw *hw, · 5 unmodified lines | |||
| 398 | u32 stream; | 397 | u32 stream; |
| 399 | 398 | ||
| 400 | for (stream = 0; stream < 2; stream++) { | 399 | for (stream = 0; stream < 2; stream++) { |
| 401 | if (pstats->rx_mimo_signalquality[stream] != -1) { | 400 | if (pstats->rx_mimo_sig_qual[stream] != -1) { |
| 402 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { | 401 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { |
| 403 | rtlpriv->stats.rx_evm_percentage[stream] = | 402 | rtlpriv->stats.rx_evm_percentage[stream] = |
| 404 | pstats->rx_mimo_signalquality[stream]; | 403 | pstats->rx_mimo_sig_qual[stream]; |
| 405 | } | 404 | } |
| 406 | 405 | ||
| 407 | rtlpriv->stats.rx_evm_percentage[stream] = | 406 | rtlpriv->stats.rx_evm_percentage[stream] = |
| 408 | ((rtlpriv->stats.rx_evm_percentage[stream] * | 407 | ((rtlpriv->stats.rx_evm_percentage[stream] * |
| 409 | (RX_SMOOTH_FACTOR - 1)) + | 408 | (RX_SMOOTH_FACTOR - 1)) + |
| 410 | (pstats->rx_mimo_signalquality[stream] * | 409 | (pstats->rx_mimo_sig_qual[stream] * |
| 411 | 1)) / (RX_SMOOTH_FACTOR); | 410 | 1)) / (RX_SMOOTH_FACTOR); |
| 412 | } | 411 | } |
| 413 | } | 412 | } |
| @@ -198,15 +198,15 @@ struct bb_reg_def { · 197 unmodified lines | |||
| 198 | u32 rftxgain_stage; | 198 | u32 rftxgain_stage; |
| 199 | u32 rfhssi_para1; | 199 | u32 rfhssi_para1; |
| 200 | u32 rfhssi_para2; | 200 | u32 rfhssi_para2; |
| 201 | u32 rfswitch_control; | 201 | u32 rfsw_ctrl; |
| 202 | u32 rfagc_control1; | 202 | u32 rfagc_control1; |
| 203 | u32 rfagc_control2; | 203 | u32 rfagc_control2; |
| 204 | u32 rfrxiq_imbalance; | 204 | u32 rfrxiq_imbal; |
| 205 | u32 rfrx_afe; | 205 | u32 rfrx_afe; |
| 206 | u32 rftxiq_imbalance; | 206 | u32 rftxiq_imbal; |
| 207 | u32 rftx_afe; | 207 | u32 rftx_afe; |
| 208 | u32 rflssi_readback; | 208 | u32 rf_rb; /* rflssi_readback */ |
| 209 | u32 rflssi_readbackpi; | 209 | u32 rf_rbpi; /* rflssi_readbackpi */ |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | enum io_type { | 212 | enum io_type { |
| @@ -885,7 +885,7 @@ struct rtl_phy { · 672 unmodified lines | |||
| 885 | u8 pwrgroup_cnt; | 885 | u8 pwrgroup_cnt; |
| 886 | u8 cck_high_power; | 886 | u8 cck_high_power; |
| 887 | /* MAX_PG_GROUP groups of pwr diff by rates */ | 887 | /* MAX_PG_GROUP groups of pwr diff by rates */ |
| 888 | u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; | 888 | u32 mcs_offset[MAX_PG_GROUP][16]; |
| 889 | u8 default_initialgain[4]; | 889 | u8 default_initialgain[4]; |
| 890 | 890 | ||
| 891 | /* the current Tx power level */ | 891 | /* the current Tx power level */ |
| @@ -933,7 +933,7 @@ struct rtl_tid_data { · 41 unmodified lines | |||
| 933 | }; | 933 | }; |
| 934 | 934 | ||
| 935 | struct rssi_sta { | 935 | struct rssi_sta { |
| 936 | long undecorated_smoothed_pwdb; | 936 | long undec_sm_pwdb; |
| 937 | }; | 937 | }; |
| 938 | 938 | ||
| 939 | struct rtl_sta_info { | 939 | struct rtl_sta_info { |
| @@ -1131,9 +1131,9 @@ struct rtl_security { · 191 unmodified lines | |||
| 1131 | 1131 | ||
| 1132 | struct rtl_dm { | 1132 | struct rtl_dm { |
| 1133 | /*PHY status for Dynamic Management */ | 1133 | /*PHY status for Dynamic Management */ |
| 1134 | long entry_min_undecoratedsmoothed_pwdb; | 1134 | long entry_min_undec_sm_pwdb; |
| 1135 | long undecorated_smoothed_pwdb; /*out dm */ | 1135 | long undec_sm_pwdb; /*out dm */ |
| 1136 | long entry_max_undecoratedsmoothed_pwdb; | 1136 | long entry_max_undec_sm_pwdb; |
| 1137 | bool dm_initialgain_enable; | 1137 | bool dm_initialgain_enable; |
| 1138 | bool dynamic_txpower_enable; | 1138 | bool dynamic_txpower_enable; |
| 1139 | bool current_turbo_edca; | 1139 | bool current_turbo_edca; |
| @@ -1209,7 +1209,7 @@ struct rtl_efuse { · 69 unmodified lines | |||
| 1209 | u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; | 1209 | u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; |
| 1210 | u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; | 1210 | u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; |
| 1211 | u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; | 1211 | u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; |
| 1212 | u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX]; | 1212 | u8 eprom_chnl_txpwr_ht40_2sdf[2][CHANNEL_GROUP_MAX]; |
| 1213 | u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; | 1213 | u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; |
| 1214 | u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ | 1214 | u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ |
| 1215 | u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ | 1215 | u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ |
| @@ -1351,7 +1351,7 @@ struct rtl_stats { · 135 unmodified lines | |||
| 1351 | bool rx_is40Mhzpacket; | 1351 | bool rx_is40Mhzpacket; |
| 1352 | u32 rx_pwdb_all; | 1352 | u32 rx_pwdb_all; |
| 1353 | u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ | 1353 | u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ |
| 1354 | s8 rx_mimo_signalquality[2]; | 1354 | s8 rx_mimo_sig_qual[2]; |
| 1355 | bool packet_matchbssid; | 1355 | bool packet_matchbssid; |
| 1356 | bool is_cck; | 1356 | bool is_cck; |
| 1357 | bool is_ht; | 1357 | bool is_ht; |
| @@ -1503,6 +1503,9 @@ struct rtl_hal_ops { · 145 unmodified lines | |||
| 1503 | void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); | 1503 | void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); |
| 1504 | void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); | 1504 | void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); |
| 1505 | void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); | 1505 | void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); |
| 1506 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, | ||
| 1507 | bool mstate); | ||
| 1508 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); | ||
| 1506 | }; | 1509 | }; |
| 1507 | 1510 | ||
| 1508 | struct rtl_intf_ops { | 1511 | struct rtl_intf_ops { |
| @@ -1679,7 +1682,7 @@ struct dig_t { · 170 unmodified lines | |||
| 1679 | u32 rssi_highthresh; | 1682 | u32 rssi_highthresh; |
| 1680 | u32 fa_lowthresh; | 1683 | u32 fa_lowthresh; |
| 1681 | u32 fa_highthresh; | 1684 | u32 fa_highthresh; |
| 1682 | long last_min_undecorated_pwdb_for_dm; | 1685 | long last_min_undec_pwdb_for_dm; |
| 1683 | long rssi_highpower_lowthresh; | 1686 | long rssi_highpower_lowthresh; |
| 1684 | long rssi_highpower_highthresh; | 1687 | long rssi_highpower_highthresh; |
| 1685 | u32 recover_cnt; | 1688 | u32 recover_cnt; |
| @@ -1692,15 +1695,15 @@ struct dig_t { · 6 unmodified lines | |||
| 1692 | u8 dig_twoport_algorithm; | 1695 | u8 dig_twoport_algorithm; |
| 1693 | u8 dig_dbgmode; | 1696 | u8 dig_dbgmode; |
| 1694 | u8 dig_slgorithm_switch; | 1697 | u8 dig_slgorithm_switch; |
| 1695 | u8 cursta_connectstate; | 1698 | u8 cursta_cstate; |
| 1696 | u8 presta_connectstate; | 1699 | u8 presta_cstate; |
| 1697 | u8 curmultista_connectstate; | 1700 | u8 curmultista_cstate; |
| 1698 | char backoff_val; | 1701 | char back_val; |
| 1699 | char backoff_val_range_max; | 1702 | char back_range_max; |
| 1700 | char backoff_val_range_min; | 1703 | char back_range_min; |
| 1701 | u8 rx_gain_range_max; | 1704 | u8 rx_gain_range_max; |
| 1702 | u8 rx_gain_range_min; | 1705 | u8 rx_gain_range_min; |
| 1703 | u8 min_undecorated_pwdb_for_dm; | 1706 | u8 min_undec_pwdb_for_dm; |
| 1704 | u8 rssi_val_min; | 1707 | u8 rssi_val_min; |
| 1705 | u8 pre_cck_pd_state; | 1708 | u8 pre_cck_pd_state; |
| 1706 | u8 cur_cck_pd_state; | 1709 | u8 cur_cck_pd_state; |
| @@ -1712,10 +1715,10 @@ struct dig_t { · 5 unmodified lines | |||
| 1712 | u8 forbidden_igi; | 1715 | u8 forbidden_igi; |
| 1713 | u8 dig_state; | 1716 | u8 dig_state; |
| 1714 | u8 dig_highpwrstate; | 1717 | u8 dig_highpwrstate; |
| 1715 | u8 cur_sta_connectstate; | 1718 | u8 cur_sta_cstate; |
| 1716 | u8 pre_sta_connectstate; | 1719 | u8 pre_sta_cstate; |
| 1717 | u8 cur_ap_connectstate; | 1720 | u8 cur_ap_cstate; |
| 1718 | u8 pre_ap_connectstate; | 1721 | u8 pre_ap_cstate; |
| 1719 | u8 cur_pd_thstate; | 1722 | u8 cur_pd_thstate; |
| 1720 | u8 pre_pd_thstate; | 1723 | u8 pre_pd_thstate; |
| 1721 | u8 cur_cs_ratiostate; | 1724 | u8 cur_cs_ratiostate; |
| @@ -1846,7 +1849,7 @@ struct bt_coexist_info { · 124 unmodified lines | |||
| 1846 | u8 eeprom_bt_coexist; | 1849 | u8 eeprom_bt_coexist; |
| 1847 | u8 eeprom_bt_type; | 1850 | u8 eeprom_bt_type; |
| 1848 | u8 eeprom_bt_ant_num; | 1851 | u8 eeprom_bt_ant_num; |
| 1849 | u8 eeprom_bt_ant_isolation; | 1852 | u8 eeprom_bt_ant_isol; |
| 1850 | u8 eeprom_bt_radio_shared; | 1853 | u8 eeprom_bt_radio_shared; |
| 1851 | 1854 | ||
| 1852 | u8 bt_coexistence; | 1855 | u8 bt_coexistence; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | # Makefile for nfc devices | 2 | # Makefile for nfc devices |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_PN544_HCI_NFC) += pn544_hci.o | 5 | obj-$(CONFIG_PN544_HCI_NFC) += pn544/ |
| 6 | obj-$(CONFIG_NFC_PN533) += pn533.o | 6 | obj-$(CONFIG_NFC_PN533) += pn533.o |
| 7 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o | 7 | obj-$(CONFIG_NFC_WILINK) += nfcwilink.o |
| 8 | 8 | ||
| @@ -84,6 +84,10 @@ MODULE_DEVICE_TABLE(usb, pn533_table); · 83 unmodified lines | |||
| 84 | #define PN533_LISTEN_TIME 2 | 84 | #define PN533_LISTEN_TIME 2 |
| 85 | 85 | ||
| 86 | /* frame definitions */ | 86 | /* frame definitions */ |
| 87 | #define PN533_NORMAL_FRAME_MAX_LEN 262 /* 6 (PREAMBLE, SOF, LEN, LCS, TFI) | ||
| 88 | 254 (DATA) | ||
| 89 | 2 (DCS, postamble) */ | ||
| 90 | |||
| 87 | #define PN533_FRAME_TAIL_SIZE 2 | 91 | #define PN533_FRAME_TAIL_SIZE 2 |
| 88 | #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ | 92 | #define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \ |
| 89 | PN533_FRAME_TAIL_SIZE) | 93 | PN533_FRAME_TAIL_SIZE) |
| @@ -1165,8 +1169,7 @@ static void pn533_poll_create_mod_list(struct pn533 *dev, · 1075 unmodified lines | |||
| 1165 | pn533_poll_add_mod(dev, PN533_LISTEN_MOD); | 1169 | pn533_poll_add_mod(dev, PN533_LISTEN_MOD); |
| 1166 | } | 1170 | } |
| 1167 | 1171 | ||
| 1168 | static int pn533_start_poll_complete(struct pn533 *dev, void *arg, | 1172 | static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_len) |
| 1169 | u8 *params, int params_len) | ||
| 1170 | { | 1173 | { |
| 1171 | struct pn533_poll_response *resp; | 1174 | struct pn533_poll_response *resp; |
| 1172 | int rc; | 1175 | int rc; |
| @@ -1304,8 +1307,7 @@ static void pn533_wq_tg_get_data(struct work_struct *work) · 131 unmodified lines | |||
| 1304 | } | 1307 | } |
| 1305 | 1308 | ||
| 1306 | #define ATR_REQ_GB_OFFSET 17 | 1309 | #define ATR_REQ_GB_OFFSET 17 |
| 1307 | static int pn533_init_target_complete(struct pn533 *dev, void *arg, | 1310 | static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_len) |
| 1308 | u8 *params, int params_len) | ||
| 1309 | { | 1311 | { |
| 1310 | struct pn533_cmd_init_target_response *resp; | 1312 | struct pn533_cmd_init_target_response *resp; |
| 1311 | u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; | 1313 | u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; |
| @@ -1402,9 +1404,9 @@ static int pn533_poll_complete(struct pn533 *dev, void *arg, · 90 unmodified lines | |||
| 1402 | if (cur_mod->len == 0) { | 1404 | if (cur_mod->len == 0) { |
| 1403 | del_timer(&dev->listen_timer); | 1405 | del_timer(&dev->listen_timer); |
| 1404 | 1406 | ||
| 1405 | return pn533_init_target_complete(dev, arg, params, params_len); | 1407 | return pn533_init_target_complete(dev, params, params_len); |
| 1406 | } else { | 1408 | } else { |
| 1407 | rc = pn533_start_poll_complete(dev, arg, params, params_len); | 1409 | rc = pn533_start_poll_complete(dev, params, params_len); |
| 1408 | if (!rc) | 1410 | if (!rc) |
| 1409 | return rc; | 1411 | return rc; |
| 1410 | } | 1412 | } |
| @@ -2373,9 +2375,9 @@ static int pn533_probe(struct usb_interface *interface, · 962 unmodified lines | |||
| 2373 | goto error; | 2375 | goto error; |
| 2374 | } | 2376 | } |
| 2375 | 2377 | ||
| 2376 | dev->in_frame = kmalloc(dev->in_maxlen, GFP_KERNEL); | 2378 | dev->in_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL); |
| 2377 | dev->in_urb = usb_alloc_urb(0, GFP_KERNEL); | 2379 | dev->in_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 2378 | dev->out_frame = kmalloc(dev->out_maxlen, GFP_KERNEL); | 2380 | dev->out_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL); |
| 2379 | dev->out_urb = usb_alloc_urb(0, GFP_KERNEL); | 2381 | dev->out_urb = usb_alloc_urb(0, GFP_KERNEL); |
| 2380 | 2382 | ||
| 2381 | if (!dev->in_frame || !dev->out_frame || | 2383 | if (!dev->in_frame || !dev->out_frame || |
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # Makefile for PN544 HCI based NFC driver | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_PN544_HCI_NFC) += pn544_i2c.o | ||
| 6 | |||
| 7 | pn544_i2c-y := pn544.o i2c.o | ||
| @@ -0,0 +1,500 @@ | |||
| 1 | /* | ||
| 2 | * I2C Link Layer for PN544 HCI based Driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Intel Corporation. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the | ||
| 17 | * Free Software Foundation, Inc., | ||
| 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/crc-ccitt.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/i2c.h> | ||
| 24 | #include <linux/gpio.h> | ||
| 25 | #include <linux/miscdevice.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/delay.h> | ||
| 28 | |||
| 29 | #include <linux/nfc/pn544.h> | ||
| 30 | |||
| 31 | #include <net/nfc/hci.h> | ||
| 32 | #include <net/nfc/llc.h> | ||
| 33 | |||
| 34 | #include "pn544.h" | ||
| 35 | |||
| 36 | #define PN544_I2C_FRAME_HEADROOM 1 | ||
| 37 | #define PN544_I2C_FRAME_TAILROOM 2 | ||
| 38 | |||
| 39 | /* framing in HCI mode */ | ||
| 40 | #define PN544_HCI_I2C_LLC_LEN 1 | ||
| 41 | #define PN544_HCI_I2C_LLC_CRC 2 | ||
| 42 | #define PN544_HCI_I2C_LLC_LEN_CRC (PN544_HCI_I2C_LLC_LEN + \ | ||
| 43 | PN544_HCI_I2C_LLC_CRC) | ||
| 44 | #define PN544_HCI_I2C_LLC_MIN_SIZE (1 + PN544_HCI_I2C_LLC_LEN_CRC) | ||
| 45 | #define PN544_HCI_I2C_LLC_MAX_PAYLOAD 29 | ||
| 46 | #define PN544_HCI_I2C_LLC_MAX_SIZE (PN544_HCI_I2C_LLC_LEN_CRC + 1 + \ | ||
| 47 | PN544_HCI_I2C_LLC_MAX_PAYLOAD) | ||
| 48 | |||
| 49 | static struct i2c_device_id pn544_hci_i2c_id_table[] = { | ||
| 50 | {"pn544", 0}, | ||
| 51 | {} | ||
| 52 | }; | ||
| 53 | |||
| 54 | MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table); | ||
| 55 | |||
| 56 | #define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" | ||
| 57 | |||
| 58 | struct pn544_i2c_phy { | ||
| 59 | struct i2c_client *i2c_dev; | ||
| 60 | struct nfc_hci_dev *hdev; | ||
| 61 | |||
| 62 | unsigned int gpio_en; | ||
| 63 | unsigned int gpio_irq; | ||
| 64 | unsigned int gpio_fw; | ||
| 65 | unsigned int en_polarity; | ||
| 66 | |||
| 67 | int powered; | ||
| 68 | |||
| 69 | int hard_fault; /* | ||
| 70 | * < 0 if hardware error occured (e.g. i2c err) | ||
| 71 | * and prevents normal operation. | ||
| 72 | */ | ||
| 73 | }; | ||
| 74 | |||
| 75 | #define I2C_DUMP_SKB(info, skb) \ | ||
| 76 | do { \ | ||
| 77 | pr_debug("%s:\n", info); \ | ||
| 78 | print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \ | ||
| 79 | 16, 1, (skb)->data, (skb)->len, 0); \ | ||
| 80 | } while (0) | ||
| 81 | |||
| 82 | static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) | ||
| 83 | { | ||
| 84 | int polarity, retry, ret; | ||
| 85 | char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; | ||
| 86 | int count = sizeof(rset_cmd); | ||
| 87 | |||
| 88 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 89 | dev_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); | ||
| 90 | |||
| 91 | /* Disable fw download */ | ||
| 92 | gpio_set_value(phy->gpio_fw, 0); | ||
| 93 | |||
| 94 | for (polarity = 0; polarity < 2; polarity++) { | ||
| 95 | phy->en_polarity = polarity; | ||
| 96 | retry = 3; | ||
| 97 | while (retry--) { | ||
| 98 | /* power off */ | ||
| 99 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | ||
| 100 | usleep_range(10000, 15000); | ||
| 101 | |||
| 102 | /* power on */ | ||
| 103 | gpio_set_value(phy->gpio_en, phy->en_polarity); | ||
| 104 | usleep_range(10000, 15000); | ||
| 105 | |||
| 106 | /* send reset */ | ||
| 107 | dev_dbg(&phy->i2c_dev->dev, "Sending reset cmd\n"); | ||
| 108 | ret = i2c_master_send(phy->i2c_dev, rset_cmd, count); | ||
| 109 | if (ret == count) { | ||
| 110 | dev_info(&phy->i2c_dev->dev, | ||
| 111 | "nfc_en polarity : active %s\n", | ||
| 112 | (polarity == 0 ? "low" : "high")); | ||
| 113 | goto out; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | dev_err(&phy->i2c_dev->dev, | ||
| 119 | "Could not detect nfc_en polarity, fallback to active high\n"); | ||
| 120 | |||
| 121 | out: | ||
| 122 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | ||
| 123 | } | ||
| 124 | |||
| 125 | static int pn544_hci_i2c_enable(void *phy_id) | ||
| 126 | { | ||
| 127 | struct pn544_i2c_phy *phy = phy_id; | ||
| 128 | |||
| 129 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 130 | |||
| 131 | gpio_set_value(phy->gpio_fw, 0); | ||
| 132 | gpio_set_value(phy->gpio_en, phy->en_polarity); | ||
| 133 | usleep_range(10000, 15000); | ||
| 134 | |||
| 135 | phy->powered = 1; | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static void pn544_hci_i2c_disable(void *phy_id) | ||
| 141 | { | ||
| 142 | struct pn544_i2c_phy *phy = phy_id; | ||
| 143 | |||
| 144 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 145 | |||
| 146 | gpio_set_value(phy->gpio_fw, 0); | ||
| 147 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | ||
| 148 | usleep_range(10000, 15000); | ||
| 149 | |||
| 150 | gpio_set_value(phy->gpio_en, phy->en_polarity); | ||
| 151 | usleep_range(10000, 15000); | ||
| 152 | |||
| 153 | gpio_set_value(phy->gpio_en, !phy->en_polarity); | ||
| 154 | usleep_range(10000, 15000); | ||
| 155 | |||
| 156 | phy->powered = 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static void pn544_hci_i2c_add_len_crc(struct sk_buff *skb) | ||
| 160 | { | ||
| 161 | u16 crc; | ||
| 162 | int len; | ||
| 163 | |||
| 164 | len = skb->len + 2; | ||
| 165 | *skb_push(skb, 1) = len; | ||
| 166 | |||
| 167 | crc = crc_ccitt(0xffff, skb->data, skb->len); | ||
| 168 | crc = ~crc; | ||
| 169 | *skb_put(skb, 1) = crc & 0xff; | ||
| 170 | *skb_put(skb, 1) = crc >> 8; | ||
| 171 | } | ||
| 172 | |||
| 173 | static void pn544_hci_i2c_remove_len_crc(struct sk_buff *skb) | ||
| 174 | { | ||
| 175 | skb_pull(skb, PN544_I2C_FRAME_HEADROOM); | ||
| 176 | skb_trim(skb, PN544_I2C_FRAME_TAILROOM); | ||
| 177 | } | ||
| 178 | |||
| 179 | /* | ||
| 180 | * Writing a frame must not return the number of written bytes. | ||
| 181 | * It must return either zero for success, or <0 for error. | ||
| 182 | * In addition, it must not alter the skb | ||
| 183 | */ | ||
| 184 | static int pn544_hci_i2c_write(void *phy_id, struct sk_buff *skb) | ||
| 185 | { | ||
| 186 | int r; | ||
| 187 | struct pn544_i2c_phy *phy = phy_id; | ||
| 188 | struct i2c_client *client = phy->i2c_dev; | ||
| 189 | |||
| 190 | if (phy->hard_fault != 0) | ||
| 191 | return phy->hard_fault; | ||
| 192 | |||
| 193 | usleep_range(3000, 6000); | ||
| 194 | |||
| 195 | pn544_hci_i2c_add_len_crc(skb); | ||
| 196 | |||
| 197 | I2C_DUMP_SKB("i2c frame written", skb); | ||
| 198 | |||
| 199 | r = i2c_master_send(client, skb->data, skb->len); | ||
| 200 | |||
| 201 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | ||
| 202 | usleep_range(6000, 10000); | ||
| 203 | r = i2c_master_send(client, skb->data, skb->len); | ||
| 204 | } | ||
| 205 | |||
| 206 | if (r >= 0) { | ||
| 207 | if (r != skb->len) | ||
| 208 | r = -EREMOTEIO; | ||
| 209 | else | ||
| 210 | r = 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | pn544_hci_i2c_remove_len_crc(skb); | ||
| 214 | |||
| 215 | return r; | ||
| 216 | } | ||
| 217 | |||
| 218 | static int check_crc(u8 *buf, int buflen) | ||
| 219 | { | ||
| 220 | int len; | ||
| 221 | u16 crc; | ||
| 222 | |||
| 223 | len = buf[0] + 1; | ||
| 224 | crc = crc_ccitt(0xffff, buf, len - 2); | ||
| 225 | crc = ~crc; | ||
| 226 | |||
| 227 | if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { | ||
| 228 | pr_err(PN544_HCI_I2C_DRIVER_NAME | ||
| 229 | ": CRC error 0x%x != 0x%x 0x%x\n", | ||
| 230 | crc, buf[len - 1], buf[len - 2]); | ||
| 231 | |||
| 232 | pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); | ||
| 233 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | ||
| 234 | 16, 2, buf, buflen, false); | ||
| 235 | return -EPERM; | ||
| 236 | } | ||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* | ||
| 241 | * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees | ||
| 242 | * that i2c bus will be flushed and that next read will start on a new frame. | ||
| 243 | * returned skb contains only LLC header and payload. | ||
| 244 | * returns: | ||
| 245 | * -EREMOTEIO : i2c read error (fatal) | ||
| 246 | * -EBADMSG : frame was incorrect and discarded | ||
| 247 | * -ENOMEM : cannot allocate skb, frame dropped | ||
| 248 | */ | ||
| 249 | static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb) | ||
| 250 | { | ||
| 251 | int r; | ||
| 252 | u8 len; | ||
| 253 | u8 tmp[PN544_HCI_I2C_LLC_MAX_SIZE - 1]; | ||
| 254 | struct i2c_client *client = phy->i2c_dev; | ||
| 255 | |||
| 256 | r = i2c_master_recv(client, &len, 1); | ||
| 257 | if (r != 1) { | ||
| 258 | dev_err(&client->dev, "cannot read len byte\n"); | ||
| 259 | return -EREMOTEIO; | ||
| 260 | } | ||
| 261 | |||
| 262 | if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) || | ||
| 263 | (len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) { | ||
| 264 | dev_err(&client->dev, "invalid len byte\n"); | ||
| 265 | r = -EBADMSG; | ||
| 266 | goto flush; | ||
| 267 | } | ||
| 268 | |||
| 269 | *skb = alloc_skb(1 + len, GFP_KERNEL); | ||
| 270 | if (*skb == NULL) { | ||
| 271 | r = -ENOMEM; | ||
| 272 | goto flush; | ||
| 273 | } | ||
| 274 | |||
| 275 | *skb_put(*skb, 1) = len; | ||
| 276 | |||
| 277 | r = i2c_master_recv(client, skb_put(*skb, len), len); | ||
| 278 | if (r != len) { | ||
| 279 | kfree_skb(*skb); | ||
| 280 | return -EREMOTEIO; | ||
| 281 | } | ||
| 282 | |||
| 283 | I2C_DUMP_SKB("i2c frame read", *skb); | ||
| 284 | |||
| 285 | r = check_crc((*skb)->data, (*skb)->len); | ||
| 286 | if (r != 0) { | ||
| 287 | kfree_skb(*skb); | ||
| 288 | r = -EBADMSG; | ||
| 289 | goto flush; | ||
| 290 | } | ||
| 291 | |||
| 292 | skb_pull(*skb, 1); | ||
| 293 | skb_trim(*skb, (*skb)->len - 2); | ||
| 294 | |||
| 295 | usleep_range(3000, 6000); | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | |||
| 299 | flush: | ||
| 300 | if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) | ||
| 301 | r = -EREMOTEIO; | ||
| 302 | |||
| 303 | usleep_range(3000, 6000); | ||
| 304 | |||
| 305 | return r; | ||
| 306 | } | ||
| 307 | |||
| 308 | /* | ||
| 309 | * Reads an shdlc frame from the chip. This is not as straightforward as it | ||
| 310 | * seems. There are cases where we could loose the frame start synchronization. | ||
| 311 | * The frame format is len-data-crc, and corruption can occur anywhere while | ||
| 312 | * transiting on i2c bus, such that we could read an invalid len. | ||
| 313 | * In order to recover synchronization with the next frame, we must be sure | ||
| 314 | * to read the real amount of data without using the len byte. We do this by | ||
| 315 | * assuming the following: | ||
| 316 | * - the chip will always present only one single complete frame on the bus | ||
| 317 | * before triggering the interrupt | ||
| 318 | * - the chip will not present a new frame until we have completely read | ||
| 319 | * the previous one (or until we have handled the interrupt). | ||
| 320 | * The tricky case is when we read a corrupted len that is less than the real | ||
| 321 | * len. We must detect this here in order to determine that we need to flush | ||
| 322 | * the bus. This is the reason why we check the crc here. | ||
| 323 | */ | ||
| 324 | static irqreturn_t pn544_hci_i2c_irq_thread_fn(int irq, void *phy_id) | ||
| 325 | { | ||
| 326 | struct pn544_i2c_phy *phy = phy_id; | ||
| 327 | struct i2c_client *client; | ||
| 328 | struct sk_buff *skb = NULL; | ||
| 329 | int r; | ||
| 330 | |||
| 331 | if (!phy || irq != phy->i2c_dev->irq) { | ||
| 332 | WARN_ON_ONCE(1); | ||
| 333 | return IRQ_NONE; | ||
| 334 | } | ||
| 335 | |||
| 336 | client = phy->i2c_dev; | ||
| 337 | dev_dbg(&client->dev, "IRQ\n"); | ||
| 338 | |||
| 339 | if (phy->hard_fault != 0) | ||
| 340 | return IRQ_HANDLED; | ||
| 341 | |||
| 342 | r = pn544_hci_i2c_read(phy, &skb); | ||
| 343 | if (r == -EREMOTEIO) { | ||
| 344 | phy->hard_fault = r; | ||
| 345 | |||
| 346 | nfc_hci_recv_frame(phy->hdev, NULL); | ||
| 347 | |||
| 348 | return IRQ_HANDLED; | ||
| 349 | } else if ((r == -ENOMEM) || (r == -EBADMSG)) { | ||
| 350 | return IRQ_HANDLED; | ||
| 351 | } | ||
| 352 | |||
| 353 | nfc_hci_recv_frame(phy->hdev, skb); | ||
| 354 | |||
| 355 | return IRQ_HANDLED; | ||
| 356 | } | ||
| 357 | |||
| 358 | static struct nfc_phy_ops i2c_phy_ops = { | ||
| 359 | .write = pn544_hci_i2c_write, | ||
| 360 | .enable = pn544_hci_i2c_enable, | ||
| 361 | .disable = pn544_hci_i2c_disable, | ||
| 362 | }; | ||
| 363 | |||
| 364 | static int __devinit pn544_hci_i2c_probe(struct i2c_client *client, | ||
| 365 | const struct i2c_device_id *id) | ||
| 366 | { | ||
| 367 | struct pn544_i2c_phy *phy; | ||
| 368 | struct pn544_nfc_platform_data *pdata; | ||
| 369 | int r = 0; | ||
| 370 | |||
| 371 | dev_dbg(&client->dev, "%s\n", __func__); | ||
| 372 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | ||
| 373 | |||
| 374 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 375 | dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); | ||
| 376 | return -ENODEV; | ||
| 377 | } | ||
| 378 | |||
| 379 | phy = kzalloc(sizeof(struct pn544_i2c_phy), GFP_KERNEL); | ||
| 380 | if (!phy) { | ||
| 381 | dev_err(&client->dev, | ||
| 382 | "Cannot allocate memory for pn544 i2c phy.\n"); | ||
| 383 | r = -ENOMEM; | ||
| 384 | goto err_phy_alloc; | ||
| 385 | } | ||
| 386 | |||
| 387 | phy->i2c_dev = client; | ||
| 388 | i2c_set_clientdata(client, phy); | ||
| 389 | |||
| 390 | pdata = client->dev.platform_data; | ||
| 391 | if (pdata == NULL) { | ||
| 392 | dev_err(&client->dev, "No platform data\n"); | ||
| 393 | r = -EINVAL; | ||
| 394 | goto err_pdata; | ||
| 395 | } | ||
| 396 | |||
| 397 | if (pdata->request_resources == NULL) { | ||
| 398 | dev_err(&client->dev, "request_resources() missing\n"); | ||
| 399 | r = -EINVAL; | ||
| 400 | goto err_pdata; | ||
| 401 | } | ||
| 402 | |||
| 403 | r = pdata->request_resources(client); | ||
| 404 | if (r) { | ||
| 405 | dev_err(&client->dev, "Cannot get platform resources\n"); | ||
| 406 | goto err_pdata; | ||
| 407 | } | ||
| 408 | |||
| 409 | phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); | ||
| 410 | phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); | ||
| 411 | phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); | ||
| 412 | |||
| 413 | pn544_hci_i2c_platform_init(phy); | ||
| 414 | |||
| 415 | r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn, | ||
| 416 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
| 417 | PN544_HCI_I2C_DRIVER_NAME, phy); | ||
| 418 | if (r < 0) { | ||
| 419 | dev_err(&client->dev, "Unable to register IRQ handler\n"); | ||
| 420 | goto err_rti; | ||
| 421 | } | ||
| 422 | |||
| 423 | r = pn544_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, | ||
| 424 | PN544_I2C_FRAME_HEADROOM, PN544_I2C_FRAME_TAILROOM, | ||
| 425 | PN544_HCI_I2C_LLC_MAX_PAYLOAD, &phy->hdev); | ||
| 426 | if (r < 0) | ||
| 427 | goto err_hci; | ||
| 428 | |||
| 429 | return 0; | ||
| 430 | |||
| 431 | err_hci: | ||
| 432 | free_irq(client->irq, phy); | ||
| 433 | |||
| 434 | err_rti: | ||
| 435 | if (pdata->free_resources != NULL) | ||
| 436 | pdata->free_resources(); | ||
| 437 | |||
| 438 | err_pdata: | ||
| 439 | kfree(phy); | ||
| 440 | |||
| 441 | err_phy_alloc: | ||
| 442 | return r; | ||
| 443 | } | ||
| 444 | |||
| 445 | static __devexit int pn544_hci_i2c_remove(struct i2c_client *client) | ||
| 446 | { | ||
| 447 | struct pn544_i2c_phy *phy = i2c_get_clientdata(client); | ||
| 448 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | ||
| 449 | |||
| 450 | dev_dbg(&client->dev, "%s\n", __func__); | ||
| 451 | |||
| 452 | pn544_hci_remove(phy->hdev); | ||
| 453 | |||
| 454 | if (phy->powered) | ||
| 455 | pn544_hci_i2c_disable(phy); | ||
| 456 | |||
| 457 | free_irq(client->irq, phy); | ||
| 458 | if (pdata->free_resources) | ||
| 459 | pdata->free_resources(); | ||
| 460 | |||
| 461 | kfree(phy); | ||
| 462 | |||
| 463 | return 0; | ||
| 464 | } | ||
| 465 | |||
| 466 | static struct i2c_driver pn544_hci_i2c_driver = { | ||
| 467 | .driver = { | ||
| 468 | .name = PN544_HCI_I2C_DRIVER_NAME, | ||
| 469 | }, | ||
| 470 | .probe = pn544_hci_i2c_probe, | ||
| 471 | .id_table = pn544_hci_i2c_id_table, | ||
| 472 | .remove = __devexit_p(pn544_hci_i2c_remove), | ||
| 473 | }; | ||
| 474 | |||
| 475 | static int __init pn544_hci_i2c_init(void) | ||
| 476 | { | ||
| 477 | int r; | ||
| 478 | |||
| 479 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
| 480 | |||
| 481 | r = i2c_add_driver(&pn544_hci_i2c_driver); | ||
| 482 | if (r) { | ||
| 483 | pr_err(PN544_HCI_I2C_DRIVER_NAME | ||
| 484 | ": driver registration failed\n"); | ||
| 485 | return r; | ||
| 486 | } | ||
| 487 | |||
| 488 | return 0; | ||
| 489 | } | ||
| 490 | |||
| 491 | static void __exit pn544_hci_i2c_exit(void) | ||
| 492 | { | ||
| 493 | i2c_del_driver(&pn544_hci_i2c_driver); | ||
| 494 | } | ||
| 495 | |||
| 496 | module_init(pn544_hci_i2c_init); | ||
| 497 | module_exit(pn544_hci_i2c_exit); | ||
| 498 | |||
| 499 | MODULE_LICENSE("GPL"); | ||
| 500 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| @@ -18,47 +18,21 @@ · 17 unmodified lines | |||
| 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/crc-ccitt.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 24 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 25 | #include <linux/miscdevice.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/gpio.h> | ||
| 28 | #include <linux/i2c.h> | ||
| 29 | 23 | ||
| 30 | #include <linux/nfc.h> | 24 | #include <linux/nfc.h> |
| 31 | #include <net/nfc/hci.h> | 25 | #include <net/nfc/hci.h> |
| 32 | #include <net/nfc/llc.h> | 26 | #include <net/nfc/llc.h> |
| 33 | 27 | ||
| 34 | #include <linux/nfc/pn544.h> | 28 | #include "pn544.h" |
| 35 | |||
| 36 | #define DRIVER_DESC "HCI NFC driver for PN544" | ||
| 37 | |||
| 38 | #define PN544_HCI_DRIVER_NAME "pn544_hci" | ||
| 39 | 29 | ||
| 40 | /* Timing restrictions (ms) */ | 30 | /* Timing restrictions (ms) */ |
| 41 | #define PN544_HCI_RESETVEN_TIME 30 | 31 | #define PN544_HCI_RESETVEN_TIME 30 |
| 42 | 32 | ||
| 43 | static struct i2c_device_id pn544_hci_id_table[] = { | ||
| 44 | {"pn544", 0}, | ||
| 45 | {} | ||
| 46 | }; | ||
| 47 | |||
| 48 | MODULE_DEVICE_TABLE(i2c, pn544_hci_id_table); | ||
| 49 | |||
| 50 | #define HCI_MODE 0 | 33 | #define HCI_MODE 0 |
| 51 | #define FW_MODE 1 | 34 | #define FW_MODE 1 |
| 52 | 35 | ||
| 53 | /* framing in HCI mode */ | ||
| 54 | #define PN544_HCI_LLC_LEN 1 | ||
| 55 | #define PN544_HCI_LLC_CRC 2 | ||
| 56 | #define PN544_HCI_LLC_LEN_CRC (PN544_HCI_LLC_LEN + PN544_HCI_LLC_CRC) | ||
| 57 | #define PN544_HCI_LLC_MIN_SIZE (1 + PN544_HCI_LLC_LEN_CRC) | ||
| 58 | #define PN544_HCI_LLC_MAX_PAYLOAD 29 | ||
| 59 | #define PN544_HCI_LLC_MAX_SIZE (PN544_HCI_LLC_LEN_CRC + 1 + \ | ||
| 60 | PN544_HCI_LLC_MAX_PAYLOAD) | ||
| 61 | |||
| 62 | enum pn544_state { | 36 | enum pn544_state { |
| 63 | PN544_ST_COLD, | 37 | PN544_ST_COLD, |
| 64 | PN544_ST_FW_READY, | 38 | PN544_ST_FW_READY, |
| @@ -100,6 +74,10 @@ enum pn544_state { · 35 unmodified lines | |||
| 100 | #define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02 | 74 | #define PN544_SYS_MGMT_INFO_NOTIFICATION 0x02 |
| 101 | 75 | ||
| 102 | #define PN544_POLLING_LOOP_MGMT_GATE 0x94 | 76 | #define PN544_POLLING_LOOP_MGMT_GATE 0x94 |
| 77 | #define PN544_DEP_MODE 0x01 | ||
| 78 | #define PN544_DEP_ATR_REQ 0x02 | ||
| 79 | #define PN544_DEP_ATR_RES 0x03 | ||
| 80 | #define PN544_DEP_MERGE 0x0D | ||
| 103 | #define PN544_PL_RDPHASES 0x06 | 81 | #define PN544_PL_RDPHASES 0x06 |
| 104 | #define PN544_PL_EMULATION 0x07 | 82 | #define PN544_PL_EMULATION 0x07 |
| 105 | #define PN544_PL_NFCT_DEACTIVATED 0x09 | 83 | #define PN544_PL_NFCT_DEACTIVATED 0x09 |
| @@ -108,6 +86,15 @@ enum pn544_state { · 2 unmodified lines | |||
| 108 | 86 | ||
| 109 | #define PN544_NFC_WI_MGMT_GATE 0xA1 | 87 | #define PN544_NFC_WI_MGMT_GATE 0xA1 |
| 110 | 88 | ||
| 89 | #define PN544_HCI_EVT_SND_DATA 0x01 | ||
| 90 | #define PN544_HCI_EVT_ACTIVATED 0x02 | ||
| 91 | #define PN544_HCI_EVT_DEACTIVATED 0x03 | ||
| 92 | #define PN544_HCI_EVT_RCV_DATA 0x04 | ||
| 93 | #define PN544_HCI_EVT_CONTINUE_MI 0x05 | ||
| 94 | |||
| 95 | #define PN544_HCI_CMD_ATTREQUEST 0x12 | ||
| 96 | #define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13 | ||
| 97 | |||
| 111 | static struct nfc_hci_gate pn544_gates[] = { | 98 | static struct nfc_hci_gate pn544_gates[] = { |
| 112 | {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, | 99 | {NFC_HCI_ADMIN_GATE, NFC_HCI_INVALID_PIPE}, |
| 113 | {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, | 100 | {NFC_HCI_LOOPBACK_GATE, NFC_HCI_INVALID_PIPE}, |
| @@ -128,259 +115,22 @@ static struct nfc_hci_gate pn544_gates[] = { · 14 unmodified lines | |||
| 128 | 115 | ||
| 129 | /* Largest headroom needed for outgoing custom commands */ | 116 | /* Largest headroom needed for outgoing custom commands */ |
| 130 | #define PN544_CMDS_HEADROOM 2 | 117 | #define PN544_CMDS_HEADROOM 2 |
| 131 | #define PN544_FRAME_HEADROOM 1 | ||
| 132 | #define PN544_FRAME_TAILROOM 2 | ||
| 133 | 118 | ||
| 134 | struct pn544_hci_info { | 119 | struct pn544_hci_info { |
| 135 | struct i2c_client *i2c_dev; | 120 | struct nfc_phy_ops *phy_ops; |
| 121 | void *phy_id; | ||
| 122 | |||
| 136 | struct nfc_hci_dev *hdev; | 123 | struct nfc_hci_dev *hdev; |
| 137 | 124 | ||
| 138 | enum pn544_state state; | 125 | enum pn544_state state; |
| 139 | 126 | ||
| 140 | struct mutex info_lock; | 127 | struct mutex info_lock; |
| 141 | 128 | ||
| 142 | unsigned int gpio_en; | ||
| 143 | unsigned int gpio_irq; | ||
| 144 | unsigned int gpio_fw; | ||
| 145 | unsigned int en_polarity; | ||
| 146 | |||
| 147 | int hard_fault; /* | ||
| 148 | * < 0 if hardware error occured (e.g. i2c err) | ||
| 149 | * and prevents normal operation. | ||
| 150 | */ | ||
| 151 | int async_cb_type; | 129 | int async_cb_type; |
| 152 | data_exchange_cb_t async_cb; | 130 | data_exchange_cb_t async_cb; |
| 153 | void *async_cb_context; | 131 | void *async_cb_context; |
| 154 | }; | 132 | }; |
| 155 | 133 | ||
| 156 | static void pn544_hci_platform_init(struct pn544_hci_info *info) | ||
| 157 | { | ||
| 158 | int polarity, retry, ret; | ||
| 159 | char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; | ||
| 160 | int count = sizeof(rset_cmd); | ||
| 161 | |||
| 162 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 163 | dev_info(&info->i2c_dev->dev, "Detecting nfc_en polarity\n"); | ||
| 164 | |||
| 165 | /* Disable fw download */ | ||
| 166 | gpio_set_value(info->gpio_fw, 0); | ||
| 167 | |||
| 168 | for (polarity = 0; polarity < 2; polarity++) { | ||
| 169 | info->en_polarity = polarity; | ||
| 170 | retry = 3; | ||
| 171 | while (retry--) { | ||
| 172 | /* power off */ | ||
| 173 | gpio_set_value(info->gpio_en, !info->en_polarity); | ||
| 174 | usleep_range(10000, 15000); | ||
| 175 | |||
| 176 | /* power on */ | ||
| 177 | gpio_set_value(info->gpio_en, info->en_polarity); | ||
| 178 | usleep_range(10000, 15000); | ||
| 179 | |||
| 180 | /* send reset */ | ||
| 181 | dev_dbg(&info->i2c_dev->dev, "Sending reset cmd\n"); | ||
| 182 | ret = i2c_master_send(info->i2c_dev, rset_cmd, count); | ||
| 183 | if (ret == count) { | ||
| 184 | dev_info(&info->i2c_dev->dev, | ||
| 185 | "nfc_en polarity : active %s\n", | ||
| 186 | (polarity == 0 ? "low" : "high")); | ||
| 187 | goto out; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | dev_err(&info->i2c_dev->dev, | ||
| 193 | "Could not detect nfc_en polarity, fallback to active high\n"); | ||
| 194 | |||
| 195 | out: | ||
| 196 | gpio_set_value(info->gpio_en, !info->en_polarity); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int pn544_hci_enable(struct pn544_hci_info *info, int mode) | ||
| 200 | { | ||
| 201 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 202 | |||
| 203 | gpio_set_value(info->gpio_fw, 0); | ||
| 204 | gpio_set_value(info->gpio_en, info->en_polarity); | ||
| 205 | usleep_range(10000, 15000); | ||
| 206 | |||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static void pn544_hci_disable(struct pn544_hci_info *info) | ||
| 211 | { | ||
| 212 | pr_info(DRIVER_DESC ": %s\n", __func__); | ||
| 213 | |||
| 214 | gpio_set_value(info->gpio_fw, 0); | ||
| 215 | gpio_set_value(info->gpio_en, !info->en_polarity); | ||
| 216 | usleep_range(10000, 15000); | ||
| 217 | |||
| 218 | gpio_set_value(info->gpio_en, info->en_polarity); | ||
| 219 | usleep_range(10000, 15000); | ||
| 220 | |||
| 221 | gpio_set_value(info->gpio_en, !info->en_polarity); | ||
| 222 | usleep_range(10000, 15000); | ||
| 223 | } | ||
| 224 | |||
| 225 | static int pn544_hci_i2c_write(struct i2c_client *client, u8 *buf, int len) | ||
| 226 | { | ||
| 227 | int r; | ||
| 228 | |||
| 229 | usleep_range(3000, 6000); | ||
| 230 | |||
| 231 | r = i2c_master_send(client, buf, len); | ||
| 232 | |||
| 233 | if (r == -EREMOTEIO) { /* Retry, chip was in standby */ | ||
| 234 | usleep_range(6000, 10000); | ||
| 235 | r = i2c_master_send(client, buf, len); | ||
| 236 | } | ||
| 237 | |||
| 238 | if (r >= 0) { | ||
| 239 | if (r != len) | ||
| 240 | return -EREMOTEIO; | ||
| 241 | else | ||
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | return r; | ||
| 246 | } | ||
| 247 | |||
| 248 | static int check_crc(u8 *buf, int buflen) | ||
| 249 | { | ||
| 250 | int len; | ||
| 251 | u16 crc; | ||
| 252 | |||
| 253 | len = buf[0] + 1; | ||
| 254 | crc = crc_ccitt(0xffff, buf, len - 2); | ||
| 255 | crc = ~crc; | ||
| 256 | |||
| 257 | if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { | ||
| 258 | pr_err(PN544_HCI_DRIVER_NAME ": CRC error 0x%x != 0x%x 0x%x\n", | ||
| 259 | crc, buf[len - 1], buf[len - 2]); | ||
| 260 | |||
| 261 | pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__); | ||
| 262 | print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, | ||
| 263 | 16, 2, buf, buflen, false); | ||
| 264 | return -EPERM; | ||
| 265 | } | ||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* | ||
| 270 | * Reads an shdlc frame and returns it in a newly allocated sk_buff. Guarantees | ||
| 271 | * that i2c bus will be flushed and that next read will start on a new frame. | ||
| 272 | * returned skb contains only LLC header and payload. | ||
| 273 | * returns: | ||
| 274 | * -EREMOTEIO : i2c read error (fatal) | ||
| 275 | * -EBADMSG : frame was incorrect and discarded | ||
| 276 | * -ENOMEM : cannot allocate skb, frame dropped | ||
| 277 | */ | ||
| 278 | static int pn544_hci_i2c_read(struct i2c_client *client, struct sk_buff **skb) | ||
| 279 | { | ||
| 280 | int r; | ||
| 281 | u8 len; | ||
| 282 | u8 tmp[PN544_HCI_LLC_MAX_SIZE - 1]; | ||
| 283 | |||
| 284 | r = i2c_master_recv(client, &len, 1); | ||
| 285 | if (r != 1) { | ||
| 286 | dev_err(&client->dev, "cannot read len byte\n"); | ||
| 287 | return -EREMOTEIO; | ||
| 288 | } | ||
| 289 | |||
| 290 | if ((len < (PN544_HCI_LLC_MIN_SIZE - 1)) || | ||
| 291 | (len > (PN544_HCI_LLC_MAX_SIZE - 1))) { | ||
| 292 | dev_err(&client->dev, "invalid len byte\n"); | ||
| 293 | r = -EBADMSG; | ||
| 294 | goto flush; | ||
| 295 | } | ||
| 296 | |||
| 297 | *skb = alloc_skb(1 + len, GFP_KERNEL); | ||
| 298 | if (*skb == NULL) { | ||
| 299 | r = -ENOMEM; | ||
| 300 | goto flush; | ||
| 301 | } | ||
| 302 | |||
| 303 | *skb_put(*skb, 1) = len; | ||
| 304 | |||
| 305 | r = i2c_master_recv(client, skb_put(*skb, len), len); | ||
| 306 | if (r != len) { | ||
| 307 | kfree_skb(*skb); | ||
| 308 | return -EREMOTEIO; | ||
| 309 | } | ||
| 310 | |||
| 311 | r = check_crc((*skb)->data, (*skb)->len); | ||
| 312 | if (r != 0) { | ||
| 313 | kfree_skb(*skb); | ||
| 314 | r = -EBADMSG; | ||
| 315 | goto flush; | ||
| 316 | } | ||
| 317 | |||
| 318 | skb_pull(*skb, 1); | ||
| 319 | skb_trim(*skb, (*skb)->len - 2); | ||
| 320 | |||
| 321 | usleep_range(3000, 6000); | ||
| 322 | |||
| 323 | return 0; | ||
| 324 | |||
| 325 | flush: | ||
| 326 | if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) | ||
| 327 | r = -EREMOTEIO; | ||
| 328 | |||
| 329 | usleep_range(3000, 6000); | ||
| 330 | |||
| 331 | return r; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* | ||
| 335 | * Reads an shdlc frame from the chip. This is not as straightforward as it | ||
| 336 | * seems. There are cases where we could loose the frame start synchronization. | ||
| 337 | * The frame format is len-data-crc, and corruption can occur anywhere while | ||
| 338 | * transiting on i2c bus, such that we could read an invalid len. | ||
| 339 | * In order to recover synchronization with the next frame, we must be sure | ||
| 340 | * to read the real amount of data without using the len byte. We do this by | ||
| 341 | * assuming the following: | ||
| 342 | * - the chip will always present only one single complete frame on the bus | ||
| 343 | * before triggering the interrupt | ||
| 344 | * - the chip will not present a new frame until we have completely read | ||
| 345 | * the previous one (or until we have handled the interrupt). | ||
| 346 | * The tricky case is when we read a corrupted len that is less than the real | ||
| 347 | * len. We must detect this here in order to determine that we need to flush | ||
| 348 | * the bus. This is the reason why we check the crc here. | ||
| 349 | */ | ||
| 350 | static irqreturn_t pn544_hci_irq_thread_fn(int irq, void *dev_id) | ||
| 351 | { | ||
| 352 | struct pn544_hci_info *info = dev_id; | ||
| 353 | struct i2c_client *client; | ||
| 354 | struct sk_buff *skb = NULL; | ||
| 355 | int r; | ||
| 356 | |||
| 357 | if (!info || irq != info->i2c_dev->irq) { | ||
| 358 | WARN_ON_ONCE(1); | ||
| 359 | return IRQ_NONE; | ||
| 360 | } | ||
| 361 | |||
| 362 | client = info->i2c_dev; | ||
| 363 | dev_dbg(&client->dev, "IRQ\n"); | ||
| 364 | |||
| 365 | if (info->hard_fault != 0) | ||
| 366 | return IRQ_HANDLED; | ||
| 367 | |||
| 368 | r = pn544_hci_i2c_read(client, &skb); | ||
| 369 | if (r == -EREMOTEIO) { | ||
| 370 | info->hard_fault = r; | ||
| 371 | |||
| 372 | nfc_hci_recv_frame(info->hdev, NULL); | ||
| 373 | |||
| 374 | return IRQ_HANDLED; | ||
| 375 | } else if ((r == -ENOMEM) || (r == -EBADMSG)) { | ||
| 376 | return IRQ_HANDLED; | ||
| 377 | } | ||
| 378 | |||
| 379 | nfc_hci_recv_frame(info->hdev, skb); | ||
| 380 | |||
| 381 | return IRQ_HANDLED; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int pn544_hci_open(struct nfc_hci_dev *hdev) | 134 | static int pn544_hci_open(struct nfc_hci_dev *hdev) |
| 385 | { | 135 | { |
| 386 | struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); | 136 | struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); |
| @@ -393,7 +143,7 @@ static int pn544_hci_open(struct nfc_hci_dev *hdev) · 6 unmodified lines | |||
| 393 | goto out; | 143 | goto out; |
| 394 | } | 144 | } |
| 395 | 145 | ||
| 396 | r = pn544_hci_enable(info, HCI_MODE); | 146 | r = info->phy_ops->enable(info->phy_id); |
| 397 | 147 | ||
| 398 | if (r == 0) | 148 | if (r == 0) |
| 399 | info->state = PN544_ST_READY; | 149 | info->state = PN544_ST_READY; |
| @@ -412,7 +162,7 @@ static void pn544_hci_close(struct nfc_hci_dev *hdev) · 12 unmodified lines | |||
| 412 | if (info->state == PN544_ST_COLD) | 162 | if (info->state == PN544_ST_COLD) |
| 413 | goto out; | 163 | goto out; |
| 414 | 164 | ||
| 415 | pn544_hci_disable(info); | 165 | info->phy_ops->disable(info->phy_id); |
| 416 | 166 | ||
| 417 | info->state = PN544_ST_COLD; | 167 | info->state = PN544_ST_COLD; |
| 418 | 168 | ||
| @@ -587,40 +337,11 @@ static int pn544_hci_ready(struct nfc_hci_dev *hdev) · 168 unmodified lines | |||
| 587 | return 0; | 337 | return 0; |
| 588 | } | 338 | } |
| 589 | 339 | ||
| 590 | static void pn544_hci_add_len_crc(struct sk_buff *skb) | ||
| 591 | { | ||
| 592 | u16 crc; | ||
| 593 | int len; | ||
| 594 | |||
| 595 | len = skb->len + 2; | ||
| 596 | *skb_push(skb, 1) = len; | ||
| 597 | |||
| 598 | crc = crc_ccitt(0xffff, skb->data, skb->len); | ||
| 599 | crc = ~crc; | ||
| 600 | *skb_put(skb, 1) = crc & 0xff; | ||
| 601 | *skb_put(skb, 1) = crc >> 8; | ||
| 602 | } | ||
| 603 | |||
| 604 | static void pn544_hci_remove_len_crc(struct sk_buff *skb) | ||
| 605 | { | ||
| 606 | skb_pull(skb, PN544_FRAME_HEADROOM); | ||
| 607 | skb_trim(skb, PN544_FRAME_TAILROOM); | ||
| 608 | } | ||
| 609 | |||
| 610 | static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) | 340 | static int pn544_hci_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb) |
| 611 | { | 341 | { |
| 612 | struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); | 342 | struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); |
| 613 | struct i2c_client *client = info->i2c_dev; | ||
| 614 | int r; | ||
| 615 | 343 | ||
| 616 | if (info->hard_fault != 0) | 344 | return info->phy_ops->write(info->phy_id, skb); |
| 617 | return info->hard_fault; | ||
| 618 | |||
| 619 | pn544_hci_add_len_crc(skb); | ||
| 620 | r = pn544_hci_i2c_write(client, skb->data, skb->len); | ||
| 621 | pn544_hci_remove_len_crc(skb); | ||
| 622 | |||
| 623 | return r; | ||
| 624 | } | 345 | } |
| 625 | 346 | ||
| 626 | static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, | 347 | static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, |
| @@ -630,6 +351,9 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, · 3 unmodified lines | |||
| 630 | int r; | 351 | int r; |
| 631 | u8 duration[2]; | 352 | u8 duration[2]; |
| 632 | u8 activated; | 353 | u8 activated; |
| 354 | u8 i_mode = 0x3f; /* Enable all supported modes */ | ||
| 355 | u8 t_mode = 0x0f; | ||
| 356 | u8 t_merge = 0x01; /* Enable merge by default */ | ||
| 633 | 357 | ||
| 634 | pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", | 358 | pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n", |
| 635 | __func__, im_protocols, tm_protocols); | 359 | __func__, im_protocols, tm_protocols); |
| @@ -667,6 +391,61 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, · 31 unmodified lines | |||
| 667 | if (r < 0) | 391 | if (r < 0) |
| 668 | return r; | 392 | return r; |
| 669 | 393 | ||
| 394 | if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { | ||
| 395 | hdev->gb = nfc_get_local_general_bytes(hdev->ndev, | ||
| 396 | &hdev->gb_len); | ||
| 397 | pr_debug("generate local bytes %p", hdev->gb); | ||
| 398 | if (hdev->gb == NULL || hdev->gb_len == 0) { | ||
| 399 | im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | ||
| 400 | tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
| 405 | r = nfc_hci_send_event(hdev, | ||
| 406 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 407 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | ||
| 408 | if (r < 0) | ||
| 409 | return r; | ||
| 410 | |||
| 411 | r = nfc_hci_set_param(hdev, | ||
| 412 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 413 | PN544_DEP_MODE, &i_mode, 1); | ||
| 414 | if (r < 0) | ||
| 415 | return r; | ||
| 416 | |||
| 417 | r = nfc_hci_set_param(hdev, | ||
| 418 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 419 | PN544_DEP_ATR_REQ, hdev->gb, hdev->gb_len); | ||
| 420 | if (r < 0) | ||
| 421 | return r; | ||
| 422 | |||
| 423 | r = nfc_hci_send_event(hdev, | ||
| 424 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 425 | NFC_HCI_EVT_READER_REQUESTED, NULL, 0); | ||
| 426 | if (r < 0) | ||
| 427 | nfc_hci_send_event(hdev, | ||
| 428 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 429 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | ||
| 430 | } | ||
| 431 | |||
| 432 | if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
| 433 | r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, | ||
| 434 | PN544_DEP_MODE, &t_mode, 1); | ||
| 435 | if (r < 0) | ||
| 436 | return r; | ||
| 437 | |||
| 438 | r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, | ||
| 439 | PN544_DEP_ATR_RES, hdev->gb, hdev->gb_len); | ||
| 440 | if (r < 0) | ||
| 441 | return r; | ||
| 442 | |||
| 443 | r = nfc_hci_set_param(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, | ||
| 444 | PN544_DEP_MERGE, &t_merge, 1); | ||
| 445 | if (r < 0) | ||
| 446 | return r; | ||
| 447 | } | ||
| 448 | |||
| 670 | r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, | 449 | r = nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE, |
| 671 | NFC_HCI_EVT_READER_REQUESTED, NULL, 0); | 450 | NFC_HCI_EVT_READER_REQUESTED, NULL, 0); |
| 672 | if (r < 0) | 451 | if (r < 0) |
| @@ -676,6 +455,43 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, · 3 unmodified lines | |||
| 676 | return r; | 455 | return r; |
| 677 | } | 456 | } |
| 678 | 457 | ||
| 458 | static int pn544_hci_dep_link_up(struct nfc_hci_dev *hdev, | ||
| 459 | struct nfc_target *target, u8 comm_mode, | ||
| 460 | u8 *gb, size_t gb_len) | ||
| 461 | { | ||
| 462 | struct sk_buff *rgb_skb = NULL; | ||
| 463 | int r; | ||
| 464 | |||
| 465 | r = nfc_hci_get_param(hdev, target->hci_reader_gate, | ||
| 466 | PN544_DEP_ATR_RES, &rgb_skb); | ||
| 467 | if (r < 0) | ||
| 468 | return r; | ||
| 469 | |||
| 470 | if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) { | ||
| 471 | r = -EPROTO; | ||
| 472 | goto exit; | ||
| 473 | } | ||
| 474 | print_hex_dump(KERN_DEBUG, "remote gb: ", DUMP_PREFIX_OFFSET, | ||
| 475 | 16, 1, rgb_skb->data, rgb_skb->len, true); | ||
| 476 | |||
| 477 | r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data, | ||
| 478 | rgb_skb->len); | ||
| 479 | |||
| 480 | if (r == 0) | ||
| 481 | r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode, | ||
| 482 | NFC_RF_INITIATOR); | ||
| 483 | exit: | ||
| 484 | kfree_skb(rgb_skb); | ||
| 485 | return r; | ||
| 486 | } | ||
| 487 | |||
| 488 | static int pn544_hci_dep_link_down(struct nfc_hci_dev *hdev) | ||
| 489 | { | ||
| 490 | |||
| 491 | return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 492 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | ||
| 493 | } | ||
| 494 | |||
| 679 | static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, | 495 | static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, |
| 680 | struct nfc_target *target) | 496 | struct nfc_target *target) |
| 681 | { | 497 | { |
| @@ -687,6 +503,9 @@ static int pn544_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, · 5 unmodified lines | |||
| 687 | target->supported_protocols = NFC_PROTO_JEWEL_MASK; | 503 | target->supported_protocols = NFC_PROTO_JEWEL_MASK; |
| 688 | target->sens_res = 0x0c00; | 504 | target->sens_res = 0x0c00; |
| 689 | break; | 505 | break; |
| 506 | case PN544_RF_READER_NFCIP1_INITIATOR_GATE: | ||
| 507 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; | ||
| 508 | break; | ||
| 690 | default: | 509 | default: |
| 691 | return -EPROTO; | 510 | return -EPROTO; |
| 692 | } | 511 | } |
| @@ -701,7 +520,18 @@ static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev, · 8 unmodified lines | |||
| 701 | struct sk_buff *uid_skb; | 520 | struct sk_buff *uid_skb; |
| 702 | int r = 0; | 521 | int r = 0; |
| 703 | 522 | ||
| 704 | if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { | 523 | if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) |
| 524 | return r; | ||
| 525 | |||
| 526 | if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
| 527 | r = nfc_hci_send_cmd(hdev, | ||
| 528 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 529 | PN544_HCI_CMD_CONTINUE_ACTIVATION, NULL, 0, NULL); | ||
| 530 | if (r < 0) | ||
| 531 | return r; | ||
| 532 | |||
| 533 | target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; | ||
| 534 | } else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { | ||
| 705 | if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && | 535 | if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && |
| 706 | target->nfcid1_len != 10) | 536 | target->nfcid1_len != 10) |
| 707 | return -EPROTO; | 537 | return -EPROTO; |
| @@ -724,6 +554,16 @@ static int pn544_hci_complete_target_discovered(struct nfc_hci_dev *hdev, · 16 unmodified lines | |||
| 724 | PN544_RF_READER_CMD_ACTIVATE_NEXT, | 554 | PN544_RF_READER_CMD_ACTIVATE_NEXT, |
| 725 | uid_skb->data, uid_skb->len, NULL); | 555 | uid_skb->data, uid_skb->len, NULL); |
| 726 | kfree_skb(uid_skb); | 556 | kfree_skb(uid_skb); |
| 557 | |||
| 558 | r = nfc_hci_send_cmd(hdev, | ||
| 559 | PN544_RF_READER_NFCIP1_INITIATOR_GATE, | ||
| 560 | PN544_HCI_CMD_CONTINUE_ACTIVATION, | ||
| 561 | NULL, 0, NULL); | ||
| 562 | if (r < 0) | ||
| 563 | return r; | ||
| 564 | |||
| 565 | target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE; | ||
| 566 | target->supported_protocols = NFC_PROTO_NFC_DEP_MASK; | ||
| 727 | } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) { | 567 | } else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) { |
| 728 | /* | 568 | /* |
| 729 | * TODO: maybe other ISO 14443 require some kind of continue | 569 | * TODO: maybe other ISO 14443 require some kind of continue |
| @@ -769,7 +609,7 @@ static void pn544_hci_data_exchange_cb(void *context, struct sk_buff *skb, · 39 unmodified lines | |||
| 769 | * <= 0: driver handled the data exchange | 609 | * <= 0: driver handled the data exchange |
| 770 | * 1: driver doesn't especially handle, please do standard processing | 610 | * 1: driver doesn't especially handle, please do standard processing |
| 771 | */ | 611 | */ |
| 772 | static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev, | 612 | static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, |
| 773 | struct nfc_target *target, | 613 | struct nfc_target *target, |
| 774 | struct sk_buff *skb, data_exchange_cb_t cb, | 614 | struct sk_buff *skb, data_exchange_cb_t cb, |
| 775 | void *cb_context) | 615 | void *cb_context) |
| @@ -822,17 +662,110 @@ static int pn544_hci_data_exchange(struct nfc_hci_dev *hdev, · 46 unmodified lines | |||
| 822 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, | 662 | return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, |
| 823 | PN544_JEWEL_RAW_CMD, skb->data, | 663 | PN544_JEWEL_RAW_CMD, skb->data, |
| 824 | skb->len, cb, cb_context); | 664 | skb->len, cb, cb_context); |
| 665 | case PN544_RF_READER_NFCIP1_INITIATOR_GATE: | ||
| 666 | *skb_push(skb, 1) = 0; | ||
| 667 | |||
| 668 | return nfc_hci_send_event(hdev, target->hci_reader_gate, | ||
| 669 | PN544_HCI_EVT_SND_DATA, skb->data, | ||
| 670 | skb->len); | ||
| 825 | default: | 671 | default: |
| 826 | return 1; | 672 | return 1; |
| 827 | } | 673 | } |
| 828 | } | 674 | } |
| 829 | 675 | ||
| 676 | static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) | ||
| 677 | { | ||
| 678 | /* Set default false for multiple information chaining */ | ||
| 679 | *skb_push(skb, 1) = 0; | ||
| 680 | |||
| 681 | return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, | ||
| 682 | PN544_HCI_EVT_SND_DATA, skb->data, skb->len); | ||
| 683 | } | ||
| 684 | |||
| 830 | static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, | 685 | static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, |
| 831 | struct nfc_target *target) | 686 | struct nfc_target *target) |
| 832 | { | 687 | { |
| 833 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | 688 | pr_debug("supported protocol %d", target->supported_protocols); |
| 834 | PN544_RF_READER_CMD_PRESENCE_CHECK, | 689 | if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK | |
| 835 | NULL, 0, NULL); | 690 | NFC_PROTO_ISO14443_B_MASK)) { |
| 691 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | ||
| 692 | PN544_RF_READER_CMD_PRESENCE_CHECK, | ||
| 693 | NULL, 0, NULL); | ||
| 694 | } else if (target->supported_protocols & NFC_PROTO_MIFARE_MASK) { | ||
| 695 | if (target->nfcid1_len != 4 && target->nfcid1_len != 7 && | ||
| 696 | target->nfcid1_len != 10) | ||
| 697 | return -EOPNOTSUPP; | ||
| 698 | |||
| 699 | return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, | ||
| 700 | PN544_RF_READER_CMD_ACTIVATE_NEXT, | ||
| 701 | target->nfcid1, target->nfcid1_len, NULL); | ||
| 702 | } else if (target->supported_protocols & NFC_PROTO_JEWEL_MASK) { | ||
| 703 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | ||
| 704 | PN544_JEWEL_RAW_CMD, NULL, 0, NULL); | ||
| 705 | } else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) { | ||
| 706 | return nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE, | ||
| 707 | PN544_FELICA_RAW, NULL, 0, NULL); | ||
| 708 | } else if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) { | ||
| 709 | return nfc_hci_send_cmd(hdev, target->hci_reader_gate, | ||
| 710 | PN544_HCI_CMD_ATTREQUEST, | ||
| 711 | NULL, 0, NULL); | ||
| 712 | } | ||
| 713 | |||
| 714 | return 0; | ||
| 715 | } | ||
| 716 | |||
| 717 | static void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, | ||
| 718 | u8 event, struct sk_buff *skb) | ||
| 719 | { | ||
| 720 | struct sk_buff *rgb_skb = NULL; | ||
| 721 | int r = 0; | ||
| 722 | |||
| 723 | pr_debug("hci event %d", event); | ||
| 724 | switch (event) { | ||
| 725 | case PN544_HCI_EVT_ACTIVATED: | ||
| 726 | if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) | ||
| 727 | nfc_hci_target_discovered(hdev, gate); | ||
| 728 | else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { | ||
| 729 | r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, | ||
| 730 | &rgb_skb); | ||
| 731 | |||
| 732 | if (r < 0) | ||
| 733 | goto exit; | ||
| 734 | |||
| 735 | nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, | ||
| 736 | NFC_COMM_PASSIVE, rgb_skb->data, | ||
| 737 | rgb_skb->len); | ||
| 738 | |||
| 739 | kfree_skb(rgb_skb); | ||
| 740 | } | ||
| 741 | |||
| 742 | break; | ||
| 743 | case PN544_HCI_EVT_DEACTIVATED: | ||
| 744 | nfc_hci_send_event(hdev, gate, | ||
| 745 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | ||
| 746 | break; | ||
| 747 | case PN544_HCI_EVT_RCV_DATA: | ||
| 748 | if (skb->len < 2) { | ||
| 749 | r = -EPROTO; | ||
| 750 | goto exit; | ||
| 751 | } | ||
| 752 | |||
| 753 | if (skb->data[0] != 0) { | ||
| 754 | pr_debug("data0 %d", skb->data[0]); | ||
| 755 | r = -EPROTO; | ||
| 756 | goto exit; | ||
| 757 | } | ||
| 758 | |||
| 759 | skb_pull(skb, 2); | ||
| 760 | nfc_tm_data_received(hdev->ndev, skb); | ||
| 761 | |||
| 762 | return; | ||
| 763 | default: | ||
| 764 | break; | ||
| 765 | } | ||
| 766 | |||
| 767 | exit: | ||
| 768 | kfree_skb(skb); | ||
| 836 | } | 769 | } |
| 837 | 770 | ||
| 838 | static struct nfc_hci_ops pn544_hci_ops = { | 771 | static struct nfc_hci_ops pn544_hci_ops = { |
| @@ -841,74 +774,36 @@ static struct nfc_hci_ops pn544_hci_ops = { · 2 unmodified lines | |||
| 841 | .hci_ready = pn544_hci_ready, | 774 | .hci_ready = pn544_hci_ready, |
| 842 | .xmit = pn544_hci_xmit, | 775 | .xmit = pn544_hci_xmit, |
| 843 | .start_poll = pn544_hci_start_poll, | 776 | .start_poll = pn544_hci_start_poll, |
| 777 | .dep_link_up = pn544_hci_dep_link_up, | ||
| 778 | .dep_link_down = pn544_hci_dep_link_down, | ||
| 844 | .target_from_gate = pn544_hci_target_from_gate, | 779 | .target_from_gate = pn544_hci_target_from_gate, |
| 845 | .complete_target_discovered = pn544_hci_complete_target_discovered, | 780 | .complete_target_discovered = pn544_hci_complete_target_discovered, |
| 846 | .data_exchange = pn544_hci_data_exchange, | 781 | .im_transceive = pn544_hci_im_transceive, |
| 782 | .tm_send = pn544_hci_tm_send, | ||
| 847 | .check_presence = pn544_hci_check_presence, | 783 | .check_presence = pn544_hci_check_presence, |
| 784 | .event_received = pn544_hci_event_received, | ||
| 848 | }; | 785 | }; |
| 849 | 786 | ||
| 850 | static int __devinit pn544_hci_probe(struct i2c_client *client, | 787 | int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, |
| 851 | const struct i2c_device_id *id) | 788 | int phy_headroom, int phy_tailroom, int phy_payload, |
| 789 | struct nfc_hci_dev **hdev) | ||
| 852 | { | 790 | { |
| 853 | struct pn544_hci_info *info; | 791 | struct pn544_hci_info *info; |
| 854 | struct pn544_nfc_platform_data *pdata; | ||
| 855 | int r = 0; | ||
| 856 | u32 protocols; | 792 | u32 protocols; |
| 857 | struct nfc_hci_init_data init_data; | 793 | struct nfc_hci_init_data init_data; |
| 858 | 794 | int r; | |
| 859 | dev_dbg(&client->dev, "%s\n", __func__); | ||
| 860 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | ||
| 861 | |||
| 862 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 863 | dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); | ||
| 864 | return -ENODEV; | ||
| 865 | } | ||
| 866 | 795 | ||
| 867 | info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); | 796 | info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); |
| 868 | if (!info) { | 797 | if (!info) { |
| 869 | dev_err(&client->dev, | 798 | pr_err("Cannot allocate memory for pn544_hci_info.\n"); |
| 870 | "Cannot allocate memory for pn544_hci_info.\n"); | ||
| 871 | r = -ENOMEM; | 799 | r = -ENOMEM; |
| 872 | goto err_info_alloc; | 800 | goto err_info_alloc; |
| 873 | } | 801 | } |
| 874 | 802 | ||
| 875 | info->i2c_dev = client; | 803 | info->phy_ops = phy_ops; |
| 804 | info->phy_id = phy_id; | ||
| 876 | info->state = PN544_ST_COLD; | 805 | info->state = PN544_ST_COLD; |
| 877 | mutex_init(&info->info_lock); | 806 | mutex_init(&info->info_lock); |
| 878 | i2c_set_clientdata(client, info); | ||
| 879 | |||
| 880 | pdata = client->dev.platform_data; | ||
| 881 | if (pdata == NULL) { | ||
| 882 | dev_err(&client->dev, "No platform data\n"); | ||
| 883 | r = -EINVAL; | ||
| 884 | goto err_pdata; | ||
| 885 | } | ||
| 886 | |||
| 887 | if (pdata->request_resources == NULL) { | ||
| 888 | dev_err(&client->dev, "request_resources() missing\n"); | ||
| 889 | r = -EINVAL; | ||
| 890 | goto err_pdata; | ||
| 891 | } | ||
| 892 | |||
| 893 | r = pdata->request_resources(client); | ||
| 894 | if (r) { | ||
| 895 | dev_err(&client->dev, "Cannot get platform resources\n"); | ||
| 896 | goto err_pdata; | ||
| 897 | } | ||
| 898 | |||
| 899 | info->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); | ||
| 900 | info->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); | ||
| 901 | info->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ); | ||
| 902 | |||
| 903 | pn544_hci_platform_init(info); | ||
| 904 | |||
| 905 | r = request_threaded_irq(client->irq, NULL, pn544_hci_irq_thread_fn, | ||
| 906 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
| 907 | PN544_HCI_DRIVER_NAME, info); | ||
| 908 | if (r < 0) { | ||
| 909 | dev_err(&client->dev, "Unable to register IRQ handler\n"); | ||
| 910 | goto err_rti; | ||
| 911 | } | ||
| 912 | 807 | ||
| 913 | init_data.gate_count = ARRAY_SIZE(pn544_gates); | 808 | init_data.gate_count = ARRAY_SIZE(pn544_gates); |
| 914 | 809 | ||
| @@ -928,13 +823,11 @@ static int __devinit pn544_hci_probe(struct i2c_client *client, · 13 unmodified lines | |||
| 928 | NFC_PROTO_NFC_DEP_MASK; | 823 | NFC_PROTO_NFC_DEP_MASK; |
| 929 | 824 | ||
| 930 | info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, | 825 | info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, |
| 931 | protocols, LLC_SHDLC_NAME, | 826 | protocols, llc_name, |
| 932 | PN544_FRAME_HEADROOM + | 827 | phy_headroom + PN544_CMDS_HEADROOM, |
| 933 | PN544_CMDS_HEADROOM, | 828 | phy_tailroom, phy_payload); |
| 934 | PN544_FRAME_TAILROOM, | ||
| 935 | PN544_HCI_LLC_MAX_PAYLOAD); | ||
| 936 | if (!info->hdev) { | 829 | if (!info->hdev) { |
| 937 | dev_err(&client->dev, "Cannot allocate nfc hdev.\n"); | 830 | pr_err("Cannot allocate nfc hdev.\n"); |
| 938 | r = -ENOMEM; | 831 | r = -ENOMEM; |
| 939 | goto err_alloc_hdev; | 832 | goto err_alloc_hdev; |
| 940 | } | 833 | } |
| @@ -945,79 +838,25 @@ static int __devinit pn544_hci_probe(struct i2c_client *client, · 4 unmodified lines | |||
| 945 | if (r) | 838 | if (r) |
| 946 | goto err_regdev; | 839 | goto err_regdev; |
| 947 | 840 | ||
| 841 | *hdev = info->hdev; | ||
| 842 | |||
| 948 | return 0; | 843 | return 0; |
| 949 | 844 | ||
| 950 | err_regdev: | 845 | err_regdev: |
| 951 | nfc_hci_free_device(info->hdev); | 846 | nfc_hci_free_device(info->hdev); |
| 952 | 847 | ||
| 953 | err_alloc_hdev: | 848 | err_alloc_hdev: |
| 954 | free_irq(client->irq, info); | ||
| 955 | |||
| 956 | err_rti: | ||
| 957 | if (pdata->free_resources != NULL) | ||
| 958 | pdata->free_resources(); | ||
| 959 | |||
| 960 | err_pdata: | ||
| 961 | kfree(info); | 849 | kfree(info); |
| 962 | 850 | ||
| 963 | err_info_alloc: | 851 | err_info_alloc: |
| 964 | return r; | 852 | return r; |
| 965 | } | 853 | } |
| 966 | 854 | ||
| 967 | static __devexit int pn544_hci_remove(struct i2c_client *client) | 855 | void pn544_hci_remove(struct nfc_hci_dev *hdev) |
| 968 | { | 856 | { |
| 969 | struct pn544_hci_info *info = i2c_get_clientdata(client); | 857 | struct pn544_hci_info *info = nfc_hci_get_clientdata(hdev); |
| 970 | struct pn544_nfc_platform_data *pdata = client->dev.platform_data; | ||
| 971 | |||
| 972 | dev_dbg(&client->dev, "%s\n", __func__); | ||
| 973 | |||
| 974 | nfc_hci_free_device(info->hdev); | ||
| 975 | |||
| 976 | if (info->state != PN544_ST_COLD) { | ||
| 977 | if (pdata->disable) | ||
| 978 | pdata->disable(); | ||
| 979 | } | ||
| 980 | |||
| 981 | free_irq(client->irq, info); | ||
| 982 | if (pdata->free_resources) | ||
| 983 | pdata->free_resources(); | ||
| 984 | 858 | ||
| 859 | nfc_hci_unregister_device(hdev); | ||
| 860 | nfc_hci_free_device(hdev); | ||
| 985 | kfree(info); | 861 | kfree(info); |
| 986 | |||
| 987 | return 0; | ||
| 988 | } | 862 | } |
| 989 | |||
| 990 | static struct i2c_driver pn544_hci_driver = { | ||
| 991 | .driver = { | ||
| 992 | .name = PN544_HCI_DRIVER_NAME, | ||
| 993 | }, | ||
| 994 | .probe = pn544_hci_probe, | ||
| 995 | .id_table = pn544_hci_id_table, | ||
| 996 | .remove = __devexit_p(pn544_hci_remove), | ||
| 997 | }; | ||
| 998 | |||
| 999 | static int __init pn544_hci_init(void) | ||
| 1000 | { | ||
| 1001 | int r; | ||
| 1002 | |||
| 1003 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
| 1004 | |||
| 1005 | r = i2c_add_driver(&pn544_hci_driver); | ||
| 1006 | if (r) { | ||
| 1007 | pr_err(PN544_HCI_DRIVER_NAME ": driver registration failed\n"); | ||
| 1008 | return r; | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | return 0; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | static void __exit pn544_hci_exit(void) | ||
| 1015 | { | ||
| 1016 | i2c_del_driver(&pn544_hci_driver); | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | module_init(pn544_hci_init); | ||
| 1020 | module_exit(pn544_hci_exit); | ||
| 1021 | |||
| 1022 | MODULE_LICENSE("GPL"); | ||
| 1023 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 - 2012 Intel Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the | ||
| 16 | * Free Software Foundation, Inc., | ||
| 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __LOCAL_PN544_H_ | ||
| 21 | #define __LOCAL_PN544_H_ | ||
| 22 | |||
| 23 | #include <net/nfc/hci.h> | ||
| 24 | |||
| 25 | #define DRIVER_DESC "HCI NFC driver for PN544" | ||
| 26 | |||
| 27 | int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | ||
| 28 | int phy_headroom, int phy_tailroom, int phy_payload, | ||
| 29 | struct nfc_hci_dev **hdev); | ||
| 30 | void pn544_hci_remove(struct nfc_hci_dev *hdev); | ||
| 31 | |||
| 32 | #endif /* __LOCAL_PN544_H_ */ | ||
| @@ -37,6 +37,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { · 36 unmodified lines | |||
| 37 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) }, | 37 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) }, |
| 38 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, | 38 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, |
| 39 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, | 39 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, |
| 40 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) }, | ||
| 40 | { 0, }, | 41 | { 0, }, |
| 41 | }; | 42 | }; |
| 42 | MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); | 43 | MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); |
| @@ -346,6 +346,8 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) · 345 unmodified lines | |||
| 346 | chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0); | 346 | chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0); |
| 347 | } | 347 | } |
| 348 | break; | 348 | break; |
| 349 | case 43222: | ||
| 350 | break; | ||
| 349 | default: | 351 | default: |
| 350 | ssb_printk(KERN_ERR PFX | 352 | ssb_printk(KERN_ERR PFX |
| 351 | "ERROR: PLL init unknown for device %04X\n", | 353 | "ERROR: PLL init unknown for device %04X\n", |
| @@ -434,6 +436,7 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) · 82 unmodified lines | |||
| 434 | min_msk = 0xCBB; | 436 | min_msk = 0xCBB; |
| 435 | break; | 437 | break; |
| 436 | case 0x4322: | 438 | case 0x4322: |
| 439 | case 43222: | ||
| 437 | /* We keep the default settings: | 440 | /* We keep the default settings: |
| 438 | * min_msk = 0xCBB | 441 | * min_msk = 0xCBB |
| 439 | * max_msk = 0x7FFFF | 442 | * max_msk = 0x7FFFF |
| @@ -192,9 +192,10 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) · 191 unmodified lines | |||
| 192 | 192 | ||
| 193 | /* When there is no chipcommon on the bus there is 4MB flash */ | 193 | /* When there is no chipcommon on the bus there is 4MB flash */ |
| 194 | if (!bus->chipco.dev) { | 194 | if (!bus->chipco.dev) { |
| 195 | mcore->flash_buswidth = 2; | 195 | mcore->pflash.present = true; |
| 196 | mcore->flash_window = SSB_FLASH1; | 196 | mcore->pflash.buswidth = 2; |
| 197 | mcore->flash_window_size = SSB_FLASH1_SZ; | 197 | mcore->pflash.window = SSB_FLASH1; |
| 198 | mcore->pflash.window_size = SSB_FLASH1_SZ; | ||
| 198 | return; | 199 | return; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| @@ -206,13 +207,14 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) · 5 unmodified lines | |||
| 206 | break; | 207 | break; |
| 207 | case SSB_CHIPCO_FLASHT_PARA: | 208 | case SSB_CHIPCO_FLASHT_PARA: |
| 208 | pr_debug("Found parallel flash\n"); | 209 | pr_debug("Found parallel flash\n"); |
| 209 | mcore->flash_window = SSB_FLASH2; | 210 | mcore->pflash.present = true; |
| 210 | mcore->flash_window_size = SSB_FLASH2_SZ; | 211 | mcore->pflash.window = SSB_FLASH2; |
| 212 | mcore->pflash.window_size = SSB_FLASH2_SZ; | ||
| 211 | if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) | 213 | if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) |
| 212 | & SSB_CHIPCO_CFG_DS16) == 0) | 214 | & SSB_CHIPCO_CFG_DS16) == 0) |
| 213 | mcore->flash_buswidth = 1; | 215 | mcore->pflash.buswidth = 1; |
| 214 | else | 216 | else |
| 215 | mcore->flash_buswidth = 2; | 217 | mcore->pflash.buswidth = 2; |
| 216 | break; | 218 | break; |
| 217 | } | 219 | } |
| 218 | } | 220 | } |
| @@ -251,7 +251,7 @@ struct bcma_bus { · 250 unmodified lines | |||
| 251 | u8 num; | 251 | u8 num; |
| 252 | 252 | ||
| 253 | struct bcma_drv_cc drv_cc; | 253 | struct bcma_drv_cc drv_cc; |
| 254 | struct bcma_drv_pci drv_pci; | 254 | struct bcma_drv_pci drv_pci[2]; |
| 255 | struct bcma_drv_mips drv_mips; | 255 | struct bcma_drv_mips drv_mips; |
| 256 | struct bcma_drv_gmac_cmn drv_gmac_cmn; | 256 | struct bcma_drv_gmac_cmn drv_gmac_cmn; |
| 257 | 257 | ||
| @@ -510,6 +510,7 @@ struct bcma_chipcommon_pmu { · 509 unmodified lines | |||
| 510 | 510 | ||
| 511 | #ifdef CONFIG_BCMA_DRIVER_MIPS | 511 | #ifdef CONFIG_BCMA_DRIVER_MIPS |
| 512 | struct bcma_pflash { | 512 | struct bcma_pflash { |
| 513 | bool present; | ||
| 513 | u8 buswidth; | 514 | u8 buswidth; |
| 514 | u32 window; | 515 | u32 window; |
| 515 | u32 window_size; | 516 | u32 window_size; |
| @@ -532,6 +533,7 @@ struct mtd_info; · 16 unmodified lines | |||
| 532 | 533 | ||
| 533 | struct bcma_nflash { | 534 | struct bcma_nflash { |
| 534 | bool present; | 535 | bool present; |
| 536 | bool boot; /* This is the flash the SoC boots from */ | ||
| 535 | 537 | ||
| 536 | struct mtd_info *mtd; | 538 | struct mtd_info *mtd; |
| 537 | }; | 539 | }; |
| @@ -552,6 +554,7 @@ struct bcma_drv_cc { · 14 unmodified lines | |||
| 552 | u32 capabilities; | 554 | u32 capabilities; |
| 553 | u32 capabilities_ext; | 555 | u32 capabilities_ext; |
| 554 | u8 setup_done:1; | 556 | u8 setup_done:1; |
| 557 | u8 early_setup_done:1; | ||
| 555 | /* Fast Powerup Delay constant */ | 558 | /* Fast Powerup Delay constant */ |
| 556 | u16 fast_pwrup_delay; | 559 | u16 fast_pwrup_delay; |
| 557 | struct bcma_chipcommon_pmu pmu; | 560 | struct bcma_chipcommon_pmu pmu; |
| @@ -583,6 +586,7 @@ struct bcma_drv_cc { · 25 unmodified lines | |||
| 583 | bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) | 586 | bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) |
| 584 | 587 | ||
| 585 | extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); | 588 | extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); |
| 589 | extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); | ||
| 586 | 590 | ||
| 587 | extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); | 591 | extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); |
| 588 | extern void bcma_chipco_resume(struct bcma_drv_cc *cc); | 592 | extern void bcma_chipco_resume(struct bcma_drv_cc *cc); |
| @@ -606,6 +610,7 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); · 17 unmodified lines | |||
| 606 | 610 | ||
| 607 | /* PMU support */ | 611 | /* PMU support */ |
| 608 | extern void bcma_pmu_init(struct bcma_drv_cc *cc); | 612 | extern void bcma_pmu_init(struct bcma_drv_cc *cc); |
| 613 | extern void bcma_pmu_early_init(struct bcma_drv_cc *cc); | ||
| 609 | 614 | ||
| 610 | extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, | 615 | extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, |
| 611 | u32 value); | 616 | u32 value); |
| @@ -35,13 +35,16 @@ struct bcma_device; · 34 unmodified lines | |||
| 35 | struct bcma_drv_mips { | 35 | struct bcma_drv_mips { |
| 36 | struct bcma_device *core; | 36 | struct bcma_device *core; |
| 37 | u8 setup_done:1; | 37 | u8 setup_done:1; |
| 38 | u8 early_setup_done:1; | ||
| 38 | unsigned int assigned_irqs; | 39 | unsigned int assigned_irqs; |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | #ifdef CONFIG_BCMA_DRIVER_MIPS | 42 | #ifdef CONFIG_BCMA_DRIVER_MIPS |
| 42 | extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); | 43 | extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); |
| 44 | extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore); | ||
| 43 | #else | 45 | #else |
| 44 | static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } | 46 | static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { } |
| 47 | static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { } | ||
| 45 | #endif | 48 | #endif |
| 46 | 49 | ||
| 47 | extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); | 50 | extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); |
| @@ -85,6 +85,9 @@ · 84 unmodified lines | |||
| 85 | * (2 ZettaBytes), high 32 bits | 85 | * (2 ZettaBytes), high 32 bits |
| 86 | */ | 86 | */ |
| 87 | 87 | ||
| 88 | #define BCMA_SFLASH 0x1c000000 | 88 | #define BCMA_SOC_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ |
| 89 | #define BCMA_SOC_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ | ||
| 90 | #define BCMA_SOC_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ | ||
| 91 | #define BCMA_SOC_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ | ||
| 89 | 92 | ||
| 90 | #endif /* LINUX_BCMA_REGS_H_ */ | 93 | #endif /* LINUX_BCMA_REGS_H_ */ |
| @@ -1107,20 +1107,6 @@ struct ieee80211_ht_operation { · 1106 unmodified lines | |||
| 1107 | #define WLAN_HT_SMPS_CONTROL_STATIC 1 | 1107 | #define WLAN_HT_SMPS_CONTROL_STATIC 1 |
| 1108 | #define WLAN_HT_SMPS_CONTROL_DYNAMIC 3 | 1108 | #define WLAN_HT_SMPS_CONTROL_DYNAMIC 3 |
| 1109 | 1109 | ||
| 1110 | #define VHT_MCS_SUPPORTED_SET_SIZE 8 | ||
| 1111 | |||
| 1112 | struct ieee80211_vht_capabilities { | ||
| 1113 | __le32 vht_capabilities_info; | ||
| 1114 | u8 vht_supported_mcs_set[VHT_MCS_SUPPORTED_SET_SIZE]; | ||
| 1115 | } __packed; | ||
| 1116 | |||
| 1117 | struct ieee80211_vht_operation { | ||
| 1118 | u8 vht_op_info_chwidth; | ||
| 1119 | u8 vht_op_info_chan_center_freq_seg1_idx; | ||
| 1120 | u8 vht_op_info_chan_center_freq_seg2_idx; | ||
| 1121 | __le16 vht_basic_mcs_set; | ||
| 1122 | } __packed; | ||
| 1123 | |||
| 1124 | /** | 1110 | /** |
| 1125 | * struct ieee80211_vht_mcs_info - VHT MCS information | 1111 | * struct ieee80211_vht_mcs_info - VHT MCS information |
| 1126 | * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams | 1112 | * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams |
| @@ -1141,6 +1127,37 @@ struct ieee80211_vht_mcs_info { · 14 unmodified lines | |||
| 1141 | __le16 tx_highest; | 1127 | __le16 tx_highest; |
| 1142 | } __packed; | 1128 | } __packed; |
| 1143 | 1129 | ||
| 1130 | /** | ||
| 1131 | * struct ieee80211_vht_cap - VHT capabilities | ||
| 1132 | * | ||
| 1133 | * This structure is the "VHT capabilities element" as | ||
| 1134 | * described in 802.11ac D3.0 8.4.2.160 | ||
| 1135 | * @vht_cap_info: VHT capability info | ||
| 1136 | * @supp_mcs: VHT MCS supported rates | ||
| 1137 | */ | ||
| 1138 | struct ieee80211_vht_cap { | ||
| 1139 | __le32 vht_cap_info; | ||
| 1140 | struct ieee80211_vht_mcs_info supp_mcs; | ||
| 1141 | } __packed; | ||
| 1142 | |||
| 1143 | /** | ||
| 1144 | * struct ieee80211_vht_operation - VHT operation IE | ||
| 1145 | * | ||
| 1146 | * This structure is the "VHT operation element" as | ||
| 1147 | * described in 802.11ac D3.0 8.4.2.161 | ||
| 1148 | * @chan_width: Operating channel width | ||
| 1149 | * @center_freq_seg1_idx: center freq segment 1 index | ||
| 1150 | * @center_freq_seg2_idx: center freq segment 2 index | ||
| 1151 | * @basic_mcs_set: VHT Basic MCS rate set | ||
| 1152 | */ | ||
| 1153 | struct ieee80211_vht_operation { | ||
| 1154 | u8 chan_width; | ||
| 1155 | u8 center_freq_seg1_idx; | ||
| 1156 | u8 center_freq_seg2_idx; | ||
| 1157 | __le16 basic_mcs_set; | ||
| 1158 | } __packed; | ||
| 1159 | |||
| 1160 | |||
| 1144 | #define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 | 1161 | #define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 |
| 1145 | #define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 | 1162 | #define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 |
| 1146 | #define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 | 1163 | #define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 |
| @@ -1440,8 +1457,6 @@ enum ieee80211_eid { · 293 unmodified lines | |||
| 1440 | 1457 | ||
| 1441 | WLAN_EID_RSN = 48, | 1458 | WLAN_EID_RSN = 48, |
| 1442 | WLAN_EID_MMIE = 76, | 1459 | WLAN_EID_MMIE = 76, |
| 1443 | WLAN_EID_WPA = 221, | ||
| 1444 | WLAN_EID_GENERIC = 221, | ||
| 1445 | WLAN_EID_VENDOR_SPECIFIC = 221, | 1460 | WLAN_EID_VENDOR_SPECIFIC = 221, |
| 1446 | WLAN_EID_QOS_PARAMETER = 222, | 1461 | WLAN_EID_QOS_PARAMETER = 222, |
| 1447 | 1462 | ||
| @@ -13,6 +13,12 @@ struct ssb_serial_port { · 12 unmodified lines | |||
| 13 | unsigned int reg_shift; | 13 | unsigned int reg_shift; |
| 14 | }; | 14 | }; |
| 15 | 15 | ||
| 16 | struct ssb_pflash { | ||
| 17 | bool present; | ||
| 18 | u8 buswidth; | ||
| 19 | u32 window; | ||
| 20 | u32 window_size; | ||
| 21 | }; | ||
| 16 | 22 | ||
| 17 | struct ssb_mipscore { | 23 | struct ssb_mipscore { |
| 18 | struct ssb_device *dev; | 24 | struct ssb_device *dev; |
| @@ -20,9 +26,7 @@ struct ssb_mipscore { · 1 unmodified line | |||
| 20 | int nr_serial_ports; | 26 | int nr_serial_ports; |
| 21 | struct ssb_serial_port serial_ports[4]; | 27 | struct ssb_serial_port serial_ports[4]; |
| 22 | 28 | ||
| 23 | u8 flash_buswidth; | 29 | struct ssb_pflash pflash; |
| 24 | u32 flash_window; | ||
| 25 | u32 flash_window_size; | ||
| 26 | }; | 30 | }; |
| 27 | 31 | ||
| 28 | extern void ssb_mipscore_init(struct ssb_mipscore *mcore); | 32 | extern void ssb_mipscore_init(struct ssb_mipscore *mcore); |
| @@ -19,13 +19,25 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #define A2MP_FEAT_EXT 0x8000 | 20 | #define A2MP_FEAT_EXT 0x8000 |
| 21 | 21 | ||
| 22 | enum amp_mgr_state { | ||
| 23 | READ_LOC_AMP_INFO, | ||
| 24 | READ_LOC_AMP_ASSOC, | ||
| 25 | READ_LOC_AMP_ASSOC_FINAL, | ||
| 26 | }; | ||
| 27 | |||
| 22 | struct amp_mgr { | 28 | struct amp_mgr { |
| 29 | struct list_head list; | ||
| 23 | struct l2cap_conn *l2cap_conn; | 30 | struct l2cap_conn *l2cap_conn; |
| 24 | struct l2cap_chan *a2mp_chan; | 31 | struct l2cap_chan *a2mp_chan; |
| 32 | struct l2cap_chan *bredr_chan; | ||
| 25 | struct kref kref; | 33 | struct kref kref; |
| 26 | __u8 ident; | 34 | __u8 ident; |
| 27 | __u8 handle; | 35 | __u8 handle; |
| 36 | enum amp_mgr_state state; | ||
| 28 | unsigned long flags; | 37 | unsigned long flags; |
| 38 | |||
| 39 | struct list_head amp_ctrls; | ||
| 40 | struct mutex amp_ctrls_lock; | ||
| 29 | }; | 41 | }; |
| 30 | 42 | ||
| 31 | struct a2mp_cmd { | 43 | struct a2mp_cmd { |
| @@ -118,9 +130,19 @@ struct a2mp_physlink_rsp { · 86 unmodified lines | |||
| 118 | #define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 | 130 | #define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 |
| 119 | #define A2MP_STATUS_SECURITY_VIOLATION 0x06 | 131 | #define A2MP_STATUS_SECURITY_VIOLATION 0x06 |
| 120 | 132 | ||
| 121 | void amp_mgr_get(struct amp_mgr *mgr); | 133 | extern struct list_head amp_mgr_list; |
| 134 | extern struct mutex amp_mgr_list_lock; | ||
| 135 | |||
| 136 | struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr); | ||
| 122 | int amp_mgr_put(struct amp_mgr *mgr); | 137 | int amp_mgr_put(struct amp_mgr *mgr); |
| 138 | u8 __next_ident(struct amp_mgr *mgr); | ||
| 123 | struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, | 139 | struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, |
| 124 | struct sk_buff *skb); | 140 | struct sk_buff *skb); |
| 141 | struct amp_mgr *amp_mgr_lookup_by_state(u8 state); | ||
| 142 | void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data); | ||
| 143 | void a2mp_discover_amp(struct l2cap_chan *chan); | ||
| 144 | void a2mp_send_getinfo_rsp(struct hci_dev *hdev); | ||
| 145 | void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); | ||
| 146 | void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); | ||
| 125 | 147 | ||
| 126 | #endif /* __A2MP_H */ | 148 | #endif /* __A2MP_H */ |
| @@ -0,0 +1,50 @@ | |||
| 1 | /* | ||
| 2 | Copyright (c) 2011,2012 Intel Corp. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License version 2 and | ||
| 6 | only version 2 as published by the Free Software Foundation. | ||
| 7 | |||
| 8 | This program is distributed in the hope that it will be useful, | ||
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __AMP_H | ||
| 15 | #define __AMP_H | ||
| 16 | |||
| 17 | struct amp_ctrl { | ||
| 18 | struct list_head list; | ||
| 19 | struct kref kref; | ||
| 20 | __u8 id; | ||
| 21 | __u16 assoc_len_so_far; | ||
| 22 | __u16 assoc_rem_len; | ||
| 23 | __u16 assoc_len; | ||
| 24 | __u8 *assoc; | ||
| 25 | }; | ||
| 26 | |||
| 27 | int amp_ctrl_put(struct amp_ctrl *ctrl); | ||
| 28 | void amp_ctrl_get(struct amp_ctrl *ctrl); | ||
| 29 | struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id); | ||
| 30 | struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); | ||
| 31 | void amp_ctrl_list_flush(struct amp_mgr *mgr); | ||
| 32 | |||
| 33 | struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 34 | u8 remote_id, bool out); | ||
| 35 | |||
| 36 | int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type); | ||
| 37 | |||
| 38 | void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); | ||
| 39 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle); | ||
| 40 | void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr); | ||
| 41 | void amp_read_loc_assoc_final_data(struct hci_dev *hdev, | ||
| 42 | struct hci_conn *hcon); | ||
| 43 | void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 44 | struct hci_conn *hcon); | ||
| 45 | void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 46 | struct hci_conn *hcon); | ||
| 47 | void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); | ||
| 48 | void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); | ||
| 49 | |||
| 50 | #endif /* __AMP_H */ | ||
| @@ -180,7 +180,6 @@ static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) · 179 unmodified lines | |||
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | void baswap(bdaddr_t *dst, bdaddr_t *src); | 182 | void baswap(bdaddr_t *dst, bdaddr_t *src); |
| 183 | char *batostr(bdaddr_t *ba); | ||
| 184 | 183 | ||
| 185 | /* Common socket structures and functions */ | 184 | /* Common socket structures and functions */ |
| 186 | 185 | ||
| @@ -33,6 +33,8 @@ · 32 unmodified lines | |||
| 33 | #define HCI_LINK_KEY_SIZE 16 | 33 | #define HCI_LINK_KEY_SIZE 16 |
| 34 | #define HCI_AMP_LINK_KEY_SIZE (2 * HCI_LINK_KEY_SIZE) | 34 | #define HCI_AMP_LINK_KEY_SIZE (2 * HCI_LINK_KEY_SIZE) |
| 35 | 35 | ||
| 36 | #define HCI_MAX_AMP_ASSOC_SIZE 672 | ||
| 37 | |||
| 36 | /* HCI dev events */ | 38 | /* HCI dev events */ |
| 37 | #define HCI_DEV_REG 1 | 39 | #define HCI_DEV_REG 1 |
| 38 | #define HCI_DEV_UNREG 2 | 40 | #define HCI_DEV_UNREG 2 |
| @@ -196,6 +198,7 @@ enum { · 157 unmodified lines | |||
| 196 | #define ACL_START_NO_FLUSH 0x00 | 198 | #define ACL_START_NO_FLUSH 0x00 |
| 197 | #define ACL_CONT 0x01 | 199 | #define ACL_CONT 0x01 |
| 198 | #define ACL_START 0x02 | 200 | #define ACL_START 0x02 |
| 201 | #define ACL_COMPLETE 0x03 | ||
| 199 | #define ACL_ACTIVE_BCAST 0x04 | 202 | #define ACL_ACTIVE_BCAST 0x04 |
| 200 | #define ACL_PICO_BCAST 0x08 | 203 | #define ACL_PICO_BCAST 0x08 |
| 201 | 204 | ||
| @@ -205,6 +208,7 @@ enum { · 3 unmodified lines | |||
| 205 | #define ESCO_LINK 0x02 | 208 | #define ESCO_LINK 0x02 |
| 206 | /* Low Energy links do not have defined link type. Use invented one */ | 209 | /* Low Energy links do not have defined link type. Use invented one */ |
| 207 | #define LE_LINK 0x80 | 210 | #define LE_LINK 0x80 |
| 211 | #define AMP_LINK 0x81 | ||
| 208 | 212 | ||
| 209 | /* LMP features */ | 213 | /* LMP features */ |
| 210 | #define LMP_3SLOT 0x01 | 214 | #define LMP_3SLOT 0x01 |
| @@ -556,12 +560,46 @@ struct hci_cp_accept_phy_link { · 345 unmodified lines | |||
| 556 | __u8 key[HCI_AMP_LINK_KEY_SIZE]; | 560 | __u8 key[HCI_AMP_LINK_KEY_SIZE]; |
| 557 | } __packed; | 561 | } __packed; |
| 558 | 562 | ||
| 559 | #define HCI_OP_DISCONN_PHY_LINK 0x0437 | 563 | #define HCI_OP_DISCONN_PHY_LINK 0x0437 |
| 560 | struct hci_cp_disconn_phy_link { | 564 | struct hci_cp_disconn_phy_link { |
| 561 | __u8 phy_handle; | 565 | __u8 phy_handle; |
| 562 | __u8 reason; | 566 | __u8 reason; |
| 563 | } __packed; | 567 | } __packed; |
| 564 | 568 | ||
| 569 | struct ext_flow_spec { | ||
| 570 | __u8 id; | ||
| 571 | __u8 stype; | ||
| 572 | __le16 msdu; | ||
| 573 | __le32 sdu_itime; | ||
| 574 | __le32 acc_lat; | ||
| 575 | __le32 flush_to; | ||
| 576 | } __packed; | ||
| 577 | |||
| 578 | #define HCI_OP_CREATE_LOGICAL_LINK 0x0438 | ||
| 579 | #define HCI_OP_ACCEPT_LOGICAL_LINK 0x0439 | ||
| 580 | struct hci_cp_create_accept_logical_link { | ||
| 581 | __u8 phy_handle; | ||
| 582 | struct ext_flow_spec tx_flow_spec; | ||
| 583 | struct ext_flow_spec rx_flow_spec; | ||
| 584 | } __packed; | ||
| 585 | |||
| 586 | #define HCI_OP_DISCONN_LOGICAL_LINK 0x043a | ||
| 587 | struct hci_cp_disconn_logical_link { | ||
| 588 | __le16 log_handle; | ||
| 589 | } __packed; | ||
| 590 | |||
| 591 | #define HCI_OP_LOGICAL_LINK_CANCEL 0x043b | ||
| 592 | struct hci_cp_logical_link_cancel { | ||
| 593 | __u8 phy_handle; | ||
| 594 | __u8 flow_spec_id; | ||
| 595 | } __packed; | ||
| 596 | |||
| 597 | struct hci_rp_logical_link_cancel { | ||
| 598 | __u8 status; | ||
| 599 | __u8 phy_handle; | ||
| 600 | __u8 flow_spec_id; | ||
| 601 | } __packed; | ||
| 602 | |||
| 565 | #define HCI_OP_SNIFF_MODE 0x0803 | 603 | #define HCI_OP_SNIFF_MODE 0x0803 |
| 566 | struct hci_cp_sniff_mode { | 604 | struct hci_cp_sniff_mode { |
| 567 | __le16 handle; | 605 | __le16 handle; |
| @@ -73,6 +73,7 @@ struct discovery_state { · 72 unmodified lines | |||
| 73 | struct hci_conn_hash { | 73 | struct hci_conn_hash { |
| 74 | struct list_head list; | 74 | struct list_head list; |
| 75 | unsigned int acl_num; | 75 | unsigned int acl_num; |
| 76 | unsigned int amp_num; | ||
| 76 | unsigned int sco_num; | 77 | unsigned int sco_num; |
| 77 | unsigned int le_num; | 78 | unsigned int le_num; |
| 78 | }; | 79 | }; |
| @@ -124,6 +125,14 @@ struct le_scan_params { · 45 unmodified lines | |||
| 124 | 125 | ||
| 125 | #define HCI_MAX_SHORT_NAME_LENGTH 10 | 126 | #define HCI_MAX_SHORT_NAME_LENGTH 10 |
| 126 | 127 | ||
| 128 | struct amp_assoc { | ||
| 129 | __u16 len; | ||
| 130 | __u16 offset; | ||
| 131 | __u16 rem_len; | ||
| 132 | __u16 len_so_far; | ||
| 133 | __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; | ||
| 134 | }; | ||
| 135 | |||
| 127 | #define NUM_REASSEMBLY 4 | 136 | #define NUM_REASSEMBLY 4 |
| 128 | struct hci_dev { | 137 | struct hci_dev { |
| 129 | struct list_head list; | 138 | struct list_head list; |
| @@ -177,6 +186,8 @@ struct hci_dev { · 47 unmodified lines | |||
| 177 | __u32 amp_max_flush_to; | 186 | __u32 amp_max_flush_to; |
| 178 | __u32 amp_be_flush_to; | 187 | __u32 amp_be_flush_to; |
| 179 | 188 | ||
| 189 | struct amp_assoc loc_assoc; | ||
| 190 | |||
| 180 | __u8 flow_ctl_mode; | 191 | __u8 flow_ctl_mode; |
| 181 | 192 | ||
| 182 | unsigned int auto_accept_delay; | 193 | unsigned int auto_accept_delay; |
| @@ -252,8 +263,6 @@ struct hci_dev { · 69 unmodified lines | |||
| 252 | 263 | ||
| 253 | struct sk_buff_head driver_init; | 264 | struct sk_buff_head driver_init; |
| 254 | 265 | ||
| 255 | void *core_data; | ||
| 256 | |||
| 257 | atomic_t promisc; | 266 | atomic_t promisc; |
| 258 | 267 | ||
| 259 | struct dentry *debugfs; | 268 | struct dentry *debugfs; |
| @@ -277,6 +286,8 @@ struct hci_dev { · 17 unmodified lines | |||
| 277 | int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); | 286 | int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); |
| 278 | }; | 287 | }; |
| 279 | 288 | ||
| 289 | #define HCI_PHY_HANDLE(handle) (handle & 0xff) | ||
| 290 | |||
| 280 | struct hci_conn { | 291 | struct hci_conn { |
| 281 | struct list_head list; | 292 | struct list_head list; |
| 282 | 293 | ||
| @@ -310,6 +321,7 @@ struct hci_conn { · 27 unmodified lines | |||
| 310 | 321 | ||
| 311 | __u8 remote_cap; | 322 | __u8 remote_cap; |
| 312 | __u8 remote_auth; | 323 | __u8 remote_auth; |
| 324 | __u8 remote_id; | ||
| 313 | bool flush_key; | 325 | bool flush_key; |
| 314 | 326 | ||
| 315 | unsigned int sent; | 327 | unsigned int sent; |
| @@ -339,7 +351,7 @@ struct hci_conn { · 23 unmodified lines | |||
| 339 | 351 | ||
| 340 | struct hci_chan { | 352 | struct hci_chan { |
| 341 | struct list_head list; | 353 | struct list_head list; |
| 342 | 354 | __u16 handle; | |
| 343 | struct hci_conn *conn; | 355 | struct hci_conn *conn; |
| 344 | struct sk_buff_head data_q; | 356 | struct sk_buff_head data_q; |
| 345 | unsigned int sent; | 357 | unsigned int sent; |
| @@ -438,6 +450,9 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) · 92 unmodified lines | |||
| 438 | case ACL_LINK: | 450 | case ACL_LINK: |
| 439 | h->acl_num++; | 451 | h->acl_num++; |
| 440 | break; | 452 | break; |
| 453 | case AMP_LINK: | ||
| 454 | h->amp_num++; | ||
| 455 | break; | ||
| 441 | case LE_LINK: | 456 | case LE_LINK: |
| 442 | h->le_num++; | 457 | h->le_num++; |
| 443 | break; | 458 | break; |
| @@ -459,6 +474,9 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) · 15 unmodified lines | |||
| 459 | case ACL_LINK: | 474 | case ACL_LINK: |
| 460 | h->acl_num--; | 475 | h->acl_num--; |
| 461 | break; | 476 | break; |
| 477 | case AMP_LINK: | ||
| 478 | h->amp_num--; | ||
| 479 | break; | ||
| 462 | case LE_LINK: | 480 | case LE_LINK: |
| 463 | h->le_num--; | 481 | h->le_num--; |
| 464 | break; | 482 | break; |
| @@ -475,6 +493,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) · 10 unmodified lines | |||
| 475 | switch (type) { | 493 | switch (type) { |
| 476 | case ACL_LINK: | 494 | case ACL_LINK: |
| 477 | return h->acl_num; | 495 | return h->acl_num; |
| 496 | case AMP_LINK: | ||
| 497 | return h->amp_num; | ||
| 478 | case LE_LINK: | 498 | case LE_LINK: |
| 479 | return h->le_num; | 499 | return h->le_num; |
| 480 | case SCO_LINK: | 500 | case SCO_LINK: |
| @@ -556,6 +576,7 @@ void hci_conn_check_pending(struct hci_dev *hdev); · 75 unmodified lines | |||
| 556 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | 576 | struct hci_chan *hci_chan_create(struct hci_conn *conn); |
| 557 | void hci_chan_del(struct hci_chan *chan); | 577 | void hci_chan_del(struct hci_chan *chan); |
| 558 | void hci_chan_list_flush(struct hci_conn *conn); | 578 | void hci_chan_list_flush(struct hci_conn *conn); |
| 579 | struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); | ||
| 559 | 580 | ||
| 560 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 581 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
| 561 | __u8 dst_type, __u8 sec_level, __u8 auth_type); | 582 | __u8 dst_type, __u8 sec_level, __u8 auth_type); |
| @@ -584,7 +605,10 @@ static inline void hci_conn_put(struct hci_conn *conn) · 22 unmodified lines | |||
| 584 | 605 | ||
| 585 | if (atomic_dec_and_test(&conn->refcnt)) { | 606 | if (atomic_dec_and_test(&conn->refcnt)) { |
| 586 | unsigned long timeo; | 607 | unsigned long timeo; |
| 587 | if (conn->type == ACL_LINK || conn->type == LE_LINK) { | 608 | |
| 609 | switch (conn->type) { | ||
| 610 | case ACL_LINK: | ||
| 611 | case LE_LINK: | ||
| 588 | del_timer(&conn->idle_timer); | 612 | del_timer(&conn->idle_timer); |
| 589 | if (conn->state == BT_CONNECTED) { | 613 | if (conn->state == BT_CONNECTED) { |
| 590 | timeo = conn->disc_timeout; | 614 | timeo = conn->disc_timeout; |
| @@ -593,12 +617,20 @@ static inline void hci_conn_put(struct hci_conn *conn) · 2 unmodified lines | |||
| 593 | } else { | 617 | } else { |
| 594 | timeo = msecs_to_jiffies(10); | 618 | timeo = msecs_to_jiffies(10); |
| 595 | } | 619 | } |
| 596 | } else { | 620 | break; |
| 621 | |||
| 622 | case AMP_LINK: | ||
| 623 | timeo = conn->disc_timeout; | ||
| 624 | break; | ||
| 625 | |||
| 626 | default: | ||
| 597 | timeo = msecs_to_jiffies(10); | 627 | timeo = msecs_to_jiffies(10); |
| 628 | break; | ||
| 598 | } | 629 | } |
| 630 | |||
| 599 | cancel_delayed_work(&conn->disc_work); | 631 | cancel_delayed_work(&conn->disc_work); |
| 600 | queue_delayed_work(conn->hdev->workqueue, | 632 | queue_delayed_work(conn->hdev->workqueue, |
| 601 | &conn->disc_work, timeo); | 633 | &conn->disc_work, timeo); |
| 602 | } | 634 | } |
| 603 | } | 635 | } |
| 604 | 636 | ||
| @@ -789,6 +821,10 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) · 184 unmodified lines | |||
| 789 | sco_disconn_cfm(conn, reason); | 821 | sco_disconn_cfm(conn, reason); |
| 790 | break; | 822 | break; |
| 791 | 823 | ||
| 824 | /* L2CAP would be handled for BREDR chan */ | ||
| 825 | case AMP_LINK: | ||
| 826 | break; | ||
| 827 | |||
| 792 | default: | 828 | default: |
| 793 | BT_ERR("unknown link type %d", conn->type); | 829 | BT_ERR("unknown link type %d", conn->type); |
| 794 | break; | 830 | break; |
| @@ -32,13 +32,14 @@ · 31 unmodified lines | |||
| 32 | /* L2CAP defaults */ | 32 | /* L2CAP defaults */ |
| 33 | #define L2CAP_DEFAULT_MTU 672 | 33 | #define L2CAP_DEFAULT_MTU 672 |
| 34 | #define L2CAP_DEFAULT_MIN_MTU 48 | 34 | #define L2CAP_DEFAULT_MIN_MTU 48 |
| 35 | #define L2CAP_DEFAULT_FLUSH_TO 0xffff | 35 | #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF |
| 36 | #define L2CAP_EFS_DEFAULT_FLUSH_TO 0xFFFFFFFF | ||
| 36 | #define L2CAP_DEFAULT_TX_WINDOW 63 | 37 | #define L2CAP_DEFAULT_TX_WINDOW 63 |
| 37 | #define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF | 38 | #define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF |
| 38 | #define L2CAP_DEFAULT_MAX_TX 3 | 39 | #define L2CAP_DEFAULT_MAX_TX 3 |
| 39 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ | 40 | #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ |
| 40 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ | 41 | #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ |
| 41 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ | 42 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1492 /* Sized for AMP packet */ |
| 42 | #define L2CAP_DEFAULT_ACK_TO 200 | 43 | #define L2CAP_DEFAULT_ACK_TO 200 |
| 43 | #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF | 44 | #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF |
| 44 | #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF | 45 | #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF |
| @@ -508,6 +509,8 @@ struct l2cap_chan { · 463 unmodified lines | |||
| 508 | __u32 remote_acc_lat; | 509 | __u32 remote_acc_lat; |
| 509 | __u32 remote_flush_to; | 510 | __u32 remote_flush_to; |
| 510 | 511 | ||
| 512 | __u8 ctrl_id; | ||
| 513 | |||
| 511 | struct delayed_work chan_timer; | 514 | struct delayed_work chan_timer; |
| 512 | struct delayed_work retrans_timer; | 515 | struct delayed_work retrans_timer; |
| 513 | struct delayed_work monitor_timer; | 516 | struct delayed_work monitor_timer; |
| @@ -538,6 +541,7 @@ struct l2cap_ops { · 24 unmodified lines | |||
| 538 | void (*state_change) (struct l2cap_chan *chan, | 541 | void (*state_change) (struct l2cap_chan *chan, |
| 539 | int state); | 542 | int state); |
| 540 | void (*ready) (struct l2cap_chan *chan); | 543 | void (*ready) (struct l2cap_chan *chan); |
| 544 | void (*defer) (struct l2cap_chan *chan); | ||
| 541 | struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, | 545 | struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, |
| 542 | unsigned long len, int nb); | 546 | unsigned long len, int nb); |
| 543 | }; | 547 | }; |
| @@ -745,6 +749,10 @@ static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) · 201 unmodified lines | |||
| 745 | { | 749 | { |
| 746 | } | 750 | } |
| 747 | 751 | ||
| 752 | static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) | ||
| 753 | { | ||
| 754 | } | ||
| 755 | |||
| 748 | extern bool disable_ertm; | 756 | extern bool disable_ertm; |
| 749 | 757 | ||
| 750 | int l2cap_init_sockets(void); | 758 | int l2cap_init_sockets(void); |
| @@ -767,6 +775,8 @@ int l2cap_chan_check_security(struct l2cap_chan *chan); · 16 unmodified lines | |||
| 767 | void l2cap_chan_set_defaults(struct l2cap_chan *chan); | 775 | void l2cap_chan_set_defaults(struct l2cap_chan *chan); |
| 768 | int l2cap_ertm_init(struct l2cap_chan *chan); | 776 | int l2cap_ertm_init(struct l2cap_chan *chan); |
| 769 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); | 777 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); |
| 778 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); | ||
| 770 | void l2cap_chan_del(struct l2cap_chan *chan, int err); | 779 | void l2cap_chan_del(struct l2cap_chan *chan, int err); |
| 780 | void l2cap_send_conn_req(struct l2cap_chan *chan); | ||
| 771 | 781 | ||
| 772 | #endif /* __L2CAP_H */ | 782 | #endif /* __L2CAP_H */ |
| @@ -498,6 +498,7 @@ enum station_parameters_apply_mask { · 497 unmodified lines | |||
| 498 | * @plink_action: plink action to take | 498 | * @plink_action: plink action to take |
| 499 | * @plink_state: set the peer link state for a station | 499 | * @plink_state: set the peer link state for a station |
| 500 | * @ht_capa: HT capabilities of station | 500 | * @ht_capa: HT capabilities of station |
| 501 | * @vht_capa: VHT capabilities of station | ||
| 501 | * @uapsd_queues: bitmap of queues configured for uapsd. same format | 502 | * @uapsd_queues: bitmap of queues configured for uapsd. same format |
| 502 | * as the AC bitmap in the QoS info field | 503 | * as the AC bitmap in the QoS info field |
| 503 | * @max_sp: max Service Period. same format as the MAX_SP in the | 504 | * @max_sp: max Service Period. same format as the MAX_SP in the |
| @@ -517,6 +518,7 @@ struct station_parameters { · 13 unmodified lines | |||
| 517 | u8 plink_action; | 518 | u8 plink_action; |
| 518 | u8 plink_state; | 519 | u8 plink_state; |
| 519 | struct ieee80211_ht_cap *ht_capa; | 520 | struct ieee80211_ht_cap *ht_capa; |
| 521 | struct ieee80211_vht_cap *vht_capa; | ||
| 520 | u8 uapsd_queues; | 522 | u8 uapsd_queues; |
| 521 | u8 max_sp; | 523 | u8 max_sp; |
| 522 | }; | 524 | }; |
| @@ -1000,8 +1002,10 @@ struct cfg80211_ssid { · 477 unmodified lines | |||
| 1000 | * @n_channels: total number of channels to scan | 1002 | * @n_channels: total number of channels to scan |
| 1001 | * @ie: optional information element(s) to add into Probe Request or %NULL | 1003 | * @ie: optional information element(s) to add into Probe Request or %NULL |
| 1002 | * @ie_len: length of ie in octets | 1004 | * @ie_len: length of ie in octets |
| 1005 | * @flags: bit field of flags controlling operation | ||
| 1003 | * @rates: bitmap of rates to advertise for each band | 1006 | * @rates: bitmap of rates to advertise for each band |
| 1004 | * @wiphy: the wiphy this was for | 1007 | * @wiphy: the wiphy this was for |
| 1008 | * @scan_start: time (in jiffies) when the scan started | ||
| 1005 | * @wdev: the wireless device to scan for | 1009 | * @wdev: the wireless device to scan for |
| 1006 | * @aborted: (internal) scan request was notified as aborted | 1010 | * @aborted: (internal) scan request was notified as aborted |
| 1007 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band | 1011 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band |
| @@ -1012,6 +1016,7 @@ struct cfg80211_scan_request { · 4 unmodified lines | |||
| 1012 | u32 n_channels; | 1016 | u32 n_channels; |
| 1013 | const u8 *ie; | 1017 | const u8 *ie; |
| 1014 | size_t ie_len; | 1018 | size_t ie_len; |
| 1019 | u32 flags; | ||
| 1015 | 1020 | ||
| 1016 | u32 rates[IEEE80211_NUM_BANDS]; | 1021 | u32 rates[IEEE80211_NUM_BANDS]; |
| 1017 | 1022 | ||
| @@ -1019,6 +1024,7 @@ struct cfg80211_scan_request { · 1 unmodified line | |||
| 1019 | 1024 | ||
| 1020 | /* internal */ | 1025 | /* internal */ |
| 1021 | struct wiphy *wiphy; | 1026 | struct wiphy *wiphy; |
| 1027 | unsigned long scan_start; | ||
| 1022 | bool aborted; | 1028 | bool aborted; |
| 1023 | bool no_cck; | 1029 | bool no_cck; |
| 1024 | 1030 | ||
| @@ -1044,6 +1050,7 @@ struct cfg80211_match_set { · 19 unmodified lines | |||
| 1044 | * @interval: interval between each scheduled scan cycle | 1050 | * @interval: interval between each scheduled scan cycle |
| 1045 | * @ie: optional information element(s) to add into Probe Request or %NULL | 1051 | * @ie: optional information element(s) to add into Probe Request or %NULL |
| 1046 | * @ie_len: length of ie in octets | 1052 | * @ie_len: length of ie in octets |
| 1053 | * @flags: bit field of flags controlling operation | ||
| 1047 | * @match_sets: sets of parameters to be matched for a scan result | 1054 | * @match_sets: sets of parameters to be matched for a scan result |
| 1048 | * entry to be considered valid and to be passed to the host | 1055 | * entry to be considered valid and to be passed to the host |
| 1049 | * (others are filtered out). | 1056 | * (others are filtered out). |
| @@ -1061,6 +1068,7 @@ struct cfg80211_sched_scan_request { · 11 unmodified lines | |||
| 1061 | u32 interval; | 1068 | u32 interval; |
| 1062 | const u8 *ie; | 1069 | const u8 *ie; |
| 1063 | size_t ie_len; | 1070 | size_t ie_len; |
| 1071 | u32 flags; | ||
| 1064 | struct cfg80211_match_set *match_sets; | 1072 | struct cfg80211_match_set *match_sets; |
| 1065 | int n_match_sets; | 1073 | int n_match_sets; |
| 1066 | s32 rssi_thold; | 1074 | s32 rssi_thold; |
| @@ -1068,6 +1076,7 @@ struct cfg80211_sched_scan_request { · 1 unmodified line | |||
| 1068 | /* internal */ | 1076 | /* internal */ |
| 1069 | struct wiphy *wiphy; | 1077 | struct wiphy *wiphy; |
| 1070 | struct net_device *dev; | 1078 | struct net_device *dev; |
| 1079 | unsigned long scan_start; | ||
| 1071 | 1080 | ||
| 1072 | /* keep last */ | 1081 | /* keep last */ |
| 1073 | struct ieee80211_channel *channels[0]; | 1082 | struct ieee80211_channel *channels[0]; |
| @@ -1152,6 +1161,9 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); · 78 unmodified lines | |||
| 1152 | * @key_len: length of WEP key for shared key authentication | 1161 | * @key_len: length of WEP key for shared key authentication |
| 1153 | * @key_idx: index of WEP key for shared key authentication | 1162 | * @key_idx: index of WEP key for shared key authentication |
| 1154 | * @key: WEP key for shared key authentication | 1163 | * @key: WEP key for shared key authentication |
| 1164 | * @sae_data: Non-IE data to use with SAE or %NULL. This starts with | ||
| 1165 | * Authentication transaction sequence number field. | ||
| 1166 | * @sae_data_len: Length of sae_data buffer in octets | ||
| 1155 | */ | 1167 | */ |
| 1156 | struct cfg80211_auth_request { | 1168 | struct cfg80211_auth_request { |
| 1157 | struct cfg80211_bss *bss; | 1169 | struct cfg80211_bss *bss; |
| @@ -1160,6 +1172,8 @@ struct cfg80211_auth_request { · 2 unmodified lines | |||
| 1160 | enum nl80211_auth_type auth_type; | 1172 | enum nl80211_auth_type auth_type; |
| 1161 | const u8 *key; | 1173 | const u8 *key; |
| 1162 | u8 key_len, key_idx; | 1174 | u8 key_len, key_idx; |
| 1175 | const u8 *sae_data; | ||
| 1176 | size_t sae_data_len; | ||
| 1163 | }; | 1177 | }; |
| 1164 | 1178 | ||
| 1165 | /** | 1179 | /** |
| @@ -143,6 +143,41 @@ struct ieee80211_low_level_stats { · 142 unmodified lines | |||
| 143 | unsigned int dot11RTSSuccessCount; | 143 | unsigned int dot11RTSSuccessCount; |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | /** | ||
| 147 | * enum ieee80211_chanctx_change - change flag for channel context | ||
| 148 | * @IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE: The channel type was changed | ||
| 149 | * @IEEE80211_CHANCTX_CHANGE_RX_CHAINS: The number of RX chains changed | ||
| 150 | */ | ||
| 151 | enum ieee80211_chanctx_change { | ||
| 152 | IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE = BIT(0), | ||
| 153 | IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), | ||
| 154 | }; | ||
| 155 | |||
| 156 | /** | ||
| 157 | * struct ieee80211_chanctx_conf - channel context that vifs may be tuned to | ||
| 158 | * | ||
| 159 | * This is the driver-visible part. The ieee80211_chanctx | ||
| 160 | * that contains it is visible in mac80211 only. | ||
| 161 | * | ||
| 162 | * @channel: the channel to tune to | ||
| 163 | * @channel_type: the channel (HT) type | ||
| 164 | * @rx_chains_static: The number of RX chains that must always be | ||
| 165 | * active on the channel to receive MIMO transmissions | ||
| 166 | * @rx_chains_dynamic: The number of RX chains that must be enabled | ||
| 167 | * after RTS/CTS handshake to receive SMPS MIMO transmissions; | ||
| 168 | * this will always be >= @rx_chains_always. | ||
| 169 | * @drv_priv: data area for driver use, will always be aligned to | ||
| 170 | * sizeof(void *), size is determined in hw information. | ||
| 171 | */ | ||
| 172 | struct ieee80211_chanctx_conf { | ||
| 173 | struct ieee80211_channel *channel; | ||
| 174 | enum nl80211_channel_type channel_type; | ||
| 175 | |||
| 176 | u8 rx_chains_static, rx_chains_dynamic; | ||
| 177 | |||
| 178 | u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); | ||
| 179 | }; | ||
| 180 | |||
| 146 | /** | 181 | /** |
| 147 | * enum ieee80211_bss_change - BSS change notification flags | 182 | * enum ieee80211_bss_change - BSS change notification flags |
| 148 | * | 183 | * |
| @@ -223,6 +258,7 @@ enum ieee80211_rssi_event { · 74 unmodified lines | |||
| 223 | * @assoc: association status | 258 | * @assoc: association status |
| 224 | * @ibss_joined: indicates whether this station is part of an IBSS | 259 | * @ibss_joined: indicates whether this station is part of an IBSS |
| 225 | * or not | 260 | * or not |
| 261 | * @ibss_creator: indicates if a new IBSS network is being created | ||
| 226 | * @aid: association ID number, valid only when @assoc is true | 262 | * @aid: association ID number, valid only when @assoc is true |
| 227 | * @use_cts_prot: use CTS protection | 263 | * @use_cts_prot: use CTS protection |
| 228 | * @use_short_preamble: use 802.11b short preamble; | 264 | * @use_short_preamble: use 802.11b short preamble; |
| @@ -278,6 +314,7 @@ struct ieee80211_bss_conf { · 49 unmodified lines | |||
| 278 | const u8 *bssid; | 314 | const u8 *bssid; |
| 279 | /* association related data */ | 315 | /* association related data */ |
| 280 | bool assoc, ibss_joined; | 316 | bool assoc, ibss_joined; |
| 317 | bool ibss_creator; | ||
| 281 | u16 aid; | 318 | u16 aid; |
| 282 | /* erp related data */ | 319 | /* erp related data */ |
| 283 | bool use_cts_prot; | 320 | bool use_cts_prot; |
| @@ -794,6 +831,8 @@ enum ieee80211_conf_flags { · 510 unmodified lines | |||
| 794 | * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed | 831 | * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed |
| 795 | * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed | 832 | * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed |
| 796 | * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed | 833 | * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed |
| 834 | * Note that this is only valid if channel contexts are not used, | ||
| 835 | * otherwise each channel context has the number of chains listed. | ||
| 797 | */ | 836 | */ |
| 798 | enum ieee80211_conf_changed { | 837 | enum ieee80211_conf_changed { |
| 799 | IEEE80211_CONF_CHANGE_SMPS = BIT(1), | 838 | IEEE80211_CONF_CHANGE_SMPS = BIT(1), |
| @@ -859,7 +898,9 @@ enum ieee80211_smps_mode { · 59 unmodified lines | |||
| 859 | * | 898 | * |
| 860 | * @smps_mode: spatial multiplexing powersave mode; note that | 899 | * @smps_mode: spatial multiplexing powersave mode; note that |
| 861 | * %IEEE80211_SMPS_STATIC is used when the device is not | 900 | * %IEEE80211_SMPS_STATIC is used when the device is not |
| 862 | * configured for an HT channel | 901 | * configured for an HT channel. |
| 902 | * Note that this is only valid if channel contexts are not used, | ||
| 903 | * otherwise each channel context has the number of chains listed. | ||
| 863 | */ | 904 | */ |
| 864 | struct ieee80211_conf { | 905 | struct ieee80211_conf { |
| 865 | u32 flags; | 906 | u32 flags; |
| @@ -931,6 +972,11 @@ enum ieee80211_vif_flags { · 65 unmodified lines | |||
| 931 | * at runtime, mac80211 will never touch this field | 972 | * at runtime, mac80211 will never touch this field |
| 932 | * @hw_queue: hardware queue for each AC | 973 | * @hw_queue: hardware queue for each AC |
| 933 | * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only | 974 | * @cab_queue: content-after-beacon (DTIM beacon really) queue, AP mode only |
| 975 | * @chanctx_conf: The channel context this interface is assigned to, or %NULL | ||
| 976 | * when it is not assigned. This pointer is RCU-protected due to the TX | ||
| 977 | * path needing to access it; even though the netdev carrier will always | ||
| 978 | * be off when it is %NULL there can still be races and packets could be | ||
| 979 | * processed after it switches back to %NULL. | ||
| 934 | * @drv_priv: data area for driver use, will always be aligned to | 980 | * @drv_priv: data area for driver use, will always be aligned to |
| 935 | * sizeof(void *). | 981 | * sizeof(void *). |
| 936 | */ | 982 | */ |
| @@ -943,6 +989,8 @@ struct ieee80211_vif { · 6 unmodified lines | |||
| 943 | u8 cab_queue; | 989 | u8 cab_queue; |
| 944 | u8 hw_queue[IEEE80211_NUM_ACS]; | 990 | u8 hw_queue[IEEE80211_NUM_ACS]; |
| 945 | 991 | ||
| 992 | struct ieee80211_chanctx_conf __rcu *chanctx_conf; | ||
| 993 | |||
| 946 | u32 driver_flags; | 994 | u32 driver_flags; |
| 947 | 995 | ||
| 948 | /* must be last */ | 996 | /* must be last */ |
| @@ -1076,6 +1124,8 @@ enum ieee80211_sta_state { · 127 unmodified lines | |||
| 1076 | * @aid: AID we assigned to the station if we're an AP | 1124 | * @aid: AID we assigned to the station if we're an AP |
| 1077 | * @supp_rates: Bitmap of supported rates (per band) | 1125 | * @supp_rates: Bitmap of supported rates (per band) |
| 1078 | * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities | 1126 | * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities |
| 1127 | * @vht_cap: VHT capabilities of this STA; Not restricting any capabilities | ||
| 1128 | * of remote STA. Taking as is. | ||
| 1079 | * @wme: indicates whether the STA supports WME. Only valid during AP-mode. | 1129 | * @wme: indicates whether the STA supports WME. Only valid during AP-mode. |
| 1080 | * @drv_priv: data area for driver use, will always be aligned to | 1130 | * @drv_priv: data area for driver use, will always be aligned to |
| 1081 | * sizeof(void *), size is determined in hw information. | 1131 | * sizeof(void *), size is determined in hw information. |
| @@ -1088,6 +1138,7 @@ struct ieee80211_sta { · 6 unmodified lines | |||
| 1088 | u8 addr[ETH_ALEN]; | 1138 | u8 addr[ETH_ALEN]; |
| 1089 | u16 aid; | 1139 | u16 aid; |
| 1090 | struct ieee80211_sta_ht_cap ht_cap; | 1140 | struct ieee80211_sta_ht_cap ht_cap; |
| 1141 | struct ieee80211_sta_vht_cap vht_cap; | ||
| 1091 | bool wme; | 1142 | bool wme; |
| 1092 | u8 uapsd_queues; | 1143 | u8 uapsd_queues; |
| 1093 | u8 max_sp; | 1144 | u8 max_sp; |
| @@ -1325,6 +1376,8 @@ enum ieee80211_hw_flags { · 231 unmodified lines | |||
| 1325 | * within &struct ieee80211_vif. | 1376 | * within &struct ieee80211_vif. |
| 1326 | * @sta_data_size: size (in bytes) of the drv_priv data area | 1377 | * @sta_data_size: size (in bytes) of the drv_priv data area |
| 1327 | * within &struct ieee80211_sta. | 1378 | * within &struct ieee80211_sta. |
| 1379 | * @chanctx_data_size: size (in bytes) of the drv_priv data area | ||
| 1380 | * within &struct ieee80211_chanctx_conf. | ||
| 1328 | * | 1381 | * |
| 1329 | * @max_rates: maximum number of alternate rate retry stages the hw | 1382 | * @max_rates: maximum number of alternate rate retry stages the hw |
| 1330 | * can handle. | 1383 | * can handle. |
| @@ -1369,6 +1422,7 @@ struct ieee80211_hw { · 38 unmodified lines | |||
| 1369 | int channel_change_time; | 1422 | int channel_change_time; |
| 1370 | int vif_data_size; | 1423 | int vif_data_size; |
| 1371 | int sta_data_size; | 1424 | int sta_data_size; |
| 1425 | int chanctx_data_size; | ||
| 1372 | int napi_weight; | 1426 | int napi_weight; |
| 1373 | u16 queues; | 1427 | u16 queues; |
| 1374 | u16 max_listen_interval; | 1428 | u16 max_listen_interval; |
| @@ -2317,6 +2371,16 @@ enum ieee80211_rate_control_changed { · 942 unmodified lines | |||
| 2317 | * The callback will be called before each transmission and upon return | 2371 | * The callback will be called before each transmission and upon return |
| 2318 | * mac80211 will transmit the frame right away. | 2372 | * mac80211 will transmit the frame right away. |
| 2319 | * The callback is optional and can (should!) sleep. | 2373 | * The callback is optional and can (should!) sleep. |
| 2374 | * | ||
| 2375 | * @add_chanctx: Notifies device driver about new channel context creation. | ||
| 2376 | * @remove_chanctx: Notifies device driver about channel context destruction. | ||
| 2377 | * @change_chanctx: Notifies device driver about channel context changes that | ||
| 2378 | * may happen when combining different virtual interfaces on the same | ||
| 2379 | * channel context with different settings | ||
| 2380 | * @assign_vif_chanctx: Notifies device driver about channel context being bound | ||
| 2381 | * to vif. Possible use is for hw queue remapping. | ||
| 2382 | * @unassign_vif_chanctx: Notifies device driver about channel context being | ||
| 2383 | * unbound from vif. | ||
| 2320 | */ | 2384 | */ |
| 2321 | struct ieee80211_ops { | 2385 | struct ieee80211_ops { |
| 2322 | void (*tx)(struct ieee80211_hw *hw, | 2386 | void (*tx)(struct ieee80211_hw *hw, |
| @@ -2461,6 +2525,20 @@ struct ieee80211_ops { · 138 unmodified lines | |||
| 2461 | 2525 | ||
| 2462 | void (*mgd_prepare_tx)(struct ieee80211_hw *hw, | 2526 | void (*mgd_prepare_tx)(struct ieee80211_hw *hw, |
| 2463 | struct ieee80211_vif *vif); | 2527 | struct ieee80211_vif *vif); |
| 2528 | |||
| 2529 | int (*add_chanctx)(struct ieee80211_hw *hw, | ||
| 2530 | struct ieee80211_chanctx_conf *ctx); | ||
| 2531 | void (*remove_chanctx)(struct ieee80211_hw *hw, | ||
| 2532 | struct ieee80211_chanctx_conf *ctx); | ||
| 2533 | void (*change_chanctx)(struct ieee80211_hw *hw, | ||
| 2534 | struct ieee80211_chanctx_conf *ctx, | ||
| 2535 | u32 changed); | ||
| 2536 | int (*assign_vif_chanctx)(struct ieee80211_hw *hw, | ||
| 2537 | struct ieee80211_vif *vif, | ||
| 2538 | struct ieee80211_chanctx_conf *ctx); | ||
| 2539 | void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, | ||
| 2540 | struct ieee80211_vif *vif, | ||
| 2541 | struct ieee80211_chanctx_conf *ctx); | ||
| 2464 | }; | 2542 | }; |
| 2465 | 2543 | ||
| 2466 | /** | 2544 | /** |
| @@ -3144,6 +3222,19 @@ void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf, · 677 unmodified lines | |||
| 3144 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, | 3222 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, |
| 3145 | struct sk_buff *skb, u8 *p2k); | 3223 | struct sk_buff *skb, u8 *p2k); |
| 3146 | 3224 | ||
| 3225 | /** | ||
| 3226 | * ieee80211_aes_cmac_calculate_k1_k2 - calculate the AES-CMAC sub keys | ||
| 3227 | * | ||
| 3228 | * This function computes the two AES-CMAC sub-keys, based on the | ||
| 3229 | * previously installed master key. | ||
| 3230 | * | ||
| 3231 | * @keyconf: the parameter passed with the set key | ||
| 3232 | * @k1: a buffer to be filled with the 1st sub-key | ||
| 3233 | * @k2: a buffer to be filled with the 2nd sub-key | ||
| 3234 | */ | ||
| 3235 | void ieee80211_aes_cmac_calculate_k1_k2(struct ieee80211_key_conf *keyconf, | ||
| 3236 | u8 *k1, u8 *k2); | ||
| 3237 | |||
| 3147 | /** | 3238 | /** |
| 3148 | * struct ieee80211_key_seq - key sequence counter | 3239 | * struct ieee80211_key_seq - key sequence counter |
| 3149 | * | 3240 | * |
| @@ -3523,6 +3614,27 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, · 373 unmodified lines | |||
| 3523 | void *data), | 3614 | void *data), |
| 3524 | void *iter_data); | 3615 | void *iter_data); |
| 3525 | 3616 | ||
| 3617 | /** | ||
| 3618 | * ieee80211_iter_chan_contexts_atomic - iterate channel contexts | ||
| 3619 | * @hw: pointre obtained from ieee80211_alloc_hw(). | ||
| 3620 | * @iter: iterator function | ||
| 3621 | * @iter_data: data passed to iterator function | ||
| 3622 | * | ||
| 3623 | * Iterate all active channel contexts. This function is atomic and | ||
| 3624 | * doesn't acquire any locks internally that might be held in other | ||
| 3625 | * places while calling into the driver. | ||
| 3626 | * | ||
| 3627 | * The iterator will not find a context that's being added (during | ||
| 3628 | * the driver callback to add it) but will find it while it's being | ||
| 3629 | * removed. | ||
| 3630 | */ | ||
| 3631 | void ieee80211_iter_chan_contexts_atomic( | ||
| 3632 | struct ieee80211_hw *hw, | ||
| 3633 | void (*iter)(struct ieee80211_hw *hw, | ||
| 3634 | struct ieee80211_chanctx_conf *chanctx_conf, | ||
| 3635 | void *data), | ||
| 3636 | void *iter_data); | ||
| 3637 | |||
| 3526 | /** | 3638 | /** |
| 3527 | * ieee80211_ap_probereq_get - retrieve a Probe Request template | 3639 | * ieee80211_ap_probereq_get - retrieve a Probe Request template |
| 3528 | * @hw: pointer obtained from ieee80211_alloc_hw(). | 3640 | * @hw: pointer obtained from ieee80211_alloc_hw(). |
| @@ -24,6 +24,12 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | #include <net/nfc/nfc.h> | 25 | #include <net/nfc/nfc.h> |
| 26 | 26 | ||
| 27 | struct nfc_phy_ops { | ||
| 28 | int (*write)(void *dev_id, struct sk_buff *skb); | ||
| 29 | int (*enable)(void *dev_id); | ||
| 30 | void (*disable)(void *dev_id); | ||
| 31 | }; | ||
| 32 | |||
| 27 | struct nfc_hci_dev; | 33 | struct nfc_hci_dev; |
| 28 | 34 | ||
| 29 | struct nfc_hci_ops { | 35 | struct nfc_hci_ops { |
| @@ -38,15 +44,21 @@ struct nfc_hci_ops { · 8 unmodified lines | |||
| 38 | int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); | 44 | int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); |
| 39 | int (*start_poll) (struct nfc_hci_dev *hdev, | 45 | int (*start_poll) (struct nfc_hci_dev *hdev, |
| 40 | u32 im_protocols, u32 tm_protocols); | 46 | u32 im_protocols, u32 tm_protocols); |
| 47 | int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target, | ||
| 48 | u8 comm_mode, u8 *gb, size_t gb_len); | ||
| 49 | int (*dep_link_down)(struct nfc_hci_dev *hdev); | ||
| 41 | int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, | 50 | int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate, |
| 42 | struct nfc_target *target); | 51 | struct nfc_target *target); |
| 43 | int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, | 52 | int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate, |
| 44 | struct nfc_target *target); | 53 | struct nfc_target *target); |
| 45 | int (*data_exchange) (struct nfc_hci_dev *hdev, | 54 | int (*im_transceive) (struct nfc_hci_dev *hdev, |
| 46 | struct nfc_target *target, struct sk_buff *skb, | 55 | struct nfc_target *target, struct sk_buff *skb, |
| 47 | data_exchange_cb_t cb, void *cb_context); | 56 | data_exchange_cb_t cb, void *cb_context); |
| 57 | int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb); | ||
| 48 | int (*check_presence)(struct nfc_hci_dev *hdev, | 58 | int (*check_presence)(struct nfc_hci_dev *hdev, |
| 49 | struct nfc_target *target); | 59 | struct nfc_target *target); |
| 60 | void (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event, | ||
| 61 | struct sk_buff *skb); | ||
| 50 | }; | 62 | }; |
| 51 | 63 | ||
| 52 | /* Pipes */ | 64 | /* Pipes */ |
| @@ -114,6 +126,9 @@ struct nfc_hci_dev { · 61 unmodified lines | |||
| 114 | int async_cb_type; | 126 | int async_cb_type; |
| 115 | data_exchange_cb_t async_cb; | 127 | data_exchange_cb_t async_cb; |
| 116 | void *async_cb_context; | 128 | void *async_cb_context; |
| 129 | |||
| 130 | u8 *gb; | ||
| 131 | size_t gb_len; | ||
| 117 | }; | 132 | }; |
| 118 | 133 | ||
| 119 | /* hci device allocation */ | 134 | /* hci device allocation */ |
| @@ -219,5 +234,6 @@ int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, · 99 unmodified lines | |||
| 219 | const u8 *param, size_t param_len); | 234 | const u8 *param, size_t param_len); |
| 220 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, | 235 | int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, |
| 221 | const u8 *param, size_t param_len); | 236 | const u8 *param, size_t param_len); |
| 237 | int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); | ||
| 222 | 238 | ||
| 223 | #endif /* __NET_HCI_H */ | 239 | #endif /* __NET_HCI_H */ |
| @@ -95,7 +95,7 @@ struct nfc_genl_data { · 94 unmodified lines | |||
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | struct nfc_dev { | 97 | struct nfc_dev { |
| 98 | unsigned int idx; | 98 | int idx; |
| 99 | u32 target_next_idx; | 99 | u32 target_next_idx; |
| 100 | struct nfc_target *targets; | 100 | struct nfc_target *targets; |
| 101 | int n_targets; | 101 | int n_targets; |
| @@ -60,6 +60,13 @@ · 59 unmodified lines | |||
| 60 | * target mode. | 60 | * target mode. |
| 61 | * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated | 61 | * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated |
| 62 | * from target mode. | 62 | * from target mode. |
| 63 | * @NFC_CMD_LLC_GET_PARAMS: request LTO, RW, and MIUX parameters for a device | ||
| 64 | * @NFC_CMD_LLC_SET_PARAMS: set one or more of LTO, RW, and MIUX parameters for | ||
| 65 | * a device. LTO must be set before the link is up otherwise -EINPROGRESS | ||
| 66 | * is returned. RW and MIUX can be set at anytime and will be passed in | ||
| 67 | * subsequent CONNECT and CC messages. | ||
| 68 | * If one of the passed parameters is wrong none is set and -EINVAL is | ||
| 69 | * returned. | ||
| 63 | */ | 70 | */ |
| 64 | enum nfc_commands { | 71 | enum nfc_commands { |
| 65 | NFC_CMD_UNSPEC, | 72 | NFC_CMD_UNSPEC, |
| @@ -77,6 +84,8 @@ enum nfc_commands { · 11 unmodified lines | |||
| 77 | NFC_EVENT_TARGET_LOST, | 84 | NFC_EVENT_TARGET_LOST, |
| 78 | NFC_EVENT_TM_ACTIVATED, | 85 | NFC_EVENT_TM_ACTIVATED, |
| 79 | NFC_EVENT_TM_DEACTIVATED, | 86 | NFC_EVENT_TM_DEACTIVATED, |
| 87 | NFC_CMD_LLC_GET_PARAMS, | ||
| 88 | NFC_CMD_LLC_SET_PARAMS, | ||
| 80 | /* private: internal use only */ | 89 | /* private: internal use only */ |
| 81 | __NFC_CMD_AFTER_LAST | 90 | __NFC_CMD_AFTER_LAST |
| 82 | }; | 91 | }; |
| @@ -102,6 +111,9 @@ enum nfc_commands { · 19 unmodified lines | |||
| 102 | * @NFC_ATTR_RF_MODE: Initiator or target | 111 | * @NFC_ATTR_RF_MODE: Initiator or target |
| 103 | * @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for | 112 | * @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for |
| 104 | * @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for | 113 | * @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for |
| 114 | * @NFC_ATTR_LLC_PARAM_LTO: Link TimeOut parameter | ||
| 115 | * @NFC_ATTR_LLC_PARAM_RW: Receive Window size parameter | ||
| 116 | * @NFC_ATTR_LLC_PARAM_MIUX: MIU eXtension parameter | ||
| 105 | */ | 117 | */ |
| 106 | enum nfc_attrs { | 118 | enum nfc_attrs { |
| 107 | NFC_ATTR_UNSPEC, | 119 | NFC_ATTR_UNSPEC, |
| @@ -119,6 +131,9 @@ enum nfc_attrs { · 11 unmodified lines | |||
| 119 | NFC_ATTR_DEVICE_POWERED, | 131 | NFC_ATTR_DEVICE_POWERED, |
| 120 | NFC_ATTR_IM_PROTOCOLS, | 132 | NFC_ATTR_IM_PROTOCOLS, |
| 121 | NFC_ATTR_TM_PROTOCOLS, | 133 | NFC_ATTR_TM_PROTOCOLS, |
| 134 | NFC_ATTR_LLC_PARAM_LTO, | ||
| 135 | NFC_ATTR_LLC_PARAM_RW, | ||
| 136 | NFC_ATTR_LLC_PARAM_MIUX, | ||
| 122 | /* private: internal use only */ | 137 | /* private: internal use only */ |
| 123 | __NFC_ATTR_AFTER_LAST | 138 | __NFC_ATTR_AFTER_LAST |
| 124 | }; | 139 | }; |
| @@ -1273,6 +1273,14 @@ enum nl80211_commands { · 1272 unmodified lines | |||
| 1273 | * the connection request from a station. nl80211_connect_failed_reason | 1273 | * the connection request from a station. nl80211_connect_failed_reason |
| 1274 | * enum has different reasons of connection failure. | 1274 | * enum has different reasons of connection failure. |
| 1275 | * | 1275 | * |
| 1276 | * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts | ||
| 1277 | * with the Authentication transaction sequence number field. | ||
| 1278 | * | ||
| 1279 | * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from | ||
| 1280 | * association request when used with NL80211_CMD_NEW_STATION) | ||
| 1281 | * | ||
| 1282 | * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) | ||
| 1283 | * | ||
| 1276 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1284 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
| 1277 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1285 | * @__NL80211_ATTR_AFTER_LAST: internal use |
| 1278 | */ | 1286 | */ |
| @@ -1530,6 +1538,12 @@ enum nl80211_attrs { · 251 unmodified lines | |||
| 1530 | 1538 | ||
| 1531 | NL80211_ATTR_CONN_FAILED_REASON, | 1539 | NL80211_ATTR_CONN_FAILED_REASON, |
| 1532 | 1540 | ||
| 1541 | NL80211_ATTR_SAE_DATA, | ||
| 1542 | |||
| 1543 | NL80211_ATTR_VHT_CAPABILITY, | ||
| 1544 | |||
| 1545 | NL80211_ATTR_SCAN_FLAGS, | ||
| 1546 | |||
| 1533 | /* add attributes here, update the policy in nl80211.c */ | 1547 | /* add attributes here, update the policy in nl80211.c */ |
| 1534 | 1548 | ||
| 1535 | __NL80211_ATTR_AFTER_LAST, | 1549 | __NL80211_ATTR_AFTER_LAST, |
| @@ -1573,6 +1587,7 @@ enum nl80211_attrs { · 37 unmodified lines | |||
| 1573 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 | 1587 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 |
| 1574 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 | 1588 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 |
| 1575 | #define NL80211_HT_CAPABILITY_LEN 26 | 1589 | #define NL80211_HT_CAPABILITY_LEN 26 |
| 1590 | #define NL80211_VHT_CAPABILITY_LEN 12 | ||
| 1576 | 1591 | ||
| 1577 | #define NL80211_MAX_NR_CIPHER_SUITES 5 | 1592 | #define NL80211_MAX_NR_CIPHER_SUITES 5 |
| 1578 | #define NL80211_MAX_NR_AKM_SUITES 2 | 1593 | #define NL80211_MAX_NR_AKM_SUITES 2 |
| @@ -2489,6 +2504,7 @@ enum nl80211_bss_status { · 910 unmodified lines | |||
| 2489 | * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) | 2504 | * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) |
| 2490 | * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) | 2505 | * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) |
| 2491 | * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) | 2506 | * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) |
| 2507 | * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals | ||
| 2492 | * @__NL80211_AUTHTYPE_NUM: internal | 2508 | * @__NL80211_AUTHTYPE_NUM: internal |
| 2493 | * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm | 2509 | * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm |
| 2494 | * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by | 2510 | * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by |
| @@ -2500,6 +2516,7 @@ enum nl80211_auth_type { · 5 unmodified lines | |||
| 2500 | NL80211_AUTHTYPE_SHARED_KEY, | 2516 | NL80211_AUTHTYPE_SHARED_KEY, |
| 2501 | NL80211_AUTHTYPE_FT, | 2517 | NL80211_AUTHTYPE_FT, |
| 2502 | NL80211_AUTHTYPE_NETWORK_EAP, | 2518 | NL80211_AUTHTYPE_NETWORK_EAP, |
| 2519 | NL80211_AUTHTYPE_SAE, | ||
| 2503 | 2520 | ||
| 2504 | /* keep last */ | 2521 | /* keep last */ |
| 2505 | __NL80211_AUTHTYPE_NUM, | 2522 | __NL80211_AUTHTYPE_NUM, |
| @@ -3028,6 +3045,12 @@ enum nl80211_ap_sme_features { · 522 unmodified lines | |||
| 3028 | * in the interface combinations, even when it's only used for scan | 3045 | * in the interface combinations, even when it's only used for scan |
| 3029 | * and remain-on-channel. This could be due to, for example, the | 3046 | * and remain-on-channel. This could be due to, for example, the |
| 3030 | * remain-on-channel implementation requiring a channel context. | 3047 | * remain-on-channel implementation requiring a channel context. |
| 3048 | * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of | ||
| 3049 | * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station | ||
| 3050 | * mode | ||
| 3051 | * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan | ||
| 3052 | * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported | ||
| 3053 | * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif | ||
| 3031 | */ | 3054 | */ |
| 3032 | enum nl80211_feature_flags { | 3055 | enum nl80211_feature_flags { |
| 3033 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 3056 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
| @@ -3035,6 +3058,10 @@ enum nl80211_feature_flags { · 1 unmodified line | |||
| 3035 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3058 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
| 3036 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | 3059 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, |
| 3037 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, | 3060 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, |
| 3061 | NL80211_FEATURE_SAE = 1 << 5, | ||
| 3062 | NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, | ||
| 3063 | NL80211_FEATURE_SCAN_FLUSH = 1 << 7, | ||
| 3064 | NL80211_FEATURE_AP_SCAN = 1 << 8, | ||
| 3038 | }; | 3065 | }; |
| 3039 | 3066 | ||
| 3040 | /** | 3067 | /** |
| @@ -3069,4 +3096,25 @@ enum nl80211_connect_failed_reason { · 28 unmodified lines | |||
| 3069 | NL80211_CONN_FAIL_BLOCKED_CLIENT, | 3096 | NL80211_CONN_FAIL_BLOCKED_CLIENT, |
| 3070 | }; | 3097 | }; |
| 3071 | 3098 | ||
| 3099 | /** | ||
| 3100 | * enum nl80211_scan_flags - scan request control flags | ||
| 3101 | * | ||
| 3102 | * Scan request control flags are used to control the handling | ||
| 3103 | * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN | ||
| 3104 | * requests. | ||
| 3105 | * | ||
| 3106 | * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority | ||
| 3107 | * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning | ||
| 3108 | * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured | ||
| 3109 | * as AP and the beaconing has already been configured. This attribute is | ||
| 3110 | * dangerous because will destroy stations performance as a lot of frames | ||
| 3111 | * will be lost while scanning off-channel, therefore it must be used only | ||
| 3112 | * when really needed | ||
| 3113 | */ | ||
| 3114 | enum nl80211_scan_flags { | ||
| 3115 | NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, | ||
| 3116 | NL80211_SCAN_FLAG_FLUSH = 1<<1, | ||
| 3117 | NL80211_SCAN_FLAG_AP = 1<<2, | ||
| 3118 | }; | ||
| 3119 | |||
| 3072 | #endif /* __LINUX_NL80211_H */ | 3120 | #endif /* __LINUX_NL80211_H */ |
| @@ -11,6 +11,7 @@ menuconfig BT · 10 unmodified lines | |||
| 11 | select CRYPTO_BLKCIPHER | 11 | select CRYPTO_BLKCIPHER |
| 12 | select CRYPTO_AES | 12 | select CRYPTO_AES |
| 13 | select CRYPTO_ECB | 13 | select CRYPTO_ECB |
| 14 | select CRYPTO_SHA256 | ||
| 14 | help | 15 | help |
| 15 | Bluetooth is low-cost, low-power, short-range wireless technology. | 16 | Bluetooth is low-cost, low-power, short-range wireless technology. |
| 16 | It was designed as a replacement for cables and other short-range | 17 | It was designed as a replacement for cables and other short-range |
| @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_HIDP) += hidp/ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ | 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ |
| 12 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ | 12 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ |
| 13 | a2mp.o | 13 | a2mp.o amp.o |
| @@ -16,6 +16,11 @@ · 15 unmodified lines | |||
| 16 | #include <net/bluetooth/hci_core.h> | 16 | #include <net/bluetooth/hci_core.h> |
| 17 | #include <net/bluetooth/l2cap.h> | 17 | #include <net/bluetooth/l2cap.h> |
| 18 | #include <net/bluetooth/a2mp.h> | 18 | #include <net/bluetooth/a2mp.h> |
| 19 | #include <net/bluetooth/amp.h> | ||
| 20 | |||
| 21 | /* Global AMP Manager list */ | ||
| 22 | LIST_HEAD(amp_mgr_list); | ||
| 23 | DEFINE_MUTEX(amp_mgr_list_lock); | ||
| 19 | 24 | ||
| 20 | /* A2MP build & send command helper functions */ | 25 | /* A2MP build & send command helper functions */ |
| 21 | static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) | 26 | static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) |
| @@ -37,8 +42,7 @@ static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) · 15 unmodified lines | |||
| 37 | return cmd; | 42 | return cmd; |
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, | 45 | void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data) |
| 41 | void *data) | ||
| 42 | { | 46 | { |
| 43 | struct l2cap_chan *chan = mgr->a2mp_chan; | 47 | struct l2cap_chan *chan = mgr->a2mp_chan; |
| 44 | struct a2mp_cmd *cmd; | 48 | struct a2mp_cmd *cmd; |
| @@ -63,6 +67,14 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, · 18 unmodified lines | |||
| 63 | kfree(cmd); | 67 | kfree(cmd); |
| 64 | } | 68 | } |
| 65 | 69 | ||
| 70 | u8 __next_ident(struct amp_mgr *mgr) | ||
| 71 | { | ||
| 72 | if (++mgr->ident == 0) | ||
| 73 | mgr->ident = 1; | ||
| 74 | |||
| 75 | return mgr->ident; | ||
| 76 | } | ||
| 77 | |||
| 66 | static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) | 78 | static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) |
| 67 | { | 79 | { |
| 68 | cl->id = 0; | 80 | cl->id = 0; |
| @@ -161,6 +173,83 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, · 92 unmodified lines | |||
| 161 | return 0; | 173 | return 0; |
| 162 | } | 174 | } |
| 163 | 175 | ||
| 176 | static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, | ||
| 177 | struct a2mp_cmd *hdr) | ||
| 178 | { | ||
| 179 | struct a2mp_discov_rsp *rsp = (void *) skb->data; | ||
| 180 | u16 len = le16_to_cpu(hdr->len); | ||
| 181 | struct a2mp_cl *cl; | ||
| 182 | u16 ext_feat; | ||
| 183 | bool found = false; | ||
| 184 | |||
| 185 | if (len < sizeof(*rsp)) | ||
| 186 | return -EINVAL; | ||
| 187 | |||
| 188 | len -= sizeof(*rsp); | ||
| 189 | skb_pull(skb, sizeof(*rsp)); | ||
| 190 | |||
| 191 | ext_feat = le16_to_cpu(rsp->ext_feat); | ||
| 192 | |||
| 193 | BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(rsp->mtu), ext_feat); | ||
| 194 | |||
| 195 | /* check that packet is not broken for now */ | ||
| 196 | while (ext_feat & A2MP_FEAT_EXT) { | ||
| 197 | if (len < sizeof(ext_feat)) | ||
| 198 | return -EINVAL; | ||
| 199 | |||
| 200 | ext_feat = get_unaligned_le16(skb->data); | ||
| 201 | BT_DBG("efm 0x%4.4x", ext_feat); | ||
| 202 | len -= sizeof(ext_feat); | ||
| 203 | skb_pull(skb, sizeof(ext_feat)); | ||
| 204 | } | ||
| 205 | |||
| 206 | cl = (void *) skb->data; | ||
| 207 | while (len >= sizeof(*cl)) { | ||
| 208 | BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type, | ||
| 209 | cl->status); | ||
| 210 | |||
| 211 | if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { | ||
| 212 | struct a2mp_info_req req; | ||
| 213 | |||
| 214 | found = true; | ||
| 215 | req.id = cl->id; | ||
| 216 | a2mp_send(mgr, A2MP_GETINFO_REQ, __next_ident(mgr), | ||
| 217 | sizeof(req), &req); | ||
| 218 | } | ||
| 219 | |||
| 220 | len -= sizeof(*cl); | ||
| 221 | cl = (void *) skb_pull(skb, sizeof(*cl)); | ||
| 222 | } | ||
| 223 | |||
| 224 | /* Fall back to L2CAP init sequence */ | ||
| 225 | if (!found) { | ||
| 226 | struct l2cap_conn *conn = mgr->l2cap_conn; | ||
| 227 | struct l2cap_chan *chan; | ||
| 228 | |||
| 229 | mutex_lock(&conn->chan_lock); | ||
| 230 | |||
| 231 | list_for_each_entry(chan, &conn->chan_l, list) { | ||
| 232 | |||
| 233 | BT_DBG("chan %p state %s", chan, | ||
| 234 | state_to_string(chan->state)); | ||
| 235 | |||
| 236 | if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) | ||
| 237 | continue; | ||
| 238 | |||
| 239 | l2cap_chan_lock(chan); | ||
| 240 | |||
| 241 | if (chan->state == BT_CONNECT) | ||
| 242 | l2cap_send_conn_req(chan); | ||
| 243 | |||
| 244 | l2cap_chan_unlock(chan); | ||
| 245 | } | ||
| 246 | |||
| 247 | mutex_unlock(&conn->chan_lock); | ||
| 248 | } | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 164 | static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, | 253 | static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, |
| 165 | struct a2mp_cmd *hdr) | 254 | struct a2mp_cmd *hdr) |
| 166 | { | 255 | { |
| @@ -181,7 +270,6 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, · 14 unmodified lines | |||
| 181 | struct a2mp_cmd *hdr) | 270 | struct a2mp_cmd *hdr) |
| 182 | { | 271 | { |
| 183 | struct a2mp_info_req *req = (void *) skb->data; | 272 | struct a2mp_info_req *req = (void *) skb->data; |
| 184 | struct a2mp_info_rsp rsp; | ||
| 185 | struct hci_dev *hdev; | 273 | struct hci_dev *hdev; |
| 186 | 274 | ||
| 187 | if (le16_to_cpu(hdr->len) < sizeof(*req)) | 275 | if (le16_to_cpu(hdr->len) < sizeof(*req)) |
| @@ -189,53 +277,93 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, · 1 unmodified line | |||
| 189 | 277 | ||
| 190 | BT_DBG("id %d", req->id); | 278 | BT_DBG("id %d", req->id); |
| 191 | 279 | ||
| 192 | rsp.id = req->id; | ||
| 193 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; | ||
| 194 | |||
| 195 | hdev = hci_dev_get(req->id); | 280 | hdev = hci_dev_get(req->id); |
| 196 | if (hdev && hdev->amp_type != HCI_BREDR) { | 281 | if (!hdev || hdev->dev_type != HCI_AMP) { |
| 197 | rsp.status = 0; | 282 | struct a2mp_info_rsp rsp; |
| 198 | rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); | 283 | |
| 199 | rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); | 284 | rsp.id = req->id; |
| 200 | rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); | 285 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; |
| 201 | rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); | 286 | |
| 202 | rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); | 287 | a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), |
| 288 | &rsp); | ||
| 289 | |||
| 290 | goto done; | ||
| 203 | } | 291 | } |
| 204 | 292 | ||
| 293 | mgr->state = READ_LOC_AMP_INFO; | ||
| 294 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); | ||
| 295 | |||
| 296 | done: | ||
| 205 | if (hdev) | 297 | if (hdev) |
| 206 | hci_dev_put(hdev); | 298 | hci_dev_put(hdev); |
| 207 | 299 | ||
| 208 | a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp); | ||
| 209 | |||
| 210 | skb_pull(skb, sizeof(*req)); | 300 | skb_pull(skb, sizeof(*req)); |
| 211 | return 0; | 301 | return 0; |
| 212 | } | 302 | } |
| 213 | 303 | ||
| 304 | static int a2mp_getinfo_rsp(struct amp_mgr *mgr, struct sk_buff *skb, | ||
| 305 | struct a2mp_cmd *hdr) | ||
| 306 | { | ||
| 307 | struct a2mp_info_rsp *rsp = (struct a2mp_info_rsp *) skb->data; | ||
| 308 | struct a2mp_amp_assoc_req req; | ||
| 309 | struct amp_ctrl *ctrl; | ||
| 310 | |||
| 311 | if (le16_to_cpu(hdr->len) < sizeof(*rsp)) | ||
| 312 | return -EINVAL; | ||
| 313 | |||
| 314 | BT_DBG("id %d status 0x%2.2x", rsp->id, rsp->status); | ||
| 315 | |||
| 316 | if (rsp->status) | ||
| 317 | return -EINVAL; | ||
| 318 | |||
| 319 | ctrl = amp_ctrl_add(mgr, rsp->id); | ||
| 320 | if (!ctrl) | ||
| 321 | return -ENOMEM; | ||
| 322 | |||
| 323 | req.id = rsp->id; | ||
| 324 | a2mp_send(mgr, A2MP_GETAMPASSOC_REQ, __next_ident(mgr), sizeof(req), | ||
| 325 | &req); | ||
| 326 | |||
| 327 | skb_pull(skb, sizeof(*rsp)); | ||
| 328 | return 0; | ||
| 329 | } | ||
| 330 | |||
| 214 | static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, | 331 | static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, |
| 215 | struct a2mp_cmd *hdr) | 332 | struct a2mp_cmd *hdr) |
| 216 | { | 333 | { |
| 217 | struct a2mp_amp_assoc_req *req = (void *) skb->data; | 334 | struct a2mp_amp_assoc_req *req = (void *) skb->data; |
| 218 | struct hci_dev *hdev; | 335 | struct hci_dev *hdev; |
| 336 | struct amp_mgr *tmp; | ||
| 219 | 337 | ||
| 220 | if (le16_to_cpu(hdr->len) < sizeof(*req)) | 338 | if (le16_to_cpu(hdr->len) < sizeof(*req)) |
| 221 | return -EINVAL; | 339 | return -EINVAL; |
| 222 | 340 | ||
| 223 | BT_DBG("id %d", req->id); | 341 | BT_DBG("id %d", req->id); |
| 224 | 342 | ||
| 343 | /* Make sure that other request is not processed */ | ||
| 344 | tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); | ||
| 345 | |||
| 225 | hdev = hci_dev_get(req->id); | 346 | hdev = hci_dev_get(req->id); |
| 226 | if (!hdev || hdev->amp_type == HCI_BREDR) { | 347 | if (!hdev || hdev->amp_type == HCI_BREDR || tmp) { |
| 227 | struct a2mp_amp_assoc_rsp rsp; | 348 | struct a2mp_amp_assoc_rsp rsp; |
| 228 | rsp.id = req->id; | 349 | rsp.id = req->id; |
| 229 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; | 350 | |
| 351 | if (tmp) { | ||
| 352 | rsp.status = A2MP_STATUS_COLLISION_OCCURED; | ||
| 353 | amp_mgr_put(tmp); | ||
| 354 | } else { | ||
| 355 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; | ||
| 356 | } | ||
| 230 | 357 | ||
| 231 | a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), | 358 | a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), |
| 232 | &rsp); | 359 | &rsp); |
| 233 | goto clean; | 360 | |
| 361 | goto done; | ||
| 234 | } | 362 | } |
| 235 | 363 | ||
| 236 | /* Placeholder for HCI Read AMP Assoc */ | 364 | amp_read_loc_assoc(hdev, mgr); |
| 237 | 365 | ||
| 238 | clean: | 366 | done: |
| 239 | if (hdev) | 367 | if (hdev) |
| 240 | hci_dev_put(hdev); | 368 | hci_dev_put(hdev); |
| 241 | 369 | ||
| @@ -243,6 +371,68 @@ clean: · 1 unmodified line | |||
| 243 | return 0; | 371 | return 0; |
| 244 | } | 372 | } |
| 245 | 373 | ||
| 374 | static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb, | ||
| 375 | struct a2mp_cmd *hdr) | ||
| 376 | { | ||
| 377 | struct a2mp_amp_assoc_rsp *rsp = (void *) skb->data; | ||
| 378 | u16 len = le16_to_cpu(hdr->len); | ||
| 379 | struct hci_dev *hdev; | ||
| 380 | struct amp_ctrl *ctrl; | ||
| 381 | struct hci_conn *hcon; | ||
| 382 | size_t assoc_len; | ||
| 383 | |||
| 384 | if (len < sizeof(*rsp)) | ||
| 385 | return -EINVAL; | ||
| 386 | |||
| 387 | assoc_len = len - sizeof(*rsp); | ||
| 388 | |||
| 389 | BT_DBG("id %d status 0x%2.2x assoc len %zu", rsp->id, rsp->status, | ||
| 390 | assoc_len); | ||
| 391 | |||
| 392 | if (rsp->status) | ||
| 393 | return -EINVAL; | ||
| 394 | |||
| 395 | /* Save remote ASSOC data */ | ||
| 396 | ctrl = amp_ctrl_lookup(mgr, rsp->id); | ||
| 397 | if (ctrl) { | ||
| 398 | u8 *assoc; | ||
| 399 | |||
| 400 | assoc = kzalloc(assoc_len, GFP_KERNEL); | ||
| 401 | if (!assoc) { | ||
| 402 | amp_ctrl_put(ctrl); | ||
| 403 | return -ENOMEM; | ||
| 404 | } | ||
| 405 | |||
| 406 | memcpy(assoc, rsp->amp_assoc, assoc_len); | ||
| 407 | ctrl->assoc = assoc; | ||
| 408 | ctrl->assoc_len = assoc_len; | ||
| 409 | ctrl->assoc_rem_len = assoc_len; | ||
| 410 | ctrl->assoc_len_so_far = 0; | ||
| 411 | |||
| 412 | amp_ctrl_put(ctrl); | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Create Phys Link */ | ||
| 416 | hdev = hci_dev_get(rsp->id); | ||
| 417 | if (!hdev) | ||
| 418 | return -EINVAL; | ||
| 419 | |||
| 420 | hcon = phylink_add(hdev, mgr, rsp->id, true); | ||
| 421 | if (!hcon) | ||
| 422 | goto done; | ||
| 423 | |||
| 424 | BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id); | ||
| 425 | |||
| 426 | mgr->bredr_chan->ctrl_id = rsp->id; | ||
| 427 | |||
| 428 | amp_create_phylink(hdev, mgr, hcon); | ||
| 429 | |||
| 430 | done: | ||
| 431 | hci_dev_put(hdev); | ||
| 432 | skb_pull(skb, len); | ||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | |||
| 246 | static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, | 436 | static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, |
| 247 | struct a2mp_cmd *hdr) | 437 | struct a2mp_cmd *hdr) |
| 248 | { | 438 | { |
| @@ -250,6 +440,8 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, · 1 unmodified line | |||
| 250 | 440 | ||
| 251 | struct a2mp_physlink_rsp rsp; | 441 | struct a2mp_physlink_rsp rsp; |
| 252 | struct hci_dev *hdev; | 442 | struct hci_dev *hdev; |
| 443 | struct hci_conn *hcon; | ||
| 444 | struct amp_ctrl *ctrl; | ||
| 253 | 445 | ||
| 254 | if (le16_to_cpu(hdr->len) < sizeof(*req)) | 446 | if (le16_to_cpu(hdr->len) < sizeof(*req)) |
| 255 | return -EINVAL; | 447 | return -EINVAL; |
| @@ -265,9 +457,43 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, · 9 unmodified lines | |||
| 265 | goto send_rsp; | 457 | goto send_rsp; |
| 266 | } | 458 | } |
| 267 | 459 | ||
| 268 | /* TODO process physlink create */ | 460 | ctrl = amp_ctrl_lookup(mgr, rsp.remote_id); |
| 461 | if (!ctrl) { | ||
| 462 | ctrl = amp_ctrl_add(mgr, rsp.remote_id); | ||
| 463 | if (ctrl) { | ||
| 464 | amp_ctrl_get(ctrl); | ||
| 465 | } else { | ||
| 466 | rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; | ||
| 467 | goto send_rsp; | ||
| 468 | } | ||
| 469 | } | ||
| 269 | 470 | ||
| 270 | rsp.status = A2MP_STATUS_SUCCESS; | 471 | if (ctrl) { |
| 472 | size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req); | ||
| 473 | u8 *assoc; | ||
| 474 | |||
| 475 | assoc = kzalloc(assoc_len, GFP_KERNEL); | ||
| 476 | if (!assoc) { | ||
| 477 | amp_ctrl_put(ctrl); | ||
| 478 | return -ENOMEM; | ||
| 479 | } | ||
| 480 | |||
| 481 | memcpy(assoc, req->amp_assoc, assoc_len); | ||
| 482 | ctrl->assoc = assoc; | ||
| 483 | ctrl->assoc_len = assoc_len; | ||
| 484 | ctrl->assoc_rem_len = assoc_len; | ||
| 485 | ctrl->assoc_len_so_far = 0; | ||
| 486 | |||
| 487 | amp_ctrl_put(ctrl); | ||
| 488 | } | ||
| 489 | |||
| 490 | hcon = phylink_add(hdev, mgr, req->local_id, false); | ||
| 491 | if (hcon) { | ||
| 492 | amp_accept_phylink(hdev, mgr, hcon); | ||
| 493 | rsp.status = A2MP_STATUS_SUCCESS; | ||
| 494 | } else { | ||
| 495 | rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; | ||
| 496 | } | ||
| 271 | 497 | ||
| 272 | send_rsp: | 498 | send_rsp: |
| 273 | if (hdev) | 499 | if (hdev) |
| @@ -286,6 +512,7 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, · 12 unmodified lines | |||
| 286 | struct a2mp_physlink_req *req = (void *) skb->data; | 512 | struct a2mp_physlink_req *req = (void *) skb->data; |
| 287 | struct a2mp_physlink_rsp rsp; | 513 | struct a2mp_physlink_rsp rsp; |
| 288 | struct hci_dev *hdev; | 514 | struct hci_dev *hdev; |
| 515 | struct hci_conn *hcon; | ||
| 289 | 516 | ||
| 290 | if (le16_to_cpu(hdr->len) < sizeof(*req)) | 517 | if (le16_to_cpu(hdr->len) < sizeof(*req)) |
| 291 | return -EINVAL; | 518 | return -EINVAL; |
| @@ -296,14 +523,22 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, · 4 unmodified lines | |||
| 296 | rsp.remote_id = req->local_id; | 523 | rsp.remote_id = req->local_id; |
| 297 | rsp.status = A2MP_STATUS_SUCCESS; | 524 | rsp.status = A2MP_STATUS_SUCCESS; |
| 298 | 525 | ||
| 299 | hdev = hci_dev_get(req->local_id); | 526 | hdev = hci_dev_get(req->remote_id); |
| 300 | if (!hdev) { | 527 | if (!hdev) { |
| 301 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; | 528 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; |
| 302 | goto send_rsp; | 529 | goto send_rsp; |
| 303 | } | 530 | } |
| 304 | 531 | ||
| 532 | hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, mgr->l2cap_conn->dst); | ||
| 533 | if (!hcon) { | ||
| 534 | BT_ERR("No phys link exist"); | ||
| 535 | rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS; | ||
| 536 | goto clean; | ||
| 537 | } | ||
| 538 | |||
| 305 | /* TODO Disconnect Phys Link here */ | 539 | /* TODO Disconnect Phys Link here */ |
| 306 | 540 | ||
| 541 | clean: | ||
| 307 | hci_dev_put(hdev); | 542 | hci_dev_put(hdev); |
| 308 | 543 | ||
| 309 | send_rsp: | 544 | send_rsp: |
| @@ -377,10 +612,19 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) · 67 unmodified lines | |||
| 377 | err = a2mp_discphyslink_req(mgr, skb, hdr); | 612 | err = a2mp_discphyslink_req(mgr, skb, hdr); |
| 378 | break; | 613 | break; |
| 379 | 614 | ||
| 380 | case A2MP_CHANGE_RSP: | ||
| 381 | case A2MP_DISCOVER_RSP: | 615 | case A2MP_DISCOVER_RSP: |
| 616 | err = a2mp_discover_rsp(mgr, skb, hdr); | ||
| 617 | break; | ||
| 618 | |||
| 382 | case A2MP_GETINFO_RSP: | 619 | case A2MP_GETINFO_RSP: |
| 620 | err = a2mp_getinfo_rsp(mgr, skb, hdr); | ||
| 621 | break; | ||
| 622 | |||
| 383 | case A2MP_GETAMPASSOC_RSP: | 623 | case A2MP_GETAMPASSOC_RSP: |
| 624 | err = a2mp_getampassoc_rsp(mgr, skb, hdr); | ||
| 625 | break; | ||
| 626 | |||
| 627 | case A2MP_CHANGE_RSP: | ||
| 384 | case A2MP_CREATEPHYSLINK_RSP: | 628 | case A2MP_CREATEPHYSLINK_RSP: |
| 385 | case A2MP_DISCONNPHYSLINK_RSP: | 629 | case A2MP_DISCONNPHYSLINK_RSP: |
| 386 | err = a2mp_cmd_rsp(mgr, skb, hdr); | 630 | err = a2mp_cmd_rsp(mgr, skb, hdr); |
| @@ -455,9 +699,10 @@ static struct l2cap_ops a2mp_chan_ops = { · 68 unmodified lines | |||
| 455 | .new_connection = l2cap_chan_no_new_connection, | 699 | .new_connection = l2cap_chan_no_new_connection, |
| 456 | .teardown = l2cap_chan_no_teardown, | 700 | .teardown = l2cap_chan_no_teardown, |
| 457 | .ready = l2cap_chan_no_ready, | 701 | .ready = l2cap_chan_no_ready, |
| 702 | .defer = l2cap_chan_no_defer, | ||
| 458 | }; | 703 | }; |
| 459 | 704 | ||
| 460 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) | 705 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) |
| 461 | { | 706 | { |
| 462 | struct l2cap_chan *chan; | 707 | struct l2cap_chan *chan; |
| 463 | int err; | 708 | int err; |
| @@ -492,7 +737,10 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) · 28 unmodified lines | |||
| 492 | 737 | ||
| 493 | chan->conf_state = 0; | 738 | chan->conf_state = 0; |
| 494 | 739 | ||
| 495 | l2cap_chan_add(conn, chan); | 740 | if (locked) |
| 741 | __l2cap_chan_add(conn, chan); | ||
| 742 | else | ||
| 743 | l2cap_chan_add(conn, chan); | ||
| 496 | 744 | ||
| 497 | chan->remote_mps = chan->omtu; | 745 | chan->remote_mps = chan->omtu; |
| 498 | chan->mps = chan->omtu; | 746 | chan->mps = chan->omtu; |
| @@ -503,11 +751,13 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) · 4 unmodified lines | |||
| 503 | } | 751 | } |
| 504 | 752 | ||
| 505 | /* AMP Manager functions */ | 753 | /* AMP Manager functions */ |
| 506 | void amp_mgr_get(struct amp_mgr *mgr) | 754 | struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr) |
| 507 | { | 755 | { |
| 508 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); | 756 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); |
| 509 | 757 | ||
| 510 | kref_get(&mgr->kref); | 758 | kref_get(&mgr->kref); |
| 759 | |||
| 760 | return mgr; | ||
| 511 | } | 761 | } |
| 512 | 762 | ||
| 513 | static void amp_mgr_destroy(struct kref *kref) | 763 | static void amp_mgr_destroy(struct kref *kref) |
| @@ -516,6 +766,11 @@ static void amp_mgr_destroy(struct kref *kref) · 2 unmodified lines | |||
| 516 | 766 | ||
| 517 | BT_DBG("mgr %p", mgr); | 767 | BT_DBG("mgr %p", mgr); |
| 518 | 768 | ||
| 769 | mutex_lock(&_mgr_list_lock); | ||
| 770 | list_del(&mgr->list); | ||
| 771 | mutex_unlock(&_mgr_list_lock); | ||
| 772 | |||
| 773 | amp_ctrl_list_flush(mgr); | ||
| 519 | kfree(mgr); | 774 | kfree(mgr); |
| 520 | } | 775 | } |
| 521 | 776 | ||
| @@ -526,7 +781,7 @@ int amp_mgr_put(struct amp_mgr *mgr) · 4 unmodified lines | |||
| 526 | return kref_put(&mgr->kref, &_mgr_destroy); | 781 | return kref_put(&mgr->kref, &_mgr_destroy); |
| 527 | } | 782 | } |
| 528 | 783 | ||
| 529 | static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) | 784 | static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn, bool locked) |
| 530 | { | 785 | { |
| 531 | struct amp_mgr *mgr; | 786 | struct amp_mgr *mgr; |
| 532 | struct l2cap_chan *chan; | 787 | struct l2cap_chan *chan; |
| @@ -539,7 +794,7 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) · 6 unmodified lines | |||
| 539 | 794 | ||
| 540 | mgr->l2cap_conn = conn; | 795 | mgr->l2cap_conn = conn; |
| 541 | 796 | ||
| 542 | chan = a2mp_chan_open(conn); | 797 | chan = a2mp_chan_open(conn, locked); |
| 543 | if (!chan) { | 798 | if (!chan) { |
| 544 | kfree(mgr); | 799 | kfree(mgr); |
| 545 | return NULL; | 800 | return NULL; |
| @@ -552,6 +807,14 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) · 6 unmodified lines | |||
| 552 | 807 | ||
| 553 | kref_init(&mgr->kref); | 808 | kref_init(&mgr->kref); |
| 554 | 809 | ||
| 810 | /* Remote AMP ctrl list initialization */ | ||
| 811 | INIT_LIST_HEAD(&mgr->amp_ctrls); | ||
| 812 | mutex_init(&mgr->amp_ctrls_lock); | ||
| 813 | |||
| 814 | mutex_lock(&_mgr_list_lock); | ||
| 815 | list_add(&mgr->list, &_mgr_list); | ||
| 816 | mutex_unlock(&_mgr_list_lock); | ||
| 817 | |||
| 555 | return mgr; | 818 | return mgr; |
| 556 | } | 819 | } |
| 557 | 820 | ||
| @@ -560,7 +823,7 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, · 2 unmodified lines | |||
| 560 | { | 823 | { |
| 561 | struct amp_mgr *mgr; | 824 | struct amp_mgr *mgr; |
| 562 | 825 | ||
| 563 | mgr = amp_mgr_create(conn); | 826 | mgr = amp_mgr_create(conn, false); |
| 564 | if (!mgr) { | 827 | if (!mgr) { |
| 565 | BT_ERR("Could not create AMP manager"); | 828 | BT_ERR("Could not create AMP manager"); |
| 566 | return NULL; | 829 | return NULL; |
| @@ -570,3 +833,139 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, · 3 unmodified lines | |||
| 570 | 833 | ||
| 571 | return mgr->a2mp_chan; | 834 | return mgr->a2mp_chan; |
| 572 | } | 835 | } |
| 836 | |||
| 837 | struct amp_mgr *amp_mgr_lookup_by_state(u8 state) | ||
| 838 | { | ||
| 839 | struct amp_mgr *mgr; | ||
| 840 | |||
| 841 | mutex_lock(&_mgr_list_lock); | ||
| 842 | list_for_each_entry(mgr, &_mgr_list, list) { | ||
| 843 | if (mgr->state == state) { | ||
| 844 | amp_mgr_get(mgr); | ||
| 845 | mutex_unlock(&_mgr_list_lock); | ||
| 846 | return mgr; | ||
| 847 | } | ||
| 848 | } | ||
| 849 | mutex_unlock(&_mgr_list_lock); | ||
| 850 | |||
| 851 | return NULL; | ||
| 852 | } | ||
| 853 | |||
| 854 | void a2mp_send_getinfo_rsp(struct hci_dev *hdev) | ||
| 855 | { | ||
| 856 | struct amp_mgr *mgr; | ||
| 857 | struct a2mp_info_rsp rsp; | ||
| 858 | |||
| 859 | mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO); | ||
| 860 | if (!mgr) | ||
| 861 | return; | ||
| 862 | |||
| 863 | BT_DBG("%s mgr %p", hdev->name, mgr); | ||
| 864 | |||
| 865 | rsp.id = hdev->id; | ||
| 866 | rsp.status = A2MP_STATUS_INVALID_CTRL_ID; | ||
| 867 | |||
| 868 | if (hdev->amp_type != HCI_BREDR) { | ||
| 869 | rsp.status = 0; | ||
| 870 | rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); | ||
| 871 | rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); | ||
| 872 | rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); | ||
| 873 | rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); | ||
| 874 | rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); | ||
| 875 | } | ||
| 876 | |||
| 877 | a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp); | ||
| 878 | amp_mgr_put(mgr); | ||
| 879 | } | ||
| 880 | |||
| 881 | void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status) | ||
| 882 | { | ||
| 883 | struct amp_mgr *mgr; | ||
| 884 | struct amp_assoc *loc_assoc = &hdev->loc_assoc; | ||
| 885 | struct a2mp_amp_assoc_rsp *rsp; | ||
| 886 | size_t len; | ||
| 887 | |||
| 888 | mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); | ||
| 889 | if (!mgr) | ||
| 890 | return; | ||
| 891 | |||
| 892 | BT_DBG("%s mgr %p", hdev->name, mgr); | ||
| 893 | |||
| 894 | len = sizeof(struct a2mp_amp_assoc_rsp) + loc_assoc->len; | ||
| 895 | rsp = kzalloc(len, GFP_KERNEL); | ||
| 896 | if (!rsp) { | ||
| 897 | amp_mgr_put(mgr); | ||
| 898 | return; | ||
| 899 | } | ||
| 900 | |||
| 901 | rsp->id = hdev->id; | ||
| 902 | |||
| 903 | if (status) { | ||
| 904 | rsp->status = A2MP_STATUS_INVALID_CTRL_ID; | ||
| 905 | } else { | ||
| 906 | rsp->status = A2MP_STATUS_SUCCESS; | ||
| 907 | memcpy(rsp->amp_assoc, loc_assoc->data, loc_assoc->len); | ||
| 908 | } | ||
| 909 | |||
| 910 | a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, mgr->ident, len, rsp); | ||
| 911 | amp_mgr_put(mgr); | ||
| 912 | kfree(rsp); | ||
| 913 | } | ||
| 914 | |||
| 915 | void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status) | ||
| 916 | { | ||
| 917 | struct amp_mgr *mgr; | ||
| 918 | struct amp_assoc *loc_assoc = &hdev->loc_assoc; | ||
| 919 | struct a2mp_physlink_req *req; | ||
| 920 | struct l2cap_chan *bredr_chan; | ||
| 921 | size_t len; | ||
| 922 | |||
| 923 | mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC_FINAL); | ||
| 924 | if (!mgr) | ||
| 925 | return; | ||
| 926 | |||
| 927 | len = sizeof(*req) + loc_assoc->len; | ||
| 928 | |||
| 929 | BT_DBG("%s mgr %p assoc_len %zu", hdev->name, mgr, len); | ||
| 930 | |||
| 931 | req = kzalloc(len, GFP_KERNEL); | ||
| 932 | if (!req) { | ||
| 933 | amp_mgr_put(mgr); | ||
| 934 | return; | ||
| 935 | } | ||
| 936 | |||
| 937 | bredr_chan = mgr->bredr_chan; | ||
| 938 | if (!bredr_chan) | ||
| 939 | goto clean; | ||
| 940 | |||
| 941 | req->local_id = hdev->id; | ||
| 942 | req->remote_id = bredr_chan->ctrl_id; | ||
| 943 | memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len); | ||
| 944 | |||
| 945 | a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req); | ||
| 946 | |||
| 947 | clean: | ||
| 948 | amp_mgr_put(mgr); | ||
| 949 | kfree(req); | ||
| 950 | } | ||
| 951 | |||
| 952 | void a2mp_discover_amp(struct l2cap_chan *chan) | ||
| 953 | { | ||
| 954 | struct l2cap_conn *conn = chan->conn; | ||
| 955 | struct amp_mgr *mgr = conn->hcon->amp_mgr; | ||
| 956 | struct a2mp_discov_req req; | ||
| 957 | |||
| 958 | BT_DBG("chan %p conn %p mgr %p", chan, conn, mgr); | ||
| 959 | |||
| 960 | if (!mgr) { | ||
| 961 | mgr = amp_mgr_create(conn, true); | ||
| 962 | if (!mgr) | ||
| 963 | return; | ||
| 964 | } | ||
| 965 | |||
| 966 | mgr->bredr_chan = chan; | ||
| 967 | |||
| 968 | req.mtu = cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); | ||
| 969 | req.ext_feat = 0; | ||
| 970 | a2mp_send(mgr, A2MP_DISCOVER_REQ, 1, sizeof(req), &req); | ||
| 971 | } | ||
| @@ -569,7 +569,6 @@ static int bt_seq_show(struct seq_file *seq, void *v) · 568 unmodified lines | |||
| 569 | { | 569 | { |
| 570 | struct bt_seq_state *s = seq->private; | 570 | struct bt_seq_state *s = seq->private; |
| 571 | struct bt_sock_list *l = s->l; | 571 | struct bt_sock_list *l = s->l; |
| 572 | bdaddr_t src_baswapped, dst_baswapped; | ||
| 573 | 572 | ||
| 574 | if (v == SEQ_START_TOKEN) { | 573 | if (v == SEQ_START_TOKEN) { |
| 575 | seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent"); | 574 | seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent"); |
| @@ -583,18 +582,17 @@ static int bt_seq_show(struct seq_file *seq, void *v) · 7 unmodified lines | |||
| 583 | } else { | 582 | } else { |
| 584 | struct sock *sk = sk_entry(v); | 583 | struct sock *sk = sk_entry(v); |
| 585 | struct bt_sock *bt = bt_sk(sk); | 584 | struct bt_sock *bt = bt_sk(sk); |
| 586 | baswap(&src_baswapped, &bt->src); | ||
| 587 | baswap(&dst_baswapped, &bt->dst); | ||
| 588 | 585 | ||
| 589 | seq_printf(seq, "%pK %-6d %-6u %-6u %-6u %-6lu %pM %pM %-6lu", | 586 | seq_printf(seq, |
| 587 | "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu", | ||
| 590 | sk, | 588 | sk, |
| 591 | atomic_read(&sk->sk_refcnt), | 589 | atomic_read(&sk->sk_refcnt), |
| 592 | sk_rmem_alloc_get(sk), | 590 | sk_rmem_alloc_get(sk), |
| 593 | sk_wmem_alloc_get(sk), | 591 | sk_wmem_alloc_get(sk), |
| 594 | from_kuid(seq_user_ns(seq), sock_i_uid(sk)), | 592 | from_kuid(seq_user_ns(seq), sock_i_uid(sk)), |
| 595 | sock_i_ino(sk), | 593 | sock_i_ino(sk), |
| 596 | &src_baswapped, | 594 | &bt->src, |
| 597 | &dst_baswapped, | 595 | &bt->dst, |
| 598 | bt->parent? sock_i_ino(bt->parent): 0LU); | 596 | bt->parent? sock_i_ino(bt->parent): 0LU); |
| 599 | 597 | ||
| 600 | if (l->custom_seq_show) { | 598 | if (l->custom_seq_show) { |
| @@ -0,0 +1,374 @@ | |||
| 1 | /* | ||
| 2 | Copyright (c) 2011,2012 Intel Corp. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License version 2 and | ||
| 6 | only version 2 as published by the Free Software Foundation. | ||
| 7 | |||
| 8 | This program is distributed in the hope that it will be useful, | ||
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <net/bluetooth/bluetooth.h> | ||
| 15 | #include <net/bluetooth/hci.h> | ||
| 16 | #include <net/bluetooth/hci_core.h> | ||
| 17 | #include <net/bluetooth/a2mp.h> | ||
| 18 | #include <net/bluetooth/amp.h> | ||
| 19 | #include <crypto/hash.h> | ||
| 20 | |||
| 21 | /* Remote AMP Controllers interface */ | ||
| 22 | void amp_ctrl_get(struct amp_ctrl *ctrl) | ||
| 23 | { | ||
| 24 | BT_DBG("ctrl %p orig refcnt %d", ctrl, | ||
| 25 | atomic_read(&ctrl->kref.refcount)); | ||
| 26 | |||
| 27 | kref_get(&ctrl->kref); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void amp_ctrl_destroy(struct kref *kref) | ||
| 31 | { | ||
| 32 | struct amp_ctrl *ctrl = container_of(kref, struct amp_ctrl, kref); | ||
| 33 | |||
| 34 | BT_DBG("ctrl %p", ctrl); | ||
| 35 | |||
| 36 | kfree(ctrl->assoc); | ||
| 37 | kfree(ctrl); | ||
| 38 | } | ||
| 39 | |||
| 40 | int amp_ctrl_put(struct amp_ctrl *ctrl) | ||
| 41 | { | ||
| 42 | BT_DBG("ctrl %p orig refcnt %d", ctrl, | ||
| 43 | atomic_read(&ctrl->kref.refcount)); | ||
| 44 | |||
| 45 | return kref_put(&ctrl->kref, &_ctrl_destroy); | ||
| 46 | } | ||
| 47 | |||
| 48 | struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id) | ||
| 49 | { | ||
| 50 | struct amp_ctrl *ctrl; | ||
| 51 | |||
| 52 | ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); | ||
| 53 | if (!ctrl) | ||
| 54 | return NULL; | ||
| 55 | |||
| 56 | kref_init(&ctrl->kref); | ||
| 57 | ctrl->id = id; | ||
| 58 | |||
| 59 | mutex_lock(&mgr->amp_ctrls_lock); | ||
| 60 | list_add(&ctrl->list, &mgr->amp_ctrls); | ||
| 61 | mutex_unlock(&mgr->amp_ctrls_lock); | ||
| 62 | |||
| 63 | BT_DBG("mgr %p ctrl %p", mgr, ctrl); | ||
| 64 | |||
| 65 | return ctrl; | ||
| 66 | } | ||
| 67 | |||
| 68 | void amp_ctrl_list_flush(struct amp_mgr *mgr) | ||
| 69 | { | ||
| 70 | struct amp_ctrl *ctrl, *n; | ||
| 71 | |||
| 72 | BT_DBG("mgr %p", mgr); | ||
| 73 | |||
| 74 | mutex_lock(&mgr->amp_ctrls_lock); | ||
| 75 | list_for_each_entry_safe(ctrl, n, &mgr->amp_ctrls, list) { | ||
| 76 | list_del(&ctrl->list); | ||
| 77 | amp_ctrl_put(ctrl); | ||
| 78 | } | ||
| 79 | mutex_unlock(&mgr->amp_ctrls_lock); | ||
| 80 | } | ||
| 81 | |||
| 82 | struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id) | ||
| 83 | { | ||
| 84 | struct amp_ctrl *ctrl; | ||
| 85 | |||
| 86 | BT_DBG("mgr %p id %d", mgr, id); | ||
| 87 | |||
| 88 | mutex_lock(&mgr->amp_ctrls_lock); | ||
| 89 | list_for_each_entry(ctrl, &mgr->amp_ctrls, list) { | ||
| 90 | if (ctrl->id == id) { | ||
| 91 | amp_ctrl_get(ctrl); | ||
| 92 | mutex_unlock(&mgr->amp_ctrls_lock); | ||
| 93 | return ctrl; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | mutex_unlock(&mgr->amp_ctrls_lock); | ||
| 97 | |||
| 98 | return NULL; | ||
| 99 | } | ||
| 100 | |||
| 101 | /* Physical Link interface */ | ||
| 102 | static u8 __next_handle(struct amp_mgr *mgr) | ||
| 103 | { | ||
| 104 | if (++mgr->handle == 0) | ||
| 105 | mgr->handle = 1; | ||
| 106 | |||
| 107 | return mgr->handle; | ||
| 108 | } | ||
| 109 | |||
| 110 | struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 111 | u8 remote_id, bool out) | ||
| 112 | { | ||
| 113 | bdaddr_t *dst = mgr->l2cap_conn->dst; | ||
| 114 | struct hci_conn *hcon; | ||
| 115 | |||
| 116 | hcon = hci_conn_add(hdev, AMP_LINK, dst); | ||
| 117 | if (!hcon) | ||
| 118 | return NULL; | ||
| 119 | |||
| 120 | BT_DBG("hcon %p dst %pMR", hcon, dst); | ||
| 121 | |||
| 122 | hcon->state = BT_CONNECT; | ||
| 123 | hcon->attempt++; | ||
| 124 | hcon->handle = __next_handle(mgr); | ||
| 125 | hcon->remote_id = remote_id; | ||
| 126 | hcon->amp_mgr = amp_mgr_get(mgr); | ||
| 127 | hcon->out = out; | ||
| 128 | |||
| 129 | return hcon; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* AMP crypto key generation interface */ | ||
| 133 | static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output) | ||
| 134 | { | ||
| 135 | int ret = 0; | ||
| 136 | struct crypto_shash *tfm; | ||
| 137 | |||
| 138 | if (!ksize) | ||
| 139 | return -EINVAL; | ||
| 140 | |||
| 141 | tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); | ||
| 142 | if (IS_ERR(tfm)) { | ||
| 143 | BT_DBG("crypto_alloc_ahash failed: err %ld", PTR_ERR(tfm)); | ||
| 144 | return PTR_ERR(tfm); | ||
| 145 | } | ||
| 146 | |||
| 147 | ret = crypto_shash_setkey(tfm, key, ksize); | ||
| 148 | if (ret) { | ||
| 149 | BT_DBG("crypto_ahash_setkey failed: err %d", ret); | ||
| 150 | } else { | ||
| 151 | struct { | ||
| 152 | struct shash_desc shash; | ||
| 153 | char ctx[crypto_shash_descsize(tfm)]; | ||
| 154 | } desc; | ||
| 155 | |||
| 156 | desc.shash.tfm = tfm; | ||
| 157 | desc.shash.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | ||
| 158 | |||
| 159 | ret = crypto_shash_digest(&desc.shash, plaintext, psize, | ||
| 160 | output); | ||
| 161 | } | ||
| 162 | |||
| 163 | crypto_free_shash(tfm); | ||
| 164 | return ret; | ||
| 165 | } | ||
| 166 | |||
| 167 | int phylink_gen_key(struct hci_conn *conn, u8 *data, u8 *len, u8 *type) | ||
| 168 | { | ||
| 169 | struct hci_dev *hdev = conn->hdev; | ||
| 170 | struct link_key *key; | ||
| 171 | u8 keybuf[HCI_AMP_LINK_KEY_SIZE]; | ||
| 172 | u8 gamp_key[HCI_AMP_LINK_KEY_SIZE]; | ||
| 173 | int err; | ||
| 174 | |||
| 175 | if (!hci_conn_check_link_mode(conn)) | ||
| 176 | return -EACCES; | ||
| 177 | |||
| 178 | BT_DBG("conn %p key_type %d", conn, conn->key_type); | ||
| 179 | |||
| 180 | /* Legacy key */ | ||
| 181 | if (conn->key_type < 3) { | ||
| 182 | BT_ERR("Legacy key type %d", conn->key_type); | ||
| 183 | return -EACCES; | ||
| 184 | } | ||
| 185 | |||
| 186 | *type = conn->key_type; | ||
| 187 | *len = HCI_AMP_LINK_KEY_SIZE; | ||
| 188 | |||
| 189 | key = hci_find_link_key(hdev, &conn->dst); | ||
| 190 | if (!key) { | ||
| 191 | BT_DBG("No Link key for conn %p dst %pMR", conn, &conn->dst); | ||
| 192 | return -EACCES; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* BR/EDR Link Key concatenated together with itself */ | ||
| 196 | memcpy(&keybuf[0], key->val, HCI_LINK_KEY_SIZE); | ||
| 197 | memcpy(&keybuf[HCI_LINK_KEY_SIZE], key->val, HCI_LINK_KEY_SIZE); | ||
| 198 | |||
| 199 | /* Derive Generic AMP Link Key (gamp) */ | ||
| 200 | err = hmac_sha256(keybuf, HCI_AMP_LINK_KEY_SIZE, "gamp", 4, gamp_key); | ||
| 201 | if (err) { | ||
| 202 | BT_ERR("Could not derive Generic AMP Key: err %d", err); | ||
| 203 | return err; | ||
| 204 | } | ||
| 205 | |||
| 206 | if (conn->key_type == HCI_LK_DEBUG_COMBINATION) { | ||
| 207 | BT_DBG("Use Generic AMP Key (gamp)"); | ||
| 208 | memcpy(data, gamp_key, HCI_AMP_LINK_KEY_SIZE); | ||
| 209 | return err; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* Derive Dedicated AMP Link Key: "802b" is 802.11 PAL keyID */ | ||
| 213 | return hmac_sha256(gamp_key, HCI_AMP_LINK_KEY_SIZE, "802b", 4, data); | ||
| 214 | } | ||
| 215 | |||
| 216 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) | ||
| 217 | { | ||
| 218 | struct hci_cp_read_local_amp_assoc cp; | ||
| 219 | struct amp_assoc *loc_assoc = &hdev->loc_assoc; | ||
| 220 | |||
| 221 | BT_DBG("%s handle %d", hdev->name, phy_handle); | ||
| 222 | |||
| 223 | cp.phy_handle = phy_handle; | ||
| 224 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); | ||
| 225 | cp.len_so_far = cpu_to_le16(loc_assoc->offset); | ||
| 226 | |||
| 227 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
| 228 | } | ||
| 229 | |||
| 230 | void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr) | ||
| 231 | { | ||
| 232 | struct hci_cp_read_local_amp_assoc cp; | ||
| 233 | |||
| 234 | memset(&hdev->loc_assoc, 0, sizeof(struct amp_assoc)); | ||
| 235 | memset(&cp, 0, sizeof(cp)); | ||
| 236 | |||
| 237 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); | ||
| 238 | |||
| 239 | mgr->state = READ_LOC_AMP_ASSOC; | ||
| 240 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
| 241 | } | ||
| 242 | |||
| 243 | void amp_read_loc_assoc_final_data(struct hci_dev *hdev, | ||
| 244 | struct hci_conn *hcon) | ||
| 245 | { | ||
| 246 | struct hci_cp_read_local_amp_assoc cp; | ||
| 247 | struct amp_mgr *mgr = hcon->amp_mgr; | ||
| 248 | |||
| 249 | cp.phy_handle = hcon->handle; | ||
| 250 | cp.len_so_far = cpu_to_le16(0); | ||
| 251 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); | ||
| 252 | |||
| 253 | mgr->state = READ_LOC_AMP_ASSOC_FINAL; | ||
| 254 | |||
| 255 | /* Read Local AMP Assoc final link information data */ | ||
| 256 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Write AMP Assoc data fragments, returns true with last fragment written*/ | ||
| 260 | static bool amp_write_rem_assoc_frag(struct hci_dev *hdev, | ||
| 261 | struct hci_conn *hcon) | ||
| 262 | { | ||
| 263 | struct hci_cp_write_remote_amp_assoc *cp; | ||
| 264 | struct amp_mgr *mgr = hcon->amp_mgr; | ||
| 265 | struct amp_ctrl *ctrl; | ||
| 266 | u16 frag_len, len; | ||
| 267 | |||
| 268 | ctrl = amp_ctrl_lookup(mgr, hcon->remote_id); | ||
| 269 | if (!ctrl) | ||
| 270 | return false; | ||
| 271 | |||
| 272 | if (!ctrl->assoc_rem_len) { | ||
| 273 | BT_DBG("all fragments are written"); | ||
| 274 | ctrl->assoc_rem_len = ctrl->assoc_len; | ||
| 275 | ctrl->assoc_len_so_far = 0; | ||
| 276 | |||
| 277 | amp_ctrl_put(ctrl); | ||
| 278 | return true; | ||
| 279 | } | ||
| 280 | |||
| 281 | frag_len = min_t(u16, 248, ctrl->assoc_rem_len); | ||
| 282 | len = frag_len + sizeof(*cp); | ||
| 283 | |||
| 284 | cp = kzalloc(len, GFP_KERNEL); | ||
| 285 | if (!cp) { | ||
| 286 | amp_ctrl_put(ctrl); | ||
| 287 | return false; | ||
| 288 | } | ||
| 289 | |||
| 290 | BT_DBG("hcon %p ctrl %p frag_len %u assoc_len %u rem_len %u", | ||
| 291 | hcon, ctrl, frag_len, ctrl->assoc_len, ctrl->assoc_rem_len); | ||
| 292 | |||
| 293 | cp->phy_handle = hcon->handle; | ||
| 294 | cp->len_so_far = cpu_to_le16(ctrl->assoc_len_so_far); | ||
| 295 | cp->rem_len = cpu_to_le16(ctrl->assoc_rem_len); | ||
| 296 | memcpy(cp->frag, ctrl->assoc, frag_len); | ||
| 297 | |||
| 298 | ctrl->assoc_len_so_far += frag_len; | ||
| 299 | ctrl->assoc_rem_len -= frag_len; | ||
| 300 | |||
| 301 | amp_ctrl_put(ctrl); | ||
| 302 | |||
| 303 | hci_send_cmd(hdev, HCI_OP_WRITE_REMOTE_AMP_ASSOC, len, cp); | ||
| 304 | |||
| 305 | kfree(cp); | ||
| 306 | |||
| 307 | return false; | ||
| 308 | } | ||
| 309 | |||
| 310 | void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle) | ||
| 311 | { | ||
| 312 | struct hci_conn *hcon; | ||
| 313 | |||
| 314 | BT_DBG("%s phy handle 0x%2.2x", hdev->name, handle); | ||
| 315 | |||
| 316 | hcon = hci_conn_hash_lookup_handle(hdev, handle); | ||
| 317 | if (!hcon) | ||
| 318 | return; | ||
| 319 | |||
| 320 | amp_write_rem_assoc_frag(hdev, hcon); | ||
| 321 | } | ||
| 322 | |||
| 323 | void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle) | ||
| 324 | { | ||
| 325 | struct hci_conn *hcon; | ||
| 326 | |||
| 327 | BT_DBG("%s phy handle 0x%2.2x", hdev->name, handle); | ||
| 328 | |||
| 329 | hcon = hci_conn_hash_lookup_handle(hdev, handle); | ||
| 330 | if (!hcon) | ||
| 331 | return; | ||
| 332 | |||
| 333 | BT_DBG("%s phy handle 0x%2.2x hcon %p", hdev->name, handle, hcon); | ||
| 334 | |||
| 335 | amp_write_rem_assoc_frag(hdev, hcon); | ||
| 336 | } | ||
| 337 | |||
| 338 | void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 339 | struct hci_conn *hcon) | ||
| 340 | { | ||
| 341 | struct hci_cp_create_phy_link cp; | ||
| 342 | |||
| 343 | cp.phy_handle = hcon->handle; | ||
| 344 | |||
| 345 | BT_DBG("%s hcon %p phy handle 0x%2.2x", hdev->name, hcon, | ||
| 346 | hcon->handle); | ||
| 347 | |||
| 348 | if (phylink_gen_key(mgr->l2cap_conn->hcon, cp.key, &cp.key_len, | ||
| 349 | &cp.key_type)) { | ||
| 350 | BT_DBG("Cannot create link key"); | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | |||
| 354 | hci_send_cmd(hdev, HCI_OP_CREATE_PHY_LINK, sizeof(cp), &cp); | ||
| 355 | } | ||
| 356 | |||
| 357 | void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, | ||
| 358 | struct hci_conn *hcon) | ||
| 359 | { | ||
| 360 | struct hci_cp_accept_phy_link cp; | ||
| 361 | |||
| 362 | cp.phy_handle = hcon->handle; | ||
| 363 | |||
| 364 | BT_DBG("%s hcon %p phy handle 0x%2.2x", hdev->name, hcon, | ||
| 365 | hcon->handle); | ||
| 366 | |||
| 367 | if (phylink_gen_key(mgr->l2cap_conn->hcon, cp.key, &cp.key_len, | ||
| 368 | &cp.key_type)) { | ||
| 369 | BT_DBG("Cannot create link key"); | ||
| 370 | return; | ||
| 371 | } | ||
| 372 | |||
| 373 | hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp); | ||
| 374 | } | ||
| @@ -182,8 +182,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len) · 181 unmodified lines | |||
| 182 | a2 = data; | 182 | a2 = data; |
| 183 | data += ETH_ALEN; | 183 | data += ETH_ALEN; |
| 184 | 184 | ||
| 185 | BT_DBG("mc filter %s -> %s", | 185 | BT_DBG("mc filter %pMR -> %pMR", a1, a2); |
| 186 | batostr((void *) a1), batostr((void *) a2)); | ||
| 187 | 186 | ||
| 188 | /* Iterate from a1 to a2 */ | 187 | /* Iterate from a1 to a2 */ |
| 189 | set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); | 188 | set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter); |
| @@ -353,7 +353,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) · 352 unmodified lines | |||
| 353 | 353 | ||
| 354 | BT_DBG("mtu %d", session->mtu); | 354 | BT_DBG("mtu %d", session->mtu); |
| 355 | 355 | ||
| 356 | sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst)); | 356 | sprintf(session->name, "%pMR", &bt_sk(sock->sk)->dst); |
| 357 | 357 | ||
| 358 | session->sock = sock; | 358 | session->sock = sock; |
| 359 | session->state = BT_CONFIG; | 359 | session->state = BT_CONFIG; |
| @@ -130,6 +130,20 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) · 129 unmodified lines | |||
| 130 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); | 130 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static void hci_amp_disconn(struct hci_conn *conn, __u8 reason) | ||
| 134 | { | ||
| 135 | struct hci_cp_disconn_phy_link cp; | ||
| 136 | |||
| 137 | BT_DBG("hcon %p", conn); | ||
| 138 | |||
| 139 | conn->state = BT_DISCONN; | ||
| 140 | |||
| 141 | cp.phy_handle = HCI_PHY_HANDLE(conn->handle); | ||
| 142 | cp.reason = reason; | ||
| 143 | hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK, | ||
| 144 | sizeof(cp), &cp); | ||
| 145 | } | ||
| 146 | |||
| 133 | static void hci_add_sco(struct hci_conn *conn, __u16 handle) | 147 | static void hci_add_sco(struct hci_conn *conn, __u16 handle) |
| 134 | { | 148 | { |
| 135 | struct hci_dev *hdev = conn->hdev; | 149 | struct hci_dev *hdev = conn->hdev; |
| @@ -230,11 +244,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) · 94 unmodified lines | |||
| 230 | } | 244 | } |
| 231 | } | 245 | } |
| 232 | 246 | ||
| 247 | static void hci_conn_disconnect(struct hci_conn *conn) | ||
| 248 | { | ||
| 249 | __u8 reason = hci_proto_disconn_ind(conn); | ||
| 250 | |||
| 251 | switch (conn->type) { | ||
| 252 | case ACL_LINK: | ||
| 253 | hci_acl_disconn(conn, reason); | ||
| 254 | break; | ||
| 255 | case AMP_LINK: | ||
| 256 | hci_amp_disconn(conn, reason); | ||
| 257 | break; | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 233 | static void hci_conn_timeout(struct work_struct *work) | 261 | static void hci_conn_timeout(struct work_struct *work) |
| 234 | { | 262 | { |
| 235 | struct hci_conn *conn = container_of(work, struct hci_conn, | 263 | struct hci_conn *conn = container_of(work, struct hci_conn, |
| 236 | disc_work.work); | 264 | disc_work.work); |
| 237 | __u8 reason; | ||
| 238 | 265 | ||
| 239 | BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); | 266 | BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); |
| 240 | 267 | ||
| @@ -253,8 +280,7 @@ static void hci_conn_timeout(struct work_struct *work) · 12 unmodified lines | |||
| 253 | break; | 280 | break; |
| 254 | case BT_CONFIG: | 281 | case BT_CONFIG: |
| 255 | case BT_CONNECTED: | 282 | case BT_CONNECTED: |
| 256 | reason = hci_proto_disconn_ind(conn); | 283 | hci_conn_disconnect(conn); |
| 257 | hci_acl_disconn(conn, reason); | ||
| 258 | break; | 284 | break; |
| 259 | default: | 285 | default: |
| 260 | conn->state = BT_CLOSED; | 286 | conn->state = BT_CLOSED; |
| @@ -320,7 +346,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) · 59 unmodified lines | |||
| 320 | { | 346 | { |
| 321 | struct hci_conn *conn; | 347 | struct hci_conn *conn; |
| 322 | 348 | ||
| 323 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 349 | BT_DBG("%s dst %pMR", hdev->name, dst); |
| 324 | 350 | ||
| 325 | conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL); | 351 | conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL); |
| 326 | if (!conn) | 352 | if (!conn) |
| @@ -437,7 +463,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) · 110 unmodified lines | |||
| 437 | int use_src = bacmp(src, BDADDR_ANY); | 463 | int use_src = bacmp(src, BDADDR_ANY); |
| 438 | struct hci_dev *hdev = NULL, *d; | 464 | struct hci_dev *hdev = NULL, *d; |
| 439 | 465 | ||
| 440 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); | 466 | BT_DBG("%pMR -> %pMR", src, dst); |
| 441 | 467 | ||
| 442 | read_lock(&hci_dev_list_lock); | 468 | read_lock(&hci_dev_list_lock); |
| 443 | 469 | ||
| @@ -567,7 +593,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, · 123 unmodified lines | |||
| 567 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 593 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
| 568 | __u8 dst_type, __u8 sec_level, __u8 auth_type) | 594 | __u8 dst_type, __u8 sec_level, __u8 auth_type) |
| 569 | { | 595 | { |
| 570 | BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type); | 596 | BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type); |
| 571 | 597 | ||
| 572 | switch (type) { | 598 | switch (type) { |
| 573 | case LE_LINK: | 599 | case LE_LINK: |
| @@ -963,3 +989,35 @@ void hci_chan_list_flush(struct hci_conn *conn) · 389 unmodified lines | |||
| 963 | list_for_each_entry_safe(chan, n, &conn->chan_list, list) | 989 | list_for_each_entry_safe(chan, n, &conn->chan_list, list) |
| 964 | hci_chan_del(chan); | 990 | hci_chan_del(chan); |
| 965 | } | 991 | } |
| 992 | |||
| 993 | static struct hci_chan *__hci_chan_lookup_handle(struct hci_conn *hcon, | ||
| 994 | __u16 handle) | ||
| 995 | { | ||
| 996 | struct hci_chan *hchan; | ||
| 997 | |||
| 998 | list_for_each_entry(hchan, &hcon->chan_list, list) { | ||
| 999 | if (hchan->handle == handle) | ||
| 1000 | return hchan; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | return NULL; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle) | ||
| 1007 | { | ||
| 1008 | struct hci_conn_hash *h = &hdev->conn_hash; | ||
| 1009 | struct hci_conn *hcon; | ||
| 1010 | struct hci_chan *hchan = NULL; | ||
| 1011 | |||
| 1012 | rcu_read_lock(); | ||
| 1013 | |||
| 1014 | list_for_each_entry_rcu(hcon, &h->list, list) { | ||
| 1015 | hchan = __hci_chan_lookup_handle(hcon, handle); | ||
| 1016 | if (hchan) | ||
| 1017 | break; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | rcu_read_unlock(); | ||
| 1021 | |||
| 1022 | return hchan; | ||
| 1023 | } | ||
| @@ -405,7 +405,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, · 404 unmodified lines | |||
| 405 | struct discovery_state *cache = &hdev->discovery; | 405 | struct discovery_state *cache = &hdev->discovery; |
| 406 | struct inquiry_entry *e; | 406 | struct inquiry_entry *e; |
| 407 | 407 | ||
| 408 | BT_DBG("cache %p, %s", cache, batostr(bdaddr)); | 408 | BT_DBG("cache %p, %pMR", cache, bdaddr); |
| 409 | 409 | ||
| 410 | list_for_each_entry(e, &cache->all, all) { | 410 | list_for_each_entry(e, &cache->all, all) { |
| 411 | if (!bacmp(&e->data.bdaddr, bdaddr)) | 411 | if (!bacmp(&e->data.bdaddr, bdaddr)) |
| @@ -421,7 +421,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, · 9 unmodified lines | |||
| 421 | struct discovery_state *cache = &hdev->discovery; | 421 | struct discovery_state *cache = &hdev->discovery; |
| 422 | struct inquiry_entry *e; | 422 | struct inquiry_entry *e; |
| 423 | 423 | ||
| 424 | BT_DBG("cache %p, %s", cache, batostr(bdaddr)); | 424 | BT_DBG("cache %p, %pMR", cache, bdaddr); |
| 425 | 425 | ||
| 426 | list_for_each_entry(e, &cache->unknown, list) { | 426 | list_for_each_entry(e, &cache->unknown, list) { |
| 427 | if (!bacmp(&e->data.bdaddr, bdaddr)) | 427 | if (!bacmp(&e->data.bdaddr, bdaddr)) |
| @@ -438,7 +438,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, · 10 unmodified lines | |||
| 438 | struct discovery_state *cache = &hdev->discovery; | 438 | struct discovery_state *cache = &hdev->discovery; |
| 439 | struct inquiry_entry *e; | 439 | struct inquiry_entry *e; |
| 440 | 440 | ||
| 441 | BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state); | 441 | BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state); |
| 442 | 442 | ||
| 443 | list_for_each_entry(e, &cache->resolve, list) { | 443 | list_for_each_entry(e, &cache->resolve, list) { |
| 444 | if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) | 444 | if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state) |
| @@ -475,7 +475,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, · 30 unmodified lines | |||
| 475 | struct discovery_state *cache = &hdev->discovery; | 475 | struct discovery_state *cache = &hdev->discovery; |
| 476 | struct inquiry_entry *ie; | 476 | struct inquiry_entry *ie; |
| 477 | 477 | ||
| 478 | BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr)); | 478 | BT_DBG("cache %p, %pMR", cache, &data->bdaddr); |
| 479 | 479 | ||
| 480 | if (ssp) | 480 | if (ssp) |
| 481 | *ssp = data->ssp_mode; | 481 | *ssp = data->ssp_mode; |
| @@ -1259,7 +1259,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, · 777 unmodified lines | |||
| 1259 | list_add(&key->list, &hdev->link_keys); | 1259 | list_add(&key->list, &hdev->link_keys); |
| 1260 | } | 1260 | } |
| 1261 | 1261 | ||
| 1262 | BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); | 1262 | BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type); |
| 1263 | 1263 | ||
| 1264 | /* Some buggy controller combinations generate a changed | 1264 | /* Some buggy controller combinations generate a changed |
| 1265 | * combination key for legacy pairing even when there's no | 1265 | * combination key for legacy pairing even when there's no |
| @@ -1338,7 +1338,7 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) · 72 unmodified lines | |||
| 1338 | if (!key) | 1338 | if (!key) |
| 1339 | return -ENOENT; | 1339 | return -ENOENT; |
| 1340 | 1340 | ||
| 1341 | BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); | 1341 | BT_DBG("%s removing %pMR", hdev->name, bdaddr); |
| 1342 | 1342 | ||
| 1343 | list_del(&key->list); | 1343 | list_del(&key->list); |
| 1344 | kfree(key); | 1344 | kfree(key); |
| @@ -1354,7 +1354,7 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) · 9 unmodified lines | |||
| 1354 | if (bacmp(bdaddr, &k->bdaddr)) | 1354 | if (bacmp(bdaddr, &k->bdaddr)) |
| 1355 | continue; | 1355 | continue; |
| 1356 | 1356 | ||
| 1357 | BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); | 1357 | BT_DBG("%s removing %pMR", hdev->name, bdaddr); |
| 1358 | 1358 | ||
| 1359 | list_del(&k->list); | 1359 | list_del(&k->list); |
| 1360 | kfree(k); | 1360 | kfree(k); |
| @@ -1401,7 +1401,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr) · 40 unmodified lines | |||
| 1401 | if (!data) | 1401 | if (!data) |
| 1402 | return -ENOENT; | 1402 | return -ENOENT; |
| 1403 | 1403 | ||
| 1404 | BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); | 1404 | BT_DBG("%s removing %pMR", hdev->name, bdaddr); |
| 1405 | 1405 | ||
| 1406 | list_del(&data->list); | 1406 | list_del(&data->list); |
| 1407 | kfree(data); | 1407 | kfree(data); |
| @@ -1440,7 +1440,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, · 32 unmodified lines | |||
| 1440 | memcpy(data->hash, hash, sizeof(data->hash)); | 1440 | memcpy(data->hash, hash, sizeof(data->hash)); |
| 1441 | memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); | 1441 | memcpy(data->randomizer, randomizer, sizeof(data->randomizer)); |
| 1442 | 1442 | ||
| 1443 | BT_DBG("%s for %s", hdev->name, batostr(bdaddr)); | 1443 | BT_DBG("%s for %pMR", hdev->name, bdaddr); |
| 1444 | 1444 | ||
| 1445 | return 0; | 1445 | return 0; |
| 1446 | } | 1446 | } |
| @@ -2153,9 +2153,10 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) · 706 unmodified lines | |||
| 2153 | hdr->dlen = cpu_to_le16(len); | 2153 | hdr->dlen = cpu_to_le16(len); |
| 2154 | } | 2154 | } |
| 2155 | 2155 | ||
| 2156 | static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, | 2156 | static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, |
| 2157 | struct sk_buff *skb, __u16 flags) | 2157 | struct sk_buff *skb, __u16 flags) |
| 2158 | { | 2158 | { |
| 2159 | struct hci_conn *conn = chan->conn; | ||
| 2159 | struct hci_dev *hdev = conn->hdev; | 2160 | struct hci_dev *hdev = conn->hdev; |
| 2160 | struct sk_buff *list; | 2161 | struct sk_buff *list; |
| 2161 | 2162 | ||
| @@ -2163,7 +2164,18 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, · 1 unmodified line | |||
| 2163 | skb->data_len = 0; | 2164 | skb->data_len = 0; |
| 2164 | 2165 | ||
| 2165 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | 2166 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; |
| 2166 | hci_add_acl_hdr(skb, conn->handle, flags); | 2167 | |
| 2168 | switch (hdev->dev_type) { | ||
| 2169 | case HCI_BREDR: | ||
| 2170 | hci_add_acl_hdr(skb, conn->handle, flags); | ||
| 2171 | break; | ||
| 2172 | case HCI_AMP: | ||
| 2173 | hci_add_acl_hdr(skb, chan->handle, flags); | ||
| 2174 | break; | ||
| 2175 | default: | ||
| 2176 | BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); | ||
| 2177 | return; | ||
| 2178 | } | ||
| 2167 | 2179 | ||
| 2168 | list = skb_shinfo(skb)->frag_list; | 2180 | list = skb_shinfo(skb)->frag_list; |
| 2169 | if (!list) { | 2181 | if (!list) { |
| @@ -2202,14 +2214,13 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, · 32 unmodified lines | |||
| 2202 | 2214 | ||
| 2203 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) | 2215 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) |
| 2204 | { | 2216 | { |
| 2205 | struct hci_conn *conn = chan->conn; | 2217 | struct hci_dev *hdev = chan->conn->hdev; |
| 2206 | struct hci_dev *hdev = conn->hdev; | ||
| 2207 | 2218 | ||
| 2208 | BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); | 2219 | BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); |
| 2209 | 2220 | ||
| 2210 | skb->dev = (void *) hdev; | 2221 | skb->dev = (void *) hdev; |
| 2211 | 2222 | ||
| 2212 | hci_queue_acl(conn, &chan->data_q, skb, flags); | 2223 | hci_queue_acl(chan, &chan->data_q, skb, flags); |
| 2213 | 2224 | ||
| 2214 | queue_work(hdev->workqueue, &hdev->tx_work); | 2225 | queue_work(hdev->workqueue, &hdev->tx_work); |
| 2215 | } | 2226 | } |
| @@ -2311,8 +2322,8 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) · 95 unmodified lines | |||
| 2311 | /* Kill stalled connections */ | 2322 | /* Kill stalled connections */ |
| 2312 | list_for_each_entry_rcu(c, &h->list, list) { | 2323 | list_for_each_entry_rcu(c, &h->list, list) { |
| 2313 | if (c->type == type && c->sent) { | 2324 | if (c->type == type && c->sent) { |
| 2314 | BT_ERR("%s killing stalled connection %s", | 2325 | BT_ERR("%s killing stalled connection %pMR", |
| 2315 | hdev->name, batostr(&c->dst)); | 2326 | hdev->name, &c->dst); |
| 2316 | hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); | 2327 | hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); |
| 2317 | } | 2328 | } |
| 2318 | } | 2329 | } |
| @@ -2381,6 +2392,9 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, · 62 unmodified lines | |||
| 2381 | case ACL_LINK: | 2392 | case ACL_LINK: |
| 2382 | cnt = hdev->acl_cnt; | 2393 | cnt = hdev->acl_cnt; |
| 2383 | break; | 2394 | break; |
| 2395 | case AMP_LINK: | ||
| 2396 | cnt = hdev->block_cnt; | ||
| 2397 | break; | ||
| 2384 | case SCO_LINK: | 2398 | case SCO_LINK: |
| 2385 | case ESCO_LINK: | 2399 | case ESCO_LINK: |
| 2386 | cnt = hdev->sco_cnt; | 2400 | cnt = hdev->sco_cnt; |
| @@ -2510,11 +2524,19 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) · 123 unmodified lines | |||
| 2510 | struct hci_chan *chan; | 2524 | struct hci_chan *chan; |
| 2511 | struct sk_buff *skb; | 2525 | struct sk_buff *skb; |
| 2512 | int quote; | 2526 | int quote; |
| 2527 | u8 type; | ||
| 2513 | 2528 | ||
| 2514 | __check_timeout(hdev, cnt); | 2529 | __check_timeout(hdev, cnt); |
| 2515 | 2530 | ||
| 2531 | BT_DBG("%s", hdev->name); | ||
| 2532 | |||
| 2533 | if (hdev->dev_type == HCI_AMP) | ||
| 2534 | type = AMP_LINK; | ||
| 2535 | else | ||
| 2536 | type = ACL_LINK; | ||
| 2537 | |||
| 2516 | while (hdev->block_cnt > 0 && | 2538 | while (hdev->block_cnt > 0 && |
| 2517 | (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { | 2539 | (chan = hci_chan_sent(hdev, type, "e))) { |
| 2518 | u32 priority = (skb_peek(&chan->data_q))->priority; | 2540 | u32 priority = (skb_peek(&chan->data_q))->priority; |
| 2519 | while (quote > 0 && (skb = skb_peek(&chan->data_q))) { | 2541 | while (quote > 0 && (skb = skb_peek(&chan->data_q))) { |
| 2520 | int blocks; | 2542 | int blocks; |
| @@ -2547,14 +2569,19 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) · 26 unmodified lines | |||
| 2547 | } | 2569 | } |
| 2548 | 2570 | ||
| 2549 | if (cnt != hdev->block_cnt) | 2571 | if (cnt != hdev->block_cnt) |
| 2550 | hci_prio_recalculate(hdev, ACL_LINK); | 2572 | hci_prio_recalculate(hdev, type); |
| 2551 | } | 2573 | } |
| 2552 | 2574 | ||
| 2553 | static void hci_sched_acl(struct hci_dev *hdev) | 2575 | static void hci_sched_acl(struct hci_dev *hdev) |
| 2554 | { | 2576 | { |
| 2555 | BT_DBG("%s", hdev->name); | 2577 | BT_DBG("%s", hdev->name); |
| 2556 | 2578 | ||
| 2557 | if (!hci_conn_num(hdev, ACL_LINK)) | 2579 | /* No ACL link over BR/EDR controller */ |
| 2580 | if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR) | ||
| 2581 | return; | ||
| 2582 | |||
| 2583 | /* No AMP link over AMP controller */ | ||
| 2584 | if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP) | ||
| 2558 | return; | 2585 | return; |
| 2559 | 2586 | ||
| 2560 | switch (hdev->flow_ctl_mode) { | 2587 | switch (hdev->flow_ctl_mode) { |
| @@ -30,6 +30,8 @@ · 29 unmodified lines | |||
| 30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
| 31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
| 32 | #include <net/bluetooth/mgmt.h> | 32 | #include <net/bluetooth/mgmt.h> |
| 33 | #include <net/bluetooth/a2mp.h> | ||
| 34 | #include <net/bluetooth/amp.h> | ||
| 33 | 35 | ||
| 34 | /* Handle HCI Event packets */ | 36 | /* Handle HCI Event packets */ |
| 35 | 37 | ||
| @@ -846,7 +848,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, · 810 unmodified lines | |||
| 846 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | 848 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
| 847 | 849 | ||
| 848 | if (rp->status) | 850 | if (rp->status) |
| 849 | return; | 851 | goto a2mp_rsp; |
| 850 | 852 | ||
| 851 | hdev->amp_status = rp->amp_status; | 853 | hdev->amp_status = rp->amp_status; |
| 852 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); | 854 | hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); |
| @@ -860,6 +862,46 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, · 7 unmodified lines | |||
| 860 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); | 862 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); |
| 861 | 863 | ||
| 862 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); | 864 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); |
| 865 | |||
| 866 | a2mp_rsp: | ||
| 867 | a2mp_send_getinfo_rsp(hdev); | ||
| 868 | } | ||
| 869 | |||
| 870 | static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, | ||
| 871 | struct sk_buff *skb) | ||
| 872 | { | ||
| 873 | struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; | ||
| 874 | struct amp_assoc *assoc = &hdev->loc_assoc; | ||
| 875 | size_t rem_len, frag_len; | ||
| 876 | |||
| 877 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
| 878 | |||
| 879 | if (rp->status) | ||
| 880 | goto a2mp_rsp; | ||
| 881 | |||
| 882 | frag_len = skb->len - sizeof(*rp); | ||
| 883 | rem_len = __le16_to_cpu(rp->rem_len); | ||
| 884 | |||
| 885 | if (rem_len > frag_len) { | ||
| 886 | BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); | ||
| 887 | |||
| 888 | memcpy(assoc->data + assoc->offset, rp->frag, frag_len); | ||
| 889 | assoc->offset += frag_len; | ||
| 890 | |||
| 891 | /* Read other fragments */ | ||
| 892 | amp_read_loc_assoc_frag(hdev, rp->phy_handle); | ||
| 893 | |||
| 894 | return; | ||
| 895 | } | ||
| 896 | |||
| 897 | memcpy(assoc->data + assoc->offset, rp->frag, rem_len); | ||
| 898 | assoc->len = assoc->offset + rem_len; | ||
| 899 | assoc->offset = 0; | ||
| 900 | |||
| 901 | a2mp_rsp: | ||
| 902 | /* Send A2MP Rsp when all fragments are received */ | ||
| 903 | a2mp_send_getampassoc_rsp(hdev, rp->status); | ||
| 904 | a2mp_send_create_phy_link_req(hdev, rp->status); | ||
| 863 | } | 905 | } |
| 864 | 906 | ||
| 865 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | 907 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, |
| @@ -1174,6 +1216,20 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, · 308 unmodified lines | |||
| 1174 | hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); | 1216 | hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); |
| 1175 | } | 1217 | } |
| 1176 | 1218 | ||
| 1219 | static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, | ||
| 1220 | struct sk_buff *skb) | ||
| 1221 | { | ||
| 1222 | struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; | ||
| 1223 | |||
| 1224 | BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", | ||
| 1225 | hdev->name, rp->status, rp->phy_handle); | ||
| 1226 | |||
| 1227 | if (rp->status) | ||
| 1228 | return; | ||
| 1229 | |||
| 1230 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); | ||
| 1231 | } | ||
| 1232 | |||
| 1177 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 1233 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
| 1178 | { | 1234 | { |
| 1179 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1235 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
| @@ -1210,7 +1266,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) · 30 unmodified lines | |||
| 1210 | 1266 | ||
| 1211 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 1267 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
| 1212 | 1268 | ||
| 1213 | BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn); | 1269 | BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn); |
| 1214 | 1270 | ||
| 1215 | if (status) { | 1271 | if (status) { |
| 1216 | if (conn && conn->state == BT_CONNECT) { | 1272 | if (conn && conn->state == BT_CONNECT) { |
| @@ -1639,8 +1695,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) · 422 unmodified lines | |||
| 1639 | return; | 1695 | return; |
| 1640 | } | 1696 | } |
| 1641 | 1697 | ||
| 1642 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst), | 1698 | BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn); |
| 1643 | conn); | ||
| 1644 | 1699 | ||
| 1645 | conn->state = BT_CLOSED; | 1700 | conn->state = BT_CLOSED; |
| 1646 | mgmt_connect_failed(hdev, &conn->dst, conn->type, | 1701 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
| @@ -1657,6 +1712,38 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) · 10 unmodified lines | |||
| 1657 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1712 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
| 1658 | } | 1713 | } |
| 1659 | 1714 | ||
| 1715 | static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) | ||
| 1716 | { | ||
| 1717 | struct hci_cp_create_phy_link *cp; | ||
| 1718 | |||
| 1719 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
| 1720 | |||
| 1721 | if (status) | ||
| 1722 | return; | ||
| 1723 | |||
| 1724 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); | ||
| 1725 | if (!cp) | ||
| 1726 | return; | ||
| 1727 | |||
| 1728 | amp_write_remote_assoc(hdev, cp->phy_handle); | ||
| 1729 | } | ||
| 1730 | |||
| 1731 | static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) | ||
| 1732 | { | ||
| 1733 | struct hci_cp_accept_phy_link *cp; | ||
| 1734 | |||
| 1735 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
| 1736 | |||
| 1737 | if (status) | ||
| 1738 | return; | ||
| 1739 | |||
| 1740 | cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK); | ||
| 1741 | if (!cp) | ||
| 1742 | return; | ||
| 1743 | |||
| 1744 | amp_write_remote_assoc(hdev, cp->phy_handle); | ||
| 1745 | } | ||
| 1746 | |||
| 1660 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1747 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 1661 | { | 1748 | { |
| 1662 | __u8 status = *((__u8 *) skb->data); | 1749 | __u8 status = *((__u8 *) skb->data); |
| @@ -1822,7 +1909,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) · 159 unmodified lines | |||
| 1822 | struct hci_ev_conn_request *ev = (void *) skb->data; | 1909 | struct hci_ev_conn_request *ev = (void *) skb->data; |
| 1823 | int mask = hdev->link_mode; | 1910 | int mask = hdev->link_mode; |
| 1824 | 1911 | ||
| 1825 | BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), | 1912 | BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, |
| 1826 | ev->link_type); | 1913 | ev->link_type); |
| 1827 | 1914 | ||
| 1828 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); | 1915 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); |
| @@ -2314,6 +2401,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) · 485 unmodified lines | |||
| 2314 | hci_cc_read_local_amp_info(hdev, skb); | 2401 | hci_cc_read_local_amp_info(hdev, skb); |
| 2315 | break; | 2402 | break; |
| 2316 | 2403 | ||
| 2404 | case HCI_OP_READ_LOCAL_AMP_ASSOC: | ||
| 2405 | hci_cc_read_local_amp_assoc(hdev, skb); | ||
| 2406 | break; | ||
| 2407 | |||
| 2317 | case HCI_OP_DELETE_STORED_LINK_KEY: | 2408 | case HCI_OP_DELETE_STORED_LINK_KEY: |
| 2318 | hci_cc_delete_stored_link_key(hdev, skb); | 2409 | hci_cc_delete_stored_link_key(hdev, skb); |
| 2319 | break; | 2410 | break; |
| @@ -2386,6 +2477,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) · 66 unmodified lines | |||
| 2386 | hci_cc_write_le_host_supported(hdev, skb); | 2477 | hci_cc_write_le_host_supported(hdev, skb); |
| 2387 | break; | 2478 | break; |
| 2388 | 2479 | ||
| 2480 | case HCI_OP_WRITE_REMOTE_AMP_ASSOC: | ||
| 2481 | hci_cc_write_remote_amp_assoc(hdev, skb); | ||
| 2482 | break; | ||
| 2483 | |||
| 2389 | default: | 2484 | default: |
| 2390 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2485 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
| 2391 | break; | 2486 | break; |
| @@ -2467,6 +2562,14 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) · 75 unmodified lines | |||
| 2467 | hci_cs_le_start_enc(hdev, ev->status); | 2562 | hci_cs_le_start_enc(hdev, ev->status); |
| 2468 | break; | 2563 | break; |
| 2469 | 2564 | ||
| 2565 | case HCI_OP_CREATE_PHY_LINK: | ||
| 2566 | hci_cs_create_phylink(hdev, ev->status); | ||
| 2567 | break; | ||
| 2568 | |||
| 2569 | case HCI_OP_ACCEPT_PHY_LINK: | ||
| 2570 | hci_cs_accept_phylink(hdev, ev->status); | ||
| 2571 | break; | ||
| 2572 | |||
| 2470 | default: | 2573 | default: |
| 2471 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2574 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
| 2472 | break; | 2575 | break; |
| @@ -2574,6 +2677,27 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) · 101 unmodified lines | |||
| 2574 | queue_work(hdev->workqueue, &hdev->tx_work); | 2677 | queue_work(hdev->workqueue, &hdev->tx_work); |
| 2575 | } | 2678 | } |
| 2576 | 2679 | ||
| 2680 | static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev, | ||
| 2681 | __u16 handle) | ||
| 2682 | { | ||
| 2683 | struct hci_chan *chan; | ||
| 2684 | |||
| 2685 | switch (hdev->dev_type) { | ||
| 2686 | case HCI_BREDR: | ||
| 2687 | return hci_conn_hash_lookup_handle(hdev, handle); | ||
| 2688 | case HCI_AMP: | ||
| 2689 | chan = hci_chan_lookup_handle(hdev, handle); | ||
| 2690 | if (chan) | ||
| 2691 | return chan->conn; | ||
| 2692 | break; | ||
| 2693 | default: | ||
| 2694 | BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type); | ||
| 2695 | break; | ||
| 2696 | } | ||
| 2697 | |||
| 2698 | return NULL; | ||
| 2699 | } | ||
| 2700 | |||
| 2577 | static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2701 | static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) |
| 2578 | { | 2702 | { |
| 2579 | struct hci_ev_num_comp_blocks *ev = (void *) skb->data; | 2703 | struct hci_ev_num_comp_blocks *ev = (void *) skb->data; |
| @@ -2595,13 +2719,13 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) · 15 unmodified lines | |||
| 2595 | 2719 | ||
| 2596 | for (i = 0; i < ev->num_hndl; i++) { | 2720 | for (i = 0; i < ev->num_hndl; i++) { |
| 2597 | struct hci_comp_blocks_info *info = &ev->handles[i]; | 2721 | struct hci_comp_blocks_info *info = &ev->handles[i]; |
| 2598 | struct hci_conn *conn; | 2722 | struct hci_conn *conn = NULL; |
| 2599 | __u16 handle, block_count; | 2723 | __u16 handle, block_count; |
| 2600 | 2724 | ||
| 2601 | handle = __le16_to_cpu(info->handle); | 2725 | handle = __le16_to_cpu(info->handle); |
| 2602 | block_count = __le16_to_cpu(info->blocks); | 2726 | block_count = __le16_to_cpu(info->blocks); |
| 2603 | 2727 | ||
| 2604 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 2728 | conn = __hci_conn_lookup_handle(hdev, handle); |
| 2605 | if (!conn) | 2729 | if (!conn) |
| 2606 | continue; | 2730 | continue; |
| 2607 | 2731 | ||
| @@ -2609,6 +2733,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) · 1 unmodified line | |||
| 2609 | 2733 | ||
| 2610 | switch (conn->type) { | 2734 | switch (conn->type) { |
| 2611 | case ACL_LINK: | 2735 | case ACL_LINK: |
| 2736 | case AMP_LINK: | ||
| 2612 | hdev->block_cnt += block_count; | 2737 | hdev->block_cnt += block_count; |
| 2613 | if (hdev->block_cnt > hdev->num_blocks) | 2738 | if (hdev->block_cnt > hdev->num_blocks) |
| 2614 | hdev->block_cnt = hdev->num_blocks; | 2739 | hdev->block_cnt = hdev->num_blocks; |
| @@ -2705,13 +2830,13 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) · 90 unmodified lines | |||
| 2705 | 2830 | ||
| 2706 | key = hci_find_link_key(hdev, &ev->bdaddr); | 2831 | key = hci_find_link_key(hdev, &ev->bdaddr); |
| 2707 | if (!key) { | 2832 | if (!key) { |
| 2708 | BT_DBG("%s link key not found for %s", hdev->name, | 2833 | BT_DBG("%s link key not found for %pMR", hdev->name, |
| 2709 | batostr(&ev->bdaddr)); | 2834 | &ev->bdaddr); |
| 2710 | goto not_found; | 2835 | goto not_found; |
| 2711 | } | 2836 | } |
| 2712 | 2837 | ||
| 2713 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, | 2838 | BT_DBG("%s found key type %u for %pMR", hdev->name, key->type, |
| 2714 | batostr(&ev->bdaddr)); | 2839 | &ev->bdaddr); |
| 2715 | 2840 | ||
| 2716 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && | 2841 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && |
| 2717 | key->type == HCI_LK_DEBUG_COMBINATION) { | 2842 | key->type == HCI_LK_DEBUG_COMBINATION) { |
| @@ -3558,6 +3683,22 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) · 840 unmodified lines | |||
| 3558 | } | 3683 | } |
| 3559 | } | 3684 | } |
| 3560 | 3685 | ||
| 3686 | static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
| 3687 | { | ||
| 3688 | struct hci_ev_channel_selected *ev = (void *) skb->data; | ||
| 3689 | struct hci_conn *hcon; | ||
| 3690 | |||
| 3691 | BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle); | ||
| 3692 | |||
| 3693 | skb_pull(skb, sizeof(*ev)); | ||
| 3694 | |||
| 3695 | hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); | ||
| 3696 | if (!hcon) | ||
| 3697 | return; | ||
| 3698 | |||
| 3699 | amp_read_loc_assoc_final_data(hdev, hcon); | ||
| 3700 | } | ||
| 3701 | |||
| 3561 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 3702 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
| 3562 | { | 3703 | { |
| 3563 | struct hci_event_hdr *hdr = (void *) skb->data; | 3704 | struct hci_event_hdr *hdr = (void *) skb->data; |
| @@ -3722,6 +3863,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) · 158 unmodified lines | |||
| 3722 | hci_le_meta_evt(hdev, skb); | 3863 | hci_le_meta_evt(hdev, skb); |
| 3723 | break; | 3864 | break; |
| 3724 | 3865 | ||
| 3866 | case HCI_EV_CHANNEL_SELECTED: | ||
| 3867 | hci_chan_selected_evt(hdev, skb); | ||
| 3868 | break; | ||
| 3869 | |||
| 3725 | case HCI_EV_REMOTE_OOB_DATA_REQUEST: | 3870 | case HCI_EV_REMOTE_OOB_DATA_REQUEST: |
| 3726 | hci_remote_oob_data_request_evt(hdev, skb); | 3871 | hci_remote_oob_data_request_evt(hdev, skb); |
| 3727 | break; | 3872 | break; |
| @@ -38,7 +38,7 @@ static ssize_t show_link_address(struct device *dev, · 37 unmodified lines | |||
| 38 | struct device_attribute *attr, char *buf) | 38 | struct device_attribute *attr, char *buf) |
| 39 | { | 39 | { |
| 40 | struct hci_conn *conn = to_hci_conn(dev); | 40 | struct hci_conn *conn = to_hci_conn(dev); |
| 41 | return sprintf(buf, "%s\n", batostr(&conn->dst)); | 41 | return sprintf(buf, "%pMR\n", &conn->dst); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | static ssize_t show_link_features(struct device *dev, | 44 | static ssize_t show_link_features(struct device *dev, |
| @@ -224,7 +224,7 @@ static ssize_t show_address(struct device *dev, · 179 unmodified lines | |||
| 224 | struct device_attribute *attr, char *buf) | 224 | struct device_attribute *attr, char *buf) |
| 225 | { | 225 | { |
| 226 | struct hci_dev *hdev = to_hci_dev(dev); | 226 | struct hci_dev *hdev = to_hci_dev(dev); |
| 227 | return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); | 227 | return sprintf(buf, "%pMR\n", &hdev->bdaddr); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | static ssize_t show_features(struct device *dev, | 230 | static ssize_t show_features(struct device *dev, |
| @@ -406,8 +406,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p) · 175 unmodified lines | |||
| 406 | 406 | ||
| 407 | list_for_each_entry(e, &cache->all, all) { | 407 | list_for_each_entry(e, &cache->all, all) { |
| 408 | struct inquiry_data *data = &e->data; | 408 | struct inquiry_data *data = &e->data; |
| 409 | seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | 409 | seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", |
| 410 | batostr(&data->bdaddr), | 410 | &data->bdaddr, |
| 411 | data->pscan_rep_mode, data->pscan_period_mode, | 411 | data->pscan_rep_mode, data->pscan_period_mode, |
| 412 | data->pscan_mode, data->dev_class[2], | 412 | data->pscan_mode, data->dev_class[2], |
| 413 | data->dev_class[1], data->dev_class[0], | 413 | data->dev_class[1], data->dev_class[0], |
| @@ -440,7 +440,7 @@ static int blacklist_show(struct seq_file *f, void *p) · 26 unmodified lines | |||
| 440 | hci_dev_lock(hdev); | 440 | hci_dev_lock(hdev); |
| 441 | 441 | ||
| 442 | list_for_each_entry(b, &hdev->blacklist, list) | 442 | list_for_each_entry(b, &hdev->blacklist, list) |
| 443 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); | 443 | seq_printf(f, "%pMR\n", &b->bdaddr); |
| 444 | 444 | ||
| 445 | hci_dev_unlock(hdev); | 445 | hci_dev_unlock(hdev); |
| 446 | 446 | ||
| @@ -932,8 +932,12 @@ static int hidp_setup_hid(struct hidp_session *session, · 931 unmodified lines | |||
| 932 | hid->country = req->country; | 932 | hid->country = req->country; |
| 933 | 933 | ||
| 934 | strncpy(hid->name, req->name, 128); | 934 | strncpy(hid->name, req->name, 128); |
| 935 | strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); | 935 | |
| 936 | strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); | 936 | snprintf(hid->phys, sizeof(hid->phys), "%pMR", |
| 937 | &bt_sk(session->ctrl_sock->sk)->src); | ||
| 938 | |||
| 939 | snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", | ||
| 940 | &bt_sk(session->ctrl_sock->sk)->dst); | ||
| 937 | 941 | ||
| 938 | hid->dev.parent = &session->conn->dev; | 942 | hid->dev.parent = &session->conn->dev; |
| 939 | hid->ll_driver = &hidp_hid_driver; | 943 | hid->ll_driver = &hidp_hid_driver; |
| @@ -48,19 +48,20 @@ static LIST_HEAD(chan_list); · 47 unmodified lines | |||
| 48 | static DEFINE_RWLOCK(chan_list_lock); | 48 | static DEFINE_RWLOCK(chan_list_lock); |
| 49 | 49 | ||
| 50 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 50 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
| 51 | u8 code, u8 ident, u16 dlen, void *data); | 51 | u8 code, u8 ident, u16 dlen, void *data); |
| 52 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | 52 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, |
| 53 | void *data); | 53 | void *data); |
| 54 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); | 54 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); |
| 55 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, | 55 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, |
| 56 | struct l2cap_chan *chan, int err); | 56 | struct l2cap_chan *chan, int err); |
| 57 | 57 | ||
| 58 | static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, | 58 | static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, |
| 59 | struct sk_buff_head *skbs, u8 event); | 59 | struct sk_buff_head *skbs, u8 event); |
| 60 | 60 | ||
| 61 | /* ---- L2CAP channels ---- */ | 61 | /* ---- L2CAP channels ---- */ |
| 62 | 62 | ||
| 63 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) | 63 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, |
| 64 | u16 cid) | ||
| 64 | { | 65 | { |
| 65 | struct l2cap_chan *c; | 66 | struct l2cap_chan *c; |
| 66 | 67 | ||
| @@ -71,7 +72,8 @@ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 · 4 unmodified lines | |||
| 71 | return NULL; | 72 | return NULL; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) | 75 | static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, |
| 76 | u16 cid) | ||
| 75 | { | 77 | { |
| 76 | struct l2cap_chan *c; | 78 | struct l2cap_chan *c; |
| 77 | 79 | ||
| @@ -84,7 +86,8 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 · 6 unmodified lines | |||
| 84 | 86 | ||
| 85 | /* Find channel with given SCID. | 87 | /* Find channel with given SCID. |
| 86 | * Returns locked channel. */ | 88 | * Returns locked channel. */ |
| 87 | static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) | 89 | static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, |
| 90 | u16 cid) | ||
| 88 | { | 91 | { |
| 89 | struct l2cap_chan *c; | 92 | struct l2cap_chan *c; |
| 90 | 93 | ||
| @@ -97,7 +100,8 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 ci · 6 unmodified lines | |||
| 97 | return c; | 100 | return c; |
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) | 103 | static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, |
| 104 | u8 ident) | ||
| 101 | { | 105 | { |
| 102 | struct l2cap_chan *c; | 106 | struct l2cap_chan *c; |
| 103 | 107 | ||
| @@ -178,7 +182,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) · 74 unmodified lines | |||
| 178 | static void __l2cap_state_change(struct l2cap_chan *chan, int state) | 182 | static void __l2cap_state_change(struct l2cap_chan *chan, int state) |
| 179 | { | 183 | { |
| 180 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), | 184 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), |
| 181 | state_to_string(state)); | 185 | state_to_string(state)); |
| 182 | 186 | ||
| 183 | chan->state = state; | 187 | chan->state = state; |
| 184 | chan->ops->state_change(chan, state); | 188 | chan->ops->state_change(chan, state); |
| @@ -361,7 +365,7 @@ static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq) · 176 unmodified lines | |||
| 361 | static void l2cap_chan_timeout(struct work_struct *work) | 365 | static void l2cap_chan_timeout(struct work_struct *work) |
| 362 | { | 366 | { |
| 363 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, | 367 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
| 364 | chan_timer.work); | 368 | chan_timer.work); |
| 365 | struct l2cap_conn *conn = chan->conn; | 369 | struct l2cap_conn *conn = chan->conn; |
| 366 | int reason; | 370 | int reason; |
| 367 | 371 | ||
| @@ -373,7 +377,7 @@ static void l2cap_chan_timeout(struct work_struct *work) · 5 unmodified lines | |||
| 373 | if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) | 377 | if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) |
| 374 | reason = ECONNREFUSED; | 378 | reason = ECONNREFUSED; |
| 375 | else if (chan->state == BT_CONNECT && | 379 | else if (chan->state == BT_CONNECT && |
| 376 | chan->sec_level != BT_SECURITY_SDP) | 380 | chan->sec_level != BT_SECURITY_SDP) |
| 377 | reason = ECONNREFUSED; | 381 | reason = ECONNREFUSED; |
| 378 | else | 382 | else |
| 379 | reason = ETIMEDOUT; | 383 | reason = ETIMEDOUT; |
| @@ -455,7 +459,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) · 75 unmodified lines | |||
| 455 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | 459 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
| 456 | } | 460 | } |
| 457 | 461 | ||
| 458 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 462 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
| 459 | { | 463 | { |
| 460 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 464 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
| 461 | __le16_to_cpu(chan->psm), chan->dcid); | 465 | __le16_to_cpu(chan->psm), chan->dcid); |
| @@ -504,7 +508,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) · 42 unmodified lines | |||
| 504 | chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE; | 508 | chan->local_msdu = L2CAP_DEFAULT_MAX_SDU_SIZE; |
| 505 | chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME; | 509 | chan->local_sdu_itime = L2CAP_DEFAULT_SDU_ITIME; |
| 506 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; | 510 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; |
| 507 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; | 511 | chan->local_flush_to = L2CAP_EFS_DEFAULT_FLUSH_TO; |
| 508 | 512 | ||
| 509 | l2cap_chan_hold(chan); | 513 | l2cap_chan_hold(chan); |
| 510 | 514 | ||
| @@ -527,6 +531,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) · 16 unmodified lines | |||
| 527 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); | 531 | BT_DBG("chan %p, conn %p, err %d", chan, conn, err); |
| 528 | 532 | ||
| 529 | if (conn) { | 533 | if (conn) { |
| 534 | struct amp_mgr *mgr = conn->hcon->amp_mgr; | ||
| 530 | /* Delete from channel list */ | 535 | /* Delete from channel list */ |
| 531 | list_del(&chan->list); | 536 | list_del(&chan->list); |
| 532 | 537 | ||
| @@ -536,10 +541,12 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) · 3 unmodified lines | |||
| 536 | 541 | ||
| 537 | if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) | 542 | if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) |
| 538 | hci_conn_put(conn->hcon); | 543 | hci_conn_put(conn->hcon); |
| 544 | |||
| 545 | if (mgr && mgr->bredr_chan == chan) | ||
| 546 | mgr->bredr_chan = NULL; | ||
| 539 | } | 547 | } |
| 540 | 548 | ||
| 541 | if (chan->ops->teardown) | 549 | chan->ops->teardown(chan, err); |
| 542 | chan->ops->teardown(chan, err); | ||
| 543 | 550 | ||
| 544 | if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) | 551 | if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) |
| 545 | return; | 552 | return; |
| @@ -573,19 +580,18 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) · 27 unmodified lines | |||
| 573 | struct l2cap_conn *conn = chan->conn; | 580 | struct l2cap_conn *conn = chan->conn; |
| 574 | struct sock *sk = chan->sk; | 581 | struct sock *sk = chan->sk; |
| 575 | 582 | ||
| 576 | BT_DBG("chan %p state %s sk %p", chan, | 583 | BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state), |
| 577 | state_to_string(chan->state), sk); | 584 | sk); |
| 578 | 585 | ||
| 579 | switch (chan->state) { | 586 | switch (chan->state) { |
| 580 | case BT_LISTEN: | 587 | case BT_LISTEN: |
| 581 | if (chan->ops->teardown) | 588 | chan->ops->teardown(chan, 0); |
| 582 | chan->ops->teardown(chan, 0); | ||
| 583 | break; | 589 | break; |
| 584 | 590 | ||
| 585 | case BT_CONNECTED: | 591 | case BT_CONNECTED: |
| 586 | case BT_CONFIG: | 592 | case BT_CONFIG: |
| 587 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && | 593 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && |
| 588 | conn->hcon->type == ACL_LINK) { | 594 | conn->hcon->type == ACL_LINK) { |
| 589 | __set_chan_timer(chan, sk->sk_sndtimeo); | 595 | __set_chan_timer(chan, sk->sk_sndtimeo); |
| 590 | l2cap_send_disconn_req(conn, chan, reason); | 596 | l2cap_send_disconn_req(conn, chan, reason); |
| 591 | } else | 597 | } else |
| @@ -594,7 +600,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) · 2 unmodified lines | |||
| 594 | 600 | ||
| 595 | case BT_CONNECT2: | 601 | case BT_CONNECT2: |
| 596 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && | 602 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && |
| 597 | conn->hcon->type == ACL_LINK) { | 603 | conn->hcon->type == ACL_LINK) { |
| 598 | struct l2cap_conn_rsp rsp; | 604 | struct l2cap_conn_rsp rsp; |
| 599 | __u16 result; | 605 | __u16 result; |
| 600 | 606 | ||
| @@ -609,7 +615,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) · 8 unmodified lines | |||
| 609 | rsp.result = cpu_to_le16(result); | 615 | rsp.result = cpu_to_le16(result); |
| 610 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); | 616 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); |
| 611 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 617 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
| 612 | sizeof(rsp), &rsp); | 618 | sizeof(rsp), &rsp); |
| 613 | } | 619 | } |
| 614 | 620 | ||
| 615 | l2cap_chan_del(chan, reason); | 621 | l2cap_chan_del(chan, reason); |
| @@ -621,8 +627,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) · 5 unmodified lines | |||
| 621 | break; | 627 | break; |
| 622 | 628 | ||
| 623 | default: | 629 | default: |
| 624 | if (chan->ops->teardown) | 630 | chan->ops->teardown(chan, 0); |
| 625 | chan->ops->teardown(chan, 0); | ||
| 626 | break; | 631 | break; |
| 627 | } | 632 | } |
| 628 | } | 633 | } |
| @@ -691,7 +696,8 @@ static u8 l2cap_get_ident(struct l2cap_conn *conn) · 62 unmodified lines | |||
| 691 | return id; | 696 | return id; |
| 692 | } | 697 | } |
| 693 | 698 | ||
| 694 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) | 699 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, |
| 700 | void *data) | ||
| 695 | { | 701 | { |
| 696 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); | 702 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); |
| 697 | u8 flags; | 703 | u8 flags; |
| @@ -718,10 +724,10 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) · 20 unmodified lines | |||
| 718 | u16 flags; | 724 | u16 flags; |
| 719 | 725 | ||
| 720 | BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, | 726 | BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, |
| 721 | skb->priority); | 727 | skb->priority); |
| 722 | 728 | ||
| 723 | if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && | 729 | if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && |
| 724 | lmp_no_flush_capable(hcon->hdev)) | 730 | lmp_no_flush_capable(hcon->hdev)) |
| 725 | flags = ACL_START_NO_FLUSH; | 731 | flags = ACL_START_NO_FLUSH; |
| 726 | else | 732 | else |
| 727 | flags = ACL_START; | 733 | flags = ACL_START; |
| @@ -946,7 +952,19 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) · 218 unmodified lines | |||
| 946 | return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); | 952 | return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); |
| 947 | } | 953 | } |
| 948 | 954 | ||
| 949 | static void l2cap_send_conn_req(struct l2cap_chan *chan) | 955 | static bool __amp_capable(struct l2cap_chan *chan) |
| 956 | { | ||
| 957 | struct l2cap_conn *conn = chan->conn; | ||
| 958 | |||
| 959 | if (enable_hs && | ||
| 960 | chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && | ||
| 961 | conn->fixed_chan_mask & L2CAP_FC_A2MP) | ||
| 962 | return true; | ||
| 963 | else | ||
| 964 | return false; | ||
| 965 | } | ||
| 966 | |||
| 967 | void l2cap_send_conn_req(struct l2cap_chan *chan) | ||
| 950 | { | 968 | { |
| 951 | struct l2cap_conn *conn = chan->conn; | 969 | struct l2cap_conn *conn = chan->conn; |
| 952 | struct l2cap_conn_req req; | 970 | struct l2cap_conn_req req; |
| @@ -972,6 +990,16 @@ static void l2cap_chan_ready(struct l2cap_chan *chan) · 19 unmodified lines | |||
| 972 | chan->ops->ready(chan); | 990 | chan->ops->ready(chan); |
| 973 | } | 991 | } |
| 974 | 992 | ||
| 993 | static void l2cap_start_connection(struct l2cap_chan *chan) | ||
| 994 | { | ||
| 995 | if (__amp_capable(chan)) { | ||
| 996 | BT_DBG("chan %p AMP capable: discover AMPs", chan); | ||
| 997 | a2mp_discover_amp(chan); | ||
| 998 | } else { | ||
| 999 | l2cap_send_conn_req(chan); | ||
| 1000 | } | ||
| 1001 | } | ||
| 1002 | |||
| 975 | static void l2cap_do_start(struct l2cap_chan *chan) | 1003 | static void l2cap_do_start(struct l2cap_chan *chan) |
| 976 | { | 1004 | { |
| 977 | struct l2cap_conn *conn = chan->conn; | 1005 | struct l2cap_conn *conn = chan->conn; |
| @@ -986,8 +1014,9 @@ static void l2cap_do_start(struct l2cap_chan *chan) · 8 unmodified lines | |||
| 986 | return; | 1014 | return; |
| 987 | 1015 | ||
| 988 | if (l2cap_chan_check_security(chan) && | 1016 | if (l2cap_chan_check_security(chan) && |
| 989 | __l2cap_no_conn_pending(chan)) | 1017 | __l2cap_no_conn_pending(chan)) { |
| 990 | l2cap_send_conn_req(chan); | 1018 | l2cap_start_connection(chan); |
| 1019 | } | ||
| 991 | } else { | 1020 | } else { |
| 992 | struct l2cap_info_req req; | 1021 | struct l2cap_info_req req; |
| 993 | req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); | 1022 | req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); |
| @@ -997,8 +1026,8 @@ static void l2cap_do_start(struct l2cap_chan *chan) · 3 unmodified lines | |||
| 997 | 1026 | ||
| 998 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | 1027 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); |
| 999 | 1028 | ||
| 1000 | l2cap_send_cmd(conn, conn->info_ident, | 1029 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, |
| 1001 | L2CAP_INFO_REQ, sizeof(req), &req); | 1030 | sizeof(req), &req); |
| 1002 | } | 1031 | } |
| 1003 | } | 1032 | } |
| 1004 | 1033 | ||
| @@ -1018,7 +1047,8 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) · 13 unmodified lines | |||
| 1018 | } | 1047 | } |
| 1019 | } | 1048 | } |
| 1020 | 1049 | ||
| 1021 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) | 1050 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, |
| 1051 | struct l2cap_chan *chan, int err) | ||
| 1022 | { | 1052 | { |
| 1023 | struct sock *sk = chan->sk; | 1053 | struct sock *sk = chan->sk; |
| 1024 | struct l2cap_disconn_req req; | 1054 | struct l2cap_disconn_req req; |
| @@ -1033,14 +1063,14 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c · 8 unmodified lines | |||
| 1033 | } | 1063 | } |
| 1034 | 1064 | ||
| 1035 | if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { | 1065 | if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { |
| 1036 | __l2cap_state_change(chan, BT_DISCONN); | 1066 | l2cap_state_change(chan, BT_DISCONN); |
| 1037 | return; | 1067 | return; |
| 1038 | } | 1068 | } |
| 1039 | 1069 | ||
| 1040 | req.dcid = cpu_to_le16(chan->dcid); | 1070 | req.dcid = cpu_to_le16(chan->dcid); |
| 1041 | req.scid = cpu_to_le16(chan->scid); | 1071 | req.scid = cpu_to_le16(chan->scid); |
| 1042 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 1072 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, |
| 1043 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 1073 | sizeof(req), &req); |
| 1044 | 1074 | ||
| 1045 | lock_sock(sk); | 1075 | lock_sock(sk); |
| 1046 | __l2cap_state_change(chan, BT_DISCONN); | 1076 | __l2cap_state_change(chan, BT_DISCONN); |
| @@ -1069,20 +1099,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn) · 22 unmodified lines | |||
| 1069 | 1099 | ||
| 1070 | if (chan->state == BT_CONNECT) { | 1100 | if (chan->state == BT_CONNECT) { |
| 1071 | if (!l2cap_chan_check_security(chan) || | 1101 | if (!l2cap_chan_check_security(chan) || |
| 1072 | !__l2cap_no_conn_pending(chan)) { | 1102 | !__l2cap_no_conn_pending(chan)) { |
| 1073 | l2cap_chan_unlock(chan); | 1103 | l2cap_chan_unlock(chan); |
| 1074 | continue; | 1104 | continue; |
| 1075 | } | 1105 | } |
| 1076 | 1106 | ||
| 1077 | if (!l2cap_mode_supported(chan->mode, conn->feat_mask) | 1107 | if (!l2cap_mode_supported(chan->mode, conn->feat_mask) |
| 1078 | && test_bit(CONF_STATE2_DEVICE, | 1108 | && test_bit(CONF_STATE2_DEVICE, |
| 1079 | &chan->conf_state)) { | 1109 | &chan->conf_state)) { |
| 1080 | l2cap_chan_close(chan, ECONNRESET); | 1110 | l2cap_chan_close(chan, ECONNRESET); |
| 1081 | l2cap_chan_unlock(chan); | 1111 | l2cap_chan_unlock(chan); |
| 1082 | continue; | 1112 | continue; |
| 1083 | } | 1113 | } |
| 1084 | 1114 | ||
| 1085 | l2cap_send_conn_req(chan); | 1115 | l2cap_start_connection(chan); |
| 1086 | 1116 | ||
| 1087 | } else if (chan->state == BT_CONNECT2) { | 1117 | } else if (chan->state == BT_CONNECT2) { |
| 1088 | struct l2cap_conn_rsp rsp; | 1118 | struct l2cap_conn_rsp rsp; |
| @@ -1094,11 +1124,9 @@ static void l2cap_conn_start(struct l2cap_conn *conn) · 5 unmodified lines | |||
| 1094 | lock_sock(sk); | 1124 | lock_sock(sk); |
| 1095 | if (test_bit(BT_SK_DEFER_SETUP, | 1125 | if (test_bit(BT_SK_DEFER_SETUP, |
| 1096 | &bt_sk(sk)->flags)) { | 1126 | &bt_sk(sk)->flags)) { |
| 1097 | struct sock *parent = bt_sk(sk)->parent; | ||
| 1098 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); | 1127 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); |
| 1099 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); | 1128 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); |
| 1100 | if (parent) | 1129 | chan->ops->defer(chan); |
| 1101 | parent->sk_data_ready(parent, 0); | ||
| 1102 | 1130 | ||
| 1103 | } else { | 1131 | } else { |
| 1104 | __l2cap_state_change(chan, BT_CONFIG); | 1132 | __l2cap_state_change(chan, BT_CONFIG); |
| @@ -1112,17 +1140,17 @@ static void l2cap_conn_start(struct l2cap_conn *conn) · 7 unmodified lines | |||
| 1112 | } | 1140 | } |
| 1113 | 1141 | ||
| 1114 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 1142 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
| 1115 | sizeof(rsp), &rsp); | 1143 | sizeof(rsp), &rsp); |
| 1116 | 1144 | ||
| 1117 | if (test_bit(CONF_REQ_SENT, &chan->conf_state) || | 1145 | if (test_bit(CONF_REQ_SENT, &chan->conf_state) || |
| 1118 | rsp.result != L2CAP_CR_SUCCESS) { | 1146 | rsp.result != L2CAP_CR_SUCCESS) { |
| 1119 | l2cap_chan_unlock(chan); | 1147 | l2cap_chan_unlock(chan); |
| 1120 | continue; | 1148 | continue; |
| 1121 | } | 1149 | } |
| 1122 | 1150 | ||
| 1123 | set_bit(CONF_REQ_SENT, &chan->conf_state); | 1151 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
| 1124 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 1152 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
| 1125 | l2cap_build_conf_req(chan, buf), buf); | 1153 | l2cap_build_conf_req(chan, buf), buf); |
| 1126 | chan->num_conf_req++; | 1154 | chan->num_conf_req++; |
| 1127 | } | 1155 | } |
| 1128 | 1156 | ||
| @@ -1204,8 +1232,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) · 75 unmodified lines | |||
| 1204 | bacpy(&bt_sk(sk)->src, conn->src); | 1232 | bacpy(&bt_sk(sk)->src, conn->src); |
| 1205 | bacpy(&bt_sk(sk)->dst, conn->dst); | 1233 | bacpy(&bt_sk(sk)->dst, conn->dst); |
| 1206 | 1234 | ||
| 1207 | bt_accept_enqueue(parent, sk); | ||
| 1208 | |||
| 1209 | l2cap_chan_add(conn, chan); | 1235 | l2cap_chan_add(conn, chan); |
| 1210 | 1236 | ||
| 1211 | l2cap_chan_ready(chan); | 1237 | l2cap_chan_ready(chan); |
| @@ -1270,7 +1296,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) · 58 unmodified lines | |||
| 1270 | 1296 | ||
| 1271 | list_for_each_entry(chan, &conn->chan_l, list) { | 1297 | list_for_each_entry(chan, &conn->chan_l, list) { |
| 1272 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) | 1298 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
| 1273 | __l2cap_chan_set_err(chan, err); | 1299 | l2cap_chan_set_err(chan, err); |
| 1274 | } | 1300 | } |
| 1275 | 1301 | ||
| 1276 | mutex_unlock(&conn->chan_lock); | 1302 | mutex_unlock(&conn->chan_lock); |
| @@ -1279,7 +1305,7 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) · 2 unmodified lines | |||
| 1279 | static void l2cap_info_timeout(struct work_struct *work) | 1305 | static void l2cap_info_timeout(struct work_struct *work) |
| 1280 | { | 1306 | { |
| 1281 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, | 1307 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
| 1282 | info_timer.work); | 1308 | info_timer.work); |
| 1283 | 1309 | ||
| 1284 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 1310 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
| 1285 | conn->info_ident = 0; | 1311 | conn->info_ident = 0; |
| @@ -1333,7 +1359,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) · 47 unmodified lines | |||
| 1333 | static void security_timeout(struct work_struct *work) | 1359 | static void security_timeout(struct work_struct *work) |
| 1334 | { | 1360 | { |
| 1335 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, | 1361 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
| 1336 | security_timer.work); | 1362 | security_timer.work); |
| 1337 | 1363 | ||
| 1338 | BT_DBG("conn %p", conn); | 1364 | BT_DBG("conn %p", conn); |
| 1339 | 1365 | ||
| @@ -1355,7 +1381,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) · 15 unmodified lines | |||
| 1355 | if (!hchan) | 1381 | if (!hchan) |
| 1356 | return NULL; | 1382 | return NULL; |
| 1357 | 1383 | ||
| 1358 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); | 1384 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_KERNEL); |
| 1359 | if (!conn) { | 1385 | if (!conn) { |
| 1360 | hci_chan_del(hchan); | 1386 | hci_chan_del(hchan); |
| 1361 | return NULL; | 1387 | return NULL; |
| @@ -1367,10 +1393,22 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) · 5 unmodified lines | |||
| 1367 | 1393 | ||
| 1368 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); | 1394 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); |
| 1369 | 1395 | ||
| 1370 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) | 1396 | switch (hcon->type) { |
| 1371 | conn->mtu = hcon->hdev->le_mtu; | 1397 | case AMP_LINK: |
| 1372 | else | 1398 | conn->mtu = hcon->hdev->block_mtu; |
| 1399 | break; | ||
| 1400 | |||
| 1401 | case LE_LINK: | ||
| 1402 | if (hcon->hdev->le_mtu) { | ||
| 1403 | conn->mtu = hcon->hdev->le_mtu; | ||
| 1404 | break; | ||
| 1405 | } | ||
| 1406 | /* fall through */ | ||
| 1407 | |||
| 1408 | default: | ||
| 1373 | conn->mtu = hcon->hdev->acl_mtu; | 1409 | conn->mtu = hcon->hdev->acl_mtu; |
| 1410 | break; | ||
| 1411 | } | ||
| 1374 | 1412 | ||
| 1375 | conn->src = &hcon->hdev->bdaddr; | 1413 | conn->src = &hcon->hdev->bdaddr; |
| 1376 | conn->dst = &hcon->dst; | 1414 | conn->dst = &hcon->dst; |
| @@ -1448,7 +1486,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · 71 unmodified lines | |||
| 1448 | __u8 auth_type; | 1486 | __u8 auth_type; |
| 1449 | int err; | 1487 | int err; |
| 1450 | 1488 | ||
| 1451 | BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst), | 1489 | BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst, |
| 1452 | dst_type, __le16_to_cpu(psm)); | 1490 | dst_type, __le16_to_cpu(psm)); |
| 1453 | 1491 | ||
| 1454 | hdev = hci_get_route(dst, src); | 1492 | hdev = hci_get_route(dst, src); |
| @@ -1461,7 +1499,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, · 6 unmodified lines | |||
| 1461 | 1499 | ||
| 1462 | /* PSM must be odd and lsb of upper byte must be 0 */ | 1500 | /* PSM must be odd and lsb of upper byte must be 0 */ |
| 1463 | if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid && | 1501 | if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid && |
| 1464 | chan->chan_type != L2CAP_CHAN_RAW) { | 1502 | chan->chan_type != L2CAP_CHAN_RAW) { |
| 1465 | err = -EINVAL; | 1503 | err = -EINVAL; |
| 1466 | goto done; | 1504 | goto done; |
| 1467 | } | 1505 | } |
| @@ -1770,7 +1808,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) · 302 unmodified lines | |||
| 1770 | skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq); | 1808 | skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq); |
| 1771 | if (!skb) { | 1809 | if (!skb) { |
| 1772 | BT_DBG("Error: Can't retransmit seq %d, frame missing", | 1810 | BT_DBG("Error: Can't retransmit seq %d, frame missing", |
| 1773 | seq); | 1811 | seq); |
| 1774 | continue; | 1812 | continue; |
| 1775 | } | 1813 | } |
| 1776 | 1814 | ||
| @@ -1795,9 +1833,9 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) · 18 unmodified lines | |||
| 1795 | /* Cloned sk_buffs are read-only, so we need a | 1833 | /* Cloned sk_buffs are read-only, so we need a |
| 1796 | * writeable copy | 1834 | * writeable copy |
| 1797 | */ | 1835 | */ |
| 1798 | tx_skb = skb_copy(skb, GFP_ATOMIC); | 1836 | tx_skb = skb_copy(skb, GFP_KERNEL); |
| 1799 | } else { | 1837 | } else { |
| 1800 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1838 | tx_skb = skb_clone(skb, GFP_KERNEL); |
| 1801 | } | 1839 | } |
| 1802 | 1840 | ||
| 1803 | if (!tx_skb) { | 1841 | if (!tx_skb) { |
| @@ -1855,7 +1893,7 @@ static void l2cap_retransmit_all(struct l2cap_chan *chan, · 51 unmodified lines | |||
| 1855 | if (chan->unacked_frames) { | 1893 | if (chan->unacked_frames) { |
| 1856 | skb_queue_walk(&chan->tx_q, skb) { | 1894 | skb_queue_walk(&chan->tx_q, skb) { |
| 1857 | if (bt_cb(skb)->control.txseq == control->reqseq || | 1895 | if (bt_cb(skb)->control.txseq == control->reqseq || |
| 1858 | skb == chan->tx_send_head) | 1896 | skb == chan->tx_send_head) |
| 1859 | break; | 1897 | break; |
| 1860 | } | 1898 | } |
| 1861 | 1899 | ||
| @@ -2156,7 +2194,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, · 294 unmodified lines | |||
| 2156 | } | 2194 | } |
| 2157 | 2195 | ||
| 2158 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, | 2196 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
| 2159 | u32 priority) | 2197 | u32 priority) |
| 2160 | { | 2198 | { |
| 2161 | struct sk_buff *skb; | 2199 | struct sk_buff *skb; |
| 2162 | int err; | 2200 | int err; |
| @@ -2543,7 +2581,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) · 380 unmodified lines | |||
| 2543 | /* Don't send frame to the socket it came from */ | 2581 | /* Don't send frame to the socket it came from */ |
| 2544 | if (skb->sk == sk) | 2582 | if (skb->sk == sk) |
| 2545 | continue; | 2583 | continue; |
| 2546 | nskb = skb_clone(skb, GFP_ATOMIC); | 2584 | nskb = skb_clone(skb, GFP_KERNEL); |
| 2547 | if (!nskb) | 2585 | if (!nskb) |
| 2548 | continue; | 2586 | continue; |
| 2549 | 2587 | ||
| @@ -2569,7 +2607,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, · 19 unmodified lines | |||
| 2569 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; | 2607 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; |
| 2570 | count = min_t(unsigned int, conn->mtu, len); | 2608 | count = min_t(unsigned int, conn->mtu, len); |
| 2571 | 2609 | ||
| 2572 | skb = bt_skb_alloc(count, GFP_ATOMIC); | 2610 | skb = bt_skb_alloc(count, GFP_KERNEL); |
| 2573 | if (!skb) | 2611 | if (!skb) |
| 2574 | return NULL; | 2612 | return NULL; |
| 2575 | 2613 | ||
| @@ -2599,7 +2637,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, · 23 unmodified lines | |||
| 2599 | while (len) { | 2637 | while (len) { |
| 2600 | count = min_t(unsigned int, conn->mtu, len); | 2638 | count = min_t(unsigned int, conn->mtu, len); |
| 2601 | 2639 | ||
| 2602 | *frag = bt_skb_alloc(count, GFP_ATOMIC); | 2640 | *frag = bt_skb_alloc(count, GFP_KERNEL); |
| 2603 | if (!*frag) | 2641 | if (!*frag) |
| 2604 | goto fail; | 2642 | goto fail; |
| 2605 | 2643 | ||
| @@ -2618,7 +2656,8 @@ fail: · 12 unmodified lines | |||
| 2618 | return NULL; | 2656 | return NULL; |
| 2619 | } | 2657 | } |
| 2620 | 2658 | ||
| 2621 | static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val) | 2659 | static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, |
| 2660 | unsigned long *val) | ||
| 2622 | { | 2661 | { |
| 2623 | struct l2cap_conf_opt *opt = *ptr; | 2662 | struct l2cap_conf_opt *opt = *ptr; |
| 2624 | int len; | 2663 | int len; |
| @@ -2692,7 +2731,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) · 67 unmodified lines | |||
| 2692 | efs.msdu = cpu_to_le16(chan->local_msdu); | 2731 | efs.msdu = cpu_to_le16(chan->local_msdu); |
| 2693 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); | 2732 | efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); |
| 2694 | efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); | 2733 | efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); |
| 2695 | efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); | 2734 | efs.flush_to = __constant_cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO); |
| 2696 | break; | 2735 | break; |
| 2697 | 2736 | ||
| 2698 | case L2CAP_MODE_STREAMING: | 2737 | case L2CAP_MODE_STREAMING: |
| @@ -2709,7 +2748,7 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) · 10 unmodified lines | |||
| 2709 | } | 2748 | } |
| 2710 | 2749 | ||
| 2711 | l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), | 2750 | l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs), |
| 2712 | (unsigned long) &efs); | 2751 | (unsigned long) &efs); |
| 2713 | } | 2752 | } |
| 2714 | 2753 | ||
| 2715 | static void l2cap_ack_timeout(struct work_struct *work) | 2754 | static void l2cap_ack_timeout(struct work_struct *work) |
| @@ -2798,13 +2837,13 @@ static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) · 82 unmodified lines | |||
| 2798 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | 2837 | static inline void l2cap_txwin_setup(struct l2cap_chan *chan) |
| 2799 | { | 2838 | { |
| 2800 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && | 2839 | if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && |
| 2801 | __l2cap_ews_supported(chan)) { | 2840 | __l2cap_ews_supported(chan)) { |
| 2802 | /* use extended control field */ | 2841 | /* use extended control field */ |
| 2803 | set_bit(FLAG_EXT_CTRL, &chan->flags); | 2842 | set_bit(FLAG_EXT_CTRL, &chan->flags); |
| 2804 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; | 2843 | chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; |
| 2805 | } else { | 2844 | } else { |
| 2806 | chan->tx_win = min_t(u16, chan->tx_win, | 2845 | chan->tx_win = min_t(u16, chan->tx_win, |
| 2807 | L2CAP_DEFAULT_TX_WINDOW); | 2846 | L2CAP_DEFAULT_TX_WINDOW); |
| 2808 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | 2847 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; |
| 2809 | } | 2848 | } |
| 2810 | chan->ack_win = chan->tx_win; | 2849 | chan->ack_win = chan->tx_win; |
| @@ -2844,7 +2883,7 @@ done: · 33 unmodified lines | |||
| 2844 | switch (chan->mode) { | 2883 | switch (chan->mode) { |
| 2845 | case L2CAP_MODE_BASIC: | 2884 | case L2CAP_MODE_BASIC: |
| 2846 | if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) && | 2885 | if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) && |
| 2847 | !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING)) | 2886 | !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING)) |
| 2848 | break; | 2887 | break; |
| 2849 | 2888 | ||
| 2850 | rfc.mode = L2CAP_MODE_BASIC; | 2889 | rfc.mode = L2CAP_MODE_BASIC; |
| @@ -2855,7 +2894,7 @@ done: · 4 unmodified lines | |||
| 2855 | rfc.max_pdu_size = 0; | 2894 | rfc.max_pdu_size = 0; |
| 2856 | 2895 | ||
| 2857 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2896 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
| 2858 | (unsigned long) &rfc); | 2897 | (unsigned long) &rfc); |
| 2859 | break; | 2898 | break; |
| 2860 | 2899 | ||
| 2861 | case L2CAP_MODE_ERTM: | 2900 | case L2CAP_MODE_ERTM: |
| @@ -2865,18 +2904,17 @@ done: · 3 unmodified lines | |||
| 2865 | rfc.monitor_timeout = 0; | 2904 | rfc.monitor_timeout = 0; |
| 2866 | 2905 | ||
| 2867 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - | 2906 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
| 2868 | L2CAP_EXT_HDR_SIZE - | 2907 | L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - |
| 2869 | L2CAP_SDULEN_SIZE - | 2908 | L2CAP_FCS_SIZE); |
| 2870 | L2CAP_FCS_SIZE); | ||
| 2871 | rfc.max_pdu_size = cpu_to_le16(size); | 2909 | rfc.max_pdu_size = cpu_to_le16(size); |
| 2872 | 2910 | ||
| 2873 | l2cap_txwin_setup(chan); | 2911 | l2cap_txwin_setup(chan); |
| 2874 | 2912 | ||
| 2875 | rfc.txwin_size = min_t(u16, chan->tx_win, | 2913 | rfc.txwin_size = min_t(u16, chan->tx_win, |
| 2876 | L2CAP_DEFAULT_TX_WINDOW); | 2914 | L2CAP_DEFAULT_TX_WINDOW); |
| 2877 | 2915 | ||
| 2878 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2916 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
| 2879 | (unsigned long) &rfc); | 2917 | (unsigned long) &rfc); |
| 2880 | 2918 | ||
| 2881 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | 2919 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) |
| 2882 | l2cap_add_opt_efs(&ptr, chan); | 2920 | l2cap_add_opt_efs(&ptr, chan); |
| @@ -2885,14 +2923,14 @@ done: · 2 unmodified lines | |||
| 2885 | break; | 2923 | break; |
| 2886 | 2924 | ||
| 2887 | if (chan->fcs == L2CAP_FCS_NONE || | 2925 | if (chan->fcs == L2CAP_FCS_NONE || |
| 2888 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { | 2926 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { |
| 2889 | chan->fcs = L2CAP_FCS_NONE; | 2927 | chan->fcs = L2CAP_FCS_NONE; |
| 2890 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 2928 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
| 2891 | } | 2929 | } |
| 2892 | 2930 | ||
| 2893 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | 2931 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) |
| 2894 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | 2932 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, |
| 2895 | chan->tx_win); | 2933 | chan->tx_win); |
| 2896 | break; | 2934 | break; |
| 2897 | 2935 | ||
| 2898 | case L2CAP_MODE_STREAMING: | 2936 | case L2CAP_MODE_STREAMING: |
| @@ -2904,13 +2942,12 @@ done: · 5 unmodified lines | |||
| 2904 | rfc.monitor_timeout = 0; | 2942 | rfc.monitor_timeout = 0; |
| 2905 | 2943 | ||
| 2906 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - | 2944 | size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - |
| 2907 | L2CAP_EXT_HDR_SIZE - | 2945 | L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - |
| 2908 | L2CAP_SDULEN_SIZE - | 2946 | L2CAP_FCS_SIZE); |
| 2909 | L2CAP_FCS_SIZE); | ||
| 2910 | rfc.max_pdu_size = cpu_to_le16(size); | 2947 | rfc.max_pdu_size = cpu_to_le16(size); |
| 2911 | 2948 | ||
| 2912 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | 2949 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
| 2913 | (unsigned long) &rfc); | 2950 | (unsigned long) &rfc); |
| 2914 | 2951 | ||
| 2915 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) | 2952 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) |
| 2916 | l2cap_add_opt_efs(&ptr, chan); | 2953 | l2cap_add_opt_efs(&ptr, chan); |
| @@ -2919,7 +2956,7 @@ done: · 2 unmodified lines | |||
| 2919 | break; | 2956 | break; |
| 2920 | 2957 | ||
| 2921 | if (chan->fcs == L2CAP_FCS_NONE || | 2958 | if (chan->fcs == L2CAP_FCS_NONE || |
| 2922 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { | 2959 | test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { |
| 2923 | chan->fcs = L2CAP_FCS_NONE; | 2960 | chan->fcs = L2CAP_FCS_NONE; |
| 2924 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); | 2961 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); |
| 2925 | } | 2962 | } |
| @@ -3011,7 +3048,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) · 85 unmodified lines | |||
| 3011 | case L2CAP_MODE_ERTM: | 3048 | case L2CAP_MODE_ERTM: |
| 3012 | if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) { | 3049 | if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) { |
| 3013 | chan->mode = l2cap_select_mode(rfc.mode, | 3050 | chan->mode = l2cap_select_mode(rfc.mode, |
| 3014 | chan->conn->feat_mask); | 3051 | chan->conn->feat_mask); |
| 3015 | break; | 3052 | break; |
| 3016 | } | 3053 | } |
| 3017 | 3054 | ||
| @@ -3036,8 +3073,8 @@ done: · 18 unmodified lines | |||
| 3036 | if (chan->num_conf_rsp == 1) | 3073 | if (chan->num_conf_rsp == 1) |
| 3037 | return -ECONNREFUSED; | 3074 | return -ECONNREFUSED; |
| 3038 | 3075 | ||
| 3039 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 3076 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
| 3040 | sizeof(rfc), (unsigned long) &rfc); | 3077 | (unsigned long) &rfc); |
| 3041 | } | 3078 | } |
| 3042 | 3079 | ||
| 3043 | if (result == L2CAP_CONF_SUCCESS) { | 3080 | if (result == L2CAP_CONF_SUCCESS) { |
| @@ -3054,8 +3091,8 @@ done: · 10 unmodified lines | |||
| 3054 | 3091 | ||
| 3055 | if (remote_efs) { | 3092 | if (remote_efs) { |
| 3056 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | 3093 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && |
| 3057 | efs.stype != L2CAP_SERV_NOTRAFIC && | 3094 | efs.stype != L2CAP_SERV_NOTRAFIC && |
| 3058 | efs.stype != chan->local_stype) { | 3095 | efs.stype != chan->local_stype) { |
| 3059 | 3096 | ||
| 3060 | result = L2CAP_CONF_UNACCEPT; | 3097 | result = L2CAP_CONF_UNACCEPT; |
| 3061 | 3098 | ||
| @@ -3063,8 +3100,8 @@ done: · 1 unmodified line | |||
| 3063 | return -ECONNREFUSED; | 3100 | return -ECONNREFUSED; |
| 3064 | 3101 | ||
| 3065 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | 3102 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, |
| 3066 | sizeof(efs), | 3103 | sizeof(efs), |
| 3067 | (unsigned long) &efs); | 3104 | (unsigned long) &efs); |
| 3068 | } else { | 3105 | } else { |
| 3069 | /* Send PENDING Conf Rsp */ | 3106 | /* Send PENDING Conf Rsp */ |
| 3070 | result = L2CAP_CONF_PENDING; | 3107 | result = L2CAP_CONF_PENDING; |
| @@ -3087,10 +3124,8 @@ done: · 16 unmodified lines | |||
| 3087 | chan->remote_max_tx = rfc.max_transmit; | 3124 | chan->remote_max_tx = rfc.max_transmit; |
| 3088 | 3125 | ||
| 3089 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), | 3126 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
| 3090 | chan->conn->mtu - | 3127 | chan->conn->mtu - L2CAP_EXT_HDR_SIZE - |
| 3091 | L2CAP_EXT_HDR_SIZE - | 3128 | L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE); |
| 3092 | L2CAP_SDULEN_SIZE - | ||
| 3093 | L2CAP_FCS_SIZE); | ||
| 3094 | rfc.max_pdu_size = cpu_to_le16(size); | 3129 | rfc.max_pdu_size = cpu_to_le16(size); |
| 3095 | chan->remote_mps = size; | 3130 | chan->remote_mps = size; |
| 3096 | 3131 | ||
| @@ -3102,36 +3137,35 @@ done: · 5 unmodified lines | |||
| 3102 | set_bit(CONF_MODE_DONE, &chan->conf_state); | 3137 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
| 3103 | 3138 | ||
| 3104 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 3139 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
| 3105 | sizeof(rfc), (unsigned long) &rfc); | 3140 | sizeof(rfc), (unsigned long) &rfc); |
| 3106 | 3141 | ||
| 3107 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | 3142 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { |
| 3108 | chan->remote_id = efs.id; | 3143 | chan->remote_id = efs.id; |
| 3109 | chan->remote_stype = efs.stype; | 3144 | chan->remote_stype = efs.stype; |
| 3110 | chan->remote_msdu = le16_to_cpu(efs.msdu); | 3145 | chan->remote_msdu = le16_to_cpu(efs.msdu); |
| 3111 | chan->remote_flush_to = | 3146 | chan->remote_flush_to = |
| 3112 | le32_to_cpu(efs.flush_to); | 3147 | le32_to_cpu(efs.flush_to); |
| 3113 | chan->remote_acc_lat = | 3148 | chan->remote_acc_lat = |
| 3114 | le32_to_cpu(efs.acc_lat); | 3149 | le32_to_cpu(efs.acc_lat); |
| 3115 | chan->remote_sdu_itime = | 3150 | chan->remote_sdu_itime = |
| 3116 | le32_to_cpu(efs.sdu_itime); | 3151 | le32_to_cpu(efs.sdu_itime); |
| 3117 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | 3152 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, |
| 3118 | sizeof(efs), (unsigned long) &efs); | 3153 | sizeof(efs), |
| 3154 | (unsigned long) &efs); | ||
| 3119 | } | 3155 | } |
| 3120 | break; | 3156 | break; |
| 3121 | 3157 | ||
| 3122 | case L2CAP_MODE_STREAMING: | 3158 | case L2CAP_MODE_STREAMING: |
| 3123 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), | 3159 | size = min_t(u16, le16_to_cpu(rfc.max_pdu_size), |
| 3124 | chan->conn->mtu - | 3160 | chan->conn->mtu - L2CAP_EXT_HDR_SIZE - |
| 3125 | L2CAP_EXT_HDR_SIZE - | 3161 | L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE); |
| 3126 | L2CAP_SDULEN_SIZE - | ||
| 3127 | L2CAP_FCS_SIZE); | ||
| 3128 | rfc.max_pdu_size = cpu_to_le16(size); | 3162 | rfc.max_pdu_size = cpu_to_le16(size); |
| 3129 | chan->remote_mps = size; | 3163 | chan->remote_mps = size; |
| 3130 | 3164 | ||
| 3131 | set_bit(CONF_MODE_DONE, &chan->conf_state); | 3165 | set_bit(CONF_MODE_DONE, &chan->conf_state); |
| 3132 | 3166 | ||
| 3133 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 3167 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), |
| 3134 | sizeof(rfc), (unsigned long) &rfc); | 3168 | (unsigned long) &rfc); |
| 3135 | 3169 | ||
| 3136 | break; | 3170 | break; |
| 3137 | 3171 | ||
| @@ -3152,7 +3186,8 @@ done: · 14 unmodified lines | |||
| 3152 | return ptr - data; | 3186 | return ptr - data; |
| 3153 | } | 3187 | } |
| 3154 | 3188 | ||
| 3155 | static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, void *data, u16 *result) | 3189 | static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, |
| 3190 | void *data, u16 *result) | ||
| 3156 | { | 3191 | { |
| 3157 | struct l2cap_conf_req *req = data; | 3192 | struct l2cap_conf_req *req = data; |
| 3158 | void *ptr = req->data; | 3193 | void *ptr = req->data; |
| @@ -3179,7 +3214,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi · 20 unmodified lines | |||
| 3179 | case L2CAP_CONF_FLUSH_TO: | 3214 | case L2CAP_CONF_FLUSH_TO: |
| 3180 | chan->flush_to = val; | 3215 | chan->flush_to = val; |
| 3181 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, | 3216 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, |
| 3182 | 2, chan->flush_to); | 3217 | 2, chan->flush_to); |
| 3183 | break; | 3218 | break; |
| 3184 | 3219 | ||
| 3185 | case L2CAP_CONF_RFC: | 3220 | case L2CAP_CONF_RFC: |
| @@ -3187,13 +3222,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi · 1 unmodified line | |||
| 3187 | memcpy(&rfc, (void *)val, olen); | 3222 | memcpy(&rfc, (void *)val, olen); |
| 3188 | 3223 | ||
| 3189 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) && | 3224 | if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) && |
| 3190 | rfc.mode != chan->mode) | 3225 | rfc.mode != chan->mode) |
| 3191 | return -ECONNREFUSED; | 3226 | return -ECONNREFUSED; |
| 3192 | 3227 | ||
| 3193 | chan->fcs = 0; | 3228 | chan->fcs = 0; |
| 3194 | 3229 | ||
| 3195 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | 3230 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, |
| 3196 | sizeof(rfc), (unsigned long) &rfc); | 3231 | sizeof(rfc), (unsigned long) &rfc); |
| 3197 | break; | 3232 | break; |
| 3198 | 3233 | ||
| 3199 | case L2CAP_CONF_EWS: | 3234 | case L2CAP_CONF_EWS: |
| @@ -3207,12 +3242,12 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi · 7 unmodified lines | |||
| 3207 | memcpy(&efs, (void *)val, olen); | 3242 | memcpy(&efs, (void *)val, olen); |
| 3208 | 3243 | ||
| 3209 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | 3244 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && |
| 3210 | efs.stype != L2CAP_SERV_NOTRAFIC && | 3245 | efs.stype != L2CAP_SERV_NOTRAFIC && |
| 3211 | efs.stype != chan->local_stype) | 3246 | efs.stype != chan->local_stype) |
| 3212 | return -ECONNREFUSED; | 3247 | return -ECONNREFUSED; |
| 3213 | 3248 | ||
| 3214 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, | 3249 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), |
| 3215 | sizeof(efs), (unsigned long) &efs); | 3250 | (unsigned long) &efs); |
| 3216 | break; | 3251 | break; |
| 3217 | } | 3252 | } |
| 3218 | } | 3253 | } |
| @@ -3235,10 +3270,10 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi · 16 unmodified lines | |||
| 3235 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | 3270 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { |
| 3236 | chan->local_msdu = le16_to_cpu(efs.msdu); | 3271 | chan->local_msdu = le16_to_cpu(efs.msdu); |
| 3237 | chan->local_sdu_itime = | 3272 | chan->local_sdu_itime = |
| 3238 | le32_to_cpu(efs.sdu_itime); | 3273 | le32_to_cpu(efs.sdu_itime); |
| 3239 | chan->local_acc_lat = le32_to_cpu(efs.acc_lat); | 3274 | chan->local_acc_lat = le32_to_cpu(efs.acc_lat); |
| 3240 | chan->local_flush_to = | 3275 | chan->local_flush_to = |
| 3241 | le32_to_cpu(efs.flush_to); | 3276 | le32_to_cpu(efs.flush_to); |
| 3242 | } | 3277 | } |
| 3243 | break; | 3278 | break; |
| 3244 | 3279 | ||
| @@ -3253,7 +3288,8 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi · 8 unmodified lines | |||
| 3253 | return ptr - data; | 3288 | return ptr - data; |
| 3254 | } | 3289 | } |
| 3255 | 3290 | ||
| 3256 | static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, u16 result, u16 flags) | 3291 | static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data, |
| 3292 | u16 result, u16 flags) | ||
| 3257 | { | 3293 | { |
| 3258 | struct l2cap_conf_rsp *rsp = data; | 3294 | struct l2cap_conf_rsp *rsp = data; |
| 3259 | void *ptr = rsp->data; | 3295 | void *ptr = rsp->data; |
| @@ -3277,14 +3313,13 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) · 17 unmodified lines | |||
| 3277 | rsp.dcid = cpu_to_le16(chan->scid); | 3313 | rsp.dcid = cpu_to_le16(chan->scid); |
| 3278 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); | 3314 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); |
| 3279 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); | 3315 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); |
| 3280 | l2cap_send_cmd(conn, chan->ident, | 3316 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
| 3281 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
| 3282 | 3317 | ||
| 3283 | if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) | 3318 | if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) |
| 3284 | return; | 3319 | return; |
| 3285 | 3320 | ||
| 3286 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3321 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
| 3287 | l2cap_build_conf_req(chan, buf), buf); | 3322 | l2cap_build_conf_req(chan, buf), buf); |
| 3288 | chan->num_conf_req++; | 3323 | chan->num_conf_req++; |
| 3289 | } | 3324 | } |
| 3290 | 3325 | ||
| @@ -3339,7 +3374,8 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) · 48 unmodified lines | |||
| 3339 | } | 3374 | } |
| 3340 | } | 3375 | } |
| 3341 | 3376 | ||
| 3342 | static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3377 | static inline int l2cap_command_rej(struct l2cap_conn *conn, |
| 3378 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3343 | { | 3379 | { |
| 3344 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; | 3380 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
| 3345 | 3381 | ||
| @@ -3347,7 +3383,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd · 1 unmodified line | |||
| 3347 | return 0; | 3383 | return 0; |
| 3348 | 3384 | ||
| 3349 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && | 3385 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && |
| 3350 | cmd->ident == conn->info_ident) { | 3386 | cmd->ident == conn->info_ident) { |
| 3351 | cancel_delayed_work(&conn->info_timer); | 3387 | cancel_delayed_work(&conn->info_timer); |
| 3352 | 3388 | ||
| 3353 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 3389 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
| @@ -3359,7 +3395,8 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd · 5 unmodified lines | |||
| 3359 | return 0; | 3395 | return 0; |
| 3360 | } | 3396 | } |
| 3361 | 3397 | ||
| 3362 | static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3398 | static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, |
| 3399 | u8 *data, u8 rsp_code, u8 amp_id) | ||
| 3363 | { | 3400 | { |
| 3364 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 3401 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
| 3365 | struct l2cap_conn_rsp rsp; | 3402 | struct l2cap_conn_rsp rsp; |
| @@ -3386,7 +3423,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd · 20 unmodified lines | |||
| 3386 | 3423 | ||
| 3387 | /* Check if the ACL is secure enough (if not SDP) */ | 3424 | /* Check if the ACL is secure enough (if not SDP) */ |
| 3388 | if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && | 3425 | if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && |
| 3389 | !hci_conn_check_link_mode(conn->hcon)) { | 3426 | !hci_conn_check_link_mode(conn->hcon)) { |
| 3390 | conn->disc_reason = HCI_ERROR_AUTH_FAILURE; | 3427 | conn->disc_reason = HCI_ERROR_AUTH_FAILURE; |
| 3391 | result = L2CAP_CR_SEC_BLOCK; | 3428 | result = L2CAP_CR_SEC_BLOCK; |
| 3392 | goto response; | 3429 | goto response; |
| @@ -3411,8 +3448,6 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd · 18 unmodified lines | |||
| 3411 | chan->psm = psm; | 3448 | chan->psm = psm; |
| 3412 | chan->dcid = scid; | 3449 | chan->dcid = scid; |
| 3413 | 3450 | ||
| 3414 | bt_accept_enqueue(parent, sk); | ||
| 3415 | |||
| 3416 | __l2cap_chan_add(conn, chan); | 3451 | __l2cap_chan_add(conn, chan); |
| 3417 | 3452 | ||
| 3418 | dcid = chan->scid; | 3453 | dcid = chan->scid; |
| @@ -3427,7 +3462,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd · 8 unmodified lines | |||
| 3427 | __l2cap_state_change(chan, BT_CONNECT2); | 3462 | __l2cap_state_change(chan, BT_CONNECT2); |
| 3428 | result = L2CAP_CR_PEND; | 3463 | result = L2CAP_CR_PEND; |
| 3429 | status = L2CAP_CS_AUTHOR_PEND; | 3464 | status = L2CAP_CS_AUTHOR_PEND; |
| 3430 | parent->sk_data_ready(parent, 0); | 3465 | chan->ops->defer(chan); |
| 3431 | } else { | 3466 | } else { |
| 3432 | __l2cap_state_change(chan, BT_CONFIG); | 3467 | __l2cap_state_change(chan, BT_CONFIG); |
| 3433 | result = L2CAP_CR_SUCCESS; | 3468 | result = L2CAP_CR_SUCCESS; |
| @@ -3453,7 +3488,7 @@ sendresp: · 19 unmodified lines | |||
| 3453 | rsp.dcid = cpu_to_le16(dcid); | 3488 | rsp.dcid = cpu_to_le16(dcid); |
| 3454 | rsp.result = cpu_to_le16(result); | 3489 | rsp.result = cpu_to_le16(result); |
| 3455 | rsp.status = cpu_to_le16(status); | 3490 | rsp.status = cpu_to_le16(status); |
| 3456 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 3491 | l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp); |
| 3457 | 3492 | ||
| 3458 | if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { | 3493 | if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { |
| 3459 | struct l2cap_info_req info; | 3494 | struct l2cap_info_req info; |
| @@ -3464,23 +3499,29 @@ sendresp: · 4 unmodified lines | |||
| 3464 | 3499 | ||
| 3465 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | 3500 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); |
| 3466 | 3501 | ||
| 3467 | l2cap_send_cmd(conn, conn->info_ident, | 3502 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, |
| 3468 | L2CAP_INFO_REQ, sizeof(info), &info); | 3503 | sizeof(info), &info); |
| 3469 | } | 3504 | } |
| 3470 | 3505 | ||
| 3471 | if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) && | 3506 | if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) && |
| 3472 | result == L2CAP_CR_SUCCESS) { | 3507 | result == L2CAP_CR_SUCCESS) { |
| 3473 | u8 buf[128]; | 3508 | u8 buf[128]; |
| 3474 | set_bit(CONF_REQ_SENT, &chan->conf_state); | 3509 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
| 3475 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3510 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
| 3476 | l2cap_build_conf_req(chan, buf), buf); | 3511 | l2cap_build_conf_req(chan, buf), buf); |
| 3477 | chan->num_conf_req++; | 3512 | chan->num_conf_req++; |
| 3478 | } | 3513 | } |
| 3514 | } | ||
| 3479 | 3515 | ||
| 3516 | static int l2cap_connect_req(struct l2cap_conn *conn, | ||
| 3517 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3518 | { | ||
| 3519 | l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0); | ||
| 3480 | return 0; | 3520 | return 0; |
| 3481 | } | 3521 | } |
| 3482 | 3522 | ||
| 3483 | static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3523 | static inline int l2cap_connect_rsp(struct l2cap_conn *conn, |
| 3524 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3484 | { | 3525 | { |
| 3485 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; | 3526 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; |
| 3486 | u16 scid, dcid, result, status; | 3527 | u16 scid, dcid, result, status; |
| @@ -3494,7 +3535,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd · 7 unmodified lines | |||
| 3494 | status = __le16_to_cpu(rsp->status); | 3535 | status = __le16_to_cpu(rsp->status); |
| 3495 | 3536 | ||
| 3496 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", | 3537 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", |
| 3497 | dcid, scid, result, status); | 3538 | dcid, scid, result, status); |
| 3498 | 3539 | ||
| 3499 | mutex_lock(&conn->chan_lock); | 3540 | mutex_lock(&conn->chan_lock); |
| 3500 | 3541 | ||
| @@ -3527,7 +3568,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd · 26 unmodified lines | |||
| 3527 | break; | 3568 | break; |
| 3528 | 3569 | ||
| 3529 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3570 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
| 3530 | l2cap_build_conf_req(chan, req), req); | 3571 | l2cap_build_conf_req(chan, req), req); |
| 3531 | chan->num_conf_req++; | 3572 | chan->num_conf_req++; |
| 3532 | break; | 3573 | break; |
| 3533 | 3574 | ||
| @@ -3559,7 +3600,25 @@ static inline void set_default_fcs(struct l2cap_chan *chan) · 25 unmodified lines | |||
| 3559 | chan->fcs = L2CAP_FCS_CRC16; | 3600 | chan->fcs = L2CAP_FCS_CRC16; |
| 3560 | } | 3601 | } |
| 3561 | 3602 | ||
| 3562 | static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) | 3603 | static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data, |
| 3604 | u8 ident, u16 flags) | ||
| 3605 | { | ||
| 3606 | struct l2cap_conn *conn = chan->conn; | ||
| 3607 | |||
| 3608 | BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident, | ||
| 3609 | flags); | ||
| 3610 | |||
| 3611 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | ||
| 3612 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | ||
| 3613 | |||
| 3614 | l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP, | ||
| 3615 | l2cap_build_conf_rsp(chan, data, | ||
| 3616 | L2CAP_CONF_SUCCESS, flags), data); | ||
| 3617 | } | ||
| 3618 | |||
| 3619 | static inline int l2cap_config_req(struct l2cap_conn *conn, | ||
| 3620 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, | ||
| 3621 | u8 *data) | ||
| 3563 | { | 3622 | { |
| 3564 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; | 3623 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; |
| 3565 | u16 dcid, flags; | 3624 | u16 dcid, flags; |
| @@ -3584,7 +3643,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 18 unmodified lines | |||
| 3584 | rej.dcid = cpu_to_le16(chan->dcid); | 3643 | rej.dcid = cpu_to_le16(chan->dcid); |
| 3585 | 3644 | ||
| 3586 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | 3645 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, |
| 3587 | sizeof(rej), &rej); | 3646 | sizeof(rej), &rej); |
| 3588 | goto unlock; | 3647 | goto unlock; |
| 3589 | } | 3648 | } |
| 3590 | 3649 | ||
| @@ -3592,8 +3651,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 1 unmodified line | |||
| 3592 | len = cmd_len - sizeof(*req); | 3651 | len = cmd_len - sizeof(*req); |
| 3593 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { | 3652 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { |
| 3594 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3653 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
| 3595 | l2cap_build_conf_rsp(chan, rsp, | 3654 | l2cap_build_conf_rsp(chan, rsp, |
| 3596 | L2CAP_CONF_REJECT, flags), rsp); | 3655 | L2CAP_CONF_REJECT, flags), rsp); |
| 3597 | goto unlock; | 3656 | goto unlock; |
| 3598 | } | 3657 | } |
| 3599 | 3658 | ||
| @@ -3604,8 +3663,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 4 unmodified lines | |||
| 3604 | if (flags & L2CAP_CONF_FLAG_CONTINUATION) { | 3663 | if (flags & L2CAP_CONF_FLAG_CONTINUATION) { |
| 3605 | /* Incomplete config. Send empty response. */ | 3664 | /* Incomplete config. Send empty response. */ |
| 3606 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3665 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
| 3607 | l2cap_build_conf_rsp(chan, rsp, | 3666 | l2cap_build_conf_rsp(chan, rsp, |
| 3608 | L2CAP_CONF_SUCCESS, flags), rsp); | 3667 | L2CAP_CONF_SUCCESS, flags), rsp); |
| 3609 | goto unlock; | 3668 | goto unlock; |
| 3610 | } | 3669 | } |
| 3611 | 3670 | ||
| @@ -3643,23 +3702,22 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 31 unmodified lines | |||
| 3643 | if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { | 3702 | if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) { |
| 3644 | u8 buf[64]; | 3703 | u8 buf[64]; |
| 3645 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | 3704 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, |
| 3646 | l2cap_build_conf_req(chan, buf), buf); | 3705 | l2cap_build_conf_req(chan, buf), buf); |
| 3647 | chan->num_conf_req++; | 3706 | chan->num_conf_req++; |
| 3648 | } | 3707 | } |
| 3649 | 3708 | ||
| 3650 | /* Got Conf Rsp PENDING from remote side and asume we sent | 3709 | /* Got Conf Rsp PENDING from remote side and asume we sent |
| 3651 | Conf Rsp PENDING in the code above */ | 3710 | Conf Rsp PENDING in the code above */ |
| 3652 | if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && | 3711 | if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) && |
| 3653 | test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { | 3712 | test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { |
| 3654 | 3713 | ||
| 3655 | /* check compatibility */ | 3714 | /* check compatibility */ |
| 3656 | 3715 | ||
| 3657 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | 3716 | /* Send rsp for BR/EDR channel */ |
| 3658 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | 3717 | if (!chan->ctrl_id) |
| 3659 | 3718 | l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags); | |
| 3660 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3719 | else |
| 3661 | l2cap_build_conf_rsp(chan, rsp, | 3720 | chan->ident = cmd->ident; |
| 3662 | L2CAP_CONF_SUCCESS, flags), rsp); | ||
| 3663 | } | 3721 | } |
| 3664 | 3722 | ||
| 3665 | unlock: | 3723 | unlock: |
| @@ -3667,7 +3725,8 @@ unlock: · 1 unmodified line | |||
| 3667 | return err; | 3725 | return err; |
| 3668 | } | 3726 | } |
| 3669 | 3727 | ||
| 3670 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3728 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, |
| 3729 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3671 | { | 3730 | { |
| 3672 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; | 3731 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; |
| 3673 | u16 scid, flags, result; | 3732 | u16 scid, flags, result; |
| @@ -3699,7 +3758,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 25 unmodified lines | |||
| 3699 | char buf[64]; | 3758 | char buf[64]; |
| 3700 | 3759 | ||
| 3701 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | 3760 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, |
| 3702 | buf, &result); | 3761 | buf, &result); |
| 3703 | if (len < 0) { | 3762 | if (len < 0) { |
| 3704 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 3763 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
| 3705 | goto done; | 3764 | goto done; |
| @@ -3707,12 +3766,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 1 unmodified line | |||
| 3707 | 3766 | ||
| 3708 | /* check compatibility */ | 3767 | /* check compatibility */ |
| 3709 | 3768 | ||
| 3710 | clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state); | 3769 | if (!chan->ctrl_id) |
| 3711 | set_bit(CONF_OUTPUT_DONE, &chan->conf_state); | 3770 | l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, |
| 3712 | 3771 | 0); | |
| 3713 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3772 | else |
| 3714 | l2cap_build_conf_rsp(chan, buf, | 3773 | chan->ident = cmd->ident; |
| 3715 | L2CAP_CONF_SUCCESS, 0x0000), buf); | ||
| 3716 | } | 3774 | } |
| 3717 | goto done; | 3775 | goto done; |
| 3718 | 3776 | ||
| @@ -3728,14 +3786,14 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr · 9 unmodified lines | |||
| 3728 | /* throw out any old stored conf requests */ | 3786 | /* throw out any old stored conf requests */ |
| 3729 | result = L2CAP_CONF_SUCCESS; | 3787 | result = L2CAP_CONF_SUCCESS; |
| 3730 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, | 3788 | len = l2cap_parse_conf_rsp(chan, rsp->data, len, |
| 3731 | req, &result); | 3789 | req, &result); |
| 3732 | if (len < 0) { | 3790 | if (len < 0) { |
| 3733 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 3791 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |
| 3734 | goto done; | 3792 | goto done; |
| 3735 | } | 3793 | } |
| 3736 | 3794 | ||
| 3737 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 3795 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
| 3738 | L2CAP_CONF_REQ, len, req); | 3796 | L2CAP_CONF_REQ, len, req); |
| 3739 | chan->num_conf_req++; | 3797 | chan->num_conf_req++; |
| 3740 | if (result != L2CAP_CONF_SUCCESS) | 3798 | if (result != L2CAP_CONF_SUCCESS) |
| 3741 | goto done; | 3799 | goto done; |
| @@ -3773,7 +3831,8 @@ done: · 31 unmodified lines | |||
| 3773 | return err; | 3831 | return err; |
| 3774 | } | 3832 | } |
| 3775 | 3833 | ||
| 3776 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3834 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
| 3835 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3777 | { | 3836 | { |
| 3778 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; | 3837 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; |
| 3779 | struct l2cap_disconn_rsp rsp; | 3838 | struct l2cap_disconn_rsp rsp; |
| @@ -3819,7 +3878,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd · 39 unmodified lines | |||
| 3819 | return 0; | 3878 | return 0; |
| 3820 | } | 3879 | } |
| 3821 | 3880 | ||
| 3822 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3881 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, |
| 3882 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3823 | { | 3883 | { |
| 3824 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; | 3884 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; |
| 3825 | u16 dcid, scid; | 3885 | u16 dcid, scid; |
| @@ -3853,7 +3913,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd · 27 unmodified lines | |||
| 3853 | return 0; | 3913 | return 0; |
| 3854 | } | 3914 | } |
| 3855 | 3915 | ||
| 3856 | static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3916 | static inline int l2cap_information_req(struct l2cap_conn *conn, |
| 3917 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3857 | { | 3918 | { |
| 3858 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; | 3919 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; |
| 3859 | u16 type; | 3920 | u16 type; |
| @@ -3870,14 +3931,14 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm · 10 unmodified lines | |||
| 3870 | rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); | 3931 | rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); |
| 3871 | if (!disable_ertm) | 3932 | if (!disable_ertm) |
| 3872 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | 3933 | feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING |
| 3873 | | L2CAP_FEAT_FCS; | 3934 | | L2CAP_FEAT_FCS; |
| 3874 | if (enable_hs) | 3935 | if (enable_hs) |
| 3875 | feat_mask |= L2CAP_FEAT_EXT_FLOW | 3936 | feat_mask |= L2CAP_FEAT_EXT_FLOW |
| 3876 | | L2CAP_FEAT_EXT_WINDOW; | 3937 | | L2CAP_FEAT_EXT_WINDOW; |
| 3877 | 3938 | ||
| 3878 | put_unaligned_le32(feat_mask, rsp->data); | 3939 | put_unaligned_le32(feat_mask, rsp->data); |
| 3879 | l2cap_send_cmd(conn, cmd->ident, | 3940 | l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), |
| 3880 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3941 | buf); |
| 3881 | } else if (type == L2CAP_IT_FIXED_CHAN) { | 3942 | } else if (type == L2CAP_IT_FIXED_CHAN) { |
| 3882 | u8 buf[12]; | 3943 | u8 buf[12]; |
| 3883 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; | 3944 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; |
| @@ -3890,20 +3951,21 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm · 6 unmodified lines | |||
| 3890 | rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); | 3951 | rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); |
| 3891 | rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); | 3952 | rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); |
| 3892 | memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); | 3953 | memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); |
| 3893 | l2cap_send_cmd(conn, cmd->ident, | 3954 | l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), |
| 3894 | L2CAP_INFO_RSP, sizeof(buf), buf); | 3955 | buf); |
| 3895 | } else { | 3956 | } else { |
| 3896 | struct l2cap_info_rsp rsp; | 3957 | struct l2cap_info_rsp rsp; |
| 3897 | rsp.type = cpu_to_le16(type); | 3958 | rsp.type = cpu_to_le16(type); |
| 3898 | rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); | 3959 | rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); |
| 3899 | l2cap_send_cmd(conn, cmd->ident, | 3960 | l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), |
| 3900 | L2CAP_INFO_RSP, sizeof(rsp), &rsp); | 3961 | &rsp); |
| 3901 | } | 3962 | } |
| 3902 | 3963 | ||
| 3903 | return 0; | 3964 | return 0; |
| 3904 | } | 3965 | } |
| 3905 | 3966 | ||
| 3906 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) | 3967 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, |
| 3968 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
| 3907 | { | 3969 | { |
| 3908 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 3970 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
| 3909 | u16 type, result; | 3971 | u16 type, result; |
| @@ -3915,7 +3977,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm · 5 unmodified lines | |||
| 3915 | 3977 | ||
| 3916 | /* L2CAP Info req/rsp are unbound to channels, add extra checks */ | 3978 | /* L2CAP Info req/rsp are unbound to channels, add extra checks */ |
| 3917 | if (cmd->ident != conn->info_ident || | 3979 | if (cmd->ident != conn->info_ident || |
| 3918 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) | 3980 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) |
| 3919 | return 0; | 3981 | return 0; |
| 3920 | 3982 | ||
| 3921 | cancel_delayed_work(&conn->info_timer); | 3983 | cancel_delayed_work(&conn->info_timer); |
| @@ -3940,7 +4002,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm · 18 unmodified lines | |||
| 3940 | conn->info_ident = l2cap_get_ident(conn); | 4002 | conn->info_ident = l2cap_get_ident(conn); |
| 3941 | 4003 | ||
| 3942 | l2cap_send_cmd(conn, conn->info_ident, | 4004 | l2cap_send_cmd(conn, conn->info_ident, |
| 3943 | L2CAP_INFO_REQ, sizeof(req), &req); | 4005 | L2CAP_INFO_REQ, sizeof(req), &req); |
| 3944 | } else { | 4006 | } else { |
| 3945 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 4007 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
| 3946 | conn->info_ident = 0; | 4008 | conn->info_ident = 0; |
| @@ -3962,8 +4024,8 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm · 15 unmodified lines | |||
| 3962 | } | 4024 | } |
| 3963 | 4025 | ||
| 3964 | static inline int l2cap_create_channel_req(struct l2cap_conn *conn, | 4026 | static inline int l2cap_create_channel_req(struct l2cap_conn *conn, |
| 3965 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, | 4027 | struct l2cap_cmd_hdr *cmd, |
| 3966 | void *data) | 4028 | u16 cmd_len, void *data) |
| 3967 | { | 4029 | { |
| 3968 | struct l2cap_create_chan_req *req = data; | 4030 | struct l2cap_create_chan_req *req = data; |
| 3969 | struct l2cap_create_chan_rsp rsp; | 4031 | struct l2cap_create_chan_rsp rsp; |
| @@ -3993,7 +4055,8 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn, · 23 unmodified lines | |||
| 3993 | } | 4055 | } |
| 3994 | 4056 | ||
| 3995 | static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, | 4057 | static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, |
| 3996 | struct l2cap_cmd_hdr *cmd, void *data) | 4058 | struct l2cap_cmd_hdr *cmd, |
| 4059 | void *data) | ||
| 3997 | { | 4060 | { |
| 3998 | BT_DBG("conn %p", conn); | 4061 | BT_DBG("conn %p", conn); |
| 3999 | 4062 | ||
| @@ -4126,7 +4189,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, · 126 unmodified lines | |||
| 4126 | } | 4189 | } |
| 4127 | 4190 | ||
| 4128 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, | 4191 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, |
| 4129 | u16 to_multiplier) | 4192 | u16 to_multiplier) |
| 4130 | { | 4193 | { |
| 4131 | u16 max_latency; | 4194 | u16 max_latency; |
| 4132 | 4195 | ||
| @@ -4147,7 +4210,8 @@ static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, · 14 unmodified lines | |||
| 4147 | } | 4210 | } |
| 4148 | 4211 | ||
| 4149 | static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, | 4212 | static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, |
| 4150 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4213 | struct l2cap_cmd_hdr *cmd, |
| 4214 | u8 *data) | ||
| 4151 | { | 4215 | { |
| 4152 | struct hci_conn *hcon = conn->hcon; | 4216 | struct hci_conn *hcon = conn->hcon; |
| 4153 | struct l2cap_conn_param_update_req *req; | 4217 | struct l2cap_conn_param_update_req *req; |
| @@ -4169,7 +4233,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, · 15 unmodified lines | |||
| 4169 | to_multiplier = __le16_to_cpu(req->to_multiplier); | 4233 | to_multiplier = __le16_to_cpu(req->to_multiplier); |
| 4170 | 4234 | ||
| 4171 | BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x", | 4235 | BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x", |
| 4172 | min, max, latency, to_multiplier); | 4236 | min, max, latency, to_multiplier); |
| 4173 | 4237 | ||
| 4174 | memset(&rsp, 0, sizeof(rsp)); | 4238 | memset(&rsp, 0, sizeof(rsp)); |
| 4175 | 4239 | ||
| @@ -4180,7 +4244,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, · 4 unmodified lines | |||
| 4180 | rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); | 4244 | rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); |
| 4181 | 4245 | ||
| 4182 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, | 4246 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, |
| 4183 | sizeof(rsp), &rsp); | 4247 | sizeof(rsp), &rsp); |
| 4184 | 4248 | ||
| 4185 | if (!err) | 4249 | if (!err) |
| 4186 | hci_le_conn_update(hcon, min, max, latency, to_multiplier); | 4250 | hci_le_conn_update(hcon, min, max, latency, to_multiplier); |
| @@ -4189,7 +4253,8 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, · 2 unmodified lines | |||
| 4189 | } | 4253 | } |
| 4190 | 4254 | ||
| 4191 | static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | 4255 | static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, |
| 4192 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) | 4256 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
| 4257 | u8 *data) | ||
| 4193 | { | 4258 | { |
| 4194 | int err = 0; | 4259 | int err = 0; |
| 4195 | 4260 | ||
| @@ -4203,6 +4268,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, · 7 unmodified lines | |||
| 4203 | break; | 4268 | break; |
| 4204 | 4269 | ||
| 4205 | case L2CAP_CONN_RSP: | 4270 | case L2CAP_CONN_RSP: |
| 4271 | case L2CAP_CREATE_CHAN_RSP: | ||
| 4206 | err = l2cap_connect_rsp(conn, cmd, data); | 4272 | err = l2cap_connect_rsp(conn, cmd, data); |
| 4207 | break; | 4273 | break; |
| 4208 | 4274 | ||
| @@ -4241,10 +4307,6 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, · 32 unmodified lines | |||
| 4241 | err = l2cap_create_channel_req(conn, cmd, cmd_len, data); | 4307 | err = l2cap_create_channel_req(conn, cmd, cmd_len, data); |
| 4242 | break; | 4308 | break; |
| 4243 | 4309 | ||
| 4244 | case L2CAP_CREATE_CHAN_RSP: | ||
| 4245 | err = l2cap_create_channel_rsp(conn, cmd, data); | ||
| 4246 | break; | ||
| 4247 | |||
| 4248 | case L2CAP_MOVE_CHAN_REQ: | 4310 | case L2CAP_MOVE_CHAN_REQ: |
| 4249 | err = l2cap_move_channel_req(conn, cmd, cmd_len, data); | 4311 | err = l2cap_move_channel_req(conn, cmd, cmd_len, data); |
| 4250 | break; | 4312 | break; |
| @@ -4271,7 +4333,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, · 20 unmodified lines | |||
| 4271 | } | 4333 | } |
| 4272 | 4334 | ||
| 4273 | static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | 4335 | static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, |
| 4274 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4336 | struct l2cap_cmd_hdr *cmd, u8 *data) |
| 4275 | { | 4337 | { |
| 4276 | switch (cmd->code) { | 4338 | switch (cmd->code) { |
| 4277 | case L2CAP_COMMAND_REJ: | 4339 | case L2CAP_COMMAND_REJ: |
| @@ -4290,7 +4352,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, · 12 unmodified lines | |||
| 4290 | } | 4352 | } |
| 4291 | 4353 | ||
| 4292 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, | 4354 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, |
| 4293 | struct sk_buff *skb) | 4355 | struct sk_buff *skb) |
| 4294 | { | 4356 | { |
| 4295 | u8 *data = skb->data; | 4357 | u8 *data = skb->data; |
| 4296 | int len = skb->len; | 4358 | int len = skb->len; |
| @@ -4307,7 +4369,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, · 10 unmodified lines | |||
| 4307 | 4369 | ||
| 4308 | cmd_len = le16_to_cpu(cmd.len); | 4370 | cmd_len = le16_to_cpu(cmd.len); |
| 4309 | 4371 | ||
| 4310 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident); | 4372 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, |
| 4373 | cmd.ident); | ||
| 4311 | 4374 | ||
| 4312 | if (cmd_len > len || !cmd.ident) { | 4375 | if (cmd_len > len || !cmd.ident) { |
| 4313 | BT_DBG("corrupted command"); | 4376 | BT_DBG("corrupted command"); |
| @@ -4326,7 +4389,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, · 12 unmodified lines | |||
| 4326 | 4389 | ||
| 4327 | /* FIXME: Map err to a valid reason */ | 4390 | /* FIXME: Map err to a valid reason */ |
| 4328 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | 4391 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); |
| 4329 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); | 4392 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, |
| 4393 | sizeof(rej), &rej); | ||
| 4330 | } | 4394 | } |
| 4331 | 4395 | ||
| 4332 | data += cmd_len; | 4396 | data += cmd_len; |
| @@ -4391,8 +4455,8 @@ static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) · 58 unmodified lines | |||
| 4391 | } | 4455 | } |
| 4392 | } | 4456 | } |
| 4393 | 4457 | ||
| 4394 | static void append_skb_frag(struct sk_buff *skb, | 4458 | static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag, |
| 4395 | struct sk_buff *new_frag, struct sk_buff **last_frag) | 4459 | struct sk_buff **last_frag) |
| 4396 | { | 4460 | { |
| 4397 | /* skb->len reflects data in skb as well as all fragments | 4461 | /* skb->len reflects data in skb as well as all fragments |
| 4398 | * skb->data_len reflects only data in fragments | 4462 | * skb->data_len reflects only data in fragments |
| @@ -4641,7 +4705,7 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) · 242 unmodified lines | |||
| 4641 | 4705 | ||
| 4642 | if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { | 4706 | if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { |
| 4643 | if (__seq_offset(chan, txseq, chan->last_acked_seq) >= | 4707 | if (__seq_offset(chan, txseq, chan->last_acked_seq) >= |
| 4644 | chan->tx_win) { | 4708 | chan->tx_win) { |
| 4645 | /* See notes below regarding "double poll" and | 4709 | /* See notes below regarding "double poll" and |
| 4646 | * invalid packets. | 4710 | * invalid packets. |
| 4647 | */ | 4711 | */ |
| @@ -4682,8 +4746,7 @@ static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) · 34 unmodified lines | |||
| 4682 | } | 4746 | } |
| 4683 | 4747 | ||
| 4684 | if (__seq_offset(chan, txseq, chan->last_acked_seq) < | 4748 | if (__seq_offset(chan, txseq, chan->last_acked_seq) < |
| 4685 | __seq_offset(chan, chan->expected_tx_seq, | 4749 | __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) { |
| 4686 | chan->last_acked_seq)){ | ||
| 4687 | BT_DBG("Duplicate - expected_tx_seq later than txseq"); | 4750 | BT_DBG("Duplicate - expected_tx_seq later than txseq"); |
| 4688 | return L2CAP_TXSEQ_DUPLICATE; | 4751 | return L2CAP_TXSEQ_DUPLICATE; |
| 4689 | } | 4752 | } |
| @@ -5323,7 +5386,7 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) · 633 unmodified lines | |||
| 5323 | int exact = 0, lm1 = 0, lm2 = 0; | 5386 | int exact = 0, lm1 = 0, lm2 = 0; |
| 5324 | struct l2cap_chan *c; | 5387 | struct l2cap_chan *c; |
| 5325 | 5388 | ||
| 5326 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 5389 | BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); |
| 5327 | 5390 | ||
| 5328 | /* Find listening sockets and check their link_mode */ | 5391 | /* Find listening sockets and check their link_mode */ |
| 5329 | read_lock(&chan_list_lock); | 5392 | read_lock(&chan_list_lock); |
| @@ -5353,7 +5416,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) · 23 unmodified lines | |||
| 5353 | { | 5416 | { |
| 5354 | struct l2cap_conn *conn; | 5417 | struct l2cap_conn *conn; |
| 5355 | 5418 | ||
| 5356 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 5419 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); |
| 5357 | 5420 | ||
| 5358 | if (!status) { | 5421 | if (!status) { |
| 5359 | conn = l2cap_conn_add(hcon, status); | 5422 | conn = l2cap_conn_add(hcon, status); |
| @@ -5443,7 +5506,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 83 unmodified lines | |||
| 5443 | } | 5506 | } |
| 5444 | 5507 | ||
| 5445 | if (!status && (chan->state == BT_CONNECTED || | 5508 | if (!status && (chan->state == BT_CONNECTED || |
| 5446 | chan->state == BT_CONFIG)) { | 5509 | chan->state == BT_CONFIG)) { |
| 5447 | struct sock *sk = chan->sk; | 5510 | struct sock *sk = chan->sk; |
| 5448 | 5511 | ||
| 5449 | clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); | 5512 | clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); |
| @@ -5456,7 +5519,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 6 unmodified lines | |||
| 5456 | 5519 | ||
| 5457 | if (chan->state == BT_CONNECT) { | 5520 | if (chan->state == BT_CONNECT) { |
| 5458 | if (!status) { | 5521 | if (!status) { |
| 5459 | l2cap_send_conn_req(chan); | 5522 | l2cap_start_connection(chan); |
| 5460 | } else { | 5523 | } else { |
| 5461 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | 5524 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); |
| 5462 | } | 5525 | } |
| @@ -5470,11 +5533,9 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 7 unmodified lines | |||
| 5470 | if (!status) { | 5533 | if (!status) { |
| 5471 | if (test_bit(BT_SK_DEFER_SETUP, | 5534 | if (test_bit(BT_SK_DEFER_SETUP, |
| 5472 | &bt_sk(sk)->flags)) { | 5535 | &bt_sk(sk)->flags)) { |
| 5473 | struct sock *parent = bt_sk(sk)->parent; | ||
| 5474 | res = L2CAP_CR_PEND; | 5536 | res = L2CAP_CR_PEND; |
| 5475 | stat = L2CAP_CS_AUTHOR_PEND; | 5537 | stat = L2CAP_CS_AUTHOR_PEND; |
| 5476 | if (parent) | 5538 | chan->ops->defer(chan); |
| 5477 | parent->sk_data_ready(parent, 0); | ||
| 5478 | } else { | 5539 | } else { |
| 5479 | __l2cap_state_change(chan, BT_CONFIG); | 5540 | __l2cap_state_change(chan, BT_CONFIG); |
| 5480 | res = L2CAP_CR_SUCCESS; | 5541 | res = L2CAP_CR_SUCCESS; |
| @@ -5494,7 +5555,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 13 unmodified lines | |||
| 5494 | rsp.result = cpu_to_le16(res); | 5555 | rsp.result = cpu_to_le16(res); |
| 5495 | rsp.status = cpu_to_le16(stat); | 5556 | rsp.status = cpu_to_le16(stat); |
| 5496 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | 5557 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, |
| 5497 | sizeof(rsp), &rsp); | 5558 | sizeof(rsp), &rsp); |
| 5498 | 5559 | ||
| 5499 | if (!test_bit(CONF_REQ_SENT, &chan->conf_state) && | 5560 | if (!test_bit(CONF_REQ_SENT, &chan->conf_state) && |
| 5500 | res == L2CAP_CR_SUCCESS) { | 5561 | res == L2CAP_CR_SUCCESS) { |
| @@ -5519,6 +5580,12 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) · 18 unmodified lines | |||
| 5519 | int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) | 5580 | int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) |
| 5520 | { | 5581 | { |
| 5521 | struct l2cap_conn *conn = hcon->l2cap_data; | 5582 | struct l2cap_conn *conn = hcon->l2cap_data; |
| 5583 | struct l2cap_hdr *hdr; | ||
| 5584 | int len; | ||
| 5585 | |||
| 5586 | /* For AMP controller do not create l2cap conn */ | ||
| 5587 | if (!conn && hcon->hdev->dev_type != HCI_BREDR) | ||
| 5588 | goto drop; | ||
| 5522 | 5589 | ||
| 5523 | if (!conn) | 5590 | if (!conn) |
| 5524 | conn = l2cap_conn_add(hcon, 0); | 5591 | conn = l2cap_conn_add(hcon, 0); |
| @@ -5528,10 +5595,10 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 3 unmodified lines | |||
| 5528 | 5595 | ||
| 5529 | BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); | 5596 | BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); |
| 5530 | 5597 | ||
| 5531 | if (!(flags & ACL_CONT)) { | 5598 | switch (flags) { |
| 5532 | struct l2cap_hdr *hdr; | 5599 | case ACL_START: |
| 5533 | int len; | 5600 | case ACL_START_NO_FLUSH: |
| 5534 | 5601 | case ACL_COMPLETE: | |
| 5535 | if (conn->rx_len) { | 5602 | if (conn->rx_len) { |
| 5536 | BT_ERR("Unexpected start frame (len %d)", skb->len); | 5603 | BT_ERR("Unexpected start frame (len %d)", skb->len); |
| 5537 | kfree_skb(conn->rx_skb); | 5604 | kfree_skb(conn->rx_skb); |
| @@ -5560,20 +5627,22 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 22 unmodified lines | |||
| 5560 | 5627 | ||
| 5561 | if (skb->len > len) { | 5628 | if (skb->len > len) { |
| 5562 | BT_ERR("Frame is too long (len %d, expected len %d)", | 5629 | BT_ERR("Frame is too long (len %d, expected len %d)", |
| 5563 | skb->len, len); | 5630 | skb->len, len); |
| 5564 | l2cap_conn_unreliable(conn, ECOMM); | 5631 | l2cap_conn_unreliable(conn, ECOMM); |
| 5565 | goto drop; | 5632 | goto drop; |
| 5566 | } | 5633 | } |
| 5567 | 5634 | ||
| 5568 | /* Allocate skb for the complete frame (with header) */ | 5635 | /* Allocate skb for the complete frame (with header) */ |
| 5569 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); | 5636 | conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL); |
| 5570 | if (!conn->rx_skb) | 5637 | if (!conn->rx_skb) |
| 5571 | goto drop; | 5638 | goto drop; |
| 5572 | 5639 | ||
| 5573 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), | 5640 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), |
| 5574 | skb->len); | 5641 | skb->len); |
| 5575 | conn->rx_len = len - skb->len; | 5642 | conn->rx_len = len - skb->len; |
| 5576 | } else { | 5643 | break; |
| 5644 | |||
| 5645 | case ACL_CONT: | ||
| 5577 | BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len); | 5646 | BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len); |
| 5578 | 5647 | ||
| 5579 | if (!conn->rx_len) { | 5648 | if (!conn->rx_len) { |
| @@ -5584,7 +5653,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 4 unmodified lines | |||
| 5584 | 5653 | ||
| 5585 | if (skb->len > conn->rx_len) { | 5654 | if (skb->len > conn->rx_len) { |
| 5586 | BT_ERR("Fragment is too long (len %d, expected %d)", | 5655 | BT_ERR("Fragment is too long (len %d, expected %d)", |
| 5587 | skb->len, conn->rx_len); | 5656 | skb->len, conn->rx_len); |
| 5588 | kfree_skb(conn->rx_skb); | 5657 | kfree_skb(conn->rx_skb); |
| 5589 | conn->rx_skb = NULL; | 5658 | conn->rx_skb = NULL; |
| 5590 | conn->rx_len = 0; | 5659 | conn->rx_len = 0; |
| @@ -5593,7 +5662,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 2 unmodified lines | |||
| 5593 | } | 5662 | } |
| 5594 | 5663 | ||
| 5595 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), | 5664 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), |
| 5596 | skb->len); | 5665 | skb->len); |
| 5597 | conn->rx_len -= skb->len; | 5666 | conn->rx_len -= skb->len; |
| 5598 | 5667 | ||
| 5599 | if (!conn->rx_len) { | 5668 | if (!conn->rx_len) { |
| @@ -5601,6 +5670,7 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) · 1 unmodified line | |||
| 5601 | l2cap_recv_frame(conn, conn->rx_skb); | 5670 | l2cap_recv_frame(conn, conn->rx_skb); |
| 5602 | conn->rx_skb = NULL; | 5671 | conn->rx_skb = NULL; |
| 5603 | } | 5672 | } |
| 5673 | break; | ||
| 5604 | } | 5674 | } |
| 5605 | 5675 | ||
| 5606 | drop: | 5676 | drop: |
| @@ -5617,12 +5687,11 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) · 10 unmodified lines | |||
| 5617 | list_for_each_entry(c, &chan_list, global_l) { | 5687 | list_for_each_entry(c, &chan_list, global_l) { |
| 5618 | struct sock *sk = c->sk; | 5688 | struct sock *sk = c->sk; |
| 5619 | 5689 | ||
| 5620 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", | 5690 | seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", |
| 5621 | batostr(&bt_sk(sk)->src), | 5691 | &bt_sk(sk)->src, &bt_sk(sk)->dst, |
| 5622 | batostr(&bt_sk(sk)->dst), | 5692 | c->state, __le16_to_cpu(c->psm), |
| 5623 | c->state, __le16_to_cpu(c->psm), | 5693 | c->scid, c->dcid, c->imtu, c->omtu, |
| 5624 | c->scid, c->dcid, c->imtu, c->omtu, | 5694 | c->sec_level, c->mode); |
| 5625 | c->sec_level, c->mode); | ||
| 5626 | } | 5695 | } |
| 5627 | 5696 | ||
| 5628 | read_unlock(&chan_list_lock); | 5697 | read_unlock(&chan_list_lock); |
| @@ -5653,8 +5722,8 @@ int __init l2cap_init(void) · 24 unmodified lines | |||
| 5653 | return err; | 5722 | return err; |
| 5654 | 5723 | ||
| 5655 | if (bt_debugfs) { | 5724 | if (bt_debugfs) { |
| 5656 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, | 5725 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, |
| 5657 | bt_debugfs, NULL, &l2cap_debugfs_fops); | 5726 | NULL, &l2cap_debugfs_fops); |
| 5658 | if (!l2cap_debugfs) | 5727 | if (!l2cap_debugfs) |
| 5659 | BT_ERR("Failed to create L2CAP debug file"); | 5728 | BT_ERR("Failed to create L2CAP debug file"); |
| 5660 | } | 5729 | } |
| @@ -40,7 +40,8 @@ static struct bt_sock_list l2cap_sk_list = { · 39 unmodified lines | |||
| 40 | 40 | ||
| 41 | static const struct proto_ops l2cap_sock_ops; | 41 | static const struct proto_ops l2cap_sock_ops; |
| 42 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); | 42 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); |
| 43 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio); | 43 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
| 44 | int proto, gfp_t prio); | ||
| 44 | 45 | ||
| 45 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | 46 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
| 46 | { | 47 | { |
| @@ -106,7 +107,8 @@ done: · 59 unmodified lines | |||
| 106 | return err; | 107 | return err; |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | 110 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, |
| 111 | int alen, int flags) | ||
| 110 | { | 112 | { |
| 111 | struct sock *sk = sock->sk; | 113 | struct sock *sk = sock->sk; |
| 112 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 114 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -134,7 +136,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al · 21 unmodified lines | |||
| 134 | lock_sock(sk); | 136 | lock_sock(sk); |
| 135 | 137 | ||
| 136 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 138 | err = bt_sock_wait_state(sk, BT_CONNECTED, |
| 137 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 139 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
| 138 | 140 | ||
| 139 | release_sock(sk); | 141 | release_sock(sk); |
| 140 | 142 | ||
| @@ -185,7 +187,8 @@ done: · 44 unmodified lines | |||
| 185 | return err; | 187 | return err; |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 188 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) | 190 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, |
| 191 | int flags) | ||
| 189 | { | 192 | { |
| 190 | DECLARE_WAITQUEUE(wait, current); | 193 | DECLARE_WAITQUEUE(wait, current); |
| 191 | struct sock *sk = sock->sk, *nsk; | 194 | struct sock *sk = sock->sk, *nsk; |
| @@ -241,7 +244,8 @@ done: · 49 unmodified lines | |||
| 241 | return err; | 244 | return err; |
| 242 | } | 245 | } |
| 243 | 246 | ||
| 244 | static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) | 247 | static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, |
| 248 | int *len, int peer) | ||
| 245 | { | 249 | { |
| 246 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | 250 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; |
| 247 | struct sock *sk = sock->sk; | 251 | struct sock *sk = sock->sk; |
| @@ -266,7 +270,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l · 18 unmodified lines | |||
| 266 | return 0; | 270 | return 0; |
| 267 | } | 271 | } |
| 268 | 272 | ||
| 269 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | 273 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, |
| 274 | char __user *optval, int __user *optlen) | ||
| 270 | { | 275 | { |
| 271 | struct sock *sk = sock->sk; | 276 | struct sock *sk = sock->sk; |
| 272 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 277 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -309,7 +314,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us · 36 unmodified lines | |||
| 309 | break; | 314 | break; |
| 310 | case BT_SECURITY_HIGH: | 315 | case BT_SECURITY_HIGH: |
| 311 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | | 316 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | |
| 312 | L2CAP_LM_SECURE; | 317 | L2CAP_LM_SECURE; |
| 313 | break; | 318 | break; |
| 314 | default: | 319 | default: |
| 315 | opt = 0; | 320 | opt = 0; |
| @@ -353,7 +358,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us · 37 unmodified lines | |||
| 353 | return err; | 358 | return err; |
| 354 | } | 359 | } |
| 355 | 360 | ||
| 356 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | 361 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, |
| 362 | char __user *optval, int __user *optlen) | ||
| 357 | { | 363 | { |
| 358 | struct sock *sk = sock->sk; | 364 | struct sock *sk = sock->sk; |
| 359 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 365 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -377,19 +383,20 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch · 17 unmodified lines | |||
| 377 | switch (optname) { | 383 | switch (optname) { |
| 378 | case BT_SECURITY: | 384 | case BT_SECURITY: |
| 379 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && | 385 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && |
| 380 | chan->chan_type != L2CAP_CHAN_RAW) { | 386 | chan->chan_type != L2CAP_CHAN_RAW) { |
| 381 | err = -EINVAL; | 387 | err = -EINVAL; |
| 382 | break; | 388 | break; |
| 383 | } | 389 | } |
| 384 | 390 | ||
| 385 | memset(&sec, 0, sizeof(sec)); | 391 | memset(&sec, 0, sizeof(sec)); |
| 386 | if (chan->conn) | 392 | if (chan->conn) { |
| 387 | sec.level = chan->conn->hcon->sec_level; | 393 | sec.level = chan->conn->hcon->sec_level; |
| 388 | else | ||
| 389 | sec.level = chan->sec_level; | ||
| 390 | 394 | ||
| 391 | if (sk->sk_state == BT_CONNECTED) | 395 | if (sk->sk_state == BT_CONNECTED) |
| 392 | sec.key_size = chan->conn->hcon->enc_key_size; | 396 | sec.key_size = chan->conn->hcon->enc_key_size; |
| 397 | } else { | ||
| 398 | sec.level = chan->sec_level; | ||
| 399 | } | ||
| 393 | 400 | ||
| 394 | len = min_t(unsigned int, len, sizeof(sec)); | 401 | len = min_t(unsigned int, len, sizeof(sec)); |
| 395 | if (copy_to_user(optval, (char *) &sec, len)) | 402 | if (copy_to_user(optval, (char *) &sec, len)) |
| @@ -411,14 +418,14 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch · 15 unmodified lines | |||
| 411 | 418 | ||
| 412 | case BT_FLUSHABLE: | 419 | case BT_FLUSHABLE: |
| 413 | if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), | 420 | if (put_user(test_bit(FLAG_FLUSHABLE, &chan->flags), |
| 414 | (u32 __user *) optval)) | 421 | (u32 __user *) optval)) |
| 415 | err = -EFAULT; | 422 | err = -EFAULT; |
| 416 | 423 | ||
| 417 | break; | 424 | break; |
| 418 | 425 | ||
| 419 | case BT_POWER: | 426 | case BT_POWER: |
| 420 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | 427 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM |
| 421 | && sk->sk_type != SOCK_RAW) { | 428 | && sk->sk_type != SOCK_RAW) { |
| 422 | err = -EINVAL; | 429 | err = -EINVAL; |
| 423 | break; | 430 | break; |
| 424 | } | 431 | } |
| @@ -466,7 +473,8 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) · 41 unmodified lines | |||
| 466 | return true; | 473 | return true; |
| 467 | } | 474 | } |
| 468 | 475 | ||
| 469 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) | 476 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, |
| 477 | char __user *optval, unsigned int optlen) | ||
| 470 | { | 478 | { |
| 471 | struct sock *sk = sock->sk; | 479 | struct sock *sk = sock->sk; |
| 472 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 480 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -529,6 +537,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us · 56 unmodified lines | |||
| 529 | chan->fcs = opts.fcs; | 537 | chan->fcs = opts.fcs; |
| 530 | chan->max_tx = opts.max_tx; | 538 | chan->max_tx = opts.max_tx; |
| 531 | chan->tx_win = opts.txwin_size; | 539 | chan->tx_win = opts.txwin_size; |
| 540 | chan->flush_to = opts.flush_to; | ||
| 532 | break; | 541 | break; |
| 533 | 542 | ||
| 534 | case L2CAP_LM: | 543 | case L2CAP_LM: |
| @@ -564,7 +573,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us · 29 unmodified lines | |||
| 564 | return err; | 573 | return err; |
| 565 | } | 574 | } |
| 566 | 575 | ||
| 567 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) | 576 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, |
| 577 | char __user *optval, unsigned int optlen) | ||
| 568 | { | 578 | { |
| 569 | struct sock *sk = sock->sk; | 579 | struct sock *sk = sock->sk; |
| 570 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 580 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -587,7 +597,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 16 unmodified lines | |||
| 587 | switch (optname) { | 597 | switch (optname) { |
| 588 | case BT_SECURITY: | 598 | case BT_SECURITY: |
| 589 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && | 599 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && |
| 590 | chan->chan_type != L2CAP_CHAN_RAW) { | 600 | chan->chan_type != L2CAP_CHAN_RAW) { |
| 591 | err = -EINVAL; | 601 | err = -EINVAL; |
| 592 | break; | 602 | break; |
| 593 | } | 603 | } |
| @@ -601,7 +611,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 7 unmodified lines | |||
| 601 | } | 611 | } |
| 602 | 612 | ||
| 603 | if (sec.level < BT_SECURITY_LOW || | 613 | if (sec.level < BT_SECURITY_LOW || |
| 604 | sec.level > BT_SECURITY_HIGH) { | 614 | sec.level > BT_SECURITY_HIGH) { |
| 605 | err = -EINVAL; | 615 | err = -EINVAL; |
| 606 | break; | 616 | break; |
| 607 | } | 617 | } |
| @@ -627,7 +637,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 19 unmodified lines | |||
| 627 | 637 | ||
| 628 | /* or for ACL link */ | 638 | /* or for ACL link */ |
| 629 | } else if ((sk->sk_state == BT_CONNECT2 && | 639 | } else if ((sk->sk_state == BT_CONNECT2 && |
| 630 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) || | 640 | test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) || |
| 631 | sk->sk_state == BT_CONNECTED) { | 641 | sk->sk_state == BT_CONNECTED) { |
| 632 | if (!l2cap_chan_check_security(chan)) | 642 | if (!l2cap_chan_check_security(chan)) |
| 633 | set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); | 643 | set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); |
| @@ -684,7 +694,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 50 unmodified lines | |||
| 684 | 694 | ||
| 685 | case BT_POWER: | 695 | case BT_POWER: |
| 686 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && | 696 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED && |
| 687 | chan->chan_type != L2CAP_CHAN_RAW) { | 697 | chan->chan_type != L2CAP_CHAN_RAW) { |
| 688 | err = -EINVAL; | 698 | err = -EINVAL; |
| 689 | break; | 699 | break; |
| 690 | } | 700 | } |
| @@ -720,7 +730,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 29 unmodified lines | |||
| 720 | } | 730 | } |
| 721 | 731 | ||
| 722 | if (chan->mode != L2CAP_MODE_ERTM && | 732 | if (chan->mode != L2CAP_MODE_ERTM && |
| 723 | chan->mode != L2CAP_MODE_STREAMING) { | 733 | chan->mode != L2CAP_MODE_STREAMING) { |
| 724 | err = -EOPNOTSUPP; | 734 | err = -EOPNOTSUPP; |
| 725 | break; | 735 | break; |
| 726 | } | 736 | } |
| @@ -737,7 +747,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch · 10 unmodified lines | |||
| 737 | return err; | 747 | return err; |
| 738 | } | 748 | } |
| 739 | 749 | ||
| 740 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) | 750 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, |
| 751 | struct msghdr *msg, size_t len) | ||
| 741 | { | 752 | { |
| 742 | struct sock *sk = sock->sk; | 753 | struct sock *sk = sock->sk; |
| 743 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 754 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
| @@ -762,7 +773,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms · 18 unmodified lines | |||
| 762 | return err; | 773 | return err; |
| 763 | } | 774 | } |
| 764 | 775 | ||
| 765 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | 776 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
| 777 | struct msghdr *msg, size_t len, int flags) | ||
| 766 | { | 778 | { |
| 767 | struct sock *sk = sock->sk; | 779 | struct sock *sk = sock->sk; |
| 768 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 780 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
| @@ -866,7 +878,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) · 97 unmodified lines | |||
| 866 | 878 | ||
| 867 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | 879 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) |
| 868 | err = bt_sock_wait_state(sk, BT_CLOSED, | 880 | err = bt_sock_wait_state(sk, BT_CLOSED, |
| 869 | sk->sk_lingertime); | 881 | sk->sk_lingertime); |
| 870 | } | 882 | } |
| 871 | 883 | ||
| 872 | if (!err && sk->sk_err) | 884 | if (!err && sk->sk_err) |
| @@ -930,7 +942,7 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) · 57 unmodified lines | |||
| 930 | } | 942 | } |
| 931 | 943 | ||
| 932 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, | 944 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, |
| 933 | GFP_ATOMIC); | 945 | GFP_ATOMIC); |
| 934 | if (!sk) | 946 | if (!sk) |
| 935 | return NULL; | 947 | return NULL; |
| 936 | 948 | ||
| @@ -938,6 +950,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) · 1 unmodified line | |||
| 938 | 950 | ||
| 939 | l2cap_sock_init(sk, parent); | 951 | l2cap_sock_init(sk, parent); |
| 940 | 952 | ||
| 953 | bt_accept_enqueue(parent, sk); | ||
| 954 | |||
| 941 | return l2cap_pi(sk)->chan; | 955 | return l2cap_pi(sk)->chan; |
| 942 | } | 956 | } |
| 943 | 957 | ||
| @@ -1068,6 +1082,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) · 124 unmodified lines | |||
| 1068 | release_sock(sk); | 1082 | release_sock(sk); |
| 1069 | } | 1083 | } |
| 1070 | 1084 | ||
| 1085 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) | ||
| 1086 | { | ||
| 1087 | struct sock *sk = chan->data; | ||
| 1088 | struct sock *parent = bt_sk(sk)->parent; | ||
| 1089 | |||
| 1090 | if (parent) | ||
| 1091 | parent->sk_data_ready(parent, 0); | ||
| 1092 | } | ||
| 1093 | |||
| 1071 | static struct l2cap_ops l2cap_chan_ops = { | 1094 | static struct l2cap_ops l2cap_chan_ops = { |
| 1072 | .name = "L2CAP Socket Interface", | 1095 | .name = "L2CAP Socket Interface", |
| 1073 | .new_connection = l2cap_sock_new_connection_cb, | 1096 | .new_connection = l2cap_sock_new_connection_cb, |
| @@ -1076,6 +1099,7 @@ static struct l2cap_ops l2cap_chan_ops = { · 2 unmodified lines | |||
| 1076 | .teardown = l2cap_sock_teardown_cb, | 1099 | .teardown = l2cap_sock_teardown_cb, |
| 1077 | .state_change = l2cap_sock_state_change_cb, | 1100 | .state_change = l2cap_sock_state_change_cb, |
| 1078 | .ready = l2cap_sock_ready_cb, | 1101 | .ready = l2cap_sock_ready_cb, |
| 1102 | .defer = l2cap_sock_defer_cb, | ||
| 1079 | .alloc_skb = l2cap_sock_alloc_skb_cb, | 1103 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
| 1080 | }; | 1104 | }; |
| 1081 | 1105 | ||
| @@ -1083,7 +1107,8 @@ static void l2cap_sock_destruct(struct sock *sk) · 1 unmodified line | |||
| 1083 | { | 1107 | { |
| 1084 | BT_DBG("sk %p", sk); | 1108 | BT_DBG("sk %p", sk); |
| 1085 | 1109 | ||
| 1086 | l2cap_chan_put(l2cap_pi(sk)->chan); | 1110 | if (l2cap_pi(sk)->chan) |
| 1111 | l2cap_chan_put(l2cap_pi(sk)->chan); | ||
| 1087 | if (l2cap_pi(sk)->rx_busy_skb) { | 1112 | if (l2cap_pi(sk)->rx_busy_skb) { |
| 1088 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); | 1113 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); |
| 1089 | l2cap_pi(sk)->rx_busy_skb = NULL; | 1114 | l2cap_pi(sk)->rx_busy_skb = NULL; |
| @@ -1159,7 +1184,8 @@ static struct proto l2cap_proto = { · 69 unmodified lines | |||
| 1159 | .obj_size = sizeof(struct l2cap_pinfo) | 1184 | .obj_size = sizeof(struct l2cap_pinfo) |
| 1160 | }; | 1185 | }; |
| 1161 | 1186 | ||
| 1162 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) | 1187 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
| 1188 | int proto, gfp_t prio) | ||
| 1163 | { | 1189 | { |
| 1164 | struct sock *sk; | 1190 | struct sock *sk; |
| 1165 | struct l2cap_chan *chan; | 1191 | struct l2cap_chan *chan; |
| @@ -1204,7 +1230,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, · 38 unmodified lines | |||
| 1204 | sock->state = SS_UNCONNECTED; | 1230 | sock->state = SS_UNCONNECTED; |
| 1205 | 1231 | ||
| 1206 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && | 1232 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && |
| 1207 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) | 1233 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) |
| 1208 | return -ESOCKTNOSUPPORT; | 1234 | return -ESOCKTNOSUPPORT; |
| 1209 | 1235 | ||
| 1210 | if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) | 1236 | if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) |
| @@ -1261,7 +1287,8 @@ int __init l2cap_init_sockets(void) · 50 unmodified lines | |||
| 1261 | goto error; | 1287 | goto error; |
| 1262 | } | 1288 | } |
| 1263 | 1289 | ||
| 1264 | err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, NULL); | 1290 | err = bt_procfs_init(THIS_MODULE, &init_net, "l2cap", &l2cap_sk_list, |
| 1291 | NULL); | ||
| 1265 | if (err < 0) { | 1292 | if (err < 0) { |
| 1266 | BT_ERR("Failed to create L2CAP proc file"); | 1293 | BT_ERR("Failed to create L2CAP proc file"); |
| 1267 | bt_sock_unregister(BTPROTO_L2CAP); | 1294 | bt_sock_unregister(BTPROTO_L2CAP); |
| @@ -41,20 +41,6 @@ void baswap(bdaddr_t *dst, bdaddr_t *src) · 40 unmodified lines | |||
| 41 | } | 41 | } |
| 42 | EXPORT_SYMBOL(baswap); | 42 | EXPORT_SYMBOL(baswap); |
| 43 | 43 | ||
| 44 | char *batostr(bdaddr_t *ba) | ||
| 45 | { | ||
| 46 | static char str[2][18]; | ||
| 47 | static int i = 1; | ||
| 48 | |||
| 49 | i ^= 1; | ||
| 50 | sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", | ||
| 51 | ba->b[5], ba->b[4], ba->b[3], | ||
| 52 | ba->b[2], ba->b[1], ba->b[0]); | ||
| 53 | |||
| 54 | return str[i]; | ||
| 55 | } | ||
| 56 | EXPORT_SYMBOL(batostr); | ||
| 57 | |||
| 58 | /* Bluetooth error codes to Unix errno mapping */ | 44 | /* Bluetooth error codes to Unix errno mapping */ |
| 59 | int bt_to_errno(__u16 code) | 45 | int bt_to_errno(__u16 code) |
| 60 | { | 46 | { |
| @@ -3125,6 +3125,9 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, · 3124 unmodified lines | |||
| 3125 | struct pending_cmd *cmd; | 3125 | struct pending_cmd *cmd; |
| 3126 | int err; | 3126 | int err; |
| 3127 | 3127 | ||
| 3128 | mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, | ||
| 3129 | hdev); | ||
| 3130 | |||
| 3128 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); | 3131 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); |
| 3129 | if (!cmd) | 3132 | if (!cmd) |
| 3130 | return -ENOENT; | 3133 | return -ENOENT; |
| @@ -3137,8 +3140,6 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, · 6 unmodified lines | |||
| 3137 | 3140 | ||
| 3138 | mgmt_pending_remove(cmd); | 3141 | mgmt_pending_remove(cmd); |
| 3139 | 3142 | ||
| 3140 | mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, | ||
| 3141 | hdev); | ||
| 3142 | return err; | 3143 | return err; |
| 3143 | } | 3144 | } |
| 3144 | 3145 | ||
| @@ -377,8 +377,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, · 376 unmodified lines | |||
| 377 | int err = 0; | 377 | int err = 0; |
| 378 | u8 dlci; | 378 | u8 dlci; |
| 379 | 379 | ||
| 380 | BT_DBG("dlc %p state %ld %s %s channel %d", | 380 | BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d", |
| 381 | d, d->state, batostr(src), batostr(dst), channel); | 381 | d, d->state, src, dst, channel); |
| 382 | 382 | ||
| 383 | if (channel < 1 || channel > 30) | 383 | if (channel < 1 || channel > 30) |
| 384 | return -EINVAL; | 384 | return -EINVAL; |
| @@ -676,7 +676,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, · 291 unmodified lines | |||
| 676 | struct socket *sock; | 676 | struct socket *sock; |
| 677 | struct sock *sk; | 677 | struct sock *sk; |
| 678 | 678 | ||
| 679 | BT_DBG("%s %s", batostr(src), batostr(dst)); | 679 | BT_DBG("%pMR -> %pMR", src, dst); |
| 680 | 680 | ||
| 681 | *err = rfcomm_l2sock_create(&sock); | 681 | *err = rfcomm_l2sock_create(&sock); |
| 682 | if (*err < 0) | 682 | if (*err < 0) |
| @@ -709,7 +709,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, · 26 unmodified lines | |||
| 709 | 709 | ||
| 710 | bacpy(&addr.l2_bdaddr, dst); | 710 | bacpy(&addr.l2_bdaddr, dst); |
| 711 | addr.l2_family = AF_BLUETOOTH; | 711 | addr.l2_family = AF_BLUETOOTH; |
| 712 | addr.l2_psm = cpu_to_le16(RFCOMM_PSM); | 712 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); |
| 713 | addr.l2_cid = 0; | 713 | addr.l2_cid = 0; |
| 714 | *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); | 714 | *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); |
| 715 | if (*err == 0 || *err == -EINPROGRESS) | 715 | if (*err == 0 || *err == -EINPROGRESS) |
| @@ -1987,7 +1987,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) · 1271 unmodified lines | |||
| 1987 | /* Bind socket */ | 1987 | /* Bind socket */ |
| 1988 | bacpy(&addr.l2_bdaddr, ba); | 1988 | bacpy(&addr.l2_bdaddr, ba); |
| 1989 | addr.l2_family = AF_BLUETOOTH; | 1989 | addr.l2_family = AF_BLUETOOTH; |
| 1990 | addr.l2_psm = cpu_to_le16(RFCOMM_PSM); | 1990 | addr.l2_psm = __constant_cpu_to_le16(RFCOMM_PSM); |
| 1991 | addr.l2_cid = 0; | 1991 | addr.l2_cid = 0; |
| 1992 | err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); | 1992 | err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); |
| 1993 | if (err < 0) { | 1993 | if (err < 0) { |
| @@ -2125,11 +2125,10 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) · 131 unmodified lines | |||
| 2125 | list_for_each_entry(d, &s->dlcs, list) { | 2125 | list_for_each_entry(d, &s->dlcs, list) { |
| 2126 | struct sock *sk = s->sock->sk; | 2126 | struct sock *sk = s->sock->sk; |
| 2127 | 2127 | ||
| 2128 | seq_printf(f, "%s %s %ld %d %d %d %d\n", | 2128 | seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n", |
| 2129 | batostr(&bt_sk(sk)->src), | 2129 | &bt_sk(sk)->src, &bt_sk(sk)->dst, |
| 2130 | batostr(&bt_sk(sk)->dst), | 2130 | d->state, d->dlci, d->mtu, |
| 2131 | d->state, d->dlci, d->mtu, | 2131 | d->rx_credits, d->tx_credits); |
| 2132 | d->rx_credits, d->tx_credits); | ||
| 2133 | } | 2132 | } |
| 2134 | } | 2133 | } |
| 2135 | 2134 | ||
| @@ -334,7 +334,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr · 333 unmodified lines | |||
| 334 | struct sock *sk = sock->sk; | 334 | struct sock *sk = sock->sk; |
| 335 | int err = 0; | 335 | int err = 0; |
| 336 | 336 | ||
| 337 | BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr)); | 337 | BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); |
| 338 | 338 | ||
| 339 | if (!addr || addr->sa_family != AF_BLUETOOTH) | 339 | if (!addr || addr->sa_family != AF_BLUETOOTH) |
| 340 | return -EINVAL; | 340 | return -EINVAL; |
| @@ -975,10 +975,9 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) · 634 unmodified lines | |||
| 975 | read_lock(&rfcomm_sk_list.lock); | 975 | read_lock(&rfcomm_sk_list.lock); |
| 976 | 976 | ||
| 977 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | 977 | sk_for_each(sk, node, &rfcomm_sk_list.head) { |
| 978 | seq_printf(f, "%s %s %d %d\n", | 978 | seq_printf(f, "%pMR %pMR %d %d\n", |
| 979 | batostr(&bt_sk(sk)->src), | 979 | &bt_sk(sk)->src, &bt_sk(sk)->dst, |
| 980 | batostr(&bt_sk(sk)->dst), | 980 | sk->sk_state, rfcomm_pi(sk)->channel); |
| 981 | sk->sk_state, rfcomm_pi(sk)->channel); | ||
| 982 | } | 981 | } |
| 983 | 982 | ||
| 984 | read_unlock(&rfcomm_sk_list.lock); | 983 | read_unlock(&rfcomm_sk_list.lock); |
| @@ -166,7 +166,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) · 165 unmodified lines | |||
| 166 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) | 166 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) |
| 167 | { | 167 | { |
| 168 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); | 168 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); |
| 169 | return sprintf(buf, "%s\n", batostr(&dev->dst)); | 169 | return sprintf(buf, "%pMR\n", &dev->dst); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf) | 172 | 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) · 490 unmodified lines | |||
| 663 | if (!dev) | 663 | if (!dev) |
| 664 | return -ENODEV; | 664 | return -ENODEV; |
| 665 | 665 | ||
| 666 | BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), | 666 | BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, |
| 667 | dev->channel, dev->port.count); | 667 | dev->channel, dev->port.count); |
| 668 | 668 | ||
| 669 | spin_lock_irqsave(&dev->port.lock, flags); | 669 | spin_lock_irqsave(&dev->port.lock, flags); |
| 670 | if (++dev->port.count > 1) { | 670 | if (++dev->port.count > 1) { |
| @@ -172,7 +172,7 @@ static int sco_connect(struct sock *sk) · 171 unmodified lines | |||
| 172 | struct hci_dev *hdev; | 172 | struct hci_dev *hdev; |
| 173 | int err, type; | 173 | int err, type; |
| 174 | 174 | ||
| 175 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); | 175 | BT_DBG("%pMR -> %pMR", src, dst); |
| 176 | 176 | ||
| 177 | hdev = hci_get_route(dst, src); | 177 | hdev = hci_get_route(dst, src); |
| 178 | if (!hdev) | 178 | if (!hdev) |
| @@ -460,7 +460,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le · 281 unmodified lines | |||
| 460 | struct sock *sk = sock->sk; | 460 | struct sock *sk = sock->sk; |
| 461 | int err = 0; | 461 | int err = 0; |
| 462 | 462 | ||
| 463 | BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr)); | 463 | BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr); |
| 464 | 464 | ||
| 465 | if (!addr || addr->sa_family != AF_BLUETOOTH) | 465 | if (!addr || addr->sa_family != AF_BLUETOOTH) |
| 466 | return -EINVAL; | 466 | return -EINVAL; |
| @@ -893,7 +893,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) · 426 unmodified lines | |||
| 893 | struct hlist_node *node; | 893 | struct hlist_node *node; |
| 894 | int lm = 0; | 894 | int lm = 0; |
| 895 | 895 | ||
| 896 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 896 | BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); |
| 897 | 897 | ||
| 898 | /* Find listening sockets */ | 898 | /* Find listening sockets */ |
| 899 | read_lock(&sco_sk_list.lock); | 899 | read_lock(&sco_sk_list.lock); |
| @@ -914,7 +914,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) · 14 unmodified lines | |||
| 914 | 914 | ||
| 915 | void sco_connect_cfm(struct hci_conn *hcon, __u8 status) | 915 | void sco_connect_cfm(struct hci_conn *hcon, __u8 status) |
| 916 | { | 916 | { |
| 917 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 917 | BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); |
| 918 | if (!status) { | 918 | if (!status) { |
| 919 | struct sco_conn *conn; | 919 | struct sco_conn *conn; |
| 920 | 920 | ||
| @@ -959,8 +959,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p) · 38 unmodified lines | |||
| 959 | read_lock(&sco_sk_list.lock); | 959 | read_lock(&sco_sk_list.lock); |
| 960 | 960 | ||
| 961 | sk_for_each(sk, node, &sco_sk_list.head) { | 961 | sk_for_each(sk, node, &sco_sk_list.head) { |
| 962 | seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), | 962 | seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, |
| 963 | batostr(&bt_sk(sk)->dst), sk->sk_state); | 963 | &bt_sk(sk)->dst, sk->sk_state); |
| 964 | } | 964 | } |
| 965 | 965 | ||
| 966 | read_unlock(&sco_sk_list.lock); | 966 | read_unlock(&sco_sk_list.lock); |
| @@ -167,7 +167,7 @@ static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, · 166 unmodified lines | |||
| 167 | 167 | ||
| 168 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 168 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
| 169 | lh->len = cpu_to_le16(sizeof(code) + dlen); | 169 | lh->len = cpu_to_le16(sizeof(code) + dlen); |
| 170 | lh->cid = cpu_to_le16(L2CAP_CID_SMP); | 170 | lh->cid = __constant_cpu_to_le16(L2CAP_CID_SMP); |
| 171 | 171 | ||
| 172 | memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); | 172 | memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); |
| 173 | 173 | ||
| @@ -248,7 +248,7 @@ config MAC80211_MHWMP_DEBUG · 247 unmodified lines | |||
| 248 | Do not select this option. | 248 | Do not select this option. |
| 249 | 249 | ||
| 250 | config MAC80211_MESH_SYNC_DEBUG | 250 | config MAC80211_MESH_SYNC_DEBUG |
| 251 | bool "Verbose mesh mesh synchronization debugging" | 251 | bool "Verbose mesh synchronization debugging" |
| 252 | depends on MAC80211_DEBUG_MENU | 252 | depends on MAC80211_DEBUG_MENU |
| 253 | depends on MAC80211_MESH | 253 | depends on MAC80211_MESH |
| 254 | ---help--- | 254 | ---help--- |
| @@ -8,6 +8,7 @@ mac80211-y := \ · 7 unmodified lines | |||
| 8 | wpa.o \ | 8 | wpa.o \ |
| 9 | scan.o offchannel.o \ | 9 | scan.o offchannel.o \ |
| 10 | ht.o agg-tx.o agg-rx.o \ | 10 | ht.o agg-tx.o agg-rx.o \ |
| 11 | vht.o \ | ||
| 11 | ibss.o \ | 12 | ibss.o \ |
| 12 | iface.o \ | 13 | iface.o \ |
| 13 | rate.o \ | 14 | rate.o \ |
| @@ -126,3 +126,20 @@ void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) · 125 unmodified lines | |||
| 126 | { | 126 | { |
| 127 | crypto_free_cipher(tfm); | 127 | crypto_free_cipher(tfm); |
| 128 | } | 128 | } |
| 129 | |||
| 130 | void ieee80211_aes_cmac_calculate_k1_k2(struct ieee80211_key_conf *keyconf, | ||
| 131 | u8 *k1, u8 *k2) | ||
| 132 | { | ||
| 133 | u8 l[AES_BLOCK_SIZE] = {}; | ||
| 134 | struct ieee80211_key *key = | ||
| 135 | container_of(keyconf, struct ieee80211_key, conf); | ||
| 136 | |||
| 137 | crypto_cipher_encrypt_one(key->u.aes_cmac.tfm, l, l); | ||
| 138 | |||
| 139 | memcpy(k1, l, AES_BLOCK_SIZE); | ||
| 140 | gf_mulx(k1); | ||
| 141 | |||
| 142 | memcpy(k2, k1, AES_BLOCK_SIZE); | ||
| 143 | gf_mulx(k2); | ||
| 144 | } | ||
| 145 | EXPORT_SYMBOL(ieee80211_aes_cmac_calculate_k1_k2); | ||
| @@ -372,10 +372,11 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, · 371 unmodified lines | |||
| 372 | 372 | ||
| 373 | static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx) | 373 | static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx) |
| 374 | { | 374 | { |
| 375 | enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata); | ||
| 376 | |||
| 375 | if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { | 377 | if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { |
| 376 | struct ieee80211_supported_band *sband; | 378 | struct ieee80211_supported_band *sband; |
| 377 | sband = sta->local->hw.wiphy->bands[ | 379 | sband = sta->local->hw.wiphy->bands[band]; |
| 378 | sta->local->oper_channel->band]; | ||
| 379 | rate->legacy = sband->bitrates[idx].bitrate; | 380 | rate->legacy = sband->bitrates[idx].bitrate; |
| 380 | } else | 381 | } else |
| 381 | rate->mcs = idx; | 382 | rate->mcs = idx; |
| @@ -532,6 +533,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, · 150 unmodified lines | |||
| 532 | u64 *data) | 533 | u64 *data) |
| 533 | { | 534 | { |
| 534 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 535 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 536 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 537 | struct ieee80211_channel *channel; | ||
| 535 | struct sta_info *sta; | 538 | struct sta_info *sta; |
| 536 | struct ieee80211_local *local = sdata->local; | 539 | struct ieee80211_local *local = sdata->local; |
| 537 | struct station_info sinfo; | 540 | struct station_info sinfo; |
| @@ -607,19 +610,26 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, · 69 unmodified lines | |||
| 607 | do_survey: | 610 | do_survey: |
| 608 | i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; | 611 | i = STA_STATS_LEN - STA_STATS_SURVEY_LEN; |
| 609 | /* Get survey stats for current channel */ | 612 | /* Get survey stats for current channel */ |
| 610 | q = 0; | 613 | survey.filled = 0; |
| 611 | while (true) { | ||
| 612 | survey.filled = 0; | ||
| 613 | if (drv_get_survey(local, q, &survey) != 0) { | ||
| 614 | survey.filled = 0; | ||
| 615 | break; | ||
| 616 | } | ||
| 617 | 614 | ||
| 618 | if (survey.channel && | 615 | rcu_read_lock(); |
| 619 | (local->oper_channel->center_freq == | 616 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
| 620 | survey.channel->center_freq)) | 617 | if (chanctx_conf) |
| 621 | break; | 618 | channel = chanctx_conf->channel; |
| 622 | q++; | 619 | else |
| 620 | channel = NULL; | ||
| 621 | rcu_read_unlock(); | ||
| 622 | |||
| 623 | if (channel) { | ||
| 624 | q = 0; | ||
| 625 | do { | ||
| 626 | survey.filled = 0; | ||
| 627 | if (drv_get_survey(local, q, &survey) != 0) { | ||
| 628 | survey.filled = 0; | ||
| 629 | break; | ||
| 630 | } | ||
| 631 | q++; | ||
| 632 | } while (channel != survey.channel); | ||
| 623 | } | 633 | } |
| 624 | 634 | ||
| 625 | if (survey.filled) | 635 | if (survey.filled) |
| @@ -724,47 +734,42 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, · 98 unmodified lines | |||
| 724 | return ret; | 734 | return ret; |
| 725 | } | 735 | } |
| 726 | 736 | ||
| 727 | static int ieee80211_set_channel(struct wiphy *wiphy, | 737 | static int ieee80211_set_monitor_channel(struct wiphy *wiphy, |
| 728 | struct net_device *netdev, | 738 | struct ieee80211_channel *chan, |
| 729 | struct ieee80211_channel *chan, | 739 | enum nl80211_channel_type channel_type) |
| 730 | enum nl80211_channel_type channel_type) | ||
| 731 | { | 740 | { |
| 732 | struct ieee80211_local *local = wiphy_priv(wiphy); | 741 | struct ieee80211_local *local = wiphy_priv(wiphy); |
| 733 | struct ieee80211_sub_if_data *sdata = NULL; | 742 | struct ieee80211_sub_if_data *sdata; |
| 734 | 743 | int ret = 0; | |
| 735 | if (netdev) | ||
| 736 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
| 737 | |||
| 738 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
| 739 | case CHAN_MODE_HOPPING: | ||
| 740 | return -EBUSY; | ||
| 741 | case CHAN_MODE_FIXED: | ||
| 742 | if (local->oper_channel != chan || | ||
| 743 | (!sdata && local->_oper_channel_type != channel_type)) | ||
| 744 | return -EBUSY; | ||
| 745 | if (!sdata && local->_oper_channel_type == channel_type) | ||
| 746 | return 0; | ||
| 747 | break; | ||
| 748 | case CHAN_MODE_UNDEFINED: | ||
| 749 | break; | ||
| 750 | } | ||
| 751 | |||
| 752 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) | ||
| 753 | return -EBUSY; | ||
| 754 | 744 | ||
| 755 | local->oper_channel = chan; | 745 | if (local->monitor_channel == chan && |
| 746 | local->monitor_channel_type == channel_type) | ||
| 747 | return 0; | ||
| 756 | 748 | ||
| 757 | /* auto-detects changes */ | 749 | mutex_lock(&local->iflist_mtx); |
| 758 | ieee80211_hw_config(local, 0); | 750 | if (local->use_chanctx) { |
| 751 | sdata = rcu_dereference_protected( | ||
| 752 | local->monitor_sdata, | ||
| 753 | lockdep_is_held(&local->iflist_mtx)); | ||
| 754 | if (sdata) { | ||
| 755 | ieee80211_vif_release_channel(sdata); | ||
| 756 | ret = ieee80211_vif_use_channel( | ||
| 757 | sdata, chan, channel_type, | ||
| 758 | IEEE80211_CHANCTX_EXCLUSIVE); | ||
| 759 | } | ||
| 760 | } else if (local->open_count == local->monitors) { | ||
| 761 | local->_oper_channel = chan; | ||
| 762 | local->_oper_channel_type = channel_type; | ||
| 763 | ieee80211_hw_config(local, 0); | ||
| 764 | } | ||
| 759 | 765 | ||
| 760 | return 0; | 766 | if (ret == 0) { |
| 761 | } | 767 | local->monitor_channel = chan; |
| 768 | local->monitor_channel_type = channel_type; | ||
| 769 | } | ||
| 770 | mutex_unlock(&local->iflist_mtx); | ||
| 762 | 771 | ||
| 763 | static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | 772 | return ret; |
| 764 | struct ieee80211_channel *chan, | ||
| 765 | enum nl80211_channel_type channel_type) | ||
| 766 | { | ||
| 767 | return ieee80211_set_channel(wiphy, NULL, chan, channel_type); | ||
| 768 | } | 773 | } |
| 769 | 774 | ||
| 770 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | 775 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, |
| @@ -879,8 +884,13 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, · 108 unmodified lines | |||
| 879 | if (old) | 884 | if (old) |
| 880 | return -EALREADY; | 885 | return -EALREADY; |
| 881 | 886 | ||
| 882 | err = ieee80211_set_channel(wiphy, dev, params->channel, | 887 | /* TODO: make hostapd tell us what it wants */ |
| 883 | params->channel_type); | 888 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
| 889 | sdata->needed_rx_chains = sdata->local->rx_chains; | ||
| 890 | |||
| 891 | err = ieee80211_vif_use_channel(sdata, params->channel, | ||
| 892 | params->channel_type, | ||
| 893 | IEEE80211_CHANCTX_SHARED); | ||
| 884 | if (err) | 894 | if (err) |
| 885 | return err; | 895 | return err; |
| 886 | 896 | ||
| @@ -963,6 +973,8 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) · 76 unmodified lines | |||
| 963 | sta_info_flush(sdata->local, sdata); | 973 | sta_info_flush(sdata->local, sdata); |
| 964 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 974 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
| 965 | 975 | ||
| 976 | ieee80211_vif_release_channel(sdata); | ||
| 977 | |||
| 966 | return 0; | 978 | return 0; |
| 967 | } | 979 | } |
| 968 | 980 | ||
| @@ -1019,9 +1031,10 @@ static int sta_apply_parameters(struct ieee80211_local *local, · 50 unmodified lines | |||
| 1019 | int i, j; | 1031 | int i, j; |
| 1020 | struct ieee80211_supported_band *sband; | 1032 | struct ieee80211_supported_band *sband; |
| 1021 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1033 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 1034 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
| 1022 | u32 mask, set; | 1035 | u32 mask, set; |
| 1023 | 1036 | ||
| 1024 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 1037 | sband = local->hw.wiphy->bands[band]; |
| 1025 | 1038 | ||
| 1026 | mask = params->sta_flags_mask; | 1039 | mask = params->sta_flags_mask; |
| 1027 | set = params->sta_flags_set; | 1040 | set = params->sta_flags_set; |
| @@ -1136,7 +1149,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, · 108 unmodified lines | |||
| 1136 | rates |= BIT(j); | 1149 | rates |= BIT(j); |
| 1137 | } | 1150 | } |
| 1138 | } | 1151 | } |
| 1139 | sta->sta.supp_rates[local->oper_channel->band] = rates; | 1152 | sta->sta.supp_rates[band] = rates; |
| 1140 | } | 1153 | } |
| 1141 | 1154 | ||
| 1142 | if (params->ht_capa) | 1155 | if (params->ht_capa) |
| @@ -1144,6 +1157,11 @@ static int sta_apply_parameters(struct ieee80211_local *local, · 1 unmodified line | |||
| 1144 | params->ht_capa, | 1157 | params->ht_capa, |
| 1145 | &sta->sta.ht_cap); | 1158 | &sta->sta.ht_cap); |
| 1146 | 1159 | ||
| 1160 | if (params->vht_capa) | ||
| 1161 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | ||
| 1162 | params->vht_capa, | ||
| 1163 | &sta->sta.vht_cap); | ||
| 1164 | |||
| 1147 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1165 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
| 1148 | #ifdef CONFIG_MAC80211_MESH | 1166 | #ifdef CONFIG_MAC80211_MESH |
| 1149 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) | 1167 | if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED) |
| @@ -1664,8 +1682,13 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, · 514 unmodified lines | |||
| 1664 | if (err) | 1682 | if (err) |
| 1665 | return err; | 1683 | return err; |
| 1666 | 1684 | ||
| 1667 | err = ieee80211_set_channel(wiphy, dev, setup->channel, | 1685 | /* can mesh use other SMPS modes? */ |
| 1668 | setup->channel_type); | 1686 | sdata->smps_mode = IEEE80211_SMPS_OFF; |
| 1687 | sdata->needed_rx_chains = sdata->local->rx_chains; | ||
| 1688 | |||
| 1689 | err = ieee80211_vif_use_channel(sdata, setup->channel, | ||
| 1690 | setup->channel_type, | ||
| 1691 | IEEE80211_CHANCTX_SHARED); | ||
| 1669 | if (err) | 1692 | if (err) |
| 1670 | return err; | 1693 | return err; |
| 1671 | 1694 | ||
| @@ -1679,6 +1702,7 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev) · 7 unmodified lines | |||
| 1679 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1702 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1680 | 1703 | ||
| 1681 | ieee80211_stop_mesh(sdata); | 1704 | ieee80211_stop_mesh(sdata); |
| 1705 | ieee80211_vif_release_channel(sdata); | ||
| 1682 | 1706 | ||
| 1683 | return 0; | 1707 | return 0; |
| 1684 | } | 1708 | } |
| @@ -1688,10 +1712,14 @@ static int ieee80211_change_bss(struct wiphy *wiphy, · 3 unmodified lines | |||
| 1688 | struct net_device *dev, | 1712 | struct net_device *dev, |
| 1689 | struct bss_parameters *params) | 1713 | struct bss_parameters *params) |
| 1690 | { | 1714 | { |
| 1691 | struct ieee80211_sub_if_data *sdata; | 1715 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1716 | enum ieee80211_band band; | ||
| 1692 | u32 changed = 0; | 1717 | u32 changed = 0; |
| 1693 | 1718 | ||
| 1694 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1719 | if (!rtnl_dereference(sdata->u.ap.beacon)) |
| 1720 | return -ENOENT; | ||
| 1721 | |||
| 1722 | band = ieee80211_get_sdata_band(sdata); | ||
| 1695 | 1723 | ||
| 1696 | if (params->use_cts_prot >= 0) { | 1724 | if (params->use_cts_prot >= 0) { |
| 1697 | sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; | 1725 | sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot; |
| @@ -1704,7 +1732,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, · 6 unmodified lines | |||
| 1704 | } | 1732 | } |
| 1705 | 1733 | ||
| 1706 | if (!sdata->vif.bss_conf.use_short_slot && | 1734 | if (!sdata->vif.bss_conf.use_short_slot && |
| 1707 | sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) { | 1735 | band == IEEE80211_BAND_5GHZ) { |
| 1708 | sdata->vif.bss_conf.use_short_slot = true; | 1736 | sdata->vif.bss_conf.use_short_slot = true; |
| 1709 | changed |= BSS_CHANGED_ERP_SLOT; | 1737 | changed |= BSS_CHANGED_ERP_SLOT; |
| 1710 | } | 1738 | } |
| @@ -1718,9 +1746,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, · 7 unmodified lines | |||
| 1718 | if (params->basic_rates) { | 1746 | if (params->basic_rates) { |
| 1719 | int i, j; | 1747 | int i, j; |
| 1720 | u32 rates = 0; | 1748 | u32 rates = 0; |
| 1721 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1749 | struct ieee80211_supported_band *sband = wiphy->bands[band]; |
| 1722 | struct ieee80211_supported_band *sband = | ||
| 1723 | wiphy->bands[local->oper_channel->band]; | ||
| 1724 | 1750 | ||
| 1725 | for (i = 0; i < params->basic_rates_len; i++) { | 1751 | for (i = 0; i < params->basic_rates_len; i++) { |
| 1726 | int rate = (params->basic_rates[i] & 0x7f) * 5; | 1752 | int rate = (params->basic_rates[i] & 0x7f) * 5; |
| @@ -1829,7 +1855,16 @@ static int ieee80211_scan(struct wiphy *wiphy, · 102 unmodified lines | |||
| 1829 | * beaconing hasn't been configured yet | 1855 | * beaconing hasn't been configured yet |
| 1830 | */ | 1856 | */ |
| 1831 | case NL80211_IFTYPE_AP: | 1857 | case NL80211_IFTYPE_AP: |
| 1832 | if (sdata->u.ap.beacon) | 1858 | /* |
| 1859 | * If the scan has been forced (and the driver supports | ||
| 1860 | * forcing), don't care about being beaconing already. | ||
| 1861 | * This will create problems to the attached stations (e.g. all | ||
| 1862 | * the frames sent while scanning on other channel will be | ||
| 1863 | * lost) | ||
| 1864 | */ | ||
| 1865 | if (sdata->u.ap.beacon && | ||
| 1866 | (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || | ||
| 1867 | !(req->flags & NL80211_SCAN_FLAG_AP))) | ||
| 1833 | return -EOPNOTSUPP; | 1868 | return -EOPNOTSUPP; |
| 1834 | break; | 1869 | break; |
| 1835 | default: | 1870 | default: |
| @@ -1872,20 +1907,6 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, · 36 unmodified lines | |||
| 1872 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | 1907 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, |
| 1873 | struct cfg80211_assoc_request *req) | 1908 | struct cfg80211_assoc_request *req) |
| 1874 | { | 1909 | { |
| 1875 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
| 1876 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 1877 | |||
| 1878 | switch (ieee80211_get_channel_mode(local, sdata)) { | ||
| 1879 | case CHAN_MODE_HOPPING: | ||
| 1880 | return -EBUSY; | ||
| 1881 | case CHAN_MODE_FIXED: | ||
| 1882 | if (local->oper_channel == req->bss->channel) | ||
| 1883 | break; | ||
| 1884 | return -EBUSY; | ||
| 1885 | case CHAN_MODE_UNDEFINED: | ||
| 1886 | break; | ||
| 1887 | } | ||
| 1888 | |||
| 1889 | return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); | 1910 | return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); |
| 1890 | } | 1911 | } |
| 1891 | 1912 | ||
| @@ -1904,30 +1925,12 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, · 12 unmodified lines | |||
| 1904 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | 1925 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, |
| 1905 | struct cfg80211_ibss_params *params) | 1926 | struct cfg80211_ibss_params *params) |
| 1906 | { | 1927 | { |
| 1907 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1928 | return ieee80211_ibss_join(IEEE80211_DEV_TO_SUB_IF(dev), params); |
| 1908 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 1909 | |||
| 1910 | switch (ieee80211_get_channel_mode(local, sdata)) { | ||
| 1911 | case CHAN_MODE_HOPPING: | ||
| 1912 | return -EBUSY; | ||
| 1913 | case CHAN_MODE_FIXED: | ||
| 1914 | if (!params->channel_fixed) | ||
| 1915 | return -EBUSY; | ||
| 1916 | if (local->oper_channel == params->channel) | ||
| 1917 | break; | ||
| 1918 | return -EBUSY; | ||
| 1919 | case CHAN_MODE_UNDEFINED: | ||
| 1920 | break; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | return ieee80211_ibss_join(sdata, params); | ||
| 1924 | } | 1929 | } |
| 1925 | 1930 | ||
| 1926 | static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | 1931 | static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) |
| 1927 | { | 1932 | { |
| 1928 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1933 | return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); |
| 1929 | |||
| 1930 | return ieee80211_ibss_leave(sdata); | ||
| 1931 | } | 1934 | } |
| 1932 | 1935 | ||
| 1933 | static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | 1936 | static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) |
| @@ -1971,9 +1974,13 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, · 37 unmodified lines | |||
| 1971 | enum nl80211_tx_power_setting type, int mbm) | 1974 | enum nl80211_tx_power_setting type, int mbm) |
| 1972 | { | 1975 | { |
| 1973 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1976 | struct ieee80211_local *local = wiphy_priv(wiphy); |
| 1974 | struct ieee80211_channel *chan = local->oper_channel; | 1977 | struct ieee80211_channel *chan = local->_oper_channel; |
| 1975 | u32 changes = 0; | 1978 | u32 changes = 0; |
| 1976 | 1979 | ||
| 1980 | /* FIXME */ | ||
| 1981 | if (local->use_chanctx) | ||
| 1982 | return -EOPNOTSUPP; | ||
| 1983 | |||
| 1977 | switch (type) { | 1984 | switch (type) { |
| 1978 | case NL80211_TX_POWER_AUTOMATIC: | 1985 | case NL80211_TX_POWER_AUTOMATIC: |
| 1979 | local->user_power_level = -1; | 1986 | local->user_power_level = -1; |
| @@ -2067,13 +2074,12 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, · 87 unmodified lines | |||
| 2067 | 2074 | ||
| 2068 | /* | 2075 | /* |
| 2069 | * If not associated, or current association is not an HT | 2076 | * If not associated, or current association is not an HT |
| 2070 | * association, there's no need to send an action frame. | 2077 | * association, there's no need to do anything, just store |
| 2078 | * the new value until we associate. | ||
| 2071 | */ | 2079 | */ |
| 2072 | if (!sdata->u.mgd.associated || | 2080 | if (!sdata->u.mgd.associated || |
| 2073 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { | 2081 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) |
| 2074 | ieee80211_recalc_smps(sdata->local); | ||
| 2075 | return 0; | 2082 | return 0; |
| 2076 | } | ||
| 2077 | 2083 | ||
| 2078 | ap = sdata->u.mgd.associated->bssid; | 2084 | ap = sdata->u.mgd.associated->bssid; |
| 2079 | 2085 | ||
| @@ -2189,6 +2195,9 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, · 109 unmodified lines | |||
| 2189 | 2195 | ||
| 2190 | lockdep_assert_held(&local->mtx); | 2196 | lockdep_assert_held(&local->mtx); |
| 2191 | 2197 | ||
| 2198 | if (local->use_chanctx && !local->ops->remain_on_channel) | ||
| 2199 | return -EOPNOTSUPP; | ||
| 2200 | |||
| 2192 | roc = kzalloc(sizeof(*roc), GFP_KERNEL); | 2201 | roc = kzalloc(sizeof(*roc), GFP_KERNEL); |
| 2193 | if (!roc) | 2202 | if (!roc) |
| 2194 | return -ENOMEM; | 2203 | return -ENOMEM; |
| @@ -2515,10 +2524,20 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, · 320 unmodified lines | |||
| 2515 | 2524 | ||
| 2516 | /* Check if the operating channel is the requested channel */ | 2525 | /* Check if the operating channel is the requested channel */ |
| 2517 | if (!need_offchan) { | 2526 | if (!need_offchan) { |
| 2518 | need_offchan = chan != local->oper_channel; | 2527 | struct ieee80211_chanctx_conf *chanctx_conf; |
| 2519 | if (channel_type_valid && | 2528 | |
| 2520 | channel_type != local->_oper_channel_type) | 2529 | rcu_read_lock(); |
| 2530 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
| 2531 | |||
| 2532 | if (chanctx_conf) { | ||
| 2533 | need_offchan = chan != chanctx_conf->channel; | ||
| 2534 | if (channel_type_valid && | ||
| 2535 | channel_type != chanctx_conf->channel_type) | ||
| 2536 | need_offchan = true; | ||
| 2537 | } else { | ||
| 2521 | need_offchan = true; | 2538 | need_offchan = true; |
| 2539 | } | ||
| 2540 | rcu_read_unlock(); | ||
| 2522 | } | 2541 | } |
| 2523 | 2542 | ||
| 2524 | if (need_offchan && !offchan) { | 2543 | if (need_offchan && !offchan) { |
| @@ -2667,7 +2686,7 @@ static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata) · 142 unmodified lines | |||
| 2667 | u16 capab; | 2686 | u16 capab; |
| 2668 | 2687 | ||
| 2669 | capab = 0; | 2688 | capab = 0; |
| 2670 | if (local->oper_channel->band != IEEE80211_BAND_2GHZ) | 2689 | if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ) |
| 2671 | return capab; | 2690 | return capab; |
| 2672 | 2691 | ||
| 2673 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) | 2692 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) |
| @@ -2699,7 +2718,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, · 25 unmodified lines | |||
| 2699 | u16 status_code, struct sk_buff *skb) | 2718 | u16 status_code, struct sk_buff *skb) |
| 2700 | { | 2719 | { |
| 2701 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2720 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2702 | struct ieee80211_local *local = sdata->local; | 2721 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
| 2703 | struct ieee80211_tdls_data *tf; | 2722 | struct ieee80211_tdls_data *tf; |
| 2704 | 2723 | ||
| 2705 | tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); | 2724 | tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); |
| @@ -2719,10 +2738,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, · 13 unmodified lines | |||
| 2719 | tf->u.setup_req.capability = | 2738 | tf->u.setup_req.capability = |
| 2720 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2739 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
| 2721 | 2740 | ||
| 2722 | ieee80211_add_srates_ie(sdata, skb, false, | 2741 | ieee80211_add_srates_ie(sdata, skb, false, band); |
| 2723 | local->oper_channel->band); | 2742 | ieee80211_add_ext_srates_ie(sdata, skb, false, band); |
| 2724 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
| 2725 | local->oper_channel->band); | ||
| 2726 | ieee80211_tdls_add_ext_capab(skb); | 2743 | ieee80211_tdls_add_ext_capab(skb); |
| 2727 | break; | 2744 | break; |
| 2728 | case WLAN_TDLS_SETUP_RESPONSE: | 2745 | case WLAN_TDLS_SETUP_RESPONSE: |
| @@ -2735,10 +2752,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, · 6 unmodified lines | |||
| 2735 | tf->u.setup_resp.capability = | 2752 | tf->u.setup_resp.capability = |
| 2736 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2753 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
| 2737 | 2754 | ||
| 2738 | ieee80211_add_srates_ie(sdata, skb, false, | 2755 | ieee80211_add_srates_ie(sdata, skb, false, band); |
| 2739 | local->oper_channel->band); | 2756 | ieee80211_add_ext_srates_ie(sdata, skb, false, band); |
| 2740 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
| 2741 | local->oper_channel->band); | ||
| 2742 | ieee80211_tdls_add_ext_capab(skb); | 2757 | ieee80211_tdls_add_ext_capab(skb); |
| 2743 | break; | 2758 | break; |
| 2744 | case WLAN_TDLS_SETUP_CONFIRM: | 2759 | case WLAN_TDLS_SETUP_CONFIRM: |
| @@ -2776,7 +2791,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, · 31 unmodified lines | |||
| 2776 | u16 status_code, struct sk_buff *skb) | 2791 | u16 status_code, struct sk_buff *skb) |
| 2777 | { | 2792 | { |
| 2778 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2793 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2779 | struct ieee80211_local *local = sdata->local; | 2794 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
| 2780 | struct ieee80211_mgmt *mgmt; | 2795 | struct ieee80211_mgmt *mgmt; |
| 2781 | 2796 | ||
| 2782 | mgmt = (void *)skb_put(skb, 24); | 2797 | mgmt = (void *)skb_put(skb, 24); |
| @@ -2799,10 +2814,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, · 16 unmodified lines | |||
| 2799 | mgmt->u.action.u.tdls_discover_resp.capability = | 2814 | mgmt->u.action.u.tdls_discover_resp.capability = |
| 2800 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2815 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
| 2801 | 2816 | ||
| 2802 | ieee80211_add_srates_ie(sdata, skb, false, | 2817 | ieee80211_add_srates_ie(sdata, skb, false, band); |
| 2803 | local->oper_channel->band); | 2818 | ieee80211_add_ext_srates_ie(sdata, skb, false, band); |
| 2804 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
| 2805 | local->oper_channel->band); | ||
| 2806 | ieee80211_tdls_add_ext_capab(skb); | 2819 | ieee80211_tdls_add_ext_capab(skb); |
| 2807 | break; | 2820 | break; |
| 2808 | default: | 2821 | default: |
| @@ -2819,7 +2832,6 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, · 10 unmodified lines | |||
| 2819 | { | 2832 | { |
| 2820 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2833 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2821 | struct ieee80211_local *local = sdata->local; | 2834 | struct ieee80211_local *local = sdata->local; |
| 2822 | struct ieee80211_tx_info *info; | ||
| 2823 | struct sk_buff *skb = NULL; | 2835 | struct sk_buff *skb = NULL; |
| 2824 | bool send_direct; | 2836 | bool send_direct; |
| 2825 | int ret; | 2837 | int ret; |
| @@ -2845,7 +2857,6 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, · 19 unmodified lines | |||
| 2845 | if (!skb) | 2857 | if (!skb) |
| 2846 | return -ENOMEM; | 2858 | return -ENOMEM; |
| 2847 | 2859 | ||
| 2848 | info = IEEE80211_SKB_CB(skb); | ||
| 2849 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2860 | skb_reserve(skb, local->hw.extra_tx_headroom); |
| 2850 | 2861 | ||
| 2851 | switch (action_code) { | 2862 | switch (action_code) { |
| @@ -2982,12 +2993,19 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, · 130 unmodified lines | |||
| 2982 | bool qos; | 2993 | bool qos; |
| 2983 | struct ieee80211_tx_info *info; | 2994 | struct ieee80211_tx_info *info; |
| 2984 | struct sta_info *sta; | 2995 | struct sta_info *sta; |
| 2996 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
| 2997 | enum ieee80211_band band; | ||
| 2985 | 2998 | ||
| 2986 | rcu_read_lock(); | 2999 | rcu_read_lock(); |
| 3000 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
| 3001 | if (WARN_ON(!chanctx_conf)) { | ||
| 3002 | rcu_read_unlock(); | ||
| 3003 | return -EINVAL; | ||
| 3004 | } | ||
| 3005 | band = chanctx_conf->channel->band; | ||
| 2987 | sta = sta_info_get(sdata, peer); | 3006 | sta = sta_info_get(sdata, peer); |
| 2988 | if (sta) { | 3007 | if (sta) { |
| 2989 | qos = test_sta_flag(sta, WLAN_STA_WME); | 3008 | qos = test_sta_flag(sta, WLAN_STA_WME); |
| 2990 | rcu_read_unlock(); | ||
| 2991 | } else { | 3009 | } else { |
| 2992 | rcu_read_unlock(); | 3010 | rcu_read_unlock(); |
| 2993 | return -ENOLINK; | 3011 | return -ENOLINK; |
| @@ -3005,8 +3023,10 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, · 11 unmodified lines | |||
| 3005 | } | 3023 | } |
| 3006 | 3024 | ||
| 3007 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); | 3025 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + size); |
| 3008 | if (!skb) | 3026 | if (!skb) { |
| 3027 | rcu_read_unlock(); | ||
| 3009 | return -ENOMEM; | 3028 | return -ENOMEM; |
| 3029 | } | ||
| 3010 | 3030 | ||
| 3011 | skb->dev = dev; | 3031 | skb->dev = dev; |
| 3012 | 3032 | ||
| @@ -3031,8 +3051,9 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, · 18 unmodified lines | |||
| 3031 | nullfunc->qos_ctrl = cpu_to_le16(7); | 3051 | nullfunc->qos_ctrl = cpu_to_le16(7); |
| 3032 | 3052 | ||
| 3033 | local_bh_disable(); | 3053 | local_bh_disable(); |
| 3034 | ieee80211_xmit(sdata, skb); | 3054 | ieee80211_xmit(sdata, skb, band); |
| 3035 | local_bh_enable(); | 3055 | local_bh_enable(); |
| 3056 | rcu_read_unlock(); | ||
| 3036 | 3057 | ||
| 3037 | *cookie = (unsigned long) skb; | 3058 | *cookie = (unsigned long) skb; |
| 3038 | return 0; | 3059 | return 0; |
| @@ -3042,10 +3063,19 @@ static struct ieee80211_channel * · 3 unmodified lines | |||
| 3042 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, | 3063 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, |
21 more lines aren’t shown here.
This diff is large: its 475 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 355 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 523 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 196 lines aren’t shown here.
This diff is large: its 724 lines aren’t shown here.
This diff is large: its 271 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 391 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 353 lines aren’t shown here.
This diff is large: its 746 lines aren’t shown here.
This diff is large: its 880 lines aren’t shown here.
This diff is large: its 267 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 2297 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.